From 57dbda42351155c374ca31d27fc3e480cbbde2a8 Mon Sep 17 00:00:00 2001 From: CWX Date: Sat, 19 Nov 2022 21:28:18 +0000 Subject: [PATCH] buymp --- .../plugins/Faupi-HideoutArchitect.dll | Bin 21504 -> 21504 bytes .../user/mods/HideoutArchitect/LICENSE | 0 .../user/mods/HideoutArchitect/config.jsonc | 0 .../user/mods/HideoutArchitect/package.json | 4 +- .../res/icon_neededforhideout_small.png | Bin .../HideoutArchitect/res/translations.json | 0 .../HideoutArchitect/src/hideoutarchitect.ts | 0 .../HideoutArchitect/Program.cs | 6 +- .../server/dist/package.json | 4 +- Faupi-HideoutArchitect/server/package.json | 4 +- .../server/types/callbacks/BotCallbacks.d.ts | 21 ++++ .../callbacks/CustomizationCallbacks.d.ts | 14 ++- .../server/types/callbacks/DataCallbacks.d.ts | 29 +++++- .../types/callbacks/DialogueCallbacks.d.ts | 14 ++- .../server/types/callbacks/GameCallbacks.d.ts | 33 +++++- .../types/callbacks/HealthCallbacks.d.ts | 12 +++ .../types/callbacks/HideoutCallbacks.d.ts | 63 ++++++++++++ .../types/callbacks/InraidCallbacks.d.ts | 48 +++++++-- .../types/callbacks/InsuranceCallbacks.d.ts | 8 ++ .../types/callbacks/InventoryCallbacks.d.ts | 2 + .../types/callbacks/ItemEventCallbacks.d.ts | 2 + .../types/callbacks/MatchCallbacks.d.ts | 4 + .../types/callbacks/NotifierCallbacks.d.ts | 7 +- .../types/callbacks/QuestCallbacks.d.ts | 7 ++ .../types/callbacks/RagfairCallbacks.d.ts | 2 +- .../types/callbacks/TraderCallbacks.d.ts | 4 + .../types/callbacks/WeatherCallbacks.d.ts | 7 +- .../types/context/ContextVariableType.d.ts | 6 +- .../types/controllers/BotController.d.ts | 23 ++++- .../types/controllers/DialogueController.d.ts | 2 +- .../types/controllers/GameController.d.ts | 26 ++++- .../types/controllers/HideoutController.d.ts | 6 +- .../types/controllers/InraidController.d.ts | 64 +++++++++++- .../controllers/InsuranceController.d.ts | 3 +- .../controllers/InventoryController.d.ts | 29 +++++- .../types/controllers/LocationController.d.ts | 4 +- .../types/controllers/MatchController.d.ts | 4 +- .../types/controllers/RagfairController.d.ts | 11 +- .../RepeatableQuestController.d.ts | 4 +- .../types/controllers/WeatherController.d.ts | 9 +- .../server/types/generators/BotGenerator.d.ts | 57 +++++----- .../generators/BotInventoryGenerator.d.ts | 82 +++++++++++++-- .../types/generators/BotLevelGenerator.d.ts | 29 ++++++ .../types/generators/BotLootGenerator.d.ts | 21 +++- .../types/generators/BotWeaponGenerator.d.ts | 8 +- .../generators/RagfairOfferGenerator.d.ts | 48 +++++++-- .../types/generators/WeatherGenerator.d.ts | 40 +++++--- .../ExternalInventoryMagGen.d.ts | 4 +- .../types/helpers/BotDifficultyHelper.d.ts | 46 +++++++++ .../types/helpers/BotGeneratorHelper.d.ts | 66 +++++++----- .../server/types/helpers/BotHelper.d.ts | 43 +++----- .../server/types/helpers/GameEventHelper.d.ts | 11 ++ .../server/types/helpers/HideoutHelper.d.ts | 4 +- .../server/types/helpers/InventoryHelper.d.ts | 12 ++- .../server/types/helpers/ItemHelper.d.ts | 10 +- .../server/types/helpers/QuestHelper.d.ts | 97 +++++++++++++++--- .../types/helpers/RagfairServerHelper.d.ts | 10 ++ .../types/helpers/RagfairSortHelper.d.ts | 2 +- .../server/types/loaders/PreAkiModLoader.d.ts | 10 +- .../eft/bot/IGenerateBotsRequestData.d.ts | 1 + .../eft/bot/IRandomisedBotLevelResult.d.ts | 4 + .../types/models/eft/common/IGlobals.d.ts | 1 + .../models/eft/common/tables/IBotType.d.ts | 4 +- .../eft/common/tables/ITemplateItem.d.ts | 6 +- .../eft/customization/IGetSuitsResponse.d.ts | 4 + .../eft/game/IGameKeepAliveResponse.d.ts | 4 + .../eft/game/IGameLogoutResponseData.d.ts | 3 + .../models/eft/game/IGameStartResponse.d.ts | 3 + .../IOpenRandomLootContainerRequestData.d.ts | 11 ++ .../eft/itemEvent/IItemEventRouterBase.d.ts | 3 +- .../match/IStartOffineRaidRequestData.d.ts | 4 +- .../eft/notifier/ISelectProfileResponse.d.ts | 6 ++ .../models/eft/ragfair/IRagfairOffer.d.ts | 14 +-- .../models/eft/weather/IWeatherData.d.ts | 9 +- .../types/models/enums/BackendErrorCodes.d.ts | 67 ++++++++++++ .../models/enums/HideoutEventActions.d.ts | 11 ++ .../types/models/enums/ItemEventActions.d.ts | 19 ++++ .../types/models/enums/WeatherType.d.ts | 19 ++++ .../models/enums/WildSpawnTypeNumber.d.ts | 33 ++++++ .../types/models/enums/WindDirection.d.ts | 10 ++ .../models/spt/bots/BotGenerationDetails.d.ts | 16 +++ .../types/models/spt/config/IBotConfig.d.ts | 28 ++++- .../models/spt/config/IInventoryConfig.d.ts | 6 ++ .../models/spt/config/ILocaleConfig.d.ts | 7 +- .../types/models/spt/config/IPmcConfig.d.ts | 5 +- .../models/spt/config/IRagfairConfig.d.ts | 20 +++- .../spt/config/ISeasonalEventConfig.d.ts | 3 + .../models/spt/config/IWeatherConfig.d.ts | 13 ++- .../item_events/HideoutItemEventRouter.d.ts | 4 +- .../item_events/InventoryItemEventRouter.d.ts | 4 +- .../server/types/servers/HttpServer.d.ts | 4 +- .../server/types/servers/SaveServer.d.ts | 8 +- .../server/types/servers/WebSocketServer.d.ts | 14 +-- .../types/servers/http/AkiHttpListener.d.ts | 6 +- .../services/BotEquipmentFilterService.d.ts | 44 ++++++-- .../services/BotGenerationCacheService.d.ts | 26 +---- .../server/types/services/LocaleService.d.ts | 34 +++++- .../types/services/LocalisationService.d.ts | 21 ++++ .../server/types/services/PaymentService.d.ts | 6 +- .../server/types/services/PlayerService.d.ts | 4 +- .../server/types/services/PmcAiService.d.ts | 27 ----- .../types/services/ProfileFixerService.d.ts | 4 +- .../types/services/RagfairOfferService.d.ts | 7 +- .../server/types/utils/App.d.ts | 6 +- .../server/types/utils/DatabaseImporter.d.ts | 4 +- .../server/types/utils/HttpResponseUtil.d.ts | 9 +- .../server/types/utils/Logger.d.ts | 6 ++ .../server/types/utils/RandomUtil.d.ts | 6 ++ .../server/types/utils/Watermark.d.ts | 22 ++-- .../bepInEx/plugins/Faupi-MunitionsExpert.dll | Bin 12800 -> 12800 bytes .../Faupi-MunitionsExpert 1.6.7}/LICENSE.txt | 0 .../Faupi-MunitionsExpert 1.6.7}/package.json | 4 +- .../res/armorDamage.png | Bin .../res/ricochet.png | Bin .../res/translations.json | 0 .../src/MunitionsExpert.ts | 2 +- .../src/config.json | 0 .../MunitionsExpert/CachedAttributesPatch.cs | 2 +- .../MunitionsExpert/Program.cs | 8 +- .../server/dist/package.json | 4 +- .../server/dist/src/MunitionsExpert.ts | 2 +- Faupi-MunitionsExpert/server/package.json | 4 +- .../server/src/MunitionsExpert.ts | 2 +- .../server/types/callbacks/BotCallbacks.d.ts | 21 ++++ .../callbacks/CustomizationCallbacks.d.ts | 14 ++- .../server/types/callbacks/DataCallbacks.d.ts | 29 +++++- .../types/callbacks/DialogueCallbacks.d.ts | 14 ++- .../server/types/callbacks/GameCallbacks.d.ts | 33 +++++- .../types/callbacks/HealthCallbacks.d.ts | 12 +++ .../types/callbacks/HideoutCallbacks.d.ts | 63 ++++++++++++ .../types/callbacks/InraidCallbacks.d.ts | 48 +++++++-- .../types/callbacks/InsuranceCallbacks.d.ts | 8 ++ .../types/callbacks/InventoryCallbacks.d.ts | 2 + .../types/callbacks/ItemEventCallbacks.d.ts | 2 + .../types/callbacks/MatchCallbacks.d.ts | 4 + .../types/callbacks/NotifierCallbacks.d.ts | 7 +- .../types/callbacks/QuestCallbacks.d.ts | 7 ++ .../types/callbacks/RagfairCallbacks.d.ts | 2 +- .../types/callbacks/TraderCallbacks.d.ts | 4 + .../types/callbacks/WeatherCallbacks.d.ts | 7 +- .../types/context/ContextVariableType.d.ts | 6 +- .../types/controllers/BotController.d.ts | 23 ++++- .../types/controllers/DialogueController.d.ts | 2 +- .../types/controllers/GameController.d.ts | 26 ++++- .../types/controllers/HideoutController.d.ts | 6 +- .../types/controllers/InraidController.d.ts | 64 +++++++++++- .../controllers/InsuranceController.d.ts | 3 +- .../controllers/InventoryController.d.ts | 29 +++++- .../types/controllers/LocationController.d.ts | 4 +- .../types/controllers/MatchController.d.ts | 4 +- .../types/controllers/RagfairController.d.ts | 11 +- .../RepeatableQuestController.d.ts | 4 +- .../types/controllers/WeatherController.d.ts | 9 +- .../server/types/generators/BotGenerator.d.ts | 57 +++++----- .../generators/BotInventoryGenerator.d.ts | 82 +++++++++++++-- .../types/generators/BotLevelGenerator.d.ts | 29 ++++++ .../types/generators/BotLootGenerator.d.ts | 21 +++- .../types/generators/BotWeaponGenerator.d.ts | 8 +- .../generators/RagfairOfferGenerator.d.ts | 48 +++++++-- .../types/generators/WeatherGenerator.d.ts | 40 +++++--- .../ExternalInventoryMagGen.d.ts | 4 +- .../types/helpers/BotDifficultyHelper.d.ts | 46 +++++++++ .../types/helpers/BotGeneratorHelper.d.ts | 66 +++++++----- .../server/types/helpers/BotHelper.d.ts | 43 +++----- .../server/types/helpers/GameEventHelper.d.ts | 11 ++ .../server/types/helpers/HideoutHelper.d.ts | 4 +- .../server/types/helpers/InventoryHelper.d.ts | 12 ++- .../server/types/helpers/ItemHelper.d.ts | 10 +- .../server/types/helpers/QuestHelper.d.ts | 97 +++++++++++++++--- .../types/helpers/RagfairServerHelper.d.ts | 10 ++ .../types/helpers/RagfairSortHelper.d.ts | 2 +- .../server/types/loaders/PreAkiModLoader.d.ts | 10 +- .../eft/bot/IGenerateBotsRequestData.d.ts | 1 + .../eft/bot/IRandomisedBotLevelResult.d.ts | 4 + .../types/models/eft/common/IGlobals.d.ts | 1 + .../models/eft/common/tables/IBotType.d.ts | 4 +- .../eft/common/tables/ITemplateItem.d.ts | 6 +- .../eft/customization/IGetSuitsResponse.d.ts | 4 + .../eft/game/IGameKeepAliveResponse.d.ts | 4 + .../eft/game/IGameLogoutResponseData.d.ts | 3 + .../models/eft/game/IGameStartResponse.d.ts | 3 + .../IOpenRandomLootContainerRequestData.d.ts | 11 ++ .../eft/itemEvent/IItemEventRouterBase.d.ts | 3 +- .../match/IStartOffineRaidRequestData.d.ts | 4 +- .../eft/notifier/ISelectProfileResponse.d.ts | 6 ++ .../models/eft/ragfair/IRagfairOffer.d.ts | 14 +-- .../models/eft/weather/IWeatherData.d.ts | 9 +- .../types/models/enums/BackendErrorCodes.d.ts | 67 ++++++++++++ .../models/enums/HideoutEventActions.d.ts | 11 ++ .../types/models/enums/ItemEventActions.d.ts | 19 ++++ .../types/models/enums/WeatherType.d.ts | 19 ++++ .../models/enums/WildSpawnTypeNumber.d.ts | 33 ++++++ .../types/models/enums/WindDirection.d.ts | 10 ++ .../models/spt/bots/BotGenerationDetails.d.ts | 16 +++ .../types/models/spt/config/IBotConfig.d.ts | 28 ++++- .../models/spt/config/IInventoryConfig.d.ts | 6 ++ .../models/spt/config/ILocaleConfig.d.ts | 7 +- .../types/models/spt/config/IPmcConfig.d.ts | 5 +- .../models/spt/config/IRagfairConfig.d.ts | 20 +++- .../spt/config/ISeasonalEventConfig.d.ts | 3 + .../models/spt/config/IWeatherConfig.d.ts | 13 ++- .../item_events/HideoutItemEventRouter.d.ts | 4 +- .../item_events/InventoryItemEventRouter.d.ts | 4 +- .../server/types/servers/HttpServer.d.ts | 4 +- .../server/types/servers/SaveServer.d.ts | 8 +- .../server/types/servers/WebSocketServer.d.ts | 14 +-- .../types/servers/http/AkiHttpListener.d.ts | 6 +- .../services/BotEquipmentFilterService.d.ts | 44 ++++++-- .../services/BotGenerationCacheService.d.ts | 26 +---- .../server/types/services/LocaleService.d.ts | 34 +++++- .../types/services/LocalisationService.d.ts | 21 ++++ .../server/types/services/PaymentService.d.ts | 6 +- .../server/types/services/PlayerService.d.ts | 4 +- .../server/types/services/PmcAiService.d.ts | 27 ----- .../types/services/ProfileFixerService.d.ts | 4 +- .../types/services/RagfairOfferService.d.ts | 7 +- .../server/types/utils/App.d.ts | 6 +- .../server/types/utils/DatabaseImporter.d.ts | 4 +- .../server/types/utils/HttpResponseUtil.d.ts | 9 +- .../server/types/utils/Logger.d.ts | 6 ++ .../server/types/utils/RandomUtil.d.ts | 6 ++ .../server/types/utils/Watermark.d.ts | 22 ++-- .../bepInEx/plugins/KcY-SeeItemValue.dll | Bin 13312 -> 13312 bytes .../mods/KcY-SeeItemValue 1.5.0}/LICENSE.txt | 0 .../mods/KcY-SeeItemValue 1.5.0}/package.json | 4 +- .../KcY-SeeItemValue 1.5.0}/src/config.json | 0 .../mods/KcY-SeeItemValue 1.5.0}/src/mod.ts | 0 KcY-SeeItemValue/itemValue/Patches.cs | 8 +- KcY-SeeItemValue/itemValue/Program.cs | 2 +- KcY-SeeItemValue/itemValue/itemValueMod.cs | 14 +-- .../itemValue/itemValueMod.csproj | 2 +- .../itemValue/server/dist/package.json | 4 +- .../itemValue/server/package.json | 4 +- .../server/types/callbacks/BotCallbacks.d.ts | 21 ++++ .../callbacks/CustomizationCallbacks.d.ts | 14 ++- .../server/types/callbacks/DataCallbacks.d.ts | 29 +++++- .../types/callbacks/DialogueCallbacks.d.ts | 14 ++- .../server/types/callbacks/GameCallbacks.d.ts | 33 +++++- .../types/callbacks/HealthCallbacks.d.ts | 12 +++ .../types/callbacks/HideoutCallbacks.d.ts | 63 ++++++++++++ .../types/callbacks/InraidCallbacks.d.ts | 48 +++++++-- .../types/callbacks/InsuranceCallbacks.d.ts | 8 ++ .../types/callbacks/InventoryCallbacks.d.ts | 2 + .../types/callbacks/ItemEventCallbacks.d.ts | 2 + .../types/callbacks/MatchCallbacks.d.ts | 4 + .../types/callbacks/NotifierCallbacks.d.ts | 7 +- .../types/callbacks/QuestCallbacks.d.ts | 7 ++ .../types/callbacks/RagfairCallbacks.d.ts | 2 +- .../types/callbacks/TraderCallbacks.d.ts | 4 + .../types/callbacks/WeatherCallbacks.d.ts | 7 +- .../types/context/ContextVariableType.d.ts | 6 +- .../types/controllers/BotController.d.ts | 23 ++++- .../types/controllers/DialogueController.d.ts | 2 +- .../types/controllers/GameController.d.ts | 26 ++++- .../types/controllers/HideoutController.d.ts | 6 +- .../types/controllers/InraidController.d.ts | 64 +++++++++++- .../controllers/InsuranceController.d.ts | 3 +- .../controllers/InventoryController.d.ts | 29 +++++- .../types/controllers/LocationController.d.ts | 4 +- .../types/controllers/MatchController.d.ts | 4 +- .../types/controllers/RagfairController.d.ts | 11 +- .../RepeatableQuestController.d.ts | 4 +- .../types/controllers/WeatherController.d.ts | 9 +- .../server/types/generators/BotGenerator.d.ts | 57 +++++----- .../generators/BotInventoryGenerator.d.ts | 82 +++++++++++++-- .../types/generators/BotLevelGenerator.d.ts | 29 ++++++ .../types/generators/BotLootGenerator.d.ts | 21 +++- .../types/generators/BotWeaponGenerator.d.ts | 8 +- .../generators/RagfairOfferGenerator.d.ts | 48 +++++++-- .../types/generators/WeatherGenerator.d.ts | 40 +++++--- .../ExternalInventoryMagGen.d.ts | 4 +- .../types/helpers/BotDifficultyHelper.d.ts | 46 +++++++++ .../types/helpers/BotGeneratorHelper.d.ts | 66 +++++++----- .../server/types/helpers/BotHelper.d.ts | 43 +++----- .../server/types/helpers/GameEventHelper.d.ts | 11 ++ .../server/types/helpers/HideoutHelper.d.ts | 4 +- .../server/types/helpers/InventoryHelper.d.ts | 12 ++- .../server/types/helpers/ItemHelper.d.ts | 10 +- .../server/types/helpers/QuestHelper.d.ts | 97 +++++++++++++++--- .../types/helpers/RagfairServerHelper.d.ts | 10 ++ .../types/helpers/RagfairSortHelper.d.ts | 2 +- .../server/types/loaders/PreAkiModLoader.d.ts | 10 +- .../eft/bot/IGenerateBotsRequestData.d.ts | 1 + .../eft/bot/IRandomisedBotLevelResult.d.ts | 4 + .../types/models/eft/common/IGlobals.d.ts | 1 + .../models/eft/common/tables/IBotType.d.ts | 4 +- .../eft/common/tables/ITemplateItem.d.ts | 6 +- .../eft/customization/IGetSuitsResponse.d.ts | 4 + .../eft/game/IGameKeepAliveResponse.d.ts | 4 + .../eft/game/IGameLogoutResponseData.d.ts | 3 + .../models/eft/game/IGameStartResponse.d.ts | 3 + .../IOpenRandomLootContainerRequestData.d.ts | 11 ++ .../eft/itemEvent/IItemEventRouterBase.d.ts | 3 +- .../match/IStartOffineRaidRequestData.d.ts | 4 +- .../eft/notifier/ISelectProfileResponse.d.ts | 6 ++ .../models/eft/ragfair/IRagfairOffer.d.ts | 14 +-- .../models/eft/weather/IWeatherData.d.ts | 9 +- .../types/models/enums/BackendErrorCodes.d.ts | 67 ++++++++++++ .../models/enums/HideoutEventActions.d.ts | 11 ++ .../types/models/enums/ItemEventActions.d.ts | 19 ++++ .../types/models/enums/WeatherType.d.ts | 19 ++++ .../models/enums/WildSpawnTypeNumber.d.ts | 33 ++++++ .../types/models/enums/WindDirection.d.ts | 10 ++ .../models/spt/bots/BotGenerationDetails.d.ts | 16 +++ .../types/models/spt/config/IBotConfig.d.ts | 28 ++++- .../models/spt/config/IInventoryConfig.d.ts | 6 ++ .../models/spt/config/ILocaleConfig.d.ts | 7 +- .../types/models/spt/config/IPmcConfig.d.ts | 5 +- .../models/spt/config/IRagfairConfig.d.ts | 20 +++- .../spt/config/ISeasonalEventConfig.d.ts | 3 + .../models/spt/config/IWeatherConfig.d.ts | 13 ++- .../item_events/HideoutItemEventRouter.d.ts | 4 +- .../item_events/InventoryItemEventRouter.d.ts | 4 +- .../server/types/servers/HttpServer.d.ts | 4 +- .../server/types/servers/SaveServer.d.ts | 8 +- .../server/types/servers/WebSocketServer.d.ts | 14 +-- .../types/servers/http/AkiHttpListener.d.ts | 6 +- .../services/BotEquipmentFilterService.d.ts | 44 ++++++-- .../services/BotGenerationCacheService.d.ts | 26 +---- .../server/types/services/LocaleService.d.ts | 34 +++++- .../types/services/LocalisationService.d.ts | 21 ++++ .../server/types/services/PaymentService.d.ts | 6 +- .../server/types/services/PlayerService.d.ts | 4 +- .../server/types/services/PmcAiService.d.ts | 27 ----- .../types/services/ProfileFixerService.d.ts | 4 +- .../types/services/RagfairOfferService.d.ts | 7 +- .../itemValue/server/types/utils/App.d.ts | 6 +- .../server/types/utils/DatabaseImporter.d.ts | 4 +- .../server/types/utils/HttpResponseUtil.d.ts | 9 +- .../itemValue/server/types/utils/Logger.d.ts | 6 ++ .../server/types/utils/RandomUtil.d.ts | 6 ++ .../server/types/utils/Watermark.d.ts | 22 ++-- Shared/EFT/Accessibility.dll | Bin 22208 -> 22208 bytes Shared/EFT/Aki.Build.dll | Bin 3584 -> 0 bytes Shared/EFT/Aki.Common.dll | Bin 13824 -> 0 bytes Shared/EFT/Aki.Reflection.dll | Bin 13824 -> 0 bytes Shared/EFT/AmplifyMotion.dll | Bin 13504 -> 13504 bytes Shared/EFT/AnimationSystem.Recording.dll | Bin 13504 -> 13504 bytes Shared/EFT/AnimationSystem.Types.dll | Bin 17088 -> 17088 bytes Shared/EFT/Assembly-CSharp-firstpass.dll | Bin 362688 -> 362688 bytes Shared/EFT/Assembly-CSharp.dll | Bin 9728000 -> 9743872 bytes Shared/EFT/Autodesk.Fbx.dll | Bin 13504 -> 13504 bytes Shared/EFT/Cinemachine.dll | Bin 229568 -> 229568 bytes Shared/EFT/Comfort.Unity.dll | Bin 157888 -> 157888 bytes Shared/EFT/Comfort.dll | Bin 28864 -> 28864 bytes Shared/EFT/CommonExtensions.dll | Bin 20160 -> 20160 bytes Shared/EFT/DOTween.Modules.dll | Bin 45760 -> 45760 bytes Shared/EFT/DOTween.dll | Bin 165568 -> 165568 bytes Shared/EFT/DissonanceVoip.dll | Bin 287936 -> 287936 bytes Shared/EFT/FbxBuildTestAssets.dll | Bin 14016 -> 14016 bytes Shared/EFT/FilesChecker.dll | Bin 1290432 -> 1290432 bytes Shared/EFT/ItemComponent.Types.dll | Bin 14528 -> 14528 bytes Shared/EFT/ItemTemplate.Types.dll | Bin 13504 -> 13504 bytes Shared/EFT/JBooth.MicroSplat.Core.dll | Bin 44736 -> 44736 bytes Shared/EFT/LibraryLoaderUtility.dll | Bin 17088 -> 17088 bytes Shared/EFT/NLog.dll | Bin 870080 -> 870080 bytes .../EFT/Newtonsoft.Json.UnityConverters.dll | Bin 49344 -> 49344 bytes Shared/EFT/Newtonsoft.Json.dll | Bin 696000 -> 696000 bytes Shared/EFT/Novell.Directory.Ldap.dll | Bin 257216 -> 257216 bytes Shared/EFT/Polybrush.dll | Bin 52928 -> 52928 bytes .../EFT/Sirenix.OdinInspector.Attributes.dll | Bin 48320 -> 48320 bytes ...renix.OdinInspector.CompatibilityLayer.dll | Bin 15040 -> 15040 bytes Shared/EFT/Sirenix.Serialization.Config.dll | Bin 27328 -> 27328 bytes Shared/EFT/Sirenix.Serialization.dll | Bin 342208 -> 342208 bytes Shared/EFT/Sirenix.Utilities.dll | Bin 160960 -> 160960 bytes Shared/EFT/SteamAudio.dll | Bin 78016 -> 78016 bytes Shared/EFT/Unity.Formats.Fbx.Runtime.dll | Bin 6144 -> 6144 bytes Shared/EFT/Unity.MemoryProfiler.dll | Bin 5120 -> 5120 bytes Shared/EFT/Unity.PlayableGraphVisualizer.dll | Bin 4608 -> 4608 bytes Shared/EFT/Unity.Postprocessing.Runtime.dll | Bin 182784 -> 182784 bytes Shared/EFT/Unity.ProBuilder.Csg.dll | Bin 16896 -> 16896 bytes Shared/EFT/Unity.ProBuilder.KdTree.dll | Bin 18944 -> 18944 bytes Shared/EFT/Unity.ProBuilder.Poly2Tri.dll | Bin 34816 -> 34816 bytes Shared/EFT/Unity.ProBuilder.Stl.dll | Bin 13312 -> 13312 bytes Shared/EFT/Unity.ProBuilder.dll | Bin 352768 -> 352768 bytes Shared/EFT/Unity.Recorder.Base.dll | Bin 4608 -> 4608 bytes Shared/EFT/Unity.Recorder.dll | Bin 6144 -> 6144 bytes Shared/EFT/Unity.ScriptableBuildPipeline.dll | Bin 7680 -> 7680 bytes Shared/EFT/Unity.TextMeshPro.dll | Bin 369664 -> 369664 bytes Shared/EFT/Unity.Timeline.dll | Bin 116224 -> 116224 bytes Shared/EFT/UnityEngine.UI.dll | Bin 226816 -> 226816 bytes ...bsg.componentace.compression.libs.zlib.dll | Bin 69824 -> 69824 bytes Shared/EFT/bsg.console.core.dll | Bin 52416 -> 52416 bytes .../bsg.microsoft.extensions.objectpool.dll | Bin 19648 -> 19648 bytes Shared/EFT/bsg.system.buffers.dll | Bin 14528 -> 14528 bytes Shared/EFT/com.nvidia.reflex.Runtime.dll | Bin 31424 -> 31424 bytes .../com.unity.multiplayer-hlapi.Runtime.dll | Bin 241856 -> 241856 bytes Shared/EFT/mscorlib.dll | Bin 4082880 -> 4082880 bytes Shared/EFT/netstandard.dll | Bin 94912 -> 94912 bytes 389 files changed, 4074 insertions(+), 1014 deletions(-) rename Faupi-HideoutArchitect/Built/{Faupi-HideoutArchitect 1.6.7 => Faupi-HideoutArchitect 1.6.8}/bepInEx/plugins/Faupi-HideoutArchitect.dll (95%) rename Faupi-HideoutArchitect/Built/{Faupi-HideoutArchitect 1.6.7 => Faupi-HideoutArchitect 1.6.8}/user/mods/HideoutArchitect/LICENSE (100%) rename Faupi-HideoutArchitect/Built/{Faupi-HideoutArchitect 1.6.7 => Faupi-HideoutArchitect 1.6.8}/user/mods/HideoutArchitect/config.jsonc (100%) rename Faupi-HideoutArchitect/Built/{Faupi-HideoutArchitect 1.6.7 => Faupi-HideoutArchitect 1.6.8}/user/mods/HideoutArchitect/package.json (92%) rename Faupi-HideoutArchitect/Built/{Faupi-HideoutArchitect 1.6.7 => Faupi-HideoutArchitect 1.6.8}/user/mods/HideoutArchitect/res/icon_neededforhideout_small.png (100%) rename Faupi-HideoutArchitect/Built/{Faupi-HideoutArchitect 1.6.7 => Faupi-HideoutArchitect 1.6.8}/user/mods/HideoutArchitect/res/translations.json (100%) rename Faupi-HideoutArchitect/Built/{Faupi-HideoutArchitect 1.6.7 => Faupi-HideoutArchitect 1.6.8}/user/mods/HideoutArchitect/src/hideoutarchitect.ts (100%) create mode 100644 Faupi-HideoutArchitect/server/types/generators/BotLevelGenerator.d.ts create mode 100644 Faupi-HideoutArchitect/server/types/helpers/BotDifficultyHelper.d.ts create mode 100644 Faupi-HideoutArchitect/server/types/models/eft/bot/IRandomisedBotLevelResult.d.ts create mode 100644 Faupi-HideoutArchitect/server/types/models/eft/customization/IGetSuitsResponse.d.ts create mode 100644 Faupi-HideoutArchitect/server/types/models/eft/game/IGameKeepAliveResponse.d.ts create mode 100644 Faupi-HideoutArchitect/server/types/models/eft/game/IGameLogoutResponseData.d.ts create mode 100644 Faupi-HideoutArchitect/server/types/models/eft/game/IGameStartResponse.d.ts create mode 100644 Faupi-HideoutArchitect/server/types/models/eft/inventory/IOpenRandomLootContainerRequestData.d.ts create mode 100644 Faupi-HideoutArchitect/server/types/models/eft/notifier/ISelectProfileResponse.d.ts create mode 100644 Faupi-HideoutArchitect/server/types/models/enums/BackendErrorCodes.d.ts create mode 100644 Faupi-HideoutArchitect/server/types/models/enums/HideoutEventActions.d.ts create mode 100644 Faupi-HideoutArchitect/server/types/models/enums/ItemEventActions.d.ts create mode 100644 Faupi-HideoutArchitect/server/types/models/enums/WeatherType.d.ts create mode 100644 Faupi-HideoutArchitect/server/types/models/enums/WildSpawnTypeNumber.d.ts create mode 100644 Faupi-HideoutArchitect/server/types/models/enums/WindDirection.d.ts create mode 100644 Faupi-HideoutArchitect/server/types/models/spt/bots/BotGenerationDetails.d.ts create mode 100644 Faupi-HideoutArchitect/server/types/services/LocalisationService.d.ts delete mode 100644 Faupi-HideoutArchitect/server/types/services/PmcAiService.d.ts rename Faupi-MunitionsExpert/Built/{Faupi-MunitionsExpert 1.6.6 => Faupi-MunitionsExpert 1.6.7}/bepInEx/plugins/Faupi-MunitionsExpert.dll (84%) rename Faupi-MunitionsExpert/Built/{Faupi-MunitionsExpert 1.6.6/user/mods/Faupi-MunitionsExpert 1.6.6 => Faupi-MunitionsExpert 1.6.7/user/mods/Faupi-MunitionsExpert 1.6.7}/LICENSE.txt (100%) rename Faupi-MunitionsExpert/Built/{Faupi-MunitionsExpert 1.6.6/user/mods/Faupi-MunitionsExpert 1.6.6 => Faupi-MunitionsExpert 1.6.7/user/mods/Faupi-MunitionsExpert 1.6.7}/package.json (91%) rename Faupi-MunitionsExpert/Built/{Faupi-MunitionsExpert 1.6.6/user/mods/Faupi-MunitionsExpert 1.6.6 => Faupi-MunitionsExpert 1.6.7/user/mods/Faupi-MunitionsExpert 1.6.7}/res/armorDamage.png (100%) rename Faupi-MunitionsExpert/Built/{Faupi-MunitionsExpert 1.6.6/user/mods/Faupi-MunitionsExpert 1.6.6 => Faupi-MunitionsExpert 1.6.7/user/mods/Faupi-MunitionsExpert 1.6.7}/res/ricochet.png (100%) rename Faupi-MunitionsExpert/Built/{Faupi-MunitionsExpert 1.6.6/user/mods/Faupi-MunitionsExpert 1.6.6 => Faupi-MunitionsExpert 1.6.7/user/mods/Faupi-MunitionsExpert 1.6.7}/res/translations.json (100%) rename Faupi-MunitionsExpert/Built/{Faupi-MunitionsExpert 1.6.6/user/mods/Faupi-MunitionsExpert 1.6.6 => Faupi-MunitionsExpert 1.6.7/user/mods/Faupi-MunitionsExpert 1.6.7}/src/MunitionsExpert.ts (98%) rename Faupi-MunitionsExpert/Built/{Faupi-MunitionsExpert 1.6.6/user/mods/Faupi-MunitionsExpert 1.6.6 => Faupi-MunitionsExpert 1.6.7/user/mods/Faupi-MunitionsExpert 1.6.7}/src/config.json (100%) create mode 100644 Faupi-MunitionsExpert/server/types/generators/BotLevelGenerator.d.ts create mode 100644 Faupi-MunitionsExpert/server/types/helpers/BotDifficultyHelper.d.ts create mode 100644 Faupi-MunitionsExpert/server/types/models/eft/bot/IRandomisedBotLevelResult.d.ts create mode 100644 Faupi-MunitionsExpert/server/types/models/eft/customization/IGetSuitsResponse.d.ts create mode 100644 Faupi-MunitionsExpert/server/types/models/eft/game/IGameKeepAliveResponse.d.ts create mode 100644 Faupi-MunitionsExpert/server/types/models/eft/game/IGameLogoutResponseData.d.ts create mode 100644 Faupi-MunitionsExpert/server/types/models/eft/game/IGameStartResponse.d.ts create mode 100644 Faupi-MunitionsExpert/server/types/models/eft/inventory/IOpenRandomLootContainerRequestData.d.ts create mode 100644 Faupi-MunitionsExpert/server/types/models/eft/notifier/ISelectProfileResponse.d.ts create mode 100644 Faupi-MunitionsExpert/server/types/models/enums/BackendErrorCodes.d.ts create mode 100644 Faupi-MunitionsExpert/server/types/models/enums/HideoutEventActions.d.ts create mode 100644 Faupi-MunitionsExpert/server/types/models/enums/ItemEventActions.d.ts create mode 100644 Faupi-MunitionsExpert/server/types/models/enums/WeatherType.d.ts create mode 100644 Faupi-MunitionsExpert/server/types/models/enums/WildSpawnTypeNumber.d.ts create mode 100644 Faupi-MunitionsExpert/server/types/models/enums/WindDirection.d.ts create mode 100644 Faupi-MunitionsExpert/server/types/models/spt/bots/BotGenerationDetails.d.ts create mode 100644 Faupi-MunitionsExpert/server/types/services/LocalisationService.d.ts delete mode 100644 Faupi-MunitionsExpert/server/types/services/PmcAiService.d.ts rename KcY-SeeItemValue/itemValue/Built/{KcY-SeeItemValue 1.4.8 => KcY-SeeItemValue 1.5.0}/bepInEx/plugins/KcY-SeeItemValue.dll (76%) rename KcY-SeeItemValue/itemValue/Built/{KcY-SeeItemValue 1.4.8/user/mods/KcY-SeeItemValue 1.4.8 => KcY-SeeItemValue 1.5.0/user/mods/KcY-SeeItemValue 1.5.0}/LICENSE.txt (100%) rename KcY-SeeItemValue/itemValue/Built/{KcY-SeeItemValue 1.4.8/user/mods/KcY-SeeItemValue 1.4.8 => KcY-SeeItemValue 1.5.0/user/mods/KcY-SeeItemValue 1.5.0}/package.json (91%) rename KcY-SeeItemValue/itemValue/Built/{KcY-SeeItemValue 1.4.8/user/mods/KcY-SeeItemValue 1.4.8 => KcY-SeeItemValue 1.5.0/user/mods/KcY-SeeItemValue 1.5.0}/src/config.json (100%) rename KcY-SeeItemValue/itemValue/Built/{KcY-SeeItemValue 1.4.8/user/mods/KcY-SeeItemValue 1.4.8 => KcY-SeeItemValue 1.5.0/user/mods/KcY-SeeItemValue 1.5.0}/src/mod.ts (100%) create mode 100644 KcY-SeeItemValue/itemValue/server/types/generators/BotLevelGenerator.d.ts create mode 100644 KcY-SeeItemValue/itemValue/server/types/helpers/BotDifficultyHelper.d.ts create mode 100644 KcY-SeeItemValue/itemValue/server/types/models/eft/bot/IRandomisedBotLevelResult.d.ts create mode 100644 KcY-SeeItemValue/itemValue/server/types/models/eft/customization/IGetSuitsResponse.d.ts create mode 100644 KcY-SeeItemValue/itemValue/server/types/models/eft/game/IGameKeepAliveResponse.d.ts create mode 100644 KcY-SeeItemValue/itemValue/server/types/models/eft/game/IGameLogoutResponseData.d.ts create mode 100644 KcY-SeeItemValue/itemValue/server/types/models/eft/game/IGameStartResponse.d.ts create mode 100644 KcY-SeeItemValue/itemValue/server/types/models/eft/inventory/IOpenRandomLootContainerRequestData.d.ts create mode 100644 KcY-SeeItemValue/itemValue/server/types/models/eft/notifier/ISelectProfileResponse.d.ts create mode 100644 KcY-SeeItemValue/itemValue/server/types/models/enums/BackendErrorCodes.d.ts create mode 100644 KcY-SeeItemValue/itemValue/server/types/models/enums/HideoutEventActions.d.ts create mode 100644 KcY-SeeItemValue/itemValue/server/types/models/enums/ItemEventActions.d.ts create mode 100644 KcY-SeeItemValue/itemValue/server/types/models/enums/WeatherType.d.ts create mode 100644 KcY-SeeItemValue/itemValue/server/types/models/enums/WildSpawnTypeNumber.d.ts create mode 100644 KcY-SeeItemValue/itemValue/server/types/models/enums/WindDirection.d.ts create mode 100644 KcY-SeeItemValue/itemValue/server/types/models/spt/bots/BotGenerationDetails.d.ts create mode 100644 KcY-SeeItemValue/itemValue/server/types/services/LocalisationService.d.ts delete mode 100644 KcY-SeeItemValue/itemValue/server/types/services/PmcAiService.d.ts delete mode 100644 Shared/EFT/Aki.Build.dll delete mode 100644 Shared/EFT/Aki.Common.dll delete mode 100644 Shared/EFT/Aki.Reflection.dll diff --git a/Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.7/bepInEx/plugins/Faupi-HideoutArchitect.dll b/Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.8/bepInEx/plugins/Faupi-HideoutArchitect.dll similarity index 95% rename from Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.7/bepInEx/plugins/Faupi-HideoutArchitect.dll rename to Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.8/bepInEx/plugins/Faupi-HideoutArchitect.dll index 377e195333a7654c70792877e452e5a7224c1db7..8b20ae134b796aabcdd7cb17be06e4d16c5c4619 100644 GIT binary patch delta 259 zcmZoz!Pu~ZaY6@6^!8W18+&9#g;y{>XJKPVXM4-X#_(LAlZ%aE%H-Xmri`;Ee-t(4 z@L^hmAptv6D*-s1&44nX{9Ni(xav<~w4K7#TNA-Y@Z(F?{l3 zNqxqK&6gz^nHdu|UzL&NVlp$H{6%eoh`V!6VsWvdnS~L9jh$tDyrEIN(d2V#(vw%H zhcTNQm~H0Kh>#RGR6JYk#v^<0b#F{l^xyq_xVgkJh?CJ`@^Pib*_`#&t@tb3P7PA8Y!m43D delta 245 zcmZoz!Pu~ZaY6@+{j1-XHulJf3eRPH&ceo!&i0m%jp4aKCl?z-=j7d@ri>FNe-t(4 zIK{}oz{RkcVX~gs6she%4jY3OV<(pwP$@{8GG`|j7sGzW&3D8eF)}WlykFumqtE2U zlKPCLn=eZ;GBbv4zA7Wj#bj(rQ$8|00J?ToQvd(} diff --git a/Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.7/user/mods/HideoutArchitect/LICENSE b/Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.8/user/mods/HideoutArchitect/LICENSE similarity index 100% rename from Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.7/user/mods/HideoutArchitect/LICENSE rename to Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.8/user/mods/HideoutArchitect/LICENSE diff --git a/Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.7/user/mods/HideoutArchitect/config.jsonc b/Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.8/user/mods/HideoutArchitect/config.jsonc similarity index 100% rename from Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.7/user/mods/HideoutArchitect/config.jsonc rename to Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.8/user/mods/HideoutArchitect/config.jsonc diff --git a/Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.7/user/mods/HideoutArchitect/package.json b/Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.8/user/mods/HideoutArchitect/package.json similarity index 92% rename from Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.7/user/mods/HideoutArchitect/package.json rename to Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.8/user/mods/HideoutArchitect/package.json index 609967a..4e2944e 100644 --- a/Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.7/user/mods/HideoutArchitect/package.json +++ b/Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.8/user/mods/HideoutArchitect/package.json @@ -1,10 +1,10 @@ { "name": "HideoutArchitect", - "version": "1.6.7", + "version": "1.6.8", "main": "./src/hideoutarchitect.js", "license": "NCSA Open Source", "author": "Faupi", - "akiVersion": "3.2.5", + "akiVersion": "3.3.0", "updated by": "CWX", "scripts": { "setup": "npm i", diff --git a/Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.7/user/mods/HideoutArchitect/res/icon_neededforhideout_small.png b/Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.8/user/mods/HideoutArchitect/res/icon_neededforhideout_small.png similarity index 100% rename from Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.7/user/mods/HideoutArchitect/res/icon_neededforhideout_small.png rename to Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.8/user/mods/HideoutArchitect/res/icon_neededforhideout_small.png diff --git a/Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.7/user/mods/HideoutArchitect/res/translations.json b/Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.8/user/mods/HideoutArchitect/res/translations.json similarity index 100% rename from Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.7/user/mods/HideoutArchitect/res/translations.json rename to Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.8/user/mods/HideoutArchitect/res/translations.json diff --git a/Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.7/user/mods/HideoutArchitect/src/hideoutarchitect.ts b/Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.8/user/mods/HideoutArchitect/src/hideoutarchitect.ts similarity index 100% rename from Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.7/user/mods/HideoutArchitect/src/hideoutarchitect.ts rename to Faupi-HideoutArchitect/Built/Faupi-HideoutArchitect 1.6.8/user/mods/HideoutArchitect/src/hideoutarchitect.ts diff --git a/Faupi-HideoutArchitect/HideoutArchitect/HideoutArchitect/Program.cs b/Faupi-HideoutArchitect/HideoutArchitect/HideoutArchitect/Program.cs index eb0b9bf..a3d16bf 100644 --- a/Faupi-HideoutArchitect/HideoutArchitect/HideoutArchitect/Program.cs +++ b/Faupi-HideoutArchitect/HideoutArchitect/HideoutArchitect/Program.cs @@ -7,12 +7,12 @@ using System.IO; using System.Linq; using BepInEx; using UnityEngine; -using Hideout = GClass1677; -using Requirement = GClass1701; +using Hideout = GClass1682; +using Requirement = GClass1706; namespace HideoutArchitect { - [BepInPlugin("com.FAUPI.HideoutArchitect", "FAUPI-HideoutArchitect", "1.6.7")] + [BepInPlugin("com.FAUPI.HideoutArchitect", "FAUPI-HideoutArchitect", "1.6.8")] public class HideoutArchitect : BaseUnityPlugin { private void Awake() diff --git a/Faupi-HideoutArchitect/server/dist/package.json b/Faupi-HideoutArchitect/server/dist/package.json index def6cd6..4e2944e 100644 --- a/Faupi-HideoutArchitect/server/dist/package.json +++ b/Faupi-HideoutArchitect/server/dist/package.json @@ -1,10 +1,10 @@ { "name": "HideoutArchitect", - "version": "1.6.7", + "version": "1.6.8", "main": "./src/hideoutarchitect.js", "license": "NCSA Open Source", "author": "Faupi", - "akiVersion": "3.2.3", + "akiVersion": "3.3.0", "updated by": "CWX", "scripts": { "setup": "npm i", diff --git a/Faupi-HideoutArchitect/server/package.json b/Faupi-HideoutArchitect/server/package.json index 609967a..4e2944e 100644 --- a/Faupi-HideoutArchitect/server/package.json +++ b/Faupi-HideoutArchitect/server/package.json @@ -1,10 +1,10 @@ { "name": "HideoutArchitect", - "version": "1.6.7", + "version": "1.6.8", "main": "./src/hideoutarchitect.js", "license": "NCSA Open Source", "author": "Faupi", - "akiVersion": "3.2.5", + "akiVersion": "3.3.0", "updated by": "CWX", "scripts": { "setup": "npm i", diff --git a/Faupi-HideoutArchitect/server/types/callbacks/BotCallbacks.d.ts b/Faupi-HideoutArchitect/server/types/callbacks/BotCallbacks.d.ts index 2db60dc..827015e 100644 --- a/Faupi-HideoutArchitect/server/types/callbacks/BotCallbacks.d.ts +++ b/Faupi-HideoutArchitect/server/types/callbacks/BotCallbacks.d.ts @@ -8,8 +8,29 @@ export declare class BotCallbacks { protected botController: BotController; protected httpResponse: HttpResponseUtil; constructor(botController: BotController, httpResponse: HttpResponseUtil); + /** + * Handle singleplayer/settings/bot/limit + * @returns string + */ getBotLimit(url: string, info: IEmptyRequestData, sessionID: string): string; + /** + * Handle singleplayer/settings/bot/difficulty + * @returns string + */ getBotDifficulty(url: string, info: IEmptyRequestData, sessionID: string): string; + /** + * Handle client/game/bot/generate + * @returns IGetBodyResponseData + */ generateBots(url: string, info: IGenerateBotsRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle singleplayer/settings/bot/maxCap + * @returns string + */ getBotCap(): string; + /** + * Handle singleplayer/settings/bot/getBotBehaviours + * @returns string + */ + getBotBehaviours(): string; } diff --git a/Faupi-HideoutArchitect/server/types/callbacks/CustomizationCallbacks.d.ts b/Faupi-HideoutArchitect/server/types/callbacks/CustomizationCallbacks.d.ts index 3bab8c0..75d5701 100644 --- a/Faupi-HideoutArchitect/server/types/callbacks/CustomizationCallbacks.d.ts +++ b/Faupi-HideoutArchitect/server/types/callbacks/CustomizationCallbacks.d.ts @@ -3,6 +3,7 @@ import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData"; import { IPmcData } from "../models/eft/common/IPmcData"; import { ISuit } from "../models/eft/common/tables/ITrader"; import { IBuyClothingRequestData } from "../models/eft/customization/IBuyClothingRequestData"; +import { IGetSuitsResponse } from "../models/eft/customization/IGetSuitsResponse"; import { IWearClothingRequestData } from "../models/eft/customization/IWearClothingRequestData"; import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData"; import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse"; @@ -13,10 +14,15 @@ export declare class CustomizationCallbacks { protected saveServer: SaveServer; protected httpResponse: HttpResponseUtil; constructor(customizationController: CustomizationController, saveServer: SaveServer, httpResponse: HttpResponseUtil); - getSuits(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<{ - _id: string; - suites: string[]; - }>; + /** + * Handles client/trading/customization/storage + * @returns + */ + getSuits(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handles client/trading/customization + * @returns ISuit[] + */ getTraderSuits(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; wearClothing(pmcData: IPmcData, body: IWearClothingRequestData, sessionID: string): IItemEventRouterResponse; buyClothing(pmcData: IPmcData, body: IBuyClothingRequestData, sessionID: string): IItemEventRouterResponse; diff --git a/Faupi-HideoutArchitect/server/types/callbacks/DataCallbacks.d.ts b/Faupi-HideoutArchitect/server/types/callbacks/DataCallbacks.d.ts index 04566ff..2efcf81 100644 --- a/Faupi-HideoutArchitect/server/types/callbacks/DataCallbacks.d.ts +++ b/Faupi-HideoutArchitect/server/types/callbacks/DataCallbacks.d.ts @@ -12,15 +12,42 @@ import { ILanguageBase } from "../models/spt/server/ILocaleBase"; import { ISettingsBase } from "../models/spt/server/ISettingsBase"; import { DatabaseServer } from "../servers/DatabaseServer"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; +/** + * Handle client requests + */ export declare class DataCallbacks { protected httpResponse: HttpResponseUtil; protected databaseServer: DatabaseServer; constructor(httpResponse: HttpResponseUtil, databaseServer: DatabaseServer); + /** + * Handles client/settings + * @returns ISettingsBase + */ getSettings(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handles client/globals + * @returns IGlobals + */ getGlobals(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handles client/items + * @returns string + */ getTemplateItems(url: string, info: IEmptyRequestData, sessionID: string): string; + /** + * Handles client/handbook/templates + * @returns IHandbookBase + */ getTemplateHandbook(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handles client/customization + * @returns Record>; + /** + * Handles client/account/customization + * @returns string[] + */ getTemplateCharacter(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; getTemplateQuests(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; getHideoutSettings(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; @@ -28,6 +55,6 @@ export declare class DataCallbacks { gethideoutProduction(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; getHideoutScavcase(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; getLocalesLanguages(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - getLocalesMenu(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + getLocalesMenu(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; getLocalesGlobal(url: string, info: IEmptyRequestData, sessionID: string): string; } diff --git a/Faupi-HideoutArchitect/server/types/callbacks/DialogueCallbacks.d.ts b/Faupi-HideoutArchitect/server/types/callbacks/DialogueCallbacks.d.ts index 634f90b..7b2eeae 100644 --- a/Faupi-HideoutArchitect/server/types/callbacks/DialogueCallbacks.d.ts +++ b/Faupi-HideoutArchitect/server/types/callbacks/DialogueCallbacks.d.ts @@ -26,15 +26,27 @@ export declare class DialogueCallbacks extends OnUpdate { protected httpResponse: HttpResponseUtil; protected dialogueController: DialogueController; constructor(hashUtil: HashUtil, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, dialogueController: DialogueController); + /** + * Handles client/friend/list + * @returns IGetFriendListDataResponse + */ getFriendList(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handles client/chatServer/list + * @returns + */ getChatServerList(url: string, info: IGetChatServerListRequestData, sessionID: string): IGetBodyResponseData; getMailDialogList(url: string, info: IGetMailDialogListRequestData, sessionID: string): IGetBodyResponseData; getMailDialogView(url: string, info: IGetMailDialogViewRequestData, sessionID: string): IGetBodyResponseData; - getMailDialogInfo(url: string, info: IGetMailDialogInfoRequestData, sessionID: string): IGetBodyResponseData; + getMailDialogInfo(url: string, info: IGetMailDialogInfoRequestData, sessionID: string): IGetBodyResponseData; removeDialog(url: string, info: IRemoveDialogRequestData, sessionID: string): IGetBodyResponseData; pinDialog(url: string, info: IPinDialogRequestData, sessionID: string): IGetBodyResponseData; unpinDialog(url: string, info: IPinDialogRequestData, sessionID: string): IGetBodyResponseData; setRead(url: string, info: ISetDialogReadRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handles client/mail/dialog/getAllAttachments + * @returns IGetAllAttachmentsResponse + */ getAllAttachments(url: string, info: IGetAllAttachmentsRequestData, sessionID: string): IGetBodyResponseData; listOutbox(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; listInbox(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; diff --git a/Faupi-HideoutArchitect/server/types/callbacks/GameCallbacks.d.ts b/Faupi-HideoutArchitect/server/types/callbacks/GameCallbacks.d.ts index 5e4c240..3a6b7e6 100644 --- a/Faupi-HideoutArchitect/server/types/callbacks/GameCallbacks.d.ts +++ b/Faupi-HideoutArchitect/server/types/callbacks/GameCallbacks.d.ts @@ -3,6 +3,9 @@ import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData"; import { ICheckVersionResponse } from "../models/eft/game/ICheckVersionResponse"; import { IGameConfigResponse } from "../models/eft/game/IGameConfigResponse"; import { IGameEmptyCrcRequestData } from "../models/eft/game/IGameEmptyCrcRequestData"; +import { IGameKeepAliveResponse } from "../models/eft/game/IGameKeepAliveResponse"; +import { IGameLogoutResponseData } from "../models/eft/game/IGameLogoutResponseData"; +import { IGameStartResponse } from "../models/eft/game/IGameStartResponse"; import { IReportNicknameRequestData } from "../models/eft/game/IReportNicknameRequestData"; import { IServerDetails } from "../models/eft/game/IServerDetails"; import { IVersionValidateRequestData } from "../models/eft/game/IVersionValidateRequestData"; @@ -15,13 +18,37 @@ declare class GameCallbacks { protected watermark: Watermark; protected gameController: GameController; constructor(httpResponse: HttpResponseUtil, watermark: Watermark, gameController: GameController); + /** + * Handle client/game/version/validate + * @returns INullResponseData + */ versionValidate(url: string, info: IVersionValidateRequestData, sessionID: string): INullResponseData; - gameStart(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - gameLogout(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle client/game/start + * @returns IGameStartResponse + */ + gameStart(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle client/game/logout + * @returns IGameLogoutResponseData + */ + gameLogout(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle client/game/config + * @returns IGameConfigResponse + */ getGameConfig(url: string, info: IGameEmptyCrcRequestData, sessionID: string): IGetBodyResponseData; getServer(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; validateGameVersion(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - gameKeepalive(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle client/game/keepalive + * @returns IGameKeepAliveResponse + */ + gameKeepalive(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle singleplayer/settings/version + * @returns string + */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; } diff --git a/Faupi-HideoutArchitect/server/types/callbacks/HealthCallbacks.d.ts b/Faupi-HideoutArchitect/server/types/callbacks/HealthCallbacks.d.ts index 8672be7..7edf03e 100644 --- a/Faupi-HideoutArchitect/server/types/callbacks/HealthCallbacks.d.ts +++ b/Faupi-HideoutArchitect/server/types/callbacks/HealthCallbacks.d.ts @@ -21,7 +21,19 @@ export declare class HealthCallbacks { * @returns empty response, no data sent back to client */ syncHealth(url: string, info: ISyncHealthRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle Eat + * @returns IItemEventRouterResponse + */ offraidEat(pmcData: IPmcData, body: IOffraidEatRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle Heal + * @returns IItemEventRouterResponse + */ offraidHeal(pmcData: IPmcData, body: IOffraidHealRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle RestoreHealth + * @returns IItemEventRouterResponse + */ healthTreatment(pmcData: IPmcData, info: IHealthTreatmentRequestData, sessionID: string): IItemEventRouterResponse; } diff --git a/Faupi-HideoutArchitect/server/types/callbacks/HideoutCallbacks.d.ts b/Faupi-HideoutArchitect/server/types/callbacks/HideoutCallbacks.d.ts index 99ab4c9..e39e806 100644 --- a/Faupi-HideoutArchitect/server/types/callbacks/HideoutCallbacks.d.ts +++ b/Faupi-HideoutArchitect/server/types/callbacks/HideoutCallbacks.d.ts @@ -19,14 +19,77 @@ export declare class HideoutCallbacks extends OnUpdate { protected hideoutConfig: IHideoutConfig; constructor(hideoutController: HideoutController, // TODO: delay needed configServer: ConfigServer); + /** + * Handle HideoutUpgrade + * @param pmcData + * @param body + * @param sessionID + * @returns + */ upgrade(pmcData: IPmcData, body: IHideoutUpgradeRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutUpgradeComplete + * @param pmcData + * @param body + * @param sessionID + * @returns + */ upgradeComplete(pmcData: IPmcData, body: IHideoutUpgradeCompleteRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutPutItemsInAreaSlots + * @param pmcData + * @param body + * @param sessionID + * @returns + */ putItemsInAreaSlots(pmcData: IPmcData, body: IHideoutPutItemInRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutTakeItemsFromAreaSlots + * @param pmcData + * @param body + * @param sessionID + * @returns + */ takeItemsFromAreaSlots(pmcData: IPmcData, body: IHideoutTakeItemOutRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutToggleArea + * @param pmcData + * @param body + * @param sessionID + * @returns + */ toggleArea(pmcData: IPmcData, body: IHideoutToggleAreaRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutSingleProductionStart + * @param pmcData + * @param body + * @param sessionID + * @returns + */ singleProductionStart(pmcData: IPmcData, body: IHideoutSingleProductionStartRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutScavCaseProductionStart + * @param pmcData + * @param body + * @param sessionID + * @returns + */ scavCaseProductionStart(pmcData: IPmcData, body: IHideoutScavCaseStartRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutContinuousProductionStart + * @param pmcData + * @param body + * @param sessionID + * @returns + */ continuousProductionStart(pmcData: IPmcData, body: IHideoutContinousProductionStartRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutTakeProduction + * @param pmcData + * @param body + * @param sessionID + * @returns + */ takeProduction(pmcData: IPmcData, body: IHideoutTakeProductionRequestData, sessionID: string): IItemEventRouterResponse; onUpdate(timeSinceLastRun: number): boolean; getRoute(): string; diff --git a/Faupi-HideoutArchitect/server/types/callbacks/InraidCallbacks.d.ts b/Faupi-HideoutArchitect/server/types/callbacks/InraidCallbacks.d.ts index 05bcce4..918bfaf 100644 --- a/Faupi-HideoutArchitect/server/types/callbacks/InraidCallbacks.d.ts +++ b/Faupi-HideoutArchitect/server/types/callbacks/InraidCallbacks.d.ts @@ -1,23 +1,49 @@ import { InraidController } from "../controllers/InraidController"; -import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData"; import { INullResponseData } from "../models/eft/httpResponse/INullResponseData"; import { IRegisterPlayerRequestData } from "../models/eft/inRaid/IRegisterPlayerRequestData"; import { ISaveProgressRequestData } from "../models/eft/inRaid/ISaveProgressRequestData"; -import { IAirdropConfig } from "../models/spt/config/IAirdropConfig"; -import { IInRaidConfig } from "../models/spt/config/IInRaidConfig"; -import { ConfigServer } from "../servers/ConfigServer"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; +/** + * Handle client requests + */ export declare class InraidCallbacks { protected inraidController: InraidController; protected httpResponse: HttpResponseUtil; - protected configServer: ConfigServer; - protected airdropConfig: IAirdropConfig; - protected inraidConfig: IInRaidConfig; - constructor(inraidController: InraidController, httpResponse: HttpResponseUtil, configServer: ConfigServer); + constructor(inraidController: InraidController, httpResponse: HttpResponseUtil); + /** + * Handle client/location/getLocalloot + * @param url + * @param info register player request + * @param sessionID Session id + * @returns Null http response + */ registerPlayer(url: string, info: IRegisterPlayerRequestData, sessionID: string): INullResponseData; + /** + * Handle raid/profile/save + * @param url + * @param info Save progress request + * @param sessionID Session id + * @returns Null http response + */ saveProgress(url: string, info: ISaveProgressRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/raid/endstate + * @returns + */ getRaidEndState(): string; - getRaidMenuSettings(url: string, info: IEmptyRequestData, sessionID: string): string; - getWeaponDurability(url: string, info: any, sessionID: string): string; - getAirdropConfig(url: string, info: any, sessionID: string): string; + /** + * Handle singleplayer/settings/raid/menu + * @returns JSON as string + */ + getRaidMenuSettings(): string; + /** + * Handle singleplayer/settings/weapon/durability + * @returns + */ + getWeaponDurability(): string; + /** + * Handle singleplayer/airdrop/config + * @returns JSON as string + */ + getAirdropConfig(): string; } diff --git a/Faupi-HideoutArchitect/server/types/callbacks/InsuranceCallbacks.d.ts b/Faupi-HideoutArchitect/server/types/callbacks/InsuranceCallbacks.d.ts index 8835ba2..a171e1c 100644 --- a/Faupi-HideoutArchitect/server/types/callbacks/InsuranceCallbacks.d.ts +++ b/Faupi-HideoutArchitect/server/types/callbacks/InsuranceCallbacks.d.ts @@ -17,7 +17,15 @@ export declare class InsuranceCallbacks extends OnUpdate { protected configServer: ConfigServer; protected insuranceConfig: IInsuranceConfig; constructor(insuranceController: InsuranceController, insuranceService: InsuranceService, httpResponse: HttpResponseUtil, configServer: ConfigServer); + /** + * Handle client/insurance/items/list/cost + * @returns IGetInsuranceCostResponseData + */ getInsuranceCost(url: string, info: IGetInsuranceCostRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle Insure + * @returns IItemEventRouterResponse + */ insure(pmcData: IPmcData, body: IInsureRequestData, sessionID: string): IItemEventRouterResponse; onUpdate(secondsSinceLastRun: number): boolean; getRoute(): string; diff --git a/Faupi-HideoutArchitect/server/types/callbacks/InventoryCallbacks.d.ts b/Faupi-HideoutArchitect/server/types/callbacks/InventoryCallbacks.d.ts index 9ab1486..46bf6fd 100644 --- a/Faupi-HideoutArchitect/server/types/callbacks/InventoryCallbacks.d.ts +++ b/Faupi-HideoutArchitect/server/types/callbacks/InventoryCallbacks.d.ts @@ -16,6 +16,7 @@ import { IInventorySwapRequestData } from "../models/eft/inventory/IInventorySwa import { IInventoryTagRequestData } from "../models/eft/inventory/IInventoryTagRequestData"; import { IInventoryToggleRequestData } from "../models/eft/inventory/IInventoryToggleRequestData"; import { IInventoryTransferRequestData } from "../models/eft/inventory/IInventoryTransferRequestData"; +import { IOpenRandomLootContainerRequestData } from "../models/eft/inventory/IOpenRandomLootContainerRequestData"; import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse"; export declare class InventoryCallbacks { protected inventoryController: InventoryController; @@ -36,4 +37,5 @@ export declare class InventoryCallbacks { createMapMarker(pmcData: IPmcData, body: IInventoryCreateMarkerRequestData, sessionID: string): IItemEventRouterResponse; deleteMapMarker(pmcData: IPmcData, body: IInventoryDeleteMarkerRequestData, sessionID: string): IItemEventRouterResponse; editMapMarker(pmcData: IPmcData, body: IInventoryEditMarkerRequestData, sessionID: string): IItemEventRouterResponse; + openRandomLootContainer(pmcData: IPmcData, body: IOpenRandomLootContainerRequestData, sessionID: string): IItemEventRouterResponse; } diff --git a/Faupi-HideoutArchitect/server/types/callbacks/ItemEventCallbacks.d.ts b/Faupi-HideoutArchitect/server/types/callbacks/ItemEventCallbacks.d.ts index f4f04f9..fbb0b5f 100644 --- a/Faupi-HideoutArchitect/server/types/callbacks/ItemEventCallbacks.d.ts +++ b/Faupi-HideoutArchitect/server/types/callbacks/ItemEventCallbacks.d.ts @@ -1,4 +1,5 @@ import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData"; +import { Warning } from "../models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterRequest } from "../models/eft/itemEvent/IItemEventRouterRequest"; import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse"; import { ItemEventRouter } from "../routers/ItemEventRouter"; @@ -8,4 +9,5 @@ export declare class ItemEventCallbacks { protected itemEventRouter: ItemEventRouter; constructor(httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter); handleEvents(url: string, info: IItemEventRouterRequest, sessionID: string): IGetBodyResponseData; + protected getErrorCode(warnings: Warning[]): number; } diff --git a/Faupi-HideoutArchitect/server/types/callbacks/MatchCallbacks.d.ts b/Faupi-HideoutArchitect/server/types/callbacks/MatchCallbacks.d.ts index 2a92ef5..10fbc44 100644 --- a/Faupi-HideoutArchitect/server/types/callbacks/MatchCallbacks.d.ts +++ b/Faupi-HideoutArchitect/server/types/callbacks/MatchCallbacks.d.ts @@ -34,6 +34,10 @@ export declare class MatchCallbacks { serverAvailable(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData | IGetBodyResponseData; joinMatch(url: string, info: IJoinMatchRequestData, sessionID: string): IGetBodyResponseData; getMetrics(url: string, info: any, sessionID: string): IGetBodyResponseData; + /** + * Handle client/match/group/status + * @returns + */ getGroupStatus(url: string, info: IGetGroupStatusRequestData, sessionID: string): IGetBodyResponseData; createGroup(url: string, info: ICreateGroupRequestData, sessionID: string): IGetBodyResponseData; deleteGroup(url: string, info: any, sessionID: string): INullResponseData; diff --git a/Faupi-HideoutArchitect/server/types/callbacks/NotifierCallbacks.d.ts b/Faupi-HideoutArchitect/server/types/callbacks/NotifierCallbacks.d.ts index c42058f..fab325b 100644 --- a/Faupi-HideoutArchitect/server/types/callbacks/NotifierCallbacks.d.ts +++ b/Faupi-HideoutArchitect/server/types/callbacks/NotifierCallbacks.d.ts @@ -4,6 +4,7 @@ import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData"; import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData"; import { INotifierChannel } from "../models/eft/notifier/INotifier"; import { ISelectProfileRequestData } from "../models/eft/notifier/ISelectProfileRequestData"; +import { ISelectProfileResponse } from "../models/eft/notifier/ISelectProfileResponse"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; export declare class NotifierCallbacks { protected httpServerHelper: HttpServerHelper; @@ -19,6 +20,10 @@ export declare class NotifierCallbacks { sendNotification(sessionID: string, req: any, resp: any, data: any): void; getNotifier(url: string, info: any, sessionID: string): IGetBodyResponseData; createNotifierChannel(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - selectProfile(url: string, info: ISelectProfileRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle client/game/profile/select + * @returns ISelectProfileResponse + */ + selectProfile(url: string, info: ISelectProfileRequestData, sessionID: string): IGetBodyResponseData; notify(url: string, info: any, sessionID: string): string; } diff --git a/Faupi-HideoutArchitect/server/types/callbacks/QuestCallbacks.d.ts b/Faupi-HideoutArchitect/server/types/callbacks/QuestCallbacks.d.ts index 559c29e..2a3eb20 100644 --- a/Faupi-HideoutArchitect/server/types/callbacks/QuestCallbacks.d.ts +++ b/Faupi-HideoutArchitect/server/types/callbacks/QuestCallbacks.d.ts @@ -21,6 +21,13 @@ export declare class QuestCallbacks { acceptQuest(pmcData: IPmcData, body: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; completeQuest(pmcData: IPmcData, body: ICompleteQuestRequestData, sessionID: string): IItemEventRouterResponse; handoverQuest(pmcData: IPmcData, body: IHandoverQuestRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle client/quest/list + * @param url + * @param info + * @param sessionID + * @returns + */ listQuests(url: string, info: IListQuestsRequestData, sessionID: string): IGetBodyResponseData; activityPeriods(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; } diff --git a/Faupi-HideoutArchitect/server/types/callbacks/RagfairCallbacks.d.ts b/Faupi-HideoutArchitect/server/types/callbacks/RagfairCallbacks.d.ts index c609f2f..37f3807 100644 --- a/Faupi-HideoutArchitect/server/types/callbacks/RagfairCallbacks.d.ts +++ b/Faupi-HideoutArchitect/server/types/callbacks/RagfairCallbacks.d.ts @@ -35,7 +35,7 @@ export declare class RagfairCallbacks extends OnLoadOnUpdate { getRoute(): string; search(url: string, info: ISearchRequestData, sessionID: string): IGetBodyResponseData; getMarketPrice(url: string, info: IGetMarketPriceRequestData, sessionID: string): IGetBodyResponseData; - getItemPrices(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + getItemPrices(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData>; addOffer(pmcData: IPmcData, info: IAddOfferRequestData, sessionID: string): IItemEventRouterResponse; removeOffer(pmcData: IPmcData, info: IRemoveOfferRequestData, sessionID: string): IItemEventRouterResponse; extendOffer(pmcData: IPmcData, info: IExtendOfferRequestData, sessionID: string): IItemEventRouterResponse; diff --git a/Faupi-HideoutArchitect/server/types/callbacks/TraderCallbacks.d.ts b/Faupi-HideoutArchitect/server/types/callbacks/TraderCallbacks.d.ts index e4fd099..40a1455 100644 --- a/Faupi-HideoutArchitect/server/types/callbacks/TraderCallbacks.d.ts +++ b/Faupi-HideoutArchitect/server/types/callbacks/TraderCallbacks.d.ts @@ -12,6 +12,10 @@ export declare class TraderCallbacks extends OnLoadOnUpdate { onUpdate(): boolean; getRoute(): string; getTraderSettings(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle client/trading/api/getUserAssortPrice/trader + * @returns + */ getProfilePurchases(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData>; getTrader(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; getAssort(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; diff --git a/Faupi-HideoutArchitect/server/types/callbacks/WeatherCallbacks.d.ts b/Faupi-HideoutArchitect/server/types/callbacks/WeatherCallbacks.d.ts index ae784c8..f9d2002 100644 --- a/Faupi-HideoutArchitect/server/types/callbacks/WeatherCallbacks.d.ts +++ b/Faupi-HideoutArchitect/server/types/callbacks/WeatherCallbacks.d.ts @@ -1,10 +1,15 @@ import { WeatherController } from "../controllers/WeatherController"; import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData"; import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData"; +import { IWeatherData } from "../models/eft/weather/IWeatherData"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; export declare class WeatherCallbacks { protected httpResponse: HttpResponseUtil; protected weatherController: WeatherController; constructor(httpResponse: HttpResponseUtil, weatherController: WeatherController); - getWeather(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle client/weather + * @returns IWeatherData + */ + getWeather(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; } diff --git a/Faupi-HideoutArchitect/server/types/context/ContextVariableType.d.ts b/Faupi-HideoutArchitect/server/types/context/ContextVariableType.d.ts index 5fc1704..a7dd9b5 100644 --- a/Faupi-HideoutArchitect/server/types/context/ContextVariableType.d.ts +++ b/Faupi-HideoutArchitect/server/types/context/ContextVariableType.d.ts @@ -1,4 +1,8 @@ export declare enum ContextVariableType { + /** Logged in users session id */ SESSION_ID = 0, - MATCH_INFO = 1 + /** Currently acive raid information */ + MATCH_INFO = 1, + /** Timestamp when client first connected */ + CLIENT_START_TIMESTAMP = 2 } diff --git a/Faupi-HideoutArchitect/server/types/controllers/BotController.d.ts b/Faupi-HideoutArchitect/server/types/controllers/BotController.d.ts index a5111d5..51c0c68 100644 --- a/Faupi-HideoutArchitect/server/types/controllers/BotController.d.ts +++ b/Faupi-HideoutArchitect/server/types/controllers/BotController.d.ts @@ -1,6 +1,9 @@ import { ApplicationContext } from "../context/ApplicationContext"; import { BotGenerator } from "../generators/BotGenerator"; +import { BotDifficultyHelper } from "../helpers/BotDifficultyHelper"; import { BotHelper } from "../helpers/BotHelper"; +import { ProfileHelper } from "../helpers/ProfileHelper"; +import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper"; import { IGenerateBotsRequestData } from "../models/eft/bot/IGenerateBotsRequestData"; import { IBotBase } from "../models/eft/common/tables/IBotBase"; import { IBotCore } from "../models/eft/common/tables/IBotCore"; @@ -10,24 +13,34 @@ import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { BotGenerationCacheService } from "../services/BotGenerationCacheService"; -import { PmcAiService } from "../services/PmcAiService"; +import { LocalisationService } from "../services/LocalisationService"; +import { JsonUtil } from "../utils/JsonUtil"; export declare class BotController { protected logger: ILogger; protected databaseServer: DatabaseServer; protected botGenerator: BotGenerator; protected botHelper: BotHelper; - protected pmcAiService: PmcAiService; + protected botDifficultyHelper: BotDifficultyHelper; protected botGenerationCacheService: BotGenerationCacheService; + protected localisationService: LocalisationService; + protected weightedRandomHelper: WeightedRandomHelper; + protected profileHelper: ProfileHelper; protected configServer: ConfigServer; protected applicationContext: ApplicationContext; + protected jsonUtil: JsonUtil; protected botConfig: IBotConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, botGenerator: BotGenerator, botHelper: BotHelper, pmcAiService: PmcAiService, botGenerationCacheService: BotGenerationCacheService, configServer: ConfigServer, applicationContext: ApplicationContext); + static readonly pmcTypeLabel = "PMC"; + constructor(logger: ILogger, databaseServer: DatabaseServer, botGenerator: BotGenerator, botHelper: BotHelper, botDifficultyHelper: BotDifficultyHelper, botGenerationCacheService: BotGenerationCacheService, localisationService: LocalisationService, weightedRandomHelper: WeightedRandomHelper, profileHelper: ProfileHelper, configServer: ConfigServer, applicationContext: ApplicationContext, jsonUtil: JsonUtil); /** * Return the number of bot loadout varieties to be generated * @param type bot Type we want the loadout gen count for - * @returns + * @returns number of bots to generate */ getBotPresetGenerationLimit(type: string): number; + /** + * Get the core.json difficulty settings from database\bots + * @returns IBotCore + */ getBotCoreDifficulty(): IBotCore; /** * Get bot difficulty settings @@ -37,7 +50,6 @@ export declare class BotController { * @returns Difficulty object */ getBotDifficulty(type: string, difficulty: string): Difficulty; - protected getPmcDifficultySettings(pmcType: "bear" | "usec", difficulty: string, usecType: string, bearType: string): Difficulty; /** * Generate bot profiles and store in cache * @param sessionId Session id @@ -51,4 +63,5 @@ export declare class BotController { * @returns cap number */ getBotCap(): number; + getPmcBotTypes(): Record>>; } diff --git a/Faupi-HideoutArchitect/server/types/controllers/DialogueController.d.ts b/Faupi-HideoutArchitect/server/types/controllers/DialogueController.d.ts index 1b72522..9c8b728 100644 --- a/Faupi-HideoutArchitect/server/types/controllers/DialogueController.d.ts +++ b/Faupi-HideoutArchitect/server/types/controllers/DialogueController.d.ts @@ -23,7 +23,7 @@ export declare class DialogueController { * Get the content of a dialogue * @param dialogueID Dialog id * @param sessionID Session Id - * @returns + * @returns DialogueInfo */ getDialogueInfo(dialogueID: string, sessionID: string): DialogueInfo; /** diff --git a/Faupi-HideoutArchitect/server/types/controllers/GameController.d.ts b/Faupi-HideoutArchitect/server/types/controllers/GameController.d.ts index 3bfbdb1..f4f5849 100644 --- a/Faupi-HideoutArchitect/server/types/controllers/GameController.d.ts +++ b/Faupi-HideoutArchitect/server/types/controllers/GameController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "../context/ApplicationContext"; import { GameEventHelper } from "../helpers/GameEventHelper"; import { HttpServerHelper } from "../helpers/HttpServerHelper"; import { ProfileHelper } from "../helpers/ProfileHelper"; @@ -14,6 +15,7 @@ import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { LocaleService } from "../services/LocaleService"; +import { LocalisationService } from "../services/LocalisationService"; import { ProfileFixerService } from "../services/ProfileFixerService"; import { Watermark } from "../utils/Watermark"; export declare class GameController { @@ -24,14 +26,33 @@ export declare class GameController { protected localeService: LocaleService; protected profileHelper: ProfileHelper; protected profileFixerService: ProfileFixerService; + protected localisationService: LocalisationService; protected gameEventHelper: GameEventHelper; + protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; protected coreConfig: ICoreConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, watermark: Watermark, httpServerHelper: HttpServerHelper, localeService: LocaleService, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, gameEventHelper: GameEventHelper, configServer: ConfigServer); - gameStart(_url: string, _info: IEmptyRequestData, sessionID: string): void; + constructor(logger: ILogger, databaseServer: DatabaseServer, watermark: Watermark, httpServerHelper: HttpServerHelper, localeService: LocaleService, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, gameEventHelper: GameEventHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + gameStart(_url: string, _info: IEmptyRequestData, sessionID: string, startTimeStampMS: number): void; + /** + * Check if current date falls inside any of the seasons events pased in, if so, handle them + * @param seasonalEvents events to check for + */ protected checkForAndEnableSeasonalEvents(seasonalEvents: ISeasonalEvent[]): void; + /** + * Make adjusted to server code based on the name of the event passed in + * @param globalConfig globals.json + * @param eventName Name of the event to enable. e.g. Christmas + */ protected updateGlobalEvents(globalConfig: Config, eventName: string): void; + /** + * Read in data from seasonalEvents.json and add found equipment items to bots + * @param eventName Name of the event to read equipment in from config + */ + protected addEventGearToScavs(eventName: string): void; + /** + * Set Khorovod(dancing tree) chance to 100% on all maps that support it + */ protected enableDancingTree(): void; /** * Make non-trigger-spawned raiders spawn earlier + always @@ -40,5 +61,6 @@ export declare class GameController { protected logProfileDetails(fullProfile: IAkiProfile): void; getGameConfig(sessionID: string): IGameConfigResponse; getServer(): IServerDetails[]; + protected addPumpkinsToScavBackpacks(): void; getValidGameVersion(): ICheckVersionResponse; } diff --git a/Faupi-HideoutArchitect/server/types/controllers/HideoutController.d.ts b/Faupi-HideoutArchitect/server/types/controllers/HideoutController.d.ts index ada5bd9..5b6507b 100644 --- a/Faupi-HideoutArchitect/server/types/controllers/HideoutController.d.ts +++ b/Faupi-HideoutArchitect/server/types/controllers/HideoutController.d.ts @@ -23,12 +23,13 @@ import { EventOutputHolder } from "../routers/EventOutputHolder"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { SaveServer } from "../servers/SaveServer"; +import { LocalisationService } from "../services/LocalisationService"; import { PlayerService } from "../services/PlayerService"; import { HashUtil } from "../utils/HashUtil"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; +import { JsonUtil } from "../utils/JsonUtil"; import { RandomUtil } from "../utils/RandomUtil"; import { TimeUtil } from "../utils/TimeUtil"; -import { JsonUtil } from "../utils/JsonUtil"; export declare class HideoutController { protected logger: ILogger; protected hashUtil: HashUtil; @@ -45,11 +46,12 @@ export declare class HideoutController { protected profileHelper: ProfileHelper; protected hideoutHelper: HideoutHelper; protected scavCaseRewardGenerator: ScavCaseRewardGenerator; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected jsonUtil: JsonUtil; protected static nameBackendCountersCrafting: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, randomUtil: RandomUtil, inventoryHelper: InventoryHelper, saveServer: SaveServer, playerService: PlayerService, presetHelper: PresetHelper, paymentHelper: PaymentHelper, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, profileHelper: ProfileHelper, hideoutHelper: HideoutHelper, scavCaseRewardGenerator: ScavCaseRewardGenerator, configServer: ConfigServer, jsonUtil: JsonUtil); + constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, randomUtil: RandomUtil, inventoryHelper: InventoryHelper, saveServer: SaveServer, playerService: PlayerService, presetHelper: PresetHelper, paymentHelper: PaymentHelper, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, profileHelper: ProfileHelper, hideoutHelper: HideoutHelper, scavCaseRewardGenerator: ScavCaseRewardGenerator, localisationService: LocalisationService, configServer: ConfigServer, jsonUtil: JsonUtil); upgrade(pmcData: IPmcData, body: IHideoutUpgradeRequestData, sessionID: string): IItemEventRouterResponse; upgradeComplete(pmcData: IPmcData, body: HideoutUpgradeCompleteRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/Faupi-HideoutArchitect/server/types/controllers/InraidController.d.ts b/Faupi-HideoutArchitect/server/types/controllers/InraidController.d.ts index e84eea1..39a6396 100644 --- a/Faupi-HideoutArchitect/server/types/controllers/InraidController.d.ts +++ b/Faupi-HideoutArchitect/server/types/controllers/InraidController.d.ts @@ -6,6 +6,7 @@ import { ProfileHelper } from "../helpers/ProfileHelper"; import { QuestHelper } from "../helpers/QuestHelper"; import { TraderHelper } from "../helpers/TraderHelper"; import { IPmcData } from "../models/eft/common/IPmcData"; +import { Item } from "../models/eft/common/tables/IItem"; import { IRegisterPlayerRequestData } from "../models/eft/inRaid/IRegisterPlayerRequestData"; import { ISaveProgressRequestData } from "../models/eft/inRaid/ISaveProgressRequestData"; import { IAirdropConfig } from "../models/spt/config/IAirdropConfig"; @@ -17,6 +18,9 @@ import { SaveServer } from "../servers/SaveServer"; import { InsuranceService } from "../services/InsuranceService"; import { JsonUtil } from "../utils/JsonUtil"; import { TimeUtil } from "../utils/TimeUtil"; +/** + * Logic for handling In Raid callbacks + */ export declare class InraidController { protected logger: ILogger; protected saveServer: SaveServer; @@ -35,14 +39,42 @@ export declare class InraidController { protected airdropConfig: IAirdropConfig; protected inraidConfig: IInRaidConfig; constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, questHelper: QuestHelper, itemHelper: ItemHelper, profileHelper: ProfileHelper, playerScavGenerator: PlayerScavGenerator, healthHelper: HealthHelper, traderHelper: TraderHelper, insuranceService: InsuranceService, inRaidHelper: InRaidHelper, configServer: ConfigServer); - addPlayer(sessionID: string, info: IRegisterPlayerRequestData): void; - saveProgress(offraidData: ISaveProgressRequestData, sessionID: string): void; /** - * Handle updating the profile post-pmc raid + * Save locationid to active profiles inraid object + * @param sessionID Session id + * @param info Register player request + */ + addPlayer(sessionID: string, info: IRegisterPlayerRequestData): void; + /** + * Save profile state to disk + * Handles pmc/pscav + * @param offraidData post-raid request data + * @param sessionID Session id + */ + savePostRaidProgress(offraidData: ISaveProgressRequestData, sessionID: string): void; + /** + * Handle updating player profile post-pmc raid * @param sessionID session id - * @param offraidData post-raid data of raid + * @param offraidData post-raid data */ protected savePmcProgress(sessionID: string, offraidData: ISaveProgressRequestData): void; + /** + * Make changes to pmc profile after they left raid dead, + * alter bodypart hp, handle insurance, delete inventory items, remove carried quest items + * @param postRaidSaveRequest post-raid save request + * @param pmcData pmc profile + * @param insuranceEnabled is insurance enabled + * @param preRaidGear gear player had before raid + * @param sessionID Session id + * @returns Updated profile object + */ + protected performPostRaidActionsWhenDead(postRaidSaveRequest: ISaveProgressRequestData, pmcData: IPmcData, insuranceEnabled: boolean, preRaidGear: Item[], sessionID: string): IPmcData; + /** + * Adjust player characters bodypart hp if they left raid early + * @param postRaidSaveRequest post raid data + * @param pmcData player profile + */ + protected updatePmcHealthPostRaid(postRaidSaveRequest: ISaveProgressRequestData, pmcData: IPmcData): void; /** * Reduce body part hp to % of max * @param pmcData profile to edit @@ -68,7 +100,31 @@ export declare class InraidController { * @param isPlayerScav Was the player a pScav */ protected markOrRemoveFoundInRaidItems(offraidData: ISaveProgressRequestData, pmcData: IPmcData, isPlayerScav: boolean): void; + /** + * Update profile after player completes scav raid + * @param scavData Scav profile + * @param sessionID Session id + * @param offraidData Post-raid save request + * @param pmcData Pmc profile + * @param isDead Is player dead + */ protected handlePostRaidPlayerScavProcess(scavData: IPmcData, sessionID: string, offraidData: ISaveProgressRequestData, pmcData: IPmcData, isDead: boolean): void; + /** + * Update profile with scav karma values based on in-raid actions + * @param pmcData Pmc profile + * @param offraidData Post-raid save request + * @param scavData Scav profile + * @param sessionID Session id + */ protected handlePostRaidPlayerScavKarmaChanges(pmcData: IPmcData, offraidData: ISaveProgressRequestData, scavData: IPmcData, sessionID: string): void; + /** + * Get the inraid config from configs/inraid.json + * @returns InRaid Config + */ + getInraidConfig(): IInRaidConfig; + /** + * Get airdrop config from configs/airdrop.json + * @returns Airdrop config + */ getAirdropConfig(): IAirdropConfig; } diff --git a/Faupi-HideoutArchitect/server/types/controllers/InsuranceController.d.ts b/Faupi-HideoutArchitect/server/types/controllers/InsuranceController.d.ts index 14bf129..54f31b5 100644 --- a/Faupi-HideoutArchitect/server/types/controllers/InsuranceController.d.ts +++ b/Faupi-HideoutArchitect/server/types/controllers/InsuranceController.d.ts @@ -30,8 +30,7 @@ export declare class InsuranceController { protected insuranceService: InsuranceService; protected configServer: ConfigServer; protected insuranceConfig: IInsuranceConfig; - constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, paymentService: PaymentService, // TODO: delay required - insuranceService: InsuranceService, configServer: ConfigServer); + constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, paymentService: PaymentService, insuranceService: InsuranceService, configServer: ConfigServer); processReturn(): void; insure(pmcData: IPmcData, body: IInsureRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/Faupi-HideoutArchitect/server/types/controllers/InventoryController.d.ts b/Faupi-HideoutArchitect/server/types/controllers/InventoryController.d.ts index 6a1a21e..e1c08c0 100644 --- a/Faupi-HideoutArchitect/server/types/controllers/InventoryController.d.ts +++ b/Faupi-HideoutArchitect/server/types/controllers/InventoryController.d.ts @@ -1,8 +1,8 @@ -import { EventOutputHolder } from "../routers/EventOutputHolder"; import { InventoryHelper } from "../helpers/InventoryHelper"; import { PaymentHelper } from "../helpers/PaymentHelper"; import { PresetHelper } from "../helpers/PresetHelper"; import { ProfileHelper } from "../helpers/ProfileHelper"; +import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper"; import { IPmcData } from "../models/eft/common/IPmcData"; import { IAddItemRequestData } from "../models/eft/inventory/IAddItemRequestData"; import { IInventoryBindRequestData } from "../models/eft/inventory/IInventoryBindRequestData"; @@ -21,33 +21,46 @@ import { IInventorySwapRequestData } from "../models/eft/inventory/IInventorySwa import { IInventoryTagRequestData } from "../models/eft/inventory/IInventoryTagRequestData"; import { IInventoryToggleRequestData } from "../models/eft/inventory/IInventoryToggleRequestData"; import { IInventoryTransferRequestData } from "../models/eft/inventory/IInventoryTransferRequestData"; +import { IOpenRandomLootContainerRequestData } from "../models/eft/inventory/IOpenRandomLootContainerRequestData"; import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse"; import { ILogger } from "../models/spt/utils/ILogger"; +import { EventOutputHolder } from "../routers/EventOutputHolder"; import { DatabaseServer } from "../servers/DatabaseServer"; import { FenceService } from "../services/FenceService"; +import { LocalisationService } from "../services/LocalisationService"; import { RagfairOfferService } from "../services/RagfairOfferService"; import { HashUtil } from "../utils/HashUtil"; +import { HttpResponseUtil } from "../utils/HttpResponseUtil"; import { JsonUtil } from "../utils/JsonUtil"; +import { RandomUtil } from "../utils/RandomUtil"; export declare class InventoryController { protected logger: ILogger; protected hashUtil: HashUtil; protected jsonUtil: JsonUtil; + protected randomUtil: RandomUtil; protected databaseServer: DatabaseServer; protected fenceService: FenceService; protected presetHelper: PresetHelper; protected inventoryHelper: InventoryHelper; protected ragfairOfferService: RagfairOfferService; protected profileHelper: ProfileHelper; + protected weightedRandomHelper: WeightedRandomHelper; protected paymentHelper: PaymentHelper; + protected localisationService: LocalisationService; protected eventOutputHolder: EventOutputHolder; - constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, fenceService: FenceService, presetHelper: PresetHelper, inventoryHelper: InventoryHelper, ragfairOfferService: RagfairOfferService, profileHelper: ProfileHelper, paymentHelper: PaymentHelper, eventOutputHolder: EventOutputHolder); + protected httpResponseUtil: HttpResponseUtil; + constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, fenceService: FenceService, presetHelper: PresetHelper, inventoryHelper: InventoryHelper, ragfairOfferService: RagfairOfferService, profileHelper: ProfileHelper, weightedRandomHelper: WeightedRandomHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, eventOutputHolder: EventOutputHolder, httpResponseUtil: HttpResponseUtil); /** * Move Item * change location of item with parentId and slotId * transfers items from one profile to another if fromOwner/toOwner is set in the body. * otherwise, move is contained within the same profile_f. - */ - moveItem(pmcData: IPmcData, body: IInventoryMoveRequestData, sessionID: string): IItemEventRouterResponse; + * @param pmcData Profile + * @param moveRequest Move request data + * @param sessionID Session id + * @returns IItemEventRouterResponse + */ + moveItem(pmcData: IPmcData, moveRequest: IInventoryMoveRequestData, sessionID: string): IItemEventRouterResponse; /** * Remove Item from Profile * Deep tree item deletion, also removes items from insurance list @@ -122,4 +135,12 @@ export declare class InventoryController { createMapMarker(pmcData: IPmcData, body: IInventoryCreateMarkerRequestData, sessionID: string): IItemEventRouterResponse; deleteMapMarker(pmcData: IPmcData, body: IInventoryDeleteMarkerRequestData, sessionID: string): IItemEventRouterResponse; editMapMarker(pmcData: IPmcData, body: IInventoryEditMarkerRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle event fired when a container is unpacked (currently only the halloween pumpkin) + * @param pmcData Profile data + * @param body open loot container request data + * @param sessionID Session id + * @returns IItemEventRouterResponse + */ + openRandomLootContainer(pmcData: IPmcData, body: IOpenRandomLootContainerRequestData, sessionID: string): IItemEventRouterResponse; } diff --git a/Faupi-HideoutArchitect/server/types/controllers/LocationController.d.ts b/Faupi-HideoutArchitect/server/types/controllers/LocationController.d.ts index 9db3205..b6feba8 100644 --- a/Faupi-HideoutArchitect/server/types/controllers/LocationController.d.ts +++ b/Faupi-HideoutArchitect/server/types/controllers/LocationController.d.ts @@ -7,6 +7,7 @@ import { LootItem } from "../models/spt/services/LootItem"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "../services/LocalisationService"; import { HashUtil } from "../utils/HashUtil"; import { JsonUtil } from "../utils/JsonUtil"; import { TimeUtil } from "../utils/TimeUtil"; @@ -15,12 +16,13 @@ export declare class LocationController { protected hashUtil: HashUtil; protected logger: ILogger; protected locationGenerator: LocationGenerator; + protected localisationService: LocalisationService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; protected airdropConfig: IAirdropConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger, locationGenerator: LocationGenerator, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); get(location: string): ILocationBase; generate(name: string): ILocationBase; generateAll(): ILocationsGenerateAllResponse; diff --git a/Faupi-HideoutArchitect/server/types/controllers/MatchController.d.ts b/Faupi-HideoutArchitect/server/types/controllers/MatchController.d.ts index dac6a3f..2b0d150 100644 --- a/Faupi-HideoutArchitect/server/types/controllers/MatchController.d.ts +++ b/Faupi-HideoutArchitect/server/types/controllers/MatchController.d.ts @@ -19,7 +19,6 @@ import { SaveServer } from "../servers/SaveServer"; import { BotGenerationCacheService } from "../services/BotGenerationCacheService"; import { BotLootCacheService } from "../services/BotLootCacheService"; import { MatchLocationService } from "../services/MatchLocationService"; -import { PmcAiService } from "../services/PmcAiService"; import { ProfileSnapshotService } from "../services/ProfileSnapshotService"; export declare class MatchController { protected logger: ILogger; @@ -30,13 +29,12 @@ export declare class MatchController { protected botLootCacheService: BotLootCacheService; protected configServer: ConfigServer; protected profileSnapshotService: ProfileSnapshotService; - protected pmcAiService: PmcAiService; protected botGenerationCacheService: BotGenerationCacheService; protected applicationContext: ApplicationContext; protected matchConfig: IMatchConfig; protected inraidConfig: IInRaidConfig; protected botConfig: IBotConfig; - constructor(logger: ILogger, saveServer: SaveServer, profileHelper: ProfileHelper, matchLocationService: MatchLocationService, traderHelper: TraderHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer, profileSnapshotService: ProfileSnapshotService, pmcAiService: PmcAiService, botGenerationCacheService: BotGenerationCacheService, applicationContext: ApplicationContext); + constructor(logger: ILogger, saveServer: SaveServer, profileHelper: ProfileHelper, matchLocationService: MatchLocationService, traderHelper: TraderHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer, profileSnapshotService: ProfileSnapshotService, botGenerationCacheService: BotGenerationCacheService, applicationContext: ApplicationContext); getEnabled(): boolean; getProfile(info: IGetProfileRequestData): IPmcData[]; createGroup(sessionID: string, info: ICreateGroupRequestData): any; diff --git a/Faupi-HideoutArchitect/server/types/controllers/RagfairController.d.ts b/Faupi-HideoutArchitect/server/types/controllers/RagfairController.d.ts index 5440458..95702f2 100644 --- a/Faupi-HideoutArchitect/server/types/controllers/RagfairController.d.ts +++ b/Faupi-HideoutArchitect/server/types/controllers/RagfairController.d.ts @@ -29,6 +29,7 @@ import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { RagfairServer } from "../servers/RagfairServer"; import { SaveServer } from "../servers/SaveServer"; +import { LocalisationService } from "../services/LocalisationService"; import { PaymentService } from "../services/PaymentService"; import { RagfairOfferService } from "../services/RagfairOfferService"; import { RagfairPriceService } from "../services/RagfairPriceService"; @@ -62,9 +63,10 @@ export declare class RagfairController { protected ragfairOfferService: RagfairOfferService; protected ragfairRequiredItemsService: RagfairRequiredItemsService; protected ragfairOfferGenerator: RagfairOfferGenerator; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected ragfairConfig: IRagfairConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, eventOutputHolder: EventOutputHolder, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, traderHelper: TraderHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, eventOutputHolder: EventOutputHolder, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, traderHelper: TraderHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, localisationService: LocalisationService, configServer: ConfigServer); getOffers(sessionID: string, info: ISearchRequestData): IGetOffersResult; /** * Get offers for the client based on type of search being performed @@ -103,7 +105,12 @@ export declare class RagfairController { protected isLinkedSearch(info: ISearchRequestData): boolean; protected isRequiredSearch(info: ISearchRequestData): boolean; update(): void; - getItemPrice(info: IGetMarketPriceRequestData): IGetItemPriceResult; + /** + * Called when creating an offer on flea, fills values in top right corner + * @param getPriceRequest + * @returns min/avg/max values for an item based on flea offers available + */ + getItemMinAvgMaxFleaPriceValues(getPriceRequest: IGetMarketPriceRequestData): IGetItemPriceResult; addPlayerOffer(pmcData: IPmcData, info: IAddOfferRequestData, sessionID: string): IItemEventRouterResponse; createPlayerOffer(profile: IAkiProfile, requirements: Requirement[], items: Item[], sellInOnePiece: boolean, amountToSend: number): IRagfairOffer; getAllFleaPrices(): Record; diff --git a/Faupi-HideoutArchitect/server/types/controllers/RepeatableQuestController.d.ts b/Faupi-HideoutArchitect/server/types/controllers/RepeatableQuestController.d.ts index 7db5886..333583b 100644 --- a/Faupi-HideoutArchitect/server/types/controllers/RepeatableQuestController.d.ts +++ b/Faupi-HideoutArchitect/server/types/controllers/RepeatableQuestController.d.ts @@ -17,6 +17,7 @@ import { EventOutputHolder } from "../routers/EventOutputHolder"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { ItemFilterService } from "../services/ItemFilterService"; +import { LocalisationService } from "../services/LocalisationService"; import { PaymentService } from "../services/PaymentService"; import { ProfileFixerService } from "../services/ProfileFixerService"; import { JsonUtil } from "../utils/JsonUtil"; @@ -64,12 +65,13 @@ export declare class RepeatableQuestController { protected profileFixerService: ProfileFixerService; protected ragfairServerHelper: RagfairServerHelper; protected eventOutputHolder: EventOutputHolder; + protected localisationService: LocalisationService; protected paymentService: PaymentService; protected objectId: ObjectId; protected itemFilterService: ItemFilterService; protected configServer: ConfigServer; protected questConfig: IQuestConfig; - constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, eventOutputHolder: EventOutputHolder, paymentService: PaymentService, objectId: ObjectId, itemFilterService: ItemFilterService, configServer: ConfigServer); + constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, eventOutputHolder: EventOutputHolder, localisationService: LocalisationService, paymentService: PaymentService, objectId: ObjectId, itemFilterService: ItemFilterService, configServer: ConfigServer); /** * This is the method reached by the /client/repeatalbeQuests/activityPeriods endpoint * Returns an array of objects in the format of repeatable quests to the client. diff --git a/Faupi-HideoutArchitect/server/types/controllers/WeatherController.d.ts b/Faupi-HideoutArchitect/server/types/controllers/WeatherController.d.ts index ca7f5eb..631a90c 100644 --- a/Faupi-HideoutArchitect/server/types/controllers/WeatherController.d.ts +++ b/Faupi-HideoutArchitect/server/types/controllers/WeatherController.d.ts @@ -1,11 +1,18 @@ import { WeatherGenerator } from "../generators/WeatherGenerator"; import { IWeatherData } from "../models/eft/weather/IWeatherData"; import { IWeatherConfig } from "../models/spt/config/IWeatherConfig"; +import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; export declare class WeatherController { protected weatherGenerator: WeatherGenerator; + protected logger: ILogger; protected configServer: ConfigServer; protected weatherConfig: IWeatherConfig; - constructor(weatherGenerator: WeatherGenerator, configServer: ConfigServer); + constructor(weatherGenerator: WeatherGenerator, logger: ILogger, configServer: ConfigServer); generate(): IWeatherData; + /** + * Get the current in-raid time (MUST HAVE PLAYER LOGGED INTO CLIENT TO WORK) + * @returns Date object + */ + getCurrentInRaidTime(): Date; } diff --git a/Faupi-HideoutArchitect/server/types/generators/BotGenerator.d.ts b/Faupi-HideoutArchitect/server/types/generators/BotGenerator.d.ts index 2ac51db..08ad50a 100644 --- a/Faupi-HideoutArchitect/server/types/generators/BotGenerator.d.ts +++ b/Faupi-HideoutArchitect/server/types/generators/BotGenerator.d.ts @@ -1,25 +1,21 @@ +import { BotDifficultyHelper } from "../helpers/BotDifficultyHelper"; import { BotHelper } from "../helpers/BotHelper"; import { GameEventHelper } from "../helpers/GameEventHelper"; import { ProfileHelper } from "../helpers/ProfileHelper"; -import { IGenerateBotsRequestData } from "../models/eft/bot/IGenerateBotsRequestData"; +import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper"; import { Health as PmcHealth, IBotBase, Skills } from "../models/eft/common/tables/IBotBase"; import { Health, IBotType, Inventory } from "../models/eft/common/tables/IBotType"; +import { BotGenerationDetails } from "../models/spt/bots/BotGenerationDetails"; import { IBotConfig } from "../models/spt/config/IBotConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { BotEquipmentFilterService } from "../services/BotEquipmentFilterService"; -import { PmcAiService } from "../services/PmcAiService"; import { HashUtil } from "../utils/HashUtil"; import { JsonUtil } from "../utils/JsonUtil"; import { RandomUtil } from "../utils/RandomUtil"; import { BotInventoryGenerator } from "./BotInventoryGenerator"; -declare namespace BotGenerator { - interface IRandomisedBotLevelResult { - level: number; - exp: number; - } -} +import { BotLevelGenerator } from "./BotLevelGenerator"; export declare class BotGenerator { protected logger: ILogger; protected hashUtil: HashUtil; @@ -28,13 +24,15 @@ export declare class BotGenerator { protected profileHelper: ProfileHelper; protected databaseServer: DatabaseServer; protected botInventoryGenerator: BotInventoryGenerator; + protected botLevelGenerator: BotLevelGenerator; protected botEquipmentFilterService: BotEquipmentFilterService; + protected weightedRandomHelper: WeightedRandomHelper; protected botHelper: BotHelper; + protected botDifficultyHelper: BotDifficultyHelper; protected gameEventHelper: GameEventHelper; - protected pmcAiService: PmcAiService; protected configServer: ConfigServer; protected botConfig: IBotConfig; - constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, jsonUtil: JsonUtil, profileHelper: ProfileHelper, databaseServer: DatabaseServer, botInventoryGenerator: BotInventoryGenerator, botEquipmentFilterService: BotEquipmentFilterService, botHelper: BotHelper, gameEventHelper: GameEventHelper, pmcAiService: PmcAiService, configServer: ConfigServer); + constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, jsonUtil: JsonUtil, profileHelper: ProfileHelper, databaseServer: DatabaseServer, botInventoryGenerator: BotInventoryGenerator, botLevelGenerator: BotLevelGenerator, botEquipmentFilterService: BotEquipmentFilterService, weightedRandomHelper: WeightedRandomHelper, botHelper: BotHelper, botDifficultyHelper: BotDifficultyHelper, gameEventHelper: GameEventHelper, configServer: ConfigServer); /** * Generate a player scav bot object * @param role e.g. assault / pmcbot @@ -44,12 +42,18 @@ export declare class BotGenerator { */ generatePlayerScav(sessionId: string, role: string, difficulty: string, botTemplate: IBotType): IBotBase; /** - * Generate an array of bot objects for populate a raid with + * Generate an array of bot objects based on a condition for a raid with * @param sessionId session id - * @param info request object - * @returns bot array + * @param botGenerationDetails details on how to generate the bots + * @returns Generated bots in array */ - generate(sessionId: string, info: IGenerateBotsRequestData): IBotBase[]; + generateByCondition(sessionId: string, botGenerationDetails: BotGenerationDetails): IBotBase[]; + /** + * Get the PMCs wildSpawnType value + * @param role "usec" / "bear" + * @returns wildSpawnType value as string + */ + protected getPmcRoleByDescription(role: string): string; /** * Get a randomised PMC side based on bot config value 'isUsec' * @returns pmc side as string @@ -64,26 +68,24 @@ export declare class BotGenerator { * Create a IBotBase object with equipment/loot/exp etc * @param sessionId Session id * @param bot bots base file - * @param role botRole bot will use - * @param node Bot template from db/bots/x.json - * @param isPmc Is bot to be a PMC - * @param isPlayerScav is bot to be a p scav bot + * @param botJsonTemplate Bot template from db/bots/x.json + * @param botGenerationDetails details on how to generate the bot * @returns IBotBase object */ - protected generateBot(sessionId: string, bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase; + protected generateBot(sessionId: string, bot: IBotBase, botJsonTemplate: IBotType, botGenerationDetails: BotGenerationDetails): IBotBase; + /** + * Create a bot nickname + * @param botJsonTemplate x.json from database + * @param isPlayerScav Will bot be player scav + * @param botRole role of bot e.g. assault + * @returns Nickname for bot + */ + protected generateBotNickname(botJsonTemplate: IBotType, isPlayerScav: boolean, botRole: string): string; /** * Log the number of PMCs generated to the debug console * @param output Generated bot array, ready to send to client */ protected logPmcGeneratedCount(output: IBotBase[]): void; - /** - * Return a randomised bot level and exp value - * @param role botRole being generated for - * @param min Min exp value - * @param max Max exp value - * @returns IRandomisedBotLevelResult object - */ - protected generateRandomLevel(role: string, min: number, max: number): BotGenerator.IRandomisedBotLevelResult; /** * Converts health object to the required format * @param healthObj health object from bot json @@ -117,4 +119,3 @@ export declare class BotGenerator { */ protected generateDogtag(bot: IBotBase): IBotBase; } -export {}; diff --git a/Faupi-HideoutArchitect/server/types/generators/BotInventoryGenerator.d.ts b/Faupi-HideoutArchitect/server/types/generators/BotInventoryGenerator.d.ts index c5ed545..a3b5eaa 100644 --- a/Faupi-HideoutArchitect/server/types/generators/BotInventoryGenerator.d.ts +++ b/Faupi-HideoutArchitect/server/types/generators/BotInventoryGenerator.d.ts @@ -1,12 +1,14 @@ import { BotGeneratorHelper } from "../helpers/BotGeneratorHelper"; +import { BotHelper } from "../helpers/BotHelper"; import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper"; import { Inventory as PmcInventory } from "../models/eft/common/tables/IBotBase"; -import { Chances, Generation, Inventory, Mods } from "../models/eft/common/tables/IBotType"; +import { Chances, Generation, IBotType, Inventory, Mods } from "../models/eft/common/tables/IBotType"; import { EquipmentSlots } from "../models/enums/EquipmentSlots"; -import { IBotConfig } from "../models/spt/config/IBotConfig"; +import { IBotConfig, RandomisationDetails } from "../models/spt/config/IBotConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "../services/LocalisationService"; import { HashUtil } from "../utils/HashUtil"; import { RandomUtil } from "../utils/RandomUtil"; import { BotLootGenerator } from "./BotLootGenerator"; @@ -19,15 +21,81 @@ export declare class BotInventoryGenerator { protected botWeaponGenerator: BotWeaponGenerator; protected botLootGenerator: BotLootGenerator; protected botGeneratorHelper: BotGeneratorHelper; + protected botHelper: BotHelper; protected weightedRandomHelper: WeightedRandomHelper; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected botConfig: IBotConfig; - constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, botWeaponGenerator: BotWeaponGenerator, botLootGenerator: BotLootGenerator, botGeneratorHelper: BotGeneratorHelper, weightedRandomHelper: WeightedRandomHelper, configServer: ConfigServer); - generateInventory(sessionId: string, templateInventory: Inventory, equipmentChances: Chances, itemGenerationLimitsMinMax: Generation, botRole: string, isPmc: boolean): PmcInventory; + constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, botWeaponGenerator: BotWeaponGenerator, botLootGenerator: BotLootGenerator, botGeneratorHelper: BotGeneratorHelper, botHelper: BotHelper, weightedRandomHelper: WeightedRandomHelper, localisationService: LocalisationService, configServer: ConfigServer); + /** + * Add equipment/weapons/loot to bot + * @param sessionId Session id + * @param botJsonTemplate bot/x.json data from db + * @param botRole Role bot has (assault/pmcBot) + * @param isPmc Is bot being converted into a pmc + * @param botLevel Level of bot being generated + * @returns PmcInventory object with equipment/weapons/loot + */ + generateInventory(sessionId: string, botJsonTemplate: IBotType, botRole: string, isPmc: boolean, botLevel: number): PmcInventory; + /** + * Create a pmcInventory object with all the base/generic items needed + * @returns PmcInventory object + */ + protected generateInventoryBase(): PmcInventory; + /** + * Add equipment to a bot + * @param templateInventory bot/x.json data from db + * @param equipmentChances Chances items will be added to bot + * @param botRole Role bot has (assault/pmcBot) + * @param botInventory Inventory to add equipment to + * @param botLevel Level of bot + */ + protected generateAndAddEquipmentToBot(templateInventory: Inventory, equipmentChances: Chances, botRole: string, botInventory: PmcInventory, botLevel: number): void; + /** + * Add a piece of equipment with mods to inventory from the provided pools + * @param equipmentSlot Slot to select an item for + * @param equipmentPool Possible items to choose from + * @param modPool Possible mods to apply to item chosen + * @param spawnChances Chances items will be chosen to be added + * @param botRole Role of bot e.g. assault + * @param inventory Inventory to add item into + * @param randomisationDetails settings from bot.json to adjust how item is generated + */ + protected generateEquipment(equipmentSlot: string, equipmentPool: Record, modPool: Mods, spawnChances: Chances, botRole: string, inventory: PmcInventory, randomisationDetails: RandomisationDetails): void; + /** + * Work out what weapons bot should have equipped and add them to bot inventory + * @param templateInventory bot/x.json data from db + * @param equipmentChances Chances bot can have equipment equipped + * @param sessionId Session id + * @param botInventory Inventory to add weapons to + * @param botRole assault/pmcBot/bossTagilla etc + * @param isPmc Is the bot being generated as a pmc + * @param botLevel level of bot having weapon generated + * @param itemGenerationLimitsMinMax Limits for items the bot can have + */ + protected generateAndAddWeaponsToBot(templateInventory: Inventory, equipmentChances: Chances, sessionId: string, botInventory: PmcInventory, botRole: string, isPmc: boolean, itemGenerationLimitsMinMax: Generation, botLevel: number): void; + /** + * Calculate if the bot should have weapons in Primary/Secondary/Holster slots + * @param equipmentChances Chances bot has certain equipment + * @returns What slots bot should have weapons generated for + */ + protected getDesiredWeaponsForBot(equipmentChances: Chances): { + slot: EquipmentSlots; + shouldSpawn: boolean; + }[]; + /** + * Add weapon + spare mags/ammo to bots inventory + * @param sessionId Session id + * @param weaponSlot Weapon slot being generated + * @param templateInventory bot/x.json data from db + * @param botInventory Inventory to add weapon+mags/ammo to + * @param equipmentChances Chances bot can have equipment equipped + * @param botRole assault/pmcBot/bossTagilla etc + * @param isPmc Is the bot being generated as a pmc + * @param itemGenerationLimitsMinMax + */ protected addWeaponAndMagazinesToInventory(sessionId: string, weaponSlot: { slot: EquipmentSlots; shouldSpawn: boolean; - }, templateInventory: Inventory, botInventory: PmcInventory, equipmentChances: Chances, botRole: string, isPmc: boolean, itemGenerationLimitsMinMax: Generation): void; - protected generateEquipment(equipmentSlot: string, equipmentPool: Record, modPool: Mods, spawnChances: Chances, botRole: string, inventory: PmcInventory): void; - protected generateInventoryBase(): PmcInventory; + }, templateInventory: Inventory, botInventory: PmcInventory, equipmentChances: Chances, botRole: string, isPmc: boolean, itemGenerationLimitsMinMax: Generation, botLevel: number): void; } diff --git a/Faupi-HideoutArchitect/server/types/generators/BotLevelGenerator.d.ts b/Faupi-HideoutArchitect/server/types/generators/BotLevelGenerator.d.ts new file mode 100644 index 0000000..751e6e6 --- /dev/null +++ b/Faupi-HideoutArchitect/server/types/generators/BotLevelGenerator.d.ts @@ -0,0 +1,29 @@ +import { MinMax } from "../models/common/MinMax"; +import { IRandomisedBotLevelResult } from "../models/eft/bot/IRandomisedBotLevelResult"; +import { ExpTable } from "../models/eft/common/IGlobals"; +import { IBotBase } from "../models/eft/common/tables/IBotBase"; +import { BotGenerationDetails } from "../models/spt/bots/BotGenerationDetails"; +import { ILogger } from "../models/spt/utils/ILogger"; +import { DatabaseServer } from "../servers/DatabaseServer"; +import { RandomUtil } from "../utils/RandomUtil"; +export declare class BotLevelGenerator { + protected logger: ILogger; + protected randomUtil: RandomUtil; + protected databaseServer: DatabaseServer; + constructor(logger: ILogger, randomUtil: RandomUtil, databaseServer: DatabaseServer); + /** + * Return a randomised bot level and exp value + * @param levelDetails min and max of level for bot + * @param botGenerationDetails Deatils to help generate a bot + * @param bot being level is being generated for + * @returns IRandomisedBotLevelResult object + */ + generateBotLevel(levelDetails: MinMax, botGenerationDetails: BotGenerationDetails, bot: IBotBase): IRandomisedBotLevelResult; + /** + * Get the highest level a bot can be relative to the players level, but no futher than the max size from globals.exp_table + * @param playerLevel Players current level + * @param relativeDeltaMax max delta above player level to go + * @returns highest level possible for bot + */ + protected getHighestRelativeBotLevel(playerLevel: number, relativeDeltaMax: number, levelDetails: MinMax, expTable: ExpTable[]): number; +} diff --git a/Faupi-HideoutArchitect/server/types/generators/BotLootGenerator.d.ts b/Faupi-HideoutArchitect/server/types/generators/BotLootGenerator.d.ts index c1f5310..6273a11 100644 --- a/Faupi-HideoutArchitect/server/types/generators/BotLootGenerator.d.ts +++ b/Faupi-HideoutArchitect/server/types/generators/BotLootGenerator.d.ts @@ -10,6 +10,7 @@ import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { BotLootCacheService } from "../services/BotLootCacheService"; +import { LocalisationService } from "../services/LocalisationService"; import { HashUtil } from "../utils/HashUtil"; import { RandomUtil } from "../utils/RandomUtil"; import { BotWeaponGenerator } from "./BotWeaponGenerator"; @@ -23,10 +24,22 @@ export declare class BotLootGenerator { protected botWeaponGenerator: BotWeaponGenerator; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; protected botLootCacheService: BotLootCacheService; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected botConfig: IBotConfig; - constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, botGeneratorHelper: BotGeneratorHelper, botWeaponGenerator: BotWeaponGenerator, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer); - generateLoot(sessionId: string, templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void; + constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, botGeneratorHelper: BotGeneratorHelper, botWeaponGenerator: BotWeaponGenerator, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, botLootCacheService: BotLootCacheService, localisationService: LocalisationService, configServer: ConfigServer); + /** + * Add loot to bots containers + * @param sessionId Session id + * @param templateInventory x.json from database/bots + * @param itemCounts Liits on item types to be added as loot + * @param isPmc Will bot be a pmc + * @param botRole Role of bot, e.g. asssult + * @param botInventory Inventory to add loot to + * @param equipmentChances + * @param botLevel Level of bot + */ + generateLoot(sessionId: string, templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances, botLevel: number): void; protected getRandomisedCount(min: number, max: number, nValue: number): number; /** * Take random items from a pool and add to an inventory until totalItemCount or totalValueLimit is reached @@ -49,7 +62,7 @@ export declare class BotLootGenerator { * @param botRole bots role, .e.g. pmcBot * @param isPmc are we generating for a pmc */ - protected addLooseWeaponsToInventorySlot(sessionId: string, botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void; + protected addLooseWeaponsToInventorySlot(sessionId: string, botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): void; /** * Get a random item from the pool parameter using the biasedRandomNumber system * @param pool pool of items to pick an item from @@ -113,7 +126,7 @@ export declare class BotLootGenerator { * If no limit found for a non pmc bot, fall back to defaults * @param isPmc is the bot we want limits for a pmc * @param botRole what role does the bot have - * @returns dictionary of tplIds and limit + * @returns Dictionary of tplIds and limit */ protected getItemSpawnLimitsForBotType(isPmc: boolean, botRole: string): Record; /** diff --git a/Faupi-HideoutArchitect/server/types/generators/BotWeaponGenerator.d.ts b/Faupi-HideoutArchitect/server/types/generators/BotWeaponGenerator.d.ts index 487901b..b2eaf3b 100644 --- a/Faupi-HideoutArchitect/server/types/generators/BotWeaponGenerator.d.ts +++ b/Faupi-HideoutArchitect/server/types/generators/BotWeaponGenerator.d.ts @@ -12,6 +12,7 @@ import { IBotConfig } from "../models/spt/config/IBotConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "../services/LocalisationService"; import { HashUtil } from "../utils/HashUtil"; import { JsonUtil } from "../utils/JsonUtil"; import { RandomUtil } from "../utils/RandomUtil"; @@ -27,10 +28,11 @@ export declare class BotWeaponGenerator { protected randomUtil: RandomUtil; protected configServer: ConfigServer; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; + protected localisationService: LocalisationService; protected inventoryMagGenComponents: IInventoryMagGen[]; protected readonly modMagazineSlotId = "mod_magazine"; protected botConfig: IBotConfig; - constructor(jsonUtil: JsonUtil, logger: ILogger, hashUtil: HashUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, weightedRandomHelper: WeightedRandomHelper, botGeneratorHelper: BotGeneratorHelper, randomUtil: RandomUtil, configServer: ConfigServer, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, inventoryMagGenComponents: IInventoryMagGen[]); + constructor(jsonUtil: JsonUtil, logger: ILogger, hashUtil: HashUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, weightedRandomHelper: WeightedRandomHelper, botGeneratorHelper: BotGeneratorHelper, randomUtil: RandomUtil, configServer: ConfigServer, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, localisationService: LocalisationService, inventoryMagGenComponents: IInventoryMagGen[]); /** * Pick a random weapon based on weightings and generate a functional weapon * @param equipmentSlot Primary/secondary/holster @@ -41,7 +43,7 @@ export declare class BotWeaponGenerator { * @param isPmc Is weapon generated for a pmc * @returns GenerateWeaponResult object */ - generateRandomWeapon(sessionId: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult; + generateRandomWeapon(sessionId: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** * Get a random weighted weapon from a bots pool of weapons * @param equipmentSlot Primary/secondary/holster @@ -60,7 +62,7 @@ export declare class BotWeaponGenerator { * @param isPmc * @returns GenerateWeaponResult object */ - generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult; + generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/Faupi-HideoutArchitect/server/types/generators/RagfairOfferGenerator.d.ts b/Faupi-HideoutArchitect/server/types/generators/RagfairOfferGenerator.d.ts index b64a7e7..23882d2 100644 --- a/Faupi-HideoutArchitect/server/types/generators/RagfairOfferGenerator.d.ts +++ b/Faupi-HideoutArchitect/server/types/generators/RagfairOfferGenerator.d.ts @@ -1,16 +1,19 @@ +import { HandbookHelper } from "../helpers/HandbookHelper"; import { ItemHelper } from "../helpers/ItemHelper"; +import { PaymentHelper } from "../helpers/PaymentHelper"; import { PresetHelper } from "../helpers/PresetHelper"; import { RagfairServerHelper } from "../helpers/RagfairServerHelper"; import { Item } from "../models/eft/common/tables/IItem"; import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem"; import { IBarterScheme } from "../models/eft/common/tables/ITrader"; -import { IRagfairOffer } from "../models/eft/ragfair/IRagfairOffer"; +import { IRagfairOffer, OfferRequirement } from "../models/eft/ragfair/IRagfairOffer"; import { IRagfairConfig } from "../models/spt/config/IRagfairConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { SaveServer } from "../servers/SaveServer"; import { FenceService } from "../services/FenceService"; +import { LocalisationService } from "../services/LocalisationService"; import { RagfairCategoriesService } from "../services/RagfairCategoriesService"; import { RagfairOfferService } from "../services/RagfairOfferService"; import { RagfairPriceService } from "../services/RagfairPriceService"; @@ -27,18 +30,31 @@ export declare class RagfairOfferGenerator { protected timeUtil: TimeUtil; protected databaseServer: DatabaseServer; protected ragfairServerHelper: RagfairServerHelper; + protected handbookHelper: HandbookHelper; protected saveServer: SaveServer; protected presetHelper: PresetHelper; protected ragfairAssortGenerator: RagfairAssortGenerator; protected ragfairOfferService: RagfairOfferService; protected ragfairPriceService: RagfairPriceService; + protected localisationService: LocalisationService; + protected paymentHelper: PaymentHelper; protected ragfairCategoriesService: RagfairCategoriesService; protected fenceService: FenceService; protected itemHelper: ItemHelper; protected configServer: ConfigServer; protected ragfairConfig: IRagfairConfig; - constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, ragfairServerHelper: RagfairServerHelper, saveServer: SaveServer, presetHelper: PresetHelper, ragfairAssortGenerator: RagfairAssortGenerator, ragfairOfferService: RagfairOfferService, ragfairPriceService: RagfairPriceService, ragfairCategoriesService: RagfairCategoriesService, fenceService: FenceService, itemHelper: ItemHelper, configServer: ConfigServer); + protected allowedFleaPriceItemsForBarter: { + tpl: string; + price: number; + }[]; + constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, ragfairServerHelper: RagfairServerHelper, handbookHelper: HandbookHelper, saveServer: SaveServer, presetHelper: PresetHelper, ragfairAssortGenerator: RagfairAssortGenerator, ragfairOfferService: RagfairOfferService, ragfairPriceService: RagfairPriceService, localisationService: LocalisationService, paymentHelper: PaymentHelper, ragfairCategoriesService: RagfairCategoriesService, fenceService: FenceService, itemHelper: ItemHelper, configServer: ConfigServer); createOffer(userID: string, time: number, items: Item[], barterScheme: IBarterScheme[], loyalLevel: number, price: number, sellInOnePiece?: boolean): IRagfairOffer; + /** + * Calculate the offer price that's listed on the flea listing + * @param offerRequirements barter requirements for offer + * @returns rouble cost of offer + */ + protected calculateOfferListingPrice(offerRequirements: OfferRequirement[]): number; /** * Get avatar url from trader table in db * @param isTrader Is user we're getting avatar for a trader @@ -87,20 +103,36 @@ export declare class RagfairOfferGenerator { * @returns Item with conditions added */ protected addMissingCondition(item: Item): Item; - protected getOfferRequirements(items: Item[]): { - count: number; - _tpl: string; + /** + * Create a barter-based barter scheme, if not possible, fall back to making barter scheme currency based + * @param offerItems Items for sale in offer + * @returns barter scheme + */ + protected createBarterRequirement(offerItems: Item[]): IBarterScheme[]; + /** + * Get an array of flea prices + item tpl, cached in generator class + * @returns array with tpl/price values + */ + protected getFleaPricesAsArray(): { + tpl: string; + price: number; }[]; + /** + * Create a random currency-based barter scheme for an array of items + * @param offerItems Items on offer + * @returns Barter scheme for offer + */ + protected createCurrencyRequirement(offerItems: Item[]): IBarterScheme[]; /** * Create a flea offer and store it in the Ragfair server offers array * @param userID owner of the offer * @param time time offer is put up * @param items items in the offer - * @param barterScheme - * @param loyalLevel + * @param barterScheme cost of item (currency or barter) + * @param loyalLevel Loyalty level needed to buy item * @param price price of offer * @param sellInOnePiece - * @returns + * @returns Ragfair offer */ createFleaOffer(userID: string, time: number, items: Item[], barterScheme: IBarterScheme[], loyalLevel: number, price: number, sellInOnePiece?: boolean): IRagfairOffer; } diff --git a/Faupi-HideoutArchitect/server/types/generators/WeatherGenerator.d.ts b/Faupi-HideoutArchitect/server/types/generators/WeatherGenerator.d.ts index 8ddbe49..65d2c76 100644 --- a/Faupi-HideoutArchitect/server/types/generators/WeatherGenerator.d.ts +++ b/Faupi-HideoutArchitect/server/types/generators/WeatherGenerator.d.ts @@ -1,38 +1,54 @@ +import { ApplicationContext } from "../context/ApplicationContext"; import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper"; -import { IWeatherData } from "../models/eft/weather/IWeatherData"; +import { IWeather, IWeatherData } from "../models/eft/weather/IWeatherData"; +import { WindDirection } from "../models/enums/WindDirection"; import { IWeatherConfig } from "../models/spt/config/IWeatherConfig"; +import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { RandomUtil } from "../utils/RandomUtil"; import { TimeUtil } from "../utils/TimeUtil"; export declare class WeatherGenerator { protected weightedRandomHelper: WeightedRandomHelper; + protected logger: ILogger; protected randomUtil: RandomUtil; protected timeUtil: TimeUtil; + protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected weatherConfig: IWeatherConfig; - constructor(weightedRandomHelper: WeightedRandomHelper, randomUtil: RandomUtil, timeUtil: TimeUtil, configServer: ConfigServer); - calculateTime(data: IWeatherData): IWeatherData; + constructor(weightedRandomHelper: WeightedRandomHelper, logger: ILogger, randomUtil: RandomUtil, timeUtil: TimeUtil, applicationContext: ApplicationContext, configServer: ConfigServer); + calculateGameTime(data: IWeatherData): IWeatherData; /** * Get server uptime seconds multiplied by a multiplier and add to current time as seconds * Format to BSGs requirements - * @param computedDate current date + * @param currentDate current date * @returns formatted time */ - protected getAcceleratedTime(computedDate: Date): string; + protected getBsgFormattedInRaidTime(currentDate: Date): string; + /** + * Get the current in-raid time + * @param currentDate (new Date()) + * @returns Date object of current in-raid time + */ + getInRaidTime(currentDate: Date): Date; /** * Get current time formatted to fit BSGs requirement - * @param computedDate date to format into bsg style + * @param date date to format into bsg style * @returns */ - protected getNormalTime(computedDate: Date): string; + protected getBSGFormattedTime(date: Date): string; /** - * Return randomised Weather data - * @param weatherData weather input data + * Return randomised Weather data with help of config/weather.json * @returns Randomised weather data */ - generateWeather(weatherData: IWeatherData): IWeatherData; - protected getWeightedFog(): string; + generateWeather(): IWeather; + /** + * Set IWeather date/time/timestamp values to now + * @param weather Object to update + */ + protected setCurrentDateTime(weather: IWeather): void; + protected getWeightedWindDirection(): WindDirection; + protected getWeightedWindSpeed(): number; + protected getWeightedFog(): number; protected getWeightedRain(): number; protected getRandomFloat(node: string): number; - protected getRandomInt(node: string): number; } diff --git a/Faupi-HideoutArchitect/server/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/Faupi-HideoutArchitect/server/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index 4fcb1e2..1589707 100644 --- a/Faupi-HideoutArchitect/server/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/Faupi-HideoutArchitect/server/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -1,13 +1,15 @@ import { BotWeaponGeneratorHelper } from "../../../helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "../../../helpers/ItemHelper"; import { ILogger } from "../../../models/spt/utils/ILogger"; +import { LocalisationService } from "../../../services/LocalisationService"; import { IInventoryMagGen } from "../IInventoryMagGen"; import { InventoryMagGen } from "../InventoryMagGen"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; + protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; diff --git a/Faupi-HideoutArchitect/server/types/helpers/BotDifficultyHelper.d.ts b/Faupi-HideoutArchitect/server/types/helpers/BotDifficultyHelper.d.ts new file mode 100644 index 0000000..a58ebdb --- /dev/null +++ b/Faupi-HideoutArchitect/server/types/helpers/BotDifficultyHelper.d.ts @@ -0,0 +1,46 @@ +import { Difficulty } from "../models/eft/common/tables/IBotType"; +import { IBotConfig } from "../models/spt/config/IBotConfig"; +import { ILogger } from "../models/spt/utils/ILogger"; +import { ConfigServer } from "../servers/ConfigServer"; +import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "../services/LocalisationService"; +import { JsonUtil } from "../utils/JsonUtil"; +import { RandomUtil } from "../utils/RandomUtil"; +import { BotHelper } from "./BotHelper"; +export declare class BotDifficultyHelper { + protected logger: ILogger; + protected jsonUtil: JsonUtil; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected localisationService: LocalisationService; + protected botHelper: BotHelper; + protected configServer: ConfigServer; + protected botConfig: IBotConfig; + constructor(logger: ILogger, jsonUtil: JsonUtil, databaseServer: DatabaseServer, randomUtil: RandomUtil, localisationService: LocalisationService, botHelper: BotHelper, configServer: ConfigServer); + getPmcDifficultySettings(pmcType: "bear" | "usec", difficulty: string, usecType: string, bearType: string): Difficulty; + /** + * Get difficulty settings for desired bot type, if not found use assault bot types + * @param type bot type to retreive difficulty of + * @param difficulty difficulty to get settings for (easy/normal etc) + * @returns Difficulty object + */ + getBotDifficultySettings(type: string, difficulty: string): Difficulty; + /** + * Get difficulty settings for a PMC + * @param type "usec" / "bear" + * @param difficulty what difficulty to retrieve + * @returns Difficulty object + */ + protected getDifficultySettings(type: string, difficulty: string): Difficulty; + /** + * Translate chosen value from pre-raid difficulty dropdown into bot difficulty value + * @param dropDownDifficulty Dropdown difficulty value to convert + * @returns bot difficulty + */ + convertBotDifficultyDropdownToBotDifficulty(dropDownDifficulty: string): string; + /** + * Choose a random difficulty from - easy/normal/hard/impossible + * @returns random difficulty + */ + chooseRandomDifficulty(): string; +} diff --git a/Faupi-HideoutArchitect/server/types/helpers/BotGeneratorHelper.d.ts b/Faupi-HideoutArchitect/server/types/helpers/BotGeneratorHelper.d.ts index 5e3e501..9ee017f 100644 --- a/Faupi-HideoutArchitect/server/types/helpers/BotGeneratorHelper.d.ts +++ b/Faupi-HideoutArchitect/server/types/helpers/BotGeneratorHelper.d.ts @@ -8,9 +8,11 @@ import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { BotEquipmentFilterService } from "../services/BotEquipmentFilterService"; import { ItemFilterService } from "../services/ItemFilterService"; +import { LocalisationService } from "../services/LocalisationService"; import { HashUtil } from "../utils/HashUtil"; import { JsonUtil } from "../utils/JsonUtil"; import { RandomUtil } from "../utils/RandomUtil"; +import { BotHelper } from "./BotHelper"; import { BotWeaponGeneratorHelper } from "./BotWeaponGeneratorHelper"; import { ContainerHelper } from "./ContainerHelper"; import { InventoryHelper } from "./InventoryHelper"; @@ -43,9 +45,11 @@ export declare class BotGeneratorHelper { protected itemFilterService: ItemFilterService; protected profileHelper: ProfileHelper; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; + protected botHelper: BotHelper; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected botConfig: IBotConfig; - constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, botEquipmentFilterService: BotEquipmentFilterService, itemFilterService: ItemFilterService, profileHelper: ProfileHelper, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, configServer: ConfigServer); + constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, botEquipmentFilterService: BotEquipmentFilterService, itemFilterService: ItemFilterService, profileHelper: ProfileHelper, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, botHelper: BotHelper, localisationService: LocalisationService, configServer: ConfigServer); /** * Check mods are compatible and add to array * @param equipment Equipment item to add mods to @@ -53,10 +57,13 @@ export declare class BotGeneratorHelper { * @param parentId parentid of item to add mod to * @param parentTemplate template objet of item to add mods to * @param modSpawnChances dictionary of mod items and their chance to spawn for this bot type + * @param botRole the bot role being generated for + * @param forceSpawn should this mod be forced to spawn * @returns Item + compatible mods as an array */ - generateModsForEquipment(equipment: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[]; + generateModsForEquipment(equipment: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances, botRole: string, forceSpawn?: boolean): Item[]; /** + * Add mods to a weapon using the provided mod pool * @param sessionId session id * @param weapon Weapon to add mods to * @param modPool Pool of compatible mods to attach to weapon @@ -67,18 +74,18 @@ export declare class BotGeneratorHelper { * @param botRole Role of bot weapon is generated for * @returns Weapon + mods array */ - generateModsForWeapon(sessionId: string, weapon: Item[], modPool: Mods, weaponParentId: string, parentWeaponTemplate: ITemplateItem, modSpawnChances: ModsChances, ammoTpl: string, botRole: string): Item[]; + generateModsForWeapon(sessionId: string, weapon: Item[], modPool: Mods, weaponParentId: string, parentWeaponTemplate: ITemplateItem, modSpawnChances: ModsChances, ammoTpl: string, botRole: string, botLevel: number): Item[]; /** * - * @param modSlot - * @param isRandomisableSlot - * @param modsParent - * @param botEquipBlacklist - * @param itemModPool + * @param modSlot Slot mod will fit into + * @param isRandomisableSlot Will generate a randomised mod pool if true + * @param modsParent Parent slot the item will be a part of + * @param botEquipBlacklist Blacklist to prevent mods from being picked + * @param itemModPool Pool of items to pick from * @param weapon array with only weapon tpl in it, ready for mods to be added * @param ammoTpl ammo tpl to use if slot requires a cartridge to be added (e.g. mod_magazine) - * @param parentTemplate - * @returns + * @param parentTemplate Parent item the mod will go into + * @returns ITemplateItem */ protected chooseModToPutIntoSlot(modSlot: string, isRandomisableSlot: boolean, modsParent: Slot, botEquipBlacklist: EquipmentFilterDetails, itemModPool: Record, weapon: Item[], ammoTpl: string, parentTemplate: ITemplateItem): [boolean, ITemplateItem]; /** @@ -114,8 +121,10 @@ export declare class BotGeneratorHelper { * Find all compatible mods for equipment item and add to modPool * @param itemDetails item to find mods for * @param modPool ModPool to add mods to + * @param equipmentBlacklist equipment not allowed to be used by the bot + * @param botEquipmentRole bot type to generate pool for (e.g. assault, pmcBot, pmc for usec/bear) */ - generateDynamicModPool(itemDetails: ITemplateItem, modPool: Mods): void; + generateDynamicModPool(itemDetails: ITemplateItem, modPool: Mods, equipmentBlacklist: EquipmentFilterDetails[], botEquipmentRole: string): void; /** * Take a list of tpls and filter out blacklisted values using itemFilterService + botEquipmentBlacklist * @param allowedMods base mods to filter @@ -153,7 +162,7 @@ export declare class BotGeneratorHelper { * @param modTemplate Used to add additional properites in the upd object * @returns Item object */ - protected createModItem(modId: string, modTpl: string, parentId: string, modSlot: string, modTemplate: ITemplateItem): Item; + protected createModItem(modId: string, modTpl: string, parentId: string, modSlot: string, modTemplate: ITemplateItem, botRole: string): Item; /** * randomly choose if a mod should be spawned, 100% for required mods OR mod is ammo slot * never return true for an item that has 0% spawn chance @@ -170,10 +179,10 @@ export declare class BotGeneratorHelper { */ protected getAmmoContainers(): string[]; /** - * Get the slot details for an item (chamber/cartridge/slot) + * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon * @param parentTemplate item template - * @returns + * @returns Slot item */ protected getModItemSlot(modSlot: string, parentTemplate: ITemplateItem): Slot; /** @@ -185,7 +194,6 @@ export declare class BotGeneratorHelper { * @param modPool modPool which should include available cartrigdes * @param parentId The CylinderMagazine's UID * @param parentTemplate The CylinderMagazine's template - * @returns */ protected fillCamora(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem): void; /** @@ -197,11 +205,11 @@ export declare class BotGeneratorHelper { /** * Adds properties to an item * e.g. Repairable / HasHinge / Foldable / MaxDurability - * @param itemTemplate - * @param botRole Used by weapons to randomise the durability values + * @param itemTemplate Item extra properties are being generated for + * @param botRole Used by weapons to randomise the durability values. Null for non-equipped items * @returns Item Upd object with extra properties */ - generateExtraPropertiesForItem(itemTemplate: ITemplateItem, botRole?: any): { + generateExtraPropertiesForItem(itemTemplate: ITemplateItem, botRole?: string): { upd?: Upd; }; /** @@ -220,21 +228,27 @@ export declare class BotGeneratorHelper { protected generateArmorRepairableProperties(itemTemplate: ITemplateItem, botRole: string): Repairable; /** * Get a random mod from an items compatible mods Filter array - * @param modTpl - * @param parentSlot - * @param modSlot - * @param items + * @param modTpl ???? + * @param parentSlot item mod will go into, used to get combatible items + * @param modSlot Slot to get mod to fill + * @param items items to ensure picked mod is compatible with * @returns item tpl */ protected getModTplFromItemDb(modTpl: string, parentSlot: Slot, modSlot: string, items: Item[]): string; /** * Can an item be added to an item without issue - * @param items - * @param tplToCheck - * @param equipmentSlot - * @returns true if possible + * @param items items to check compatiblilities with + * @param tplToCheck tpl of the item to check for incompatibilities + * @param equipmentSlot Slot the item will be placed into + * @returns false if no incompatibilties */ isItemIncompatibleWithCurrentItems(items: Item[], tplToCheck: string, equipmentSlot: string): boolean; + /** + * Convert a bots role to the equipment role used in config/bot.json + * @param botRole Role to convert + * @returns Equipment role (e.g. pmc / assault / bossTagilla) + */ + getBotEquipmentRole(botRole: string): string; } /** TODO - move into own class */ export declare class ExhaustableArray { diff --git a/Faupi-HideoutArchitect/server/types/helpers/BotHelper.d.ts b/Faupi-HideoutArchitect/server/types/helpers/BotHelper.d.ts index 67a6384..2752a0e 100644 --- a/Faupi-HideoutArchitect/server/types/helpers/BotHelper.d.ts +++ b/Faupi-HideoutArchitect/server/types/helpers/BotHelper.d.ts @@ -1,8 +1,9 @@ import { Difficulty, IBotType } from "../models/eft/common/tables/IBotType"; -import { IBotConfig } from "../models/spt/config/IBotConfig"; +import { EquipmentFilters, IBotConfig, RandomisationDetails } from "../models/spt/config/IBotConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "../services/LocalisationService"; import { JsonUtil } from "../utils/JsonUtil"; import { RandomUtil } from "../utils/RandomUtil"; export declare class BotHelper { @@ -10,46 +11,27 @@ export declare class BotHelper { protected jsonUtil: JsonUtil; protected databaseServer: DatabaseServer; protected randomUtil: RandomUtil; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected botConfig: IBotConfig; - constructor(logger: ILogger, jsonUtil: JsonUtil, databaseServer: DatabaseServer, randomUtil: RandomUtil, configServer: ConfigServer); - /** - * Get difficulty settings for desired bot type, if not found use assault bot types - * @param type bot type to retreive difficulty of - * @param difficulty difficulty to get settings for (easy/normal etc) - * @returns Difficulty object - */ - getBotDifficultySettings(type: string, difficulty: string): Difficulty; + constructor(logger: ILogger, jsonUtil: JsonUtil, databaseServer: DatabaseServer, randomUtil: RandomUtil, localisationService: LocalisationService, configServer: ConfigServer); /** * Get a template object for the specified botRole from bots.types db * @param role botRole to get template for * @returns IBotType object */ getBotTemplate(role: string): IBotType; - /** - * Get difficulty settings for a PMC - * @param type "usec" / "bear" - * @param difficulty what difficulty to retrieve - * @returns Difficulty object - */ - getPmcDifficultySettings(type: string, difficulty: string): Difficulty; - /** - * Translate chosen value from pre-raid difficulty dropdown into bot difficulty value - * @param dropDownDifficulty Dropdown difficulty value to convert - * @returns bot difficulty - */ - convertBotDifficultyDropdownToBotDifficulty(dropDownDifficulty: string): string; - /** - * Choose a random difficulty from - easy/normal/hard/impossible - * @returns random difficulty - */ - chooseRandomDifficulty(): string; /** * Randomise the chance the PMC will attack their own side * Look up value in bot.json/chanceSameSideIsHostilePercent * @param difficultySettings pmc difficulty settings */ randomisePmcHostility(difficultySettings: Difficulty): void; + /** + * Is the passed in bot role a PMC (usec/bear/pmc) + * @param botRole bot role to check + * @returns true if is pmc + */ isBotPmc(botRole: string): boolean; isBotBoss(botRole: string): boolean; isBotFollower(botRole: string): boolean; @@ -77,4 +59,11 @@ export declare class BotHelper { * @returns true if should be a pmc */ shouldBotBePmc(botRole: string): boolean; + /** + * Get randomisation settings for bot from config/bot.json + * @param botLevel level of bot + * @param botEquipConfig bot equipment json + * @returns RandomisationDetails + */ + getBotRandomisationDetails(botLevel: number, botEquipConfig: EquipmentFilters): RandomisationDetails; } diff --git a/Faupi-HideoutArchitect/server/types/helpers/GameEventHelper.d.ts b/Faupi-HideoutArchitect/server/types/helpers/GameEventHelper.d.ts index fca87be..fa25eff 100644 --- a/Faupi-HideoutArchitect/server/types/helpers/GameEventHelper.d.ts +++ b/Faupi-HideoutArchitect/server/types/helpers/GameEventHelper.d.ts @@ -15,4 +15,15 @@ export declare class GameEventHelper { * @returns Record with event name + start/end date */ getEventDetails(): ISeasonalEvent[]; + /** + * Is detection of seasonal events enabled (halloween / christmas) + * @returns true if seasonal events should be checked for + */ + isAutomaticEventDetectionEnabled(): boolean; + /** + * Get a dictionary of gear changes to apply to bots for a specific event e.g. Christmas/Halloween + * @param eventName Name of event to get gear changes for + * @returns bots with equipment changes + */ + getEventBotGear(eventName: string): Record>>; } diff --git a/Faupi-HideoutArchitect/server/types/helpers/HideoutHelper.d.ts b/Faupi-HideoutArchitect/server/types/helpers/HideoutHelper.d.ts index 5f7e3b7..9d51fed 100644 --- a/Faupi-HideoutArchitect/server/types/helpers/HideoutHelper.d.ts +++ b/Faupi-HideoutArchitect/server/types/helpers/HideoutHelper.d.ts @@ -11,6 +11,7 @@ import { ILogger } from "../models/spt/utils/ILogger"; import { EventOutputHolder } from "../routers/EventOutputHolder"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "../services/LocalisationService"; import { PlayerService } from "../services/PlayerService"; import { HashUtil } from "../utils/HashUtil"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; @@ -29,13 +30,14 @@ export declare class HideoutHelper { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected playerService: PlayerService; + protected localisationService: LocalisationService; protected configServer: ConfigServer; static bitcoinFarm: string; static waterCollector: string; static bitcoin: string; static expeditionaryFuelTank: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, playerService: PlayerService, configServer: ConfigServer); + constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, playerService: PlayerService, localisationService: LocalisationService, configServer: ConfigServer); registerProduction(pmcData: IPmcData, body: IHideoutSingleProductionStartRequestData | IHideoutContinousProductionStartRequestData, sessionID: string): IItemEventRouterResponse; /** * This convinience function intialies new Production Object diff --git a/Faupi-HideoutArchitect/server/types/helpers/InventoryHelper.d.ts b/Faupi-HideoutArchitect/server/types/helpers/InventoryHelper.d.ts index b8e5c9d..6419f93 100644 --- a/Faupi-HideoutArchitect/server/types/helpers/InventoryHelper.d.ts +++ b/Faupi-HideoutArchitect/server/types/helpers/InventoryHelper.d.ts @@ -5,11 +5,12 @@ import { IInventoryMergeRequestData } from "../models/eft/inventory/IInventoryMe import { IInventoryMoveRequestData } from "../models/eft/inventory/IInventoryMoveRequestData"; import { IInventorySplitRequestData } from "../models/eft/inventory/IInventorySplitRequestData"; import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse"; -import { IInventoryConfig } from "../models/spt/config/IInventoryConfig"; +import { IInventoryConfig, RewardDetails } from "../models/spt/config/IInventoryConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { FenceService } from "../services/FenceService"; +import { LocalisationService } from "../services/LocalisationService"; import { HashUtil } from "../utils/HashUtil"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; import { JsonUtil } from "../utils/JsonUtil"; @@ -38,9 +39,10 @@ export declare class InventoryHelper { protected itemHelper: ItemHelper; protected containerHelper: ContainerHelper; protected profileHelper: ProfileHelper; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected inventoryConfig: IInventoryConfig; - constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, httpResponse: HttpResponseUtil, fenceService: FenceService, databaseServer: DatabaseServer, paymentHelper: PaymentHelper, traderAssortHelper: TraderAssortHelper, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, containerHelper: ContainerHelper, profileHelper: ProfileHelper, configServer: ConfigServer); + constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, httpResponse: HttpResponseUtil, fenceService: FenceService, databaseServer: DatabaseServer, paymentHelper: PaymentHelper, traderAssortHelper: TraderAssortHelper, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, containerHelper: ContainerHelper, profileHelper: ProfileHelper, localisationService: LocalisationService, configServer: ConfigServer); addItem(pmcData: IPmcData, body: IAddItemRequestData, output: IItemEventRouterResponse, sessionID: string, callback: any, foundInRaid?: boolean, addUpd?: any): IItemEventRouterResponse; removeItem(pmcData: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse; removeItemByCount(pmcData: IPmcData, itemId: string, count: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse; @@ -76,6 +78,12 @@ export declare class InventoryHelper { * Internal helper function to handle cartridges in inventory if any of them exist. */ protected handleCartridges(items: Item[], body: IInventoryMoveRequestData): void; + /** + * Get details for how a random loot container should be handled, max rewards, possible reward tpls + * @param itemTpl Container being opened + * @returns Reward details + */ + getRandomLootContainerRewardDetails(itemTpl: string): RewardDetails; } declare namespace InventoryHelper { interface InventoryItemHash { diff --git a/Faupi-HideoutArchitect/server/types/helpers/ItemHelper.d.ts b/Faupi-HideoutArchitect/server/types/helpers/ItemHelper.d.ts index 0effaf2..fc88a46 100644 --- a/Faupi-HideoutArchitect/server/types/helpers/ItemHelper.d.ts +++ b/Faupi-HideoutArchitect/server/types/helpers/ItemHelper.d.ts @@ -5,6 +5,7 @@ import { IStaticAmmoDetails } from "../models/eft/common/tables/ILootBase"; import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem"; import { ILogger } from "../models/spt/utils/ILogger"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocaleService } from "../services/LocaleService"; import { HashUtil } from "../utils/HashUtil"; import { JsonUtil } from "../utils/JsonUtil"; import { MathUtil } from "../utils/MathUtil"; @@ -18,7 +19,8 @@ declare class ItemHelper { protected objectId: ObjectId; protected mathUtil: MathUtil; protected databaseServer: DatabaseServer; - constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, randomUtil: RandomUtil, objectId: ObjectId, mathUtil: MathUtil, databaseServer: DatabaseServer); + protected localeService: LocaleService; + constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, randomUtil: RandomUtil, objectId: ObjectId, mathUtil: MathUtil, databaseServer: DatabaseServer, localeService: LocaleService); /** * Checks if an id is a valid item. Valid meaning that it's an item that be stored in stash * @param {string} tpl the template id / tpl @@ -212,6 +214,12 @@ declare class ItemHelper { * @returns size of stack */ getItemStackSize(item: Item): number; + /** + * Get the name of an item from the locale file using the item tpl + * @param itemTpl Tpl of item to get name of + * @returns Name of item + */ + getItemName(itemTpl: string): string; } declare namespace ItemHelper { interface ItemSize { diff --git a/Faupi-HideoutArchitect/server/types/helpers/QuestHelper.d.ts b/Faupi-HideoutArchitect/server/types/helpers/QuestHelper.d.ts index a6b4892..edbd2e1 100644 --- a/Faupi-HideoutArchitect/server/types/helpers/QuestHelper.d.ts +++ b/Faupi-HideoutArchitect/server/types/helpers/QuestHelper.d.ts @@ -50,6 +50,12 @@ export declare class QuestHelper { * @returns true if player level is greater than or equal to quest */ doesPlayerLevelFulfilCondition(playerLevel: number, condition: AvailableForConditions): boolean; + /** + * Get the quests found in both arrays (inner join) + * @param before Array of qeusts #1 + * @param after Array of quests #2 + * @returns Reduction of cartesian product between two quest arrays + */ getDeltaQuests(before: IQuest[], after: IQuest[]): IQuest[]; /** * Increase skill points of a skill on player profile @@ -66,38 +72,85 @@ export declare class QuestHelper { * quest list in question. */ dumpQuests(quests: any): void; - loyaltyRequirementCheck(loyaltyRequirementProperties: AvailableForProps, profile: IPmcData): boolean; - protected processReward(reward: Reward): any[]; + /** + * Check if trader has sufficient loyalty to fullfill quest requirement + * @param questProperties Quest props + * @param profile Player profile + * @returns true if loyalty is high enough to fulfil quest requirement + */ + traderStandingRequirementCheck(questProperties: AvailableForProps, profile: IPmcData): boolean; + protected processReward(reward: Reward): Reward[]; + /** + * Gets a flat list of reward items for the given quest at a specific state (e.g. Fail/Success) + * @param quest quest to get rewards for + * @param state Quest status that holds the items (Started, Success, Fail) + * @returns array of items with the correct maxStack + */ getQuestRewardItems(quest: IQuest, state: QuestStatus): Reward[]; /** - * Add quest with new state value to pmc profile + * Update player profile with quest status (e.g. Fail/Success) * @param pmcData profile to add quest to * @param newState state the new quest should be in when added * @param acceptedQuest Details of quest being added */ addQuestToPMCData(pmcData: IPmcData, newState: QuestStatus, acceptedQuest: IAcceptQuestRequestData): void; - acceptedUnlocked(acceptedQuestId: string, sessionID: string): IQuest[]; - failedUnlocked(failedQuestId: string, sessionID: string): IQuest[]; - applyMoneyBoost(quest: IQuest, moneyBoost: number): IQuest; - changeItemStack(pmcData: IPmcData, id: string, value: number, sessionID: string, output: any): void; /** - * Get List of All Quests as an array + * TODO: what is going on here + * @param acceptedQuestId Quest to add to profile + * @param sessionID Session id + * @returns Array of quests in profile + quest passed in as param + */ + acceptedUnlocked(acceptedQuestId: string, sessionID: string): IQuest[]; + /** + * TODO: what is going on here + * @param failedQuestId + * @param sessionID Session id + * @returns + */ + failedUnlocked(failedQuestId: string, sessionID: string): IQuest[]; + /** + * Adjust quest money rewards by passed in multipler + * @param quest Quest to multiple money rewards + * @param multipler Value to adjust money rewards by + * @returns Updated quest + */ + applyMoneyBoost(quest: IQuest, multipler: number): IQuest; + /** + * Sets the item stack to new value, or delete the item if value <= 0 + * // TODO maybe merge this function and the one from customization + * @param pmcData Profile + * @param itemId id of item to adjust stack size of + * @param newStackSize Stack size to adjust to + * @param sessionID Session id + * @param output ItemEvent router response + */ + changeItemStack(pmcData: IPmcData, itemId: string, newStackSize: number, sessionID: string, output: IItemEventRouterResponse): void; + /** + * Get List of All Quests from db + * NOT CLONED * @returns Array of IQuest objects */ - questValues(): IQuest[]; + getQuestsFromDb(): IQuest[]; /** - * Reest AvailableForStart conditions for quests - * @param quests queststo clean + * Get quests, strip all requirement conditions except level + * @param quests quests to process * @returns quest array without conditions */ - protected cleanQuestList(quests: IQuest[]): IQuest[]; + protected getQuestsWithOnlyLevelRequirementStartCondition(quests: IQuest[]): IQuest[]; /** - * Reset AvailableForStart conditions on a quest + * Remove all quest conditions except for level requirement * @param quest quest to clean * @returns reset IQuest object */ - cleanQuestConditions(quest: IQuest): IQuest; - failQuest(pmcData: IPmcData, body: any, sessionID: string): any; + getQuestWithOnlyLevelRequirementStartCondition(quest: IQuest): IQuest; + /** + * Fail a quest in a player profile + * @param pmcData Profile + * @param failRequest fail quest request data + * @param sessionID Session id + * @returns Item event router response + */ + failQuest(pmcData: IPmcData, failRequest: any, sessionID: string): IItemEventRouterResponse; /** * Get quest by id from database * @param questId questid to look for @@ -105,7 +158,12 @@ export declare class QuestHelper { * @returns IQuest object */ getQuestFromDb(questId: string, pmcData: IPmcData): IQuest; - getQuestLocaleIdFromDb(messageId: string): string; + /** + * Get the locale Id from locale db for a quest message + * @param questMessageId Quest mesage id to look up + * @returns Locale Id from locale db + */ + getQuestLocaleIdFromDb(questMessageId: string): string; /** * Alter a quests state + Add a record to tis status timers object * @param pmcData Profile to update @@ -128,5 +186,10 @@ export declare class QuestHelper { * @returns bonus in percent */ protected getIntelCenterRewardBonus(pmcData: IPmcData): number; - getFindItemIdForQuestItem(itemTpl: string): string; + /** + * Find quest with 'findItem' requirement that needs the item tpl be handed in + * @param itemTpl item tpl to look for + * @returns 'FindItem' condition id + */ + getFindItemIdForQuestHandIn(itemTpl: string): string; } diff --git a/Faupi-HideoutArchitect/server/types/helpers/RagfairServerHelper.d.ts b/Faupi-HideoutArchitect/server/types/helpers/RagfairServerHelper.d.ts index a03cdda..ec388d8 100644 --- a/Faupi-HideoutArchitect/server/types/helpers/RagfairServerHelper.d.ts +++ b/Faupi-HideoutArchitect/server/types/helpers/RagfairServerHelper.d.ts @@ -44,10 +44,20 @@ export declare class RagfairServerHelper { isPlayer(userID: string): boolean; returnItems(sessionID: string, items: any[]): void; calculateDynamicStackCount(tplId: string, isWeaponPreset: boolean): number; + /** + * Choose a currency at random with bias + * @returns currency tpl + */ getDynamicOfferCurrency(): string; getMemberType(userID: string): MemberCategory; getNickname(userID: string): string; getPresetItems(item: any): Item[]; getPresetItemsByTpl(item: Item): Item[]; + /** + * Generate new unique ids for the children while preserving hierarchy + * @param item base item + * @param preset + * @returns Item array with new IDs + */ reparentPresets(item: Item, preset: Item[]): Item[]; } diff --git a/Faupi-HideoutArchitect/server/types/helpers/RagfairSortHelper.d.ts b/Faupi-HideoutArchitect/server/types/helpers/RagfairSortHelper.d.ts index 28d1d38..4669ce6 100644 --- a/Faupi-HideoutArchitect/server/types/helpers/RagfairSortHelper.d.ts +++ b/Faupi-HideoutArchitect/server/types/helpers/RagfairSortHelper.d.ts @@ -18,7 +18,7 @@ export declare class RagfairSortHelper { protected sortOffersByRating(a: IRagfairOffer, b: IRagfairOffer): number; protected sortOffersByName(a: IRagfairOffer, b: IRagfairOffer): number; /** - * Order two offers by price value + * Order two offers by rouble price value * @param a Offer a * @param b Offer b * @returns diff --git a/Faupi-HideoutArchitect/server/types/loaders/PreAkiModLoader.d.ts b/Faupi-HideoutArchitect/server/types/loaders/PreAkiModLoader.d.ts index 7a687a5..f486a28 100644 --- a/Faupi-HideoutArchitect/server/types/loaders/PreAkiModLoader.d.ts +++ b/Faupi-HideoutArchitect/server/types/loaders/PreAkiModLoader.d.ts @@ -1,29 +1,31 @@ import { DependencyContainer } from "tsyringe"; +import { IPostAkiLoadMod } from "../models/external/IPostAkiLoadMod"; +import { IPostDBLoadMod } from "../models/external/IPostDBLoadMod"; +import { IPreAkiLoadMod } from "../models/external/IPreAkiLoadMod"; import { ICoreConfig } from "../models/spt/config/ICoreConfig"; import { ModLoader } from "../models/spt/mod/IMod"; import { IModLoader } from "../models/spt/mod/IModLoader"; import { IPackageJsonData } from "../models/spt/mod/IPackageJsonData"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; +import { LocalisationService } from "../services/LocalisationService"; import { ModCompilerService } from "../services/ModCompilerService"; import { JsonUtil } from "../utils/JsonUtil"; import { VFS } from "../utils/VFS"; import { BundleLoader } from "./BundleLoader"; -import { IPostAkiLoadMod } from "../models/external/IPostAkiLoadMod"; -import { IPreAkiLoadMod } from "../models/external/IPreAkiLoadMod"; -import { IPostDBLoadMod } from "../models/external/IPostDBLoadMod"; export declare class PreAkiModLoader implements IModLoader { protected logger: ILogger; protected vfs: VFS; protected jsonUtil: JsonUtil; protected modCompilerService: ModCompilerService; protected bundleLoader: BundleLoader; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected static container: DependencyContainer; protected readonly basepath = "user/mods/"; protected imported: Record; protected akiConfig: ICoreConfig; - constructor(logger: ILogger, vfs: VFS, jsonUtil: JsonUtil, modCompilerService: ModCompilerService, bundleLoader: BundleLoader, configServer: ConfigServer); + constructor(logger: ILogger, vfs: VFS, jsonUtil: JsonUtil, modCompilerService: ModCompilerService, bundleLoader: BundleLoader, localisationService: LocalisationService, configServer: ConfigServer); load(container: DependencyContainer): Promise; getBundles(local: boolean): string; getBundle(key: string, local: boolean): void; diff --git a/Faupi-HideoutArchitect/server/types/models/eft/bot/IGenerateBotsRequestData.d.ts b/Faupi-HideoutArchitect/server/types/models/eft/bot/IGenerateBotsRequestData.d.ts index c49cef7..f1f7013 100644 --- a/Faupi-HideoutArchitect/server/types/models/eft/bot/IGenerateBotsRequestData.d.ts +++ b/Faupi-HideoutArchitect/server/types/models/eft/bot/IGenerateBotsRequestData.d.ts @@ -2,6 +2,7 @@ export interface IGenerateBotsRequestData { conditions: Condition[]; } export interface Condition { + /** e.g. assault/pmcBot/bossKilla */ Role: string; Limit: number; Difficulty: string; diff --git a/Faupi-HideoutArchitect/server/types/models/eft/bot/IRandomisedBotLevelResult.d.ts b/Faupi-HideoutArchitect/server/types/models/eft/bot/IRandomisedBotLevelResult.d.ts new file mode 100644 index 0000000..75bd936 --- /dev/null +++ b/Faupi-HideoutArchitect/server/types/models/eft/bot/IRandomisedBotLevelResult.d.ts @@ -0,0 +1,4 @@ +export interface IRandomisedBotLevelResult { + level: number; + exp: number; +} diff --git a/Faupi-HideoutArchitect/server/types/models/eft/common/IGlobals.d.ts b/Faupi-HideoutArchitect/server/types/models/eft/common/IGlobals.d.ts index 81e2023..b53f106 100644 --- a/Faupi-HideoutArchitect/server/types/models/eft/common/IGlobals.d.ts +++ b/Faupi-HideoutArchitect/server/types/models/eft/common/IGlobals.d.ts @@ -591,6 +591,7 @@ export interface HealPrice { export interface ProfileHealthSettings { BodyPartsSettings: BodyPartsSettings; HealthFactorsSettings: HealthFactorsSettings; + DefaultStimulatorBuff: string; } export interface BodyPartsSettings { Head: BodyPartsSetting; diff --git a/Faupi-HideoutArchitect/server/types/models/eft/common/tables/IBotType.d.ts b/Faupi-HideoutArchitect/server/types/models/eft/common/tables/IBotType.d.ts index c1fe579..55b4bd9 100644 --- a/Faupi-HideoutArchitect/server/types/models/eft/common/tables/IBotType.d.ts +++ b/Faupi-HideoutArchitect/server/types/models/eft/common/tables/IBotType.d.ts @@ -13,8 +13,8 @@ export interface IBotType { skills: Skills; } export interface Appearance { - body: string[]; - feet: string[]; + body: Record; + feet: Record; hands: string[]; head: string[]; voice: string[]; diff --git a/Faupi-HideoutArchitect/server/types/models/eft/common/tables/ITemplateItem.d.ts b/Faupi-HideoutArchitect/server/types/models/eft/common/tables/ITemplateItem.d.ts index 8569e61..0fa7e18 100644 --- a/Faupi-HideoutArchitect/server/types/models/eft/common/tables/ITemplateItem.d.ts +++ b/Faupi-HideoutArchitect/server/types/models/eft/common/tables/ITemplateItem.d.ts @@ -254,7 +254,7 @@ export interface Props { foodUseTime?: number; foodEffectType?: string; StimulatorBuffs?: string; - effects_health?: any; + effects_health?: IHealthEffect[] | Record>; effects_damage?: any; MaximumNumberOfUsage?: number; knifeHitDelay?: number; @@ -366,6 +366,10 @@ export interface Props { MinTimeToContactExplode?: number; ExplosionEffectType?: string; } +export interface IHealthEffect { + type: string; + value: number; +} export interface Prefab { path: string; rcid: string; diff --git a/Faupi-HideoutArchitect/server/types/models/eft/customization/IGetSuitsResponse.d.ts b/Faupi-HideoutArchitect/server/types/models/eft/customization/IGetSuitsResponse.d.ts new file mode 100644 index 0000000..cbb909d --- /dev/null +++ b/Faupi-HideoutArchitect/server/types/models/eft/customization/IGetSuitsResponse.d.ts @@ -0,0 +1,4 @@ +export interface IGetSuitsResponse { + _id: string; + suites: string[]; +} diff --git a/Faupi-HideoutArchitect/server/types/models/eft/game/IGameKeepAliveResponse.d.ts b/Faupi-HideoutArchitect/server/types/models/eft/game/IGameKeepAliveResponse.d.ts new file mode 100644 index 0000000..170ce6a --- /dev/null +++ b/Faupi-HideoutArchitect/server/types/models/eft/game/IGameKeepAliveResponse.d.ts @@ -0,0 +1,4 @@ +export interface IGameKeepAliveResponse { + msg: string; + utc_time: number; +} diff --git a/Faupi-HideoutArchitect/server/types/models/eft/game/IGameLogoutResponseData.d.ts b/Faupi-HideoutArchitect/server/types/models/eft/game/IGameLogoutResponseData.d.ts new file mode 100644 index 0000000..0f52050 --- /dev/null +++ b/Faupi-HideoutArchitect/server/types/models/eft/game/IGameLogoutResponseData.d.ts @@ -0,0 +1,3 @@ +export interface IGameLogoutResponseData { + status: string; +} diff --git a/Faupi-HideoutArchitect/server/types/models/eft/game/IGameStartResponse.d.ts b/Faupi-HideoutArchitect/server/types/models/eft/game/IGameStartResponse.d.ts new file mode 100644 index 0000000..9f0ab6d --- /dev/null +++ b/Faupi-HideoutArchitect/server/types/models/eft/game/IGameStartResponse.d.ts @@ -0,0 +1,3 @@ +export interface IGameStartResponse { + utc_time: number; +} diff --git a/Faupi-HideoutArchitect/server/types/models/eft/inventory/IOpenRandomLootContainerRequestData.d.ts b/Faupi-HideoutArchitect/server/types/models/eft/inventory/IOpenRandomLootContainerRequestData.d.ts new file mode 100644 index 0000000..3c45124 --- /dev/null +++ b/Faupi-HideoutArchitect/server/types/models/eft/inventory/IOpenRandomLootContainerRequestData.d.ts @@ -0,0 +1,11 @@ +import { IInventoryBaseActionRequestData } from "./IInventoryBaseActionRequestData"; +export interface IOpenRandomLootContainerRequestData extends IInventoryBaseActionRequestData { + Action: "OpenRandomLootContainer"; + /** Container item opened */ + item: string; + to: To[]; +} +export interface To { + /** Player character (pmc/scav) id items will be sent to */ + id: string; +} diff --git a/Faupi-HideoutArchitect/server/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/Faupi-HideoutArchitect/server/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index 4841cfd..60ab284 100644 --- a/Faupi-HideoutArchitect/server/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/Faupi-HideoutArchitect/server/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -10,8 +10,9 @@ export interface IItemEventRouterBase { export declare type TProfileChanges = Record; export interface Warning { index: number; - err: string; errmsg: string; + code?: string; + data?: any; } export interface ProfileChange { _id: string; diff --git a/Faupi-HideoutArchitect/server/types/models/eft/match/IStartOffineRaidRequestData.d.ts b/Faupi-HideoutArchitect/server/types/models/eft/match/IStartOffineRaidRequestData.d.ts index af0625e..1983728 100644 --- a/Faupi-HideoutArchitect/server/types/models/eft/match/IStartOffineRaidRequestData.d.ts +++ b/Faupi-HideoutArchitect/server/types/models/eft/match/IStartOffineRaidRequestData.d.ts @@ -2,8 +2,10 @@ import { BotAmount } from "../../enums/BotAmount"; import { BotDifficulty } from "../../enums/BotDifficulty"; export interface IStartOfflineRaidRequestData { locationName: string; + /** Current time, not in-game time */ startTime: number; - dateTime: string; + /** CURR = am, past = pm */ + dateTime: "CURR" | "PAST"; gameSettings: GameSettings; } export interface GameSettings { diff --git a/Faupi-HideoutArchitect/server/types/models/eft/notifier/ISelectProfileResponse.d.ts b/Faupi-HideoutArchitect/server/types/models/eft/notifier/ISelectProfileResponse.d.ts new file mode 100644 index 0000000..ecb668a --- /dev/null +++ b/Faupi-HideoutArchitect/server/types/models/eft/notifier/ISelectProfileResponse.d.ts @@ -0,0 +1,6 @@ +import { INotifierChannel } from "./INotifier"; +export interface ISelectProfileResponse { + status: string; + notifier: INotifierChannel; + notifierServer: string; +} diff --git a/Faupi-HideoutArchitect/server/types/models/eft/ragfair/IRagfairOffer.d.ts b/Faupi-HideoutArchitect/server/types/models/eft/ragfair/IRagfairOffer.d.ts index 3251a37..792ec7d 100644 --- a/Faupi-HideoutArchitect/server/types/models/eft/ragfair/IRagfairOffer.d.ts +++ b/Faupi-HideoutArchitect/server/types/models/eft/ragfair/IRagfairOffer.d.ts @@ -7,19 +7,19 @@ export interface IRagfairOffer { requirements: OfferRequirement[]; root: string; intId: number; + /** Handbook price */ itemsCost: number; + /** Rouble price */ requirementsCost: number; - sptRequirementsCostRouble: number; startTime: number; endTime: number; sellInOnePiece: boolean; - name?: string; - shortName?: string; loyaltyLevel: number; buyRestrictionMax?: number; buyRestrictionCurrent?: number; locked: boolean; unlimitedCount: boolean; + /** Rouble price */ summaryCost: number; user: IRagfairOfferUser; notAvailable: boolean; @@ -33,11 +33,11 @@ export interface OfferRequirement { } export interface IRagfairOfferUser { id: string; - nickname: string; - rating: number; + nickname?: string; + rating?: number; memberType: MemberCategory; - avatar: string; - isRatingGrowing: boolean; + avatar?: string; + isRatingGrowing?: boolean; } export interface SellResult { sellTime: number; diff --git a/Faupi-HideoutArchitect/server/types/models/eft/weather/IWeatherData.d.ts b/Faupi-HideoutArchitect/server/types/models/eft/weather/IWeatherData.d.ts index ecc96ce..1f5d5b5 100644 --- a/Faupi-HideoutArchitect/server/types/models/eft/weather/IWeatherData.d.ts +++ b/Faupi-HideoutArchitect/server/types/models/eft/weather/IWeatherData.d.ts @@ -1,17 +1,18 @@ +import { WindDirection } from "../../../models/enums/WindDirection"; export interface IWeatherData { acceleration: number; time: string; date: string; - weather: IWeather; + weather?: IWeather; } export interface IWeather { pressure: number; temp: number; - fog: string; + fog: number; rain_intensity: number; - rain: any; + rain: number; wind_gustiness: number; - wind_direction: any; + wind_direction: WindDirection; wind_speed: number; cloud: number; time: string; diff --git a/Faupi-HideoutArchitect/server/types/models/enums/BackendErrorCodes.d.ts b/Faupi-HideoutArchitect/server/types/models/enums/BackendErrorCodes.d.ts new file mode 100644 index 0000000..6614b75 --- /dev/null +++ b/Faupi-HideoutArchitect/server/types/models/enums/BackendErrorCodes.d.ts @@ -0,0 +1,67 @@ +export declare enum BackendErrorCodes { + NONE = 0, + UNKNOWN_ERROR = 200, + NOT_AUTHORIZED = 201, + NEED_AUTHORIZATION_CODE = 209, + WRONG_AUTHORIZATION_CODE = 211, + NEED_CAPTCHA = 214, + NO_NEED_CAPTCHA = 215, + CAPTCHA_FAILED = 218, + CAPTCHA_BRUTE_FORCED = 219, + NO_ROOM_IN_STASH = 223, + NICKNAME_NOT_UNIQUE = 225, + NICKNAME_NOT_VALID = 226, + UNSUPPORTED_CLIENT_VERSION = 232, + REPORT_NOT_ALLOWED = 238, + NICKNAME_IS_ABUSIVE = 241, + NICKNAME_CHANGE_TIMEOUT = 242, + NOT_MODIFIED = 304, + HTTP_BAD_REQUEST = 400, + HTTP_NOT_AUTHORIZED = 401, + HTTP_FORBIDDEN = 403, + HTTP_NOT_FOUND = 404, + HTTP_METHOD_NOT_ALLOWED = 405, + UNKNOWN_TRADING_ERROR = 500, + HTTPNOTIMPLEMENTED = 501, + HTTPBADGATEWAY = 502, + HTTPSERVICEUNAVAILABLE = 503, + HTTPGATEWAYTIMEOUT = 504, + TRADEROUTOFMONEY = 505, + HTTPVARIANTALSONEGOTIATES = 506, + PRICECHANGED = 509, + TRADERDISABLED = 512, + ITEMHASBEENSOLD = 513, + NOTENOUGHSPACEFORMONEY = 518, + HTTPINVALIDSSLCERTIFICATE = 526, + UNKNOWNRAGFAIRERROR = 550, + UNKNOWNRAGFAIRERROR2 = 551, + UNKNOWNMATCHMAKERERROR = 600, + SESSIONPARAMETERSERROR = 601, + SESSIONLOST = 602, + SERVERNOTREGISTERED = 604, + UNKNOWNQUESTERROR = 700, + QUESTBADPARAM = 702, + QUESTNOTFOUND = 703, + QUESTISUNAVAILABLE = 704, + NOFREESPACEFORREWARDS = 705, + WRONGQUESTSTATUS = 706, + CANTCOMPLETEQUEST = 707, + UNKNOWNMAILERROR = 900, + TOOMANYFRIENDREQUESTS = 925, + UNKNOWNSCRIPTEXECUTIONERROR = 1000, + UNKNOWNREPAIRINGERROR = 1200, + UNKNOWNINSURANCEERROR = 1300, + UNKNOWNCURRENCYEXCHANGEERROR = 1400, + OFFERNOTFOUND = 1503, + NOTENOUGHSPACE = 1505, + OFFEROUTOFSTOCK = 1506, + OFFERSOLD = 1507, + RAGFAIRUNAVAILABLE = 1511, + BANNEDERRORCODE = 1513, + INSUFFICIENTNUMBERINSTOCK = 1516, + TOOMANYITEMSTOSELL = 1517, + EXAMINATIONFAILED = 22001, + ITEMALREADYEXAMINED = 22002, + UNKNOWNNGINXERROR = 9000, + PARSERESPONSEERROR = 9001 +} diff --git a/Faupi-HideoutArchitect/server/types/models/enums/HideoutEventActions.d.ts b/Faupi-HideoutArchitect/server/types/models/enums/HideoutEventActions.d.ts new file mode 100644 index 0000000..e441477 --- /dev/null +++ b/Faupi-HideoutArchitect/server/types/models/enums/HideoutEventActions.d.ts @@ -0,0 +1,11 @@ +export declare enum HideoutEventActions { + HIDEOUT_UPGRADE = "HideoutUpgrade", + HIDEOUT_UPGRADE_COMPLETE = "HideoutUpgradeComplete", + HIDEOUT_PUT_ITEMS_IN_AREA_SLOTS = "HideoutPutItemsInAreaSlots", + HIDEOUT_TAKE_ITEMS_FROM_AREA_SLOTS = "HideoutTakeItemsFromAreaSlots", + HIDEOUT_TOGGLE_AREA = "HideoutToggleArea", + HIDEOUT_SINGLE_PRODUCTION_START = "HideoutSingleProductionStart", + HIDEOUT_SCAV_CASE_PRODUCTION_START = "HideoutScavCaseProductionStart", + HIDEOUT_CONTINUOUS_PRODUCTION_START = "HideoutContinuousProductionStart", + HIDEOUT_TAKE_PRODUCTION = "HideoutTakeProduction" +} diff --git a/Faupi-HideoutArchitect/server/types/models/enums/ItemEventActions.d.ts b/Faupi-HideoutArchitect/server/types/models/enums/ItemEventActions.d.ts new file mode 100644 index 0000000..0e65453 --- /dev/null +++ b/Faupi-HideoutArchitect/server/types/models/enums/ItemEventActions.d.ts @@ -0,0 +1,19 @@ +export declare enum ItemEventActions { + MOVE = "Move", + REMOVE = "Remove", + SPLIT = "Split", + MERGE = "Merge", + TRANSFER = "Transfer", + SWAP = "Swap", + FOLD = "Fold", + TOGGLE = "Toggle", + TAG = "Tag", + BIND = "Bind", + EXAMINE = "Examine", + READ_ENCYCLOPEDIA = "ReadEncyclopedia", + APPLY_INVENTORY_CHANGES = "ApplyInventoryChanges", + CREATE_MAP_MARKER = "CreateMapMarker", + DELETE_MAP_MARKER = "DeleteMapMarker", + EDIT_MAP_MARKER = "EditMapMarker", + OPEN_RANDOM_LOOT_CONTAINER = "OpenRandomLootContainer" +} diff --git a/Faupi-HideoutArchitect/server/types/models/enums/WeatherType.d.ts b/Faupi-HideoutArchitect/server/types/models/enums/WeatherType.d.ts new file mode 100644 index 0000000..d31fefe --- /dev/null +++ b/Faupi-HideoutArchitect/server/types/models/enums/WeatherType.d.ts @@ -0,0 +1,19 @@ +export declare enum WeatherType { + CLEAR_DAY = 1, + CLEAR_WIND = 2, + CLEAR_NIGHT = 3, + PARTLY_CLOUD_DAY = 4, + PARTLY_CLOUD_NIGHT = 5, + CLEAR_FOG_DAY = 6, + CLEAR_FOG_NIGHT = 7, + CLOUDFOG = 8, + FOG = 9, + MOSTLY_CLOUD = 10, + LIGHT_RAIN = 11, + RAIN = 12, + CLOUD_WIND = 13, + CLOUD_WIND_RAIN = 14, + FULL_CLOUD = 15, + THUNDER_CLOUD = 16, + NONE = 0 +} diff --git a/Faupi-HideoutArchitect/server/types/models/enums/WildSpawnTypeNumber.d.ts b/Faupi-HideoutArchitect/server/types/models/enums/WildSpawnTypeNumber.d.ts new file mode 100644 index 0000000..ff806fe --- /dev/null +++ b/Faupi-HideoutArchitect/server/types/models/enums/WildSpawnTypeNumber.d.ts @@ -0,0 +1,33 @@ +export declare enum WildSpawnTypeNumber { + ASSAULT = 1, + MARKSMAN = 2, + BOSSTEST = 4, + BOSSBULLY = 8, + FOLLOWERTEST = 16, + FOLLOWERBULLY = 32, + BOSSKILLA = 64, + BOSSKOJANIY = 128, + FOLLOWERKOJANIY = 256, + PMCBOT = 512, + CURSEDASSAULT = 1024, + BOSSGLUHAR = 2048, + FOLLOWERGLUHARASSAULT = 4096, + FOLLOWERGLUHARSECURITY = 8192, + FOLLOWERGLUHARSCOUT = 16384, + FOLLOWERGLUHARSNIPE = 32768, + FOLLOWERSANITAR = 65536, + BOSSSANITAR = 131072, + TEST = 262144, + ASSAULTGROUP = 524288, + SECTANTWARRIOR = 1048576, + SECTANTPRIEST = 2097152, + BOSSTAGILLA = 4194304, + FOLLOWERTAGILLA = 8388608, + EXUSEC = 16777216, + GIFTER = 33554432, + BOSSKNIGHT = 67108864, + FOLLOWERBIGPIPE = 134217728, + FOLLOWERBIRDEYE = 268435456, + SPTUSEC = 536870912, + SPTBEAR = 1073741824 +} diff --git a/Faupi-HideoutArchitect/server/types/models/enums/WindDirection.d.ts b/Faupi-HideoutArchitect/server/types/models/enums/WindDirection.d.ts new file mode 100644 index 0000000..fb30b20 --- /dev/null +++ b/Faupi-HideoutArchitect/server/types/models/enums/WindDirection.d.ts @@ -0,0 +1,10 @@ +export declare enum WindDirection { + EAST = 1, + NORTH = 2, + WEST = 3, + SOUTH = 4, + SE = 5, + SW = 6, + NW = 7, + NE = 8 +} diff --git a/Faupi-HideoutArchitect/server/types/models/spt/bots/BotGenerationDetails.d.ts b/Faupi-HideoutArchitect/server/types/models/spt/bots/BotGenerationDetails.d.ts new file mode 100644 index 0000000..256de03 --- /dev/null +++ b/Faupi-HideoutArchitect/server/types/models/spt/bots/BotGenerationDetails.d.ts @@ -0,0 +1,16 @@ +export interface BotGenerationDetails { + /** Should the bot be generated as a PMC */ + isPmc: boolean; + /** assault/pmcBot etc */ + role: string; + /** Active players current level */ + playerLevel: number; + /** Delta of highest level of bot */ + botRelativeLevelDeltaMax: number; + /** How many to create and store */ + botCountToGenerate: number; + /** Desired difficulty of the bot */ + botDifficulty: string; + /** Will the generated bot be a player scav */ + isPlayerScav: boolean; +} diff --git a/Faupi-HideoutArchitect/server/types/models/spt/config/IBotConfig.d.ts b/Faupi-HideoutArchitect/server/types/models/spt/config/IBotConfig.d.ts index af8ceba..83897db 100644 --- a/Faupi-HideoutArchitect/server/types/models/spt/config/IBotConfig.d.ts +++ b/Faupi-HideoutArchitect/server/types/models/spt/config/IBotConfig.d.ts @@ -27,6 +27,8 @@ export interface IBotConfig extends IBaseConfig { maxBotCap: Record; /** How many stacks of secret ammo should a bot have in its bot secure container */ secureContainerAmmoStackCount: number; + /** Batch generation size when type not available in cache */ + botGenerationBatchSizePerType: number; } export interface PresetBatch { assault: number; @@ -64,10 +66,13 @@ export interface LootNvalue { } export interface EquipmentFilters { weaponModLimits: ModLimits; - randomisedWeaponModSlots?: string[]; - randomisedArmorSlots?: string[]; + faceShieldIsActiveChancePercent?: number; + lightLaserIsActiveChancePercent?: number; + randomisation: RandomisationDetails[]; blacklist: EquipmentFilterDetails[]; whitelist: EquipmentFilterDetails[]; + clothing: WeightingAdjustmentDetails[]; + weightingAdjustments: WeightingAdjustmentDetails[]; } export interface ModLimits { /** How many scopes are allowed on a weapon - hard coded to work with OPTIC_SCOPE, ASSAULT_SCOPE, COLLIMATOR, COMPACT_COLLIMATOR */ @@ -75,8 +80,27 @@ export interface ModLimits { /** How many lasers or lights are allowed on a weapon - hard coded to work with TACTICAL_COMBO, and FLASHLIGHT */ lightLaserLimit?: number; } +export interface RandomisationDetails { + levelRange: MinMax; + randomisedWeaponModSlots?: string[]; + randomisedArmorSlots?: string[]; + /** Equipment chances */ + equipment?: Record; + /** Modc chances */ + mods?: Record; +} export interface EquipmentFilterDetails { levelRange: MinMax; equipment: Record; cartridge: Record; } +export interface WeightingAdjustmentDetails { + levelRange: MinMax; + ammo?: AdjustmentDetails; + equipment?: AdjustmentDetails; + clothing?: AdjustmentDetails; +} +export interface AdjustmentDetails { + add: Record>; + edit: Record>; +} diff --git a/Faupi-HideoutArchitect/server/types/models/spt/config/IInventoryConfig.d.ts b/Faupi-HideoutArchitect/server/types/models/spt/config/IInventoryConfig.d.ts index ffffa41..4642b9b 100644 --- a/Faupi-HideoutArchitect/server/types/models/spt/config/IInventoryConfig.d.ts +++ b/Faupi-HideoutArchitect/server/types/models/spt/config/IInventoryConfig.d.ts @@ -2,4 +2,10 @@ import { IBaseConfig } from "./IBaseConfig"; export interface IInventoryConfig extends IBaseConfig { kind: "aki-inventory"; newItemsMarkedFound: boolean; + randomLootContainers: Record; +} +export interface RewardDetails { + rewardCount: number; + foundInRaid: boolean; + rewardTplPool: Record; } diff --git a/Faupi-HideoutArchitect/server/types/models/spt/config/ILocaleConfig.d.ts b/Faupi-HideoutArchitect/server/types/models/spt/config/ILocaleConfig.d.ts index fe9abf7..0a8955c 100644 --- a/Faupi-HideoutArchitect/server/types/models/spt/config/ILocaleConfig.d.ts +++ b/Faupi-HideoutArchitect/server/types/models/spt/config/ILocaleConfig.d.ts @@ -1,5 +1,10 @@ import { IBaseConfig } from "./IBaseConfig"; export interface ILocaleConfig extends IBaseConfig { kind: "aki-locale"; - desiredLocale: string; + /** e.g. ru/en/cn/fr etc, or 'system', will take computer locale setting */ + gameLocale: string; + /** e.g. ru/en/cn/fr etc, or 'system', will take computer locale setting */ + serverLocale: string; + /** Languages server can be translated into */ + serverSupportedLocales: string[]; } diff --git a/Faupi-HideoutArchitect/server/types/models/spt/config/IPmcConfig.d.ts b/Faupi-HideoutArchitect/server/types/models/spt/config/IPmcConfig.d.ts index 9db2ba1..979122c 100644 --- a/Faupi-HideoutArchitect/server/types/models/spt/config/IPmcConfig.d.ts +++ b/Faupi-HideoutArchitect/server/types/models/spt/config/IPmcConfig.d.ts @@ -6,14 +6,17 @@ export interface IPmcConfig { looseWeaponInBackpackChancePercent: number; looseWeaponInBackpackLootMinMax: MinMax; isUsec: number; + usecType: string; + bearType: string; chanceSameSideIsHostilePercent: number; /** key: location, value: type for usec/bear */ - pmcType: Record; + pmcType: Record>>; maxBackpackLootTotalRub: number; maxPocketLootTotalRub: number; maxVestLootTotalRub: number; convertIntoPmcChance: Record; enemyTypes: string[]; + botRelativeLevelDeltaMax: number; } export interface PmcTypes { usec: string; diff --git a/Faupi-HideoutArchitect/server/types/models/spt/config/IRagfairConfig.d.ts b/Faupi-HideoutArchitect/server/types/models/spt/config/IRagfairConfig.d.ts index c1b8763..6786417 100644 --- a/Faupi-HideoutArchitect/server/types/models/spt/config/IRagfairConfig.d.ts +++ b/Faupi-HideoutArchitect/server/types/models/spt/config/IRagfairConfig.d.ts @@ -28,12 +28,8 @@ export interface Reputation { gain: number; loss: number; } -export declare class OfferAdjustment { - maxPriceDifferenceBelowHandbookPercent: number; - handbookPriceMultipier: number; - priceThreshholdRub: number; -} export interface Dynamic { + barter: Barter; offerAdjustment: OfferAdjustment; expiredOfferThreshold: number; offerItemCount: MinMax; @@ -49,6 +45,20 @@ export interface Dynamic { showAsSingleStack: string[]; blacklist: Blacklist; } +export declare class Barter { + enable: boolean; + chancePercent: number; + itemCountMin: number; + itemCountMax: number; + priceRangeVariancePercent: number; + minRoubleCostToBecomeBarter: number; + itemTypeBlacklist: string[]; +} +export declare class OfferAdjustment { + maxPriceDifferenceBelowHandbookPercent: number; + handbookPriceMultipier: number; + priceThreshholdRub: number; +} export interface Condition { conditionChance: number; min: number; diff --git a/Faupi-HideoutArchitect/server/types/models/spt/config/ISeasonalEventConfig.d.ts b/Faupi-HideoutArchitect/server/types/models/spt/config/ISeasonalEventConfig.d.ts index bc60618..e410925 100644 --- a/Faupi-HideoutArchitect/server/types/models/spt/config/ISeasonalEventConfig.d.ts +++ b/Faupi-HideoutArchitect/server/types/models/spt/config/ISeasonalEventConfig.d.ts @@ -1,6 +1,9 @@ import { IBaseConfig } from "./IBaseConfig"; export interface ISeasonalEventConfig extends IBaseConfig { kind: "aki-seasonalevents"; + enableSeasonalEventDetection: boolean; + /** event / botType / equipSlot / itemid */ + eventGear: Record>>>; events: ISeasonalEvent[]; } export interface ISeasonalEvent { diff --git a/Faupi-HideoutArchitect/server/types/models/spt/config/IWeatherConfig.d.ts b/Faupi-HideoutArchitect/server/types/models/spt/config/IWeatherConfig.d.ts index bbdc43e..41a1c83 100644 --- a/Faupi-HideoutArchitect/server/types/models/spt/config/IWeatherConfig.d.ts +++ b/Faupi-HideoutArchitect/server/types/models/spt/config/IWeatherConfig.d.ts @@ -1,3 +1,4 @@ +import { WindDirection } from "../../../models/enums/WindDirection"; import { MinMax } from "../../common/MinMax"; import { IBaseConfig } from "./IBaseConfig"; export interface IWeatherConfig extends IBaseConfig { @@ -7,12 +8,16 @@ export interface IWeatherConfig extends IBaseConfig { } export interface Weather { clouds: MinMax; - windSpeed: MinMax; - windDirection: MinMax; + windSpeed: WeatherSettings; + windDirection: WeatherSettings; windGustiness: MinMax; - rain: MinMax; + rain: WeatherSettings; rainIntensity: MinMax; - fog: MinMax; + fog: WeatherSettings; temp: MinMax; pressure: MinMax; } +export interface WeatherSettings { + values: T[]; + weights: number[]; +} diff --git a/Faupi-HideoutArchitect/server/types/routers/item_events/HideoutItemEventRouter.d.ts b/Faupi-HideoutArchitect/server/types/routers/item_events/HideoutItemEventRouter.d.ts index e1e98af..44bd1cd 100644 --- a/Faupi-HideoutArchitect/server/types/routers/item_events/HideoutItemEventRouter.d.ts +++ b/Faupi-HideoutArchitect/server/types/routers/item_events/HideoutItemEventRouter.d.ts @@ -1,7 +1,7 @@ -import { IPmcData } from "../../models/eft/common/IPmcData"; -import { IItemEventRouterResponse } from "../../models/eft/itemEvent/IItemEventRouterResponse"; import { HideoutCallbacks } from "../../callbacks/HideoutCallbacks"; import { HandledRoute, ItemEventRouterDefinition } from "../../di/Router"; +import { IPmcData } from "../../models/eft/common/IPmcData"; +import { IItemEventRouterResponse } from "../../models/eft/itemEvent/IItemEventRouterResponse"; export declare class HideoutItemEventRouter extends ItemEventRouterDefinition { protected hideoutCallbacks: HideoutCallbacks; constructor(hideoutCallbacks: HideoutCallbacks); diff --git a/Faupi-HideoutArchitect/server/types/routers/item_events/InventoryItemEventRouter.d.ts b/Faupi-HideoutArchitect/server/types/routers/item_events/InventoryItemEventRouter.d.ts index 2619bb9..953d322 100644 --- a/Faupi-HideoutArchitect/server/types/routers/item_events/InventoryItemEventRouter.d.ts +++ b/Faupi-HideoutArchitect/server/types/routers/item_events/InventoryItemEventRouter.d.ts @@ -1,7 +1,7 @@ -import { IPmcData } from "../../models/eft/common/IPmcData"; -import { IItemEventRouterResponse } from "../../models/eft/itemEvent/IItemEventRouterResponse"; import { InventoryCallbacks } from "../../callbacks/InventoryCallbacks"; import { HandledRoute, ItemEventRouterDefinition } from "../../di/Router"; +import { IPmcData } from "../../models/eft/common/IPmcData"; +import { IItemEventRouterResponse } from "../../models/eft/itemEvent/IItemEventRouterResponse"; export declare class InventoryItemEventRouter extends ItemEventRouterDefinition { protected inventoryCallbacks: InventoryCallbacks; constructor(inventoryCallbacks: InventoryCallbacks); diff --git a/Faupi-HideoutArchitect/server/types/servers/HttpServer.d.ts b/Faupi-HideoutArchitect/server/types/servers/HttpServer.d.ts index bbca8af..80c1d48 100644 --- a/Faupi-HideoutArchitect/server/types/servers/HttpServer.d.ts +++ b/Faupi-HideoutArchitect/server/types/servers/HttpServer.d.ts @@ -4,6 +4,7 @@ import { ApplicationContext } from "../context/ApplicationContext"; import { HttpServerHelper } from "../helpers/HttpServerHelper"; import { IHttpConfig } from "../models/spt/config/IHttpConfig"; import { ILogger } from "../models/spt/utils/ILogger"; +import { LocalisationService } from "../services/LocalisationService"; import { ConfigServer } from "./ConfigServer"; import { DatabaseServer } from "./DatabaseServer"; import { IHttpListener } from "./http/IHttpListener"; @@ -12,11 +13,12 @@ export declare class HttpServer { protected logger: ILogger; protected databaseServer: DatabaseServer; protected httpServerHelper: HttpServerHelper; + protected localisationService: LocalisationService; protected httpListeners: IHttpListener[]; protected configServer: ConfigServer; protected applicationContext: ApplicationContext; protected webSocketServer: WebSocketServer; - constructor(logger: ILogger, databaseServer: DatabaseServer, httpServerHelper: HttpServerHelper, httpListeners: IHttpListener[], configServer: ConfigServer, applicationContext: ApplicationContext, webSocketServer: WebSocketServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, httpServerHelper: HttpServerHelper, localisationService: LocalisationService, httpListeners: IHttpListener[], configServer: ConfigServer, applicationContext: ApplicationContext, webSocketServer: WebSocketServer); protected httpConfig: IHttpConfig; getCookies(req: http.IncomingMessage): any; handleRequest(req: IncomingMessage, resp: ServerResponse): void; diff --git a/Faupi-HideoutArchitect/server/types/servers/SaveServer.d.ts b/Faupi-HideoutArchitect/server/types/servers/SaveServer.d.ts index cb28f49..4dca514 100644 --- a/Faupi-HideoutArchitect/server/types/servers/SaveServer.d.ts +++ b/Faupi-HideoutArchitect/server/types/servers/SaveServer.d.ts @@ -1,20 +1,22 @@ +import { SaveLoadRouter } from "../di/Router"; import { IAkiProfile, Info } from "../models/eft/profile/IAkiProfile"; +import { ILogger } from "../models/spt/utils/ILogger"; +import { LocalisationService } from "../services/LocalisationService"; import { HashUtil } from "../utils/HashUtil"; import { JsonUtil } from "../utils/JsonUtil"; import { VFS } from "../utils/VFS"; -import { SaveLoadRouter } from "../di/Router"; -import { ILogger } from "../models/spt/utils/ILogger"; export declare class SaveServer { protected vfs: VFS; protected saveLoadRouters: SaveLoadRouter[]; protected jsonUtil: JsonUtil; protected hashUtil: HashUtil; + protected localisationService: LocalisationService; protected logger: ILogger; protected profileFilepath: string; protected profiles: {}; protected onSave: {}; protected saveMd5: {}; - constructor(vfs: VFS, saveLoadRouters: SaveLoadRouter[], jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger); + constructor(vfs: VFS, saveLoadRouters: SaveLoadRouter[], jsonUtil: JsonUtil, hashUtil: HashUtil, localisationService: LocalisationService, logger: ILogger); load(): void; save(): void; getProfile(sessionId: string): IAkiProfile; diff --git a/Faupi-HideoutArchitect/server/types/servers/WebSocketServer.d.ts b/Faupi-HideoutArchitect/server/types/servers/WebSocketServer.d.ts index f33d214..5d40e6e 100644 --- a/Faupi-HideoutArchitect/server/types/servers/WebSocketServer.d.ts +++ b/Faupi-HideoutArchitect/server/types/servers/WebSocketServer.d.ts @@ -1,18 +1,20 @@ /// -import { HttpServerHelper } from "../helpers/HttpServerHelper"; -import WebSocket from "ws"; import http, { IncomingMessage } from "http"; -import { ILogger } from "../models/spt/utils/ILogger"; -import { RandomUtil } from "../utils/RandomUtil"; +import WebSocket from "ws"; +import { HttpServerHelper } from "../helpers/HttpServerHelper"; import { INotification } from "../models/eft/notifier/INotifier"; -import { ConfigServer } from "./ConfigServer"; import { IHttpConfig } from "../models/spt/config/IHttpConfig"; +import { ILogger } from "../models/spt/utils/ILogger"; +import { LocalisationService } from "../services/LocalisationService"; +import { RandomUtil } from "../utils/RandomUtil"; +import { ConfigServer } from "./ConfigServer"; export declare class WebSocketServer { protected logger: ILogger; protected randomUtil: RandomUtil; protected configServer: ConfigServer; + protected localisationService: LocalisationService; protected httpServerHelper: HttpServerHelper; - constructor(logger: ILogger, randomUtil: RandomUtil, configServer: ConfigServer, httpServerHelper: HttpServerHelper); + constructor(logger: ILogger, randomUtil: RandomUtil, configServer: ConfigServer, localisationService: LocalisationService, httpServerHelper: HttpServerHelper); protected httpConfig: IHttpConfig; protected defaultNotification: INotification; protected webSockets: Record; diff --git a/Faupi-HideoutArchitect/server/types/servers/http/AkiHttpListener.d.ts b/Faupi-HideoutArchitect/server/types/servers/http/AkiHttpListener.d.ts index 6f78939..acf92aa 100644 --- a/Faupi-HideoutArchitect/server/types/servers/http/AkiHttpListener.d.ts +++ b/Faupi-HideoutArchitect/server/types/servers/http/AkiHttpListener.d.ts @@ -1,22 +1,24 @@ /// /// import { IncomingMessage, ServerResponse } from "http"; -import { IHttpListener } from "./IHttpListener"; import { Serializer } from "../../di/Serializer"; import { ILogger } from "../../models/spt/utils/ILogger"; import { HttpRouter } from "../../routers/HttpRouter"; +import { LocalisationService } from "../../services/LocalisationService"; import { HttpResponseUtil } from "../../utils/HttpResponseUtil"; import { JsonUtil } from "../../utils/JsonUtil"; import { HttpBufferHandler } from "./HttpBufferHandler"; +import { IHttpListener } from "./IHttpListener"; export declare class AkiHttpListener implements IHttpListener { protected httpRouter: HttpRouter; protected serializers: Serializer[]; protected logger: ILogger; protected jsonUtil: JsonUtil; protected httpResponse: HttpResponseUtil; + protected localisationService: LocalisationService; protected httpBufferHandler: HttpBufferHandler; constructor(httpRouter: HttpRouter, // TODO: delay required - serializers: Serializer[], logger: ILogger, jsonUtil: JsonUtil, httpResponse: HttpResponseUtil, httpBufferHandler: HttpBufferHandler); + serializers: Serializer[], logger: ILogger, jsonUtil: JsonUtil, httpResponse: HttpResponseUtil, localisationService: LocalisationService, httpBufferHandler: HttpBufferHandler); canHandle(_: string, req: IncomingMessage): boolean; handle(sessionId: string, req: IncomingMessage, resp: ServerResponse): void; sendResponse(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: Buffer, output: string): void; diff --git a/Faupi-HideoutArchitect/server/types/services/BotEquipmentFilterService.d.ts b/Faupi-HideoutArchitect/server/types/services/BotEquipmentFilterService.d.ts index 632f961..43e64b0 100644 --- a/Faupi-HideoutArchitect/server/types/services/BotEquipmentFilterService.d.ts +++ b/Faupi-HideoutArchitect/server/types/services/BotEquipmentFilterService.d.ts @@ -1,21 +1,29 @@ -import { IBotType } from "../models/eft/common/tables/IBotType"; -import { EquipmentFilters, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig"; +import { BotHelper } from "../helpers/BotHelper"; +import { EquipmentChances, IBotType, ModsChances } from "../models/eft/common/tables/IBotType"; +import { BotGenerationDetails } from "../models/spt/bots/BotGenerationDetails"; +import { AdjustmentDetails, EquipmentFilterDetails, EquipmentFilters, IBotConfig, WeightingAdjustmentDetails } from "../models/spt/config/IBotConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; export declare class BotEquipmentFilterService { protected logger: ILogger; + protected botHelper: BotHelper; protected configServer: ConfigServer; protected botConfig: IBotConfig; - protected botEquipmentFilterlists: Record; - constructor(logger: ILogger, configServer: ConfigServer); + protected botEquipmentConfig: Record; + constructor(logger: ILogger, botHelper: BotHelper, configServer: ConfigServer); /** * Filter a bots data to exclude equipment and cartridges defines in the botConfig * @param baseBotNode bots json data to filter - * @param playerLevel Level of the currently playing player - * @param isPmc Is the bot we're filtering a PMC - * @param role Role of the bot we're filtering + * @param botLevel Level of the bot + * @param botGenerationDetails details on how to generate a bot */ - filterBotEquipment(baseBotNode: IBotType, playerLevel: number, isPmc: boolean, role: string): void; + filterBotEquipment(baseBotNode: IBotType, botLevel: number, botGenerationDetails: BotGenerationDetails): void; + /** + * Iterate over the changes passed in and alter data in baseValues + * @param equipmentChanges Changes to apply + * @param baseValues Values to update + */ + protected adjustChances(equipmentChanges: Record, baseValues: EquipmentChances | ModsChances): void; /** * Get an object that contains equipment and cartridge blacklists for a specified bot type * @param botRole Role of the bot we want the blacklist for @@ -30,6 +38,20 @@ export declare class BotEquipmentFilterService { * @returns EquipmentFilterDetails object */ protected getBotEquipmentWhitelist(botRole: string, playerLevel: number): EquipmentFilterDetails; + /** + * Retreive clothing weighting adjustments from bot.json config + * @param botRole Bot type to get adjustments for + * @param playerLevel level of player + * @returns Weighting adjustments for bots clothing + */ + protected getBotClothingAdjustments(botRole: string, playerLevel: number): WeightingAdjustmentDetails; + /** + * Retreive item weighting adjustments from bot.json config + * @param botRole Bot type to get adjustments for + * @param playerLevel level of player + * @returns Weighting adjustments for bot items + */ + protected getBotWeightingAdjustments(botRole: string, playerLevel: number): WeightingAdjustmentDetails; /** * Filter bot equipment based on blacklist and whitelist from config/bot.json * Prioritises whitelist first, if one is found blacklist is ignored @@ -47,4 +69,10 @@ export declare class BotEquipmentFilterService { * @returns Filtered bot file */ protected filterCartridges(baseBotNode: IBotType, blacklist: EquipmentFilterDetails, whitelist: EquipmentFilterDetails): void; + /** + * Add/Edit weighting changes to bot items using values from config/bot.json/equipment + * @param weightingAdjustments Weighting change to apply to bot + * @param botItemPool Bot item dictionary to adjust + */ + protected adjustWeighting(weightingAdjustments: AdjustmentDetails, botItemPool: Record, showEditWarnings?: boolean): void; } diff --git a/Faupi-HideoutArchitect/server/types/services/BotGenerationCacheService.d.ts b/Faupi-HideoutArchitect/server/types/services/BotGenerationCacheService.d.ts index ba53fec..0be0576 100644 --- a/Faupi-HideoutArchitect/server/types/services/BotGenerationCacheService.d.ts +++ b/Faupi-HideoutArchitect/server/types/services/BotGenerationCacheService.d.ts @@ -8,11 +8,11 @@ export declare class BotGenerationCacheService { protected randomUtil: RandomUtil; protected jsonUtil: JsonUtil; protected botHelper: BotHelper; - protected storedBots: IBotBase[]; + protected storedBots: Map; constructor(logger: ILogger, randomUtil: RandomUtil, jsonUtil: JsonUtil, botHelper: BotHelper); /** * Store array of bots in cache, shuffle results before storage - * @param botsToStore + * @param botsToStore Bots we want to store in the cache */ storeBots(botsToStore: IBotBase[]): void; /** @@ -21,25 +21,7 @@ export declare class BotGenerationCacheService { * @param role role to retreive (assault/bossTagilla etc) * @returns IBotBase object */ - getBot(role: string): IBotBase[]; - /** - * Find a bot by its index from cache - * @param indexOfBotToReturn index to find bot by - * @returns bot profile - */ - protected getBotFromCache(indexOfBotToReturn: number): IBotBase; - /** - * Remove bot profile by index from cache - * @param indexOfBotToReturn Index of bot profile to remove - */ - protected removeBotFromCache(indexOfBotToReturn: number): void; - /** - * Get index of bot profile that matches criteria - * @param role Role of bot wanted - * @param getPmc Requested bot a pmc - * @returns index of found bot, -1 if not found - */ - protected getIndexOfBotToReturn(role: string, getPmc: boolean): number; + getBot(role: string): IBotBase; /** * Remove all cached bot profiles */ @@ -48,5 +30,5 @@ export declare class BotGenerationCacheService { * Does cache have bots * @returns true if empty */ - cacheIsEmpty(): boolean; + cacheHasBotOfRole(role: string): boolean; } diff --git a/Faupi-HideoutArchitect/server/types/services/LocaleService.d.ts b/Faupi-HideoutArchitect/server/types/services/LocaleService.d.ts index 33bea7b..8275b75 100644 --- a/Faupi-HideoutArchitect/server/types/services/LocaleService.d.ts +++ b/Faupi-HideoutArchitect/server/types/services/LocaleService.d.ts @@ -1,14 +1,42 @@ import { ILocaleConfig } from "../models/spt/config/ILocaleConfig"; +import { ILocaleGlobalBase } from "../models/spt/server/ILocaleBase"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; +import { DatabaseServer } from "../servers/DatabaseServer"; +/** + * Handles getting locales from config or users machine + */ export declare class LocaleService { protected logger: ILogger; + protected databaseServer: DatabaseServer; protected configServer: ConfigServer; protected localeConfig: ILocaleConfig; - constructor(logger: ILogger, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, configServer: ConfigServer); /** - * Gets the locale key from the locale.json file + * Get the eft globals db file based on the configured locale in config/locale.json, if not found, fall back to 'en' + * @returns ILocaleGlobalBase + */ + getLocaleDb(): ILocaleGlobalBase; + /** + * Gets the game locale key from the locale.json file, + * if value is 'system' get system locale * @returns locale e.g en/ge/cz/cn */ - getDesiredLocale(): string; + getDesiredGameLocale(): string; + /** + * Gets the game locale key from the locale.json file, + * if value is 'system' get system locale + * @returns locale e.g en/ge/cz/cn + */ + getDesiredServerLocale(): string; + /** + * Get array of languages supported for localisation + * @returns array of locales e.g. en/fr/cn + */ + getServerSupportedLocales(): string[]; + /** + * Get the locale of the computer running the server + * @returns langage part of locale e.g. 'en' part of 'en-US' + */ + protected getPlatformLocale(): string; } diff --git a/Faupi-HideoutArchitect/server/types/services/LocalisationService.d.ts b/Faupi-HideoutArchitect/server/types/services/LocalisationService.d.ts new file mode 100644 index 0000000..519325d --- /dev/null +++ b/Faupi-HideoutArchitect/server/types/services/LocalisationService.d.ts @@ -0,0 +1,21 @@ +import { I18n } from "i18n"; +import { ILocaleConfig } from "../models/spt/config/ILocaleConfig"; +import { ILogger } from "../models/spt/utils/ILogger"; +import { LocaleService } from "./LocaleService"; +/** + * Handles translating server text into different langauges + */ +export declare class LocalisationService { + protected logger: ILogger; + protected localeService: LocaleService; + protected localeConfig: ILocaleConfig; + protected i18n: I18n; + constructor(logger: ILogger, localeService: LocaleService); + /** + * Get a localised value using the passed in key + * @param key Key to loop up locale for + * @param args optional arguments + * @returns Localised string + */ + getText(key: string, args?: any): string; +} diff --git a/Faupi-HideoutArchitect/server/types/services/PaymentService.d.ts b/Faupi-HideoutArchitect/server/types/services/PaymentService.d.ts index a5e538f..c9ce95a 100644 --- a/Faupi-HideoutArchitect/server/types/services/PaymentService.d.ts +++ b/Faupi-HideoutArchitect/server/types/services/PaymentService.d.ts @@ -11,6 +11,7 @@ import { IProcessSellTradeRequestData } from "../models/eft/trade/IProcessSellTr import { ILogger } from "../models/spt/utils/ILogger"; import { DatabaseServer } from "../servers/DatabaseServer"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; +import { LocalisationService } from "./LocalisationService"; export declare class PaymentService { protected logger: ILogger; protected httpResponse: HttpResponseUtil; @@ -19,8 +20,9 @@ export declare class PaymentService { protected traderHelper: TraderHelper; protected itemHelper: ItemHelper; protected inventoryHelper: InventoryHelper; + protected localisationService: LocalisationService; protected paymentHelper: PaymentHelper; - constructor(logger: ILogger, httpResponse: HttpResponseUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, traderHelper: TraderHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, paymentHelper: PaymentHelper); + constructor(logger: ILogger, httpResponse: HttpResponseUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, traderHelper: TraderHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, localisationService: LocalisationService, paymentHelper: PaymentHelper); /** * Take money and insert items into return to server request * @param {Object} pmcData @@ -50,7 +52,7 @@ export declare class PaymentService { * @param pmcData Player profile to find and remove currency from * @param currencyTpl Type of currency to pay * @param amountToPay money value to pay - * @param sessionID Sessino id + * @param sessionID Session id * @param output output object to send to client * @returns IItemEventRouterResponse */ diff --git a/Faupi-HideoutArchitect/server/types/services/PlayerService.d.ts b/Faupi-HideoutArchitect/server/types/services/PlayerService.d.ts index 519b7e5..2f364d5 100644 --- a/Faupi-HideoutArchitect/server/types/services/PlayerService.d.ts +++ b/Faupi-HideoutArchitect/server/types/services/PlayerService.d.ts @@ -2,10 +2,12 @@ import { IPmcData } from "../models/eft/common/IPmcData"; import { IPlayerIncrementSkillLevelRequestData } from "../models/eft/player/IPlayerIncrementSkillLevelRequestData"; import { ILogger } from "../models/spt/utils/ILogger"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "./LocalisationService"; export declare class PlayerService { protected logger: ILogger; + protected localisationService: LocalisationService; protected databaseServer: DatabaseServer; - constructor(logger: ILogger, databaseServer: DatabaseServer); + constructor(logger: ILogger, localisationService: LocalisationService, databaseServer: DatabaseServer); /** * increases the profile skill and updates any output * @param {Object} pmcData diff --git a/Faupi-HideoutArchitect/server/types/services/PmcAiService.d.ts b/Faupi-HideoutArchitect/server/types/services/PmcAiService.d.ts deleted file mode 100644 index 0690f1f..0000000 --- a/Faupi-HideoutArchitect/server/types/services/PmcAiService.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { IBotConfig } from "../models/spt/config/IBotConfig"; -import { ILogger } from "../models/spt/utils/ILogger"; -import { ConfigServer } from "../servers/ConfigServer"; -/** Storing/retreving pmcRoles set at the start of a raid - its done at that point as we know what location the player is heading to */ -export declare class PmcAiService { - protected logger: ILogger; - protected configServer: ConfigServer; - protected botConfig: IBotConfig; - protected usecRole: string; - protected bearRole: string; - constructor(logger: ILogger, configServer: ConfigServer); - /** - * Convert from pmc side (usec/bear) to the side as defined in the bot config (usecType/bearType) - * @param pmcSide eft side (usec/bear) - * @returns pmc side as defined in config - */ - getPmcRole(pmcSide: "usec" | "bear" | string): string; - /** - * Set the roles for pmcs - * @param location map location to look up and use as pmc types - */ - setPmcRolesByLocation(location: string): void; - /** - * Clear the saved role from usec/bear PMCs - */ - clearPmcRoles(): void; -} diff --git a/Faupi-HideoutArchitect/server/types/services/ProfileFixerService.d.ts b/Faupi-HideoutArchitect/server/types/services/ProfileFixerService.d.ts index e772919..86a6af8 100644 --- a/Faupi-HideoutArchitect/server/types/services/ProfileFixerService.d.ts +++ b/Faupi-HideoutArchitect/server/types/services/ProfileFixerService.d.ts @@ -8,12 +8,14 @@ import { HideoutAreas } from "../models/enums/HideoutAreas"; import { ILogger } from "../models/spt/utils/ILogger"; import { DatabaseServer } from "../servers/DatabaseServer"; import { Watermark } from "../utils/Watermark"; +import { LocalisationService } from "./LocalisationService"; export declare class ProfileFixerService { protected logger: ILogger; protected watermark: Watermark; protected hideoutHelper: HideoutHelper; + protected localisationService: LocalisationService; protected databaseServer: DatabaseServer; - constructor(logger: ILogger, watermark: Watermark, hideoutHelper: HideoutHelper, databaseServer: DatabaseServer); + constructor(logger: ILogger, watermark: Watermark, hideoutHelper: HideoutHelper, localisationService: LocalisationService, databaseServer: DatabaseServer); /** * Find issues in the pmc profile data that may cause issues and fix them * @param pmcProfile profile to check and fix diff --git a/Faupi-HideoutArchitect/server/types/services/RagfairOfferService.d.ts b/Faupi-HideoutArchitect/server/types/services/RagfairOfferService.d.ts index a6f6b6d..86c1e52 100644 --- a/Faupi-HideoutArchitect/server/types/services/RagfairOfferService.d.ts +++ b/Faupi-HideoutArchitect/server/types/services/RagfairOfferService.d.ts @@ -11,6 +11,7 @@ import { DatabaseServer } from "../servers/DatabaseServer"; import { SaveServer } from "../servers/SaveServer"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; import { TimeUtil } from "../utils/TimeUtil"; +import { LocalisationService } from "./LocalisationService"; import { RagfairCategoriesService } from "./RagfairCategoriesService"; export declare class RagfairOfferService { protected logger: ILogger; @@ -22,12 +23,14 @@ export declare class RagfairOfferService { protected profileHelper: ProfileHelper; protected eventOutputHolder: EventOutputHolder; protected httpResponse: HttpResponseUtil; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected playerOffersLoaded: boolean; protected expiredOffers: Item[]; - protected offers: IRagfairOffer[]; + /** offerId, offer */ + protected offers: Record; protected ragfairConfig: IRagfairConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, databaseServer: DatabaseServer, saveServer: SaveServer, ragfairServerHelper: RagfairServerHelper, ragfairCategoriesService: RagfairCategoriesService, profileHelper: ProfileHelper, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, databaseServer: DatabaseServer, saveServer: SaveServer, ragfairServerHelper: RagfairServerHelper, ragfairCategoriesService: RagfairCategoriesService, profileHelper: ProfileHelper, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, localisationService: LocalisationService, configServer: ConfigServer); /** * Get all offers * @returns IRagfairOffer array diff --git a/Faupi-HideoutArchitect/server/types/utils/App.d.ts b/Faupi-HideoutArchitect/server/types/utils/App.d.ts index dcc2669..cc8a5af 100644 --- a/Faupi-HideoutArchitect/server/types/utils/App.d.ts +++ b/Faupi-HideoutArchitect/server/types/utils/App.d.ts @@ -1,14 +1,16 @@ -import { TimeUtil } from "./TimeUtil"; import { OnLoad } from "../di/OnLoad"; import { OnUpdate } from "../di/OnUpdate"; import { ILogger } from "../models/spt/utils/ILogger"; +import { LocalisationService } from "../services/LocalisationService"; +import { TimeUtil } from "./TimeUtil"; export declare class App { protected logger: ILogger; protected timeUtil: TimeUtil; + protected localisationService: LocalisationService; protected onLoadComponents: OnLoad[]; protected onUpdateComponents: OnUpdate[]; protected onUpdateLastRun: {}; - constructor(logger: ILogger, timeUtil: TimeUtil, onLoadComponents: OnLoad[], onUpdateComponents: OnUpdate[]); + constructor(logger: ILogger, timeUtil: TimeUtil, localisationService: LocalisationService, onLoadComponents: OnLoad[], onUpdateComponents: OnUpdate[]); load(): void; protected update(onUpdateComponents: OnUpdate[]): void; protected logUpdateException(err: any, updateable: OnUpdate): void; diff --git a/Faupi-HideoutArchitect/server/types/utils/DatabaseImporter.d.ts b/Faupi-HideoutArchitect/server/types/utils/DatabaseImporter.d.ts index 483e135..31670ae 100644 --- a/Faupi-HideoutArchitect/server/types/utils/DatabaseImporter.d.ts +++ b/Faupi-HideoutArchitect/server/types/utils/DatabaseImporter.d.ts @@ -3,15 +3,17 @@ import { IDatabaseTables } from "../models/spt/server/IDatabaseTables"; import { ILogger } from "../models/spt/utils/ILogger"; import { ImageRouter } from "../routers/ImageRouter"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "../services/LocalisationService"; import { JsonUtil } from "./JsonUtil"; import { VFS } from "./VFS"; export declare class DatabaseImporter extends OnLoad { protected logger: ILogger; protected vfs: VFS; protected jsonUtil: JsonUtil; + protected localisationService: LocalisationService; protected databaseServer: DatabaseServer; protected imageRouter: ImageRouter; - constructor(logger: ILogger, vfs: VFS, jsonUtil: JsonUtil, databaseServer: DatabaseServer, imageRouter: ImageRouter); + constructor(logger: ILogger, vfs: VFS, jsonUtil: JsonUtil, localisationService: LocalisationService, databaseServer: DatabaseServer, imageRouter: ImageRouter); onLoad(): void; /** * Read all json files in database folder and map into a json object diff --git a/Faupi-HideoutArchitect/server/types/utils/HttpResponseUtil.d.ts b/Faupi-HideoutArchitect/server/types/utils/HttpResponseUtil.d.ts index 29502be..3a78618 100644 --- a/Faupi-HideoutArchitect/server/types/utils/HttpResponseUtil.d.ts +++ b/Faupi-HideoutArchitect/server/types/utils/HttpResponseUtil.d.ts @@ -1,10 +1,13 @@ -import { JsonUtil } from "./JsonUtil"; import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData"; import { INullResponseData } from "../models/eft/httpResponse/INullResponseData"; import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse"; +import { BackendErrorCodes } from "../models/enums/BackendErrorCodes"; +import { LocalisationService } from "../services/LocalisationService"; +import { JsonUtil } from "./JsonUtil"; export declare class HttpResponseUtil { protected jsonUtil: JsonUtil; - constructor(jsonUtil: JsonUtil); + protected localisationService: LocalisationService; + constructor(jsonUtil: JsonUtil, localisationService: LocalisationService); protected clearString(s: string): any; noBody(data: any): any; getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; @@ -12,5 +15,5 @@ export declare class HttpResponseUtil { emptyResponse(): IGetBodyResponseData; nullResponse(): INullResponseData; emptyArrayResponse(): IGetBodyResponseData; - appendErrorToOutput(output: IItemEventRouterResponse, message?: string, title?: string): IItemEventRouterResponse; + appendErrorToOutput(output: IItemEventRouterResponse, message?: string, errorCode?: BackendErrorCodes): IItemEventRouterResponse; } diff --git a/Faupi-HideoutArchitect/server/types/utils/Logger.d.ts b/Faupi-HideoutArchitect/server/types/utils/Logger.d.ts index 3d9013f..1088701 100644 --- a/Faupi-HideoutArchitect/server/types/utils/Logger.d.ts +++ b/Faupi-HideoutArchitect/server/types/utils/Logger.d.ts @@ -53,6 +53,12 @@ export declare class WinstonLogger implements ILogger { warning(data: string | Record): Promise; success(data: string | Record): Promise; info(data: string | Record): Promise; + /** + * Log to console text with a customisable text and background color. Background defaults to black + * @param data text to log + * @param textColor color of text + * @param backgroundColor color of background + */ logWithColor(data: string | Record, textColor: LogTextColor, backgroundColor?: LogBackgroundColor): Promise; debug(data: string | Record, onlyShowInConsole?: boolean): Promise; } diff --git a/Faupi-HideoutArchitect/server/types/utils/RandomUtil.d.ts b/Faupi-HideoutArchitect/server/types/utils/RandomUtil.d.ts index 633e472..aa556e3 100644 --- a/Faupi-HideoutArchitect/server/types/utils/RandomUtil.d.ts +++ b/Faupi-HideoutArchitect/server/types/utils/RandomUtil.d.ts @@ -110,6 +110,12 @@ export declare class RandomUtil { getIntEx(max: number): number; getFloat(min: number, max: number): number; getBool(): boolean; + /** + * Check if number passes a check out of 100 + * @param chancePercent value check needs to be above + * @returns true if value passes check + */ + getChance100(chancePercent: number): boolean; getStringArrayValue(arr: string[]): string; getArrayValue(arr: T[]): T; getKey(node: any): string; diff --git a/Faupi-HideoutArchitect/server/types/utils/Watermark.d.ts b/Faupi-HideoutArchitect/server/types/utils/Watermark.d.ts index c6dc120..e02eba2 100644 --- a/Faupi-HideoutArchitect/server/types/utils/Watermark.d.ts +++ b/Faupi-HideoutArchitect/server/types/utils/Watermark.d.ts @@ -1,20 +1,15 @@ import { ICoreConfig } from "../models/spt/config/ICoreConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; +import { LocalisationService } from "../services/LocalisationService"; export declare class WatermarkLocale { - protected locales: { - "en-US": { - description: string[]; - warning: string[]; - modding: string[]; - }; - "zh-CN": { - description: string[]; - warning: string[]; - modding: string[]; - }; + protected localisationService: LocalisationService; + constructor(localisationService: LocalisationService); + protected watermark: { + description: string[]; + warning: string[]; + modding: string[]; }; - getLocale(): string; getDescription(): string[]; getWarning(): string[]; getModding(): string[]; @@ -22,9 +17,10 @@ export declare class WatermarkLocale { export declare class Watermark { protected logger: ILogger; protected configServer: ConfigServer; + protected localisationService: LocalisationService; protected watermarkLocale?: WatermarkLocale; protected akiConfig: ICoreConfig; - constructor(logger: ILogger, configServer: ConfigServer, watermarkLocale?: WatermarkLocale); + constructor(logger: ILogger, configServer: ConfigServer, localisationService: LocalisationService, watermarkLocale?: WatermarkLocale); protected text: string[]; protected versionLabel: string; initialize(): void; diff --git a/Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.6/bepInEx/plugins/Faupi-MunitionsExpert.dll b/Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.7/bepInEx/plugins/Faupi-MunitionsExpert.dll similarity index 84% rename from Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.6/bepInEx/plugins/Faupi-MunitionsExpert.dll rename to Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.7/bepInEx/plugins/Faupi-MunitionsExpert.dll index 5b87dc62991fe4a78b12fab7b302fa431ae01965..f8c1e936f3de8d0007d1cfebd3770fe7215c030f 100644 GIT binary patch delta 700 zcmZojX-JvS!E$e6aQDWZ8$9)l3=9lh3_9!++4&eIv0h|iWB9}H1W4{;J;lk!5YCv! zA;eI`q024APzNO07~&Y8Fo`j2W1LP&XhrjL6U))QGkJqX|f!@o2ov8 zC6gILHIoxizapbBqZq>rFd4}NVplSN$hDI@`Sp1>Gx#$xGB`7a0Ld$pkMh4}w3xh6 zK$BmKaXu3_!%Q`x=?u*bA1A*QkgjiL0EsPvifsq0SPJH~Ni5)GWZ-642bD`=SPE3R z9m?CwUJ=;r##Co}>C?q=!ltMKh`Sa`X+ ow$4h@wTj=q0EjL{ZwN2!d$p ze@i_WN06K>Vn9VLWzm8P7Hm@$h1N?wc#-B(6#sy|sxzC>J-nUYdvCsPhBL#N>sN(P zOkbS1_R&*FApjZHJBv;QZaC(#2y;-S`pogxB|;m@N`A;oF}EMiQWYVNs#pWdQ4ti_ zg8@Wnc4Q@y9#}stPEzfbHp?Q6LsnA2OK0}O3%X?#mZ*yGL14|ii|Hq_=-q;zl9kGu z$amVOj+5OwEZ?VFZpjrP0@Lu5`kKW2Ux?%s9c?8=<&2sHfCTs<1a(M-KZrE>de?@a z1DkLfZ=?5@p#fWrRyiVj=nB17U9cCnaN1`*s?P`{uQeirbZG(n z-{iusSmTbnJ9}HlQmcveqvc(l$7HXg-_aRsnY`Bf)CZkUW^Z1qY`^F&OeISX`-vVM dS;b9ZnwzwJvaQrKaIhz=pZ}c7S@Y3$=`T?LrU?K5 diff --git a/Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.6/user/mods/Faupi-MunitionsExpert 1.6.6/LICENSE.txt b/Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.7/user/mods/Faupi-MunitionsExpert 1.6.7/LICENSE.txt similarity index 100% rename from Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.6/user/mods/Faupi-MunitionsExpert 1.6.6/LICENSE.txt rename to Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.7/user/mods/Faupi-MunitionsExpert 1.6.7/LICENSE.txt diff --git a/Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.6/user/mods/Faupi-MunitionsExpert 1.6.6/package.json b/Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.7/user/mods/Faupi-MunitionsExpert 1.6.7/package.json similarity index 91% rename from Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.6/user/mods/Faupi-MunitionsExpert 1.6.6/package.json rename to Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.7/user/mods/Faupi-MunitionsExpert 1.6.7/package.json index a6490f6..234a9a0 100644 --- a/Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.6/user/mods/Faupi-MunitionsExpert 1.6.6/package.json +++ b/Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.7/user/mods/Faupi-MunitionsExpert 1.6.7/package.json @@ -1,10 +1,10 @@ { "name": "MunitionsExpert", "author": "Faupi", - "version": "1.6.6", + "version": "1.6.7", "license": "NCSA Open Source", "main": "./src/MunitionsExpert.js", - "akiVersion": "3.2.5", + "akiVersion": "3.3.0", "updatedBy": "CWX", "scripts": { "setup": "npm i", diff --git a/Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.6/user/mods/Faupi-MunitionsExpert 1.6.6/res/armorDamage.png b/Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.7/user/mods/Faupi-MunitionsExpert 1.6.7/res/armorDamage.png similarity index 100% rename from Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.6/user/mods/Faupi-MunitionsExpert 1.6.6/res/armorDamage.png rename to Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.7/user/mods/Faupi-MunitionsExpert 1.6.7/res/armorDamage.png diff --git a/Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.6/user/mods/Faupi-MunitionsExpert 1.6.6/res/ricochet.png b/Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.7/user/mods/Faupi-MunitionsExpert 1.6.7/res/ricochet.png similarity index 100% rename from Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.6/user/mods/Faupi-MunitionsExpert 1.6.6/res/ricochet.png rename to Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.7/user/mods/Faupi-MunitionsExpert 1.6.7/res/ricochet.png diff --git a/Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.6/user/mods/Faupi-MunitionsExpert 1.6.6/res/translations.json b/Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.7/user/mods/Faupi-MunitionsExpert 1.6.7/res/translations.json similarity index 100% rename from Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.6/user/mods/Faupi-MunitionsExpert 1.6.6/res/translations.json rename to Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.7/user/mods/Faupi-MunitionsExpert 1.6.7/res/translations.json diff --git a/Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.6/user/mods/Faupi-MunitionsExpert 1.6.6/src/MunitionsExpert.ts b/Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.7/user/mods/Faupi-MunitionsExpert 1.6.7/src/MunitionsExpert.ts similarity index 98% rename from Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.6/user/mods/Faupi-MunitionsExpert 1.6.6/src/MunitionsExpert.ts rename to Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.7/user/mods/Faupi-MunitionsExpert 1.6.7/src/MunitionsExpert.ts index cb25940..8fae03c 100644 --- a/Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.6/user/mods/Faupi-MunitionsExpert 1.6.6/src/MunitionsExpert.ts +++ b/Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.7/user/mods/Faupi-MunitionsExpert 1.6.7/src/MunitionsExpert.ts @@ -69,7 +69,7 @@ class MunitionsExpert implements IPreAkiLoadMod, IPostAkiLoadMod url: "/MunitionsExpert/GetInfo", action: (url, info, sessionId, output) => { - return this.json.serialize(this.path.resolve(this.modLoader.getModPath("Faupi-MunitionsExpert 1.6.4"))); + return this.json.serialize(this.path.resolve(this.modLoader.getModPath("Faupi-MunitionsExpert 1.6.7"))); } } ], diff --git a/Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.6/user/mods/Faupi-MunitionsExpert 1.6.6/src/config.json b/Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.7/user/mods/Faupi-MunitionsExpert 1.6.7/src/config.json similarity index 100% rename from Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.6/user/mods/Faupi-MunitionsExpert 1.6.6/src/config.json rename to Faupi-MunitionsExpert/Built/Faupi-MunitionsExpert 1.6.7/user/mods/Faupi-MunitionsExpert 1.6.7/src/config.json diff --git a/Faupi-MunitionsExpert/MunitionsExpert/MunitionsExpert/CachedAttributesPatch.cs b/Faupi-MunitionsExpert/MunitionsExpert/MunitionsExpert/CachedAttributesPatch.cs index c74653e..ceae754 100644 --- a/Faupi-MunitionsExpert/MunitionsExpert/MunitionsExpert/CachedAttributesPatch.cs +++ b/Faupi-MunitionsExpert/MunitionsExpert/MunitionsExpert/CachedAttributesPatch.cs @@ -3,7 +3,7 @@ using EFT.InventoryLogic; using System.Collections.Generic; using System.Linq; using System.Reflection; -using ItemAttributes = GClass2203; +using ItemAttributes = GClass2210; namespace MunitionsExpert { diff --git a/Faupi-MunitionsExpert/MunitionsExpert/MunitionsExpert/Program.cs b/Faupi-MunitionsExpert/MunitionsExpert/MunitionsExpert/Program.cs index f6af546..532a528 100644 --- a/Faupi-MunitionsExpert/MunitionsExpert/MunitionsExpert/Program.cs +++ b/Faupi-MunitionsExpert/MunitionsExpert/MunitionsExpert/Program.cs @@ -10,14 +10,14 @@ using Comfort.Common; using Newtonsoft.Json; using Aki.Common.Utils; -using ItemAttribute = GClass2203; -using ServerSettings = GClass1168; +using ItemAttribute = GClass2210; +using ServerSettings = GClass1173; using static MunitionsExpert.Attributes; using Aki.Common.Http; namespace MunitionsExpert { - [BepInPlugin("com.Faupi.MunitionsExpert", "Faupi-MunitionsExpert", "1.6.6")] + [BepInPlugin("com.Faupi.MunitionsExpert", "Faupi-MunitionsExpert", "1.6.7")] public class Plugin : BaseUnityPlugin { public static Dictionary iconCache = new Dictionary(); @@ -111,7 +111,7 @@ namespace MunitionsExpert int ratedClass = 0; if (!Singleton.Instantiated) { return $"CLASS_DATA_MISSING {template.PenetrationPower.ToString()}"; } - ServerSettings.GClass1215.GClass1216[] classes = Singleton.Instance.Armor.ArmorClass; + ServerSettings.GClass1220.GClass1221[] classes = Singleton.Instance.Armor.ArmorClass; for (int i = 0; i < classes.Length; i++) { if (classes[i].Resistance > template.PenetrationPower) continue; diff --git a/Faupi-MunitionsExpert/server/dist/package.json b/Faupi-MunitionsExpert/server/dist/package.json index a6490f6..234a9a0 100644 --- a/Faupi-MunitionsExpert/server/dist/package.json +++ b/Faupi-MunitionsExpert/server/dist/package.json @@ -1,10 +1,10 @@ { "name": "MunitionsExpert", "author": "Faupi", - "version": "1.6.6", + "version": "1.6.7", "license": "NCSA Open Source", "main": "./src/MunitionsExpert.js", - "akiVersion": "3.2.5", + "akiVersion": "3.3.0", "updatedBy": "CWX", "scripts": { "setup": "npm i", diff --git a/Faupi-MunitionsExpert/server/dist/src/MunitionsExpert.ts b/Faupi-MunitionsExpert/server/dist/src/MunitionsExpert.ts index cb25940..8fae03c 100644 --- a/Faupi-MunitionsExpert/server/dist/src/MunitionsExpert.ts +++ b/Faupi-MunitionsExpert/server/dist/src/MunitionsExpert.ts @@ -69,7 +69,7 @@ class MunitionsExpert implements IPreAkiLoadMod, IPostAkiLoadMod url: "/MunitionsExpert/GetInfo", action: (url, info, sessionId, output) => { - return this.json.serialize(this.path.resolve(this.modLoader.getModPath("Faupi-MunitionsExpert 1.6.4"))); + return this.json.serialize(this.path.resolve(this.modLoader.getModPath("Faupi-MunitionsExpert 1.6.7"))); } } ], diff --git a/Faupi-MunitionsExpert/server/package.json b/Faupi-MunitionsExpert/server/package.json index a6490f6..234a9a0 100644 --- a/Faupi-MunitionsExpert/server/package.json +++ b/Faupi-MunitionsExpert/server/package.json @@ -1,10 +1,10 @@ { "name": "MunitionsExpert", "author": "Faupi", - "version": "1.6.6", + "version": "1.6.7", "license": "NCSA Open Source", "main": "./src/MunitionsExpert.js", - "akiVersion": "3.2.5", + "akiVersion": "3.3.0", "updatedBy": "CWX", "scripts": { "setup": "npm i", diff --git a/Faupi-MunitionsExpert/server/src/MunitionsExpert.ts b/Faupi-MunitionsExpert/server/src/MunitionsExpert.ts index cb25940..8fae03c 100644 --- a/Faupi-MunitionsExpert/server/src/MunitionsExpert.ts +++ b/Faupi-MunitionsExpert/server/src/MunitionsExpert.ts @@ -69,7 +69,7 @@ class MunitionsExpert implements IPreAkiLoadMod, IPostAkiLoadMod url: "/MunitionsExpert/GetInfo", action: (url, info, sessionId, output) => { - return this.json.serialize(this.path.resolve(this.modLoader.getModPath("Faupi-MunitionsExpert 1.6.4"))); + return this.json.serialize(this.path.resolve(this.modLoader.getModPath("Faupi-MunitionsExpert 1.6.7"))); } } ], diff --git a/Faupi-MunitionsExpert/server/types/callbacks/BotCallbacks.d.ts b/Faupi-MunitionsExpert/server/types/callbacks/BotCallbacks.d.ts index 2db60dc..827015e 100644 --- a/Faupi-MunitionsExpert/server/types/callbacks/BotCallbacks.d.ts +++ b/Faupi-MunitionsExpert/server/types/callbacks/BotCallbacks.d.ts @@ -8,8 +8,29 @@ export declare class BotCallbacks { protected botController: BotController; protected httpResponse: HttpResponseUtil; constructor(botController: BotController, httpResponse: HttpResponseUtil); + /** + * Handle singleplayer/settings/bot/limit + * @returns string + */ getBotLimit(url: string, info: IEmptyRequestData, sessionID: string): string; + /** + * Handle singleplayer/settings/bot/difficulty + * @returns string + */ getBotDifficulty(url: string, info: IEmptyRequestData, sessionID: string): string; + /** + * Handle client/game/bot/generate + * @returns IGetBodyResponseData + */ generateBots(url: string, info: IGenerateBotsRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle singleplayer/settings/bot/maxCap + * @returns string + */ getBotCap(): string; + /** + * Handle singleplayer/settings/bot/getBotBehaviours + * @returns string + */ + getBotBehaviours(): string; } diff --git a/Faupi-MunitionsExpert/server/types/callbacks/CustomizationCallbacks.d.ts b/Faupi-MunitionsExpert/server/types/callbacks/CustomizationCallbacks.d.ts index 3bab8c0..75d5701 100644 --- a/Faupi-MunitionsExpert/server/types/callbacks/CustomizationCallbacks.d.ts +++ b/Faupi-MunitionsExpert/server/types/callbacks/CustomizationCallbacks.d.ts @@ -3,6 +3,7 @@ import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData"; import { IPmcData } from "../models/eft/common/IPmcData"; import { ISuit } from "../models/eft/common/tables/ITrader"; import { IBuyClothingRequestData } from "../models/eft/customization/IBuyClothingRequestData"; +import { IGetSuitsResponse } from "../models/eft/customization/IGetSuitsResponse"; import { IWearClothingRequestData } from "../models/eft/customization/IWearClothingRequestData"; import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData"; import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse"; @@ -13,10 +14,15 @@ export declare class CustomizationCallbacks { protected saveServer: SaveServer; protected httpResponse: HttpResponseUtil; constructor(customizationController: CustomizationController, saveServer: SaveServer, httpResponse: HttpResponseUtil); - getSuits(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<{ - _id: string; - suites: string[]; - }>; + /** + * Handles client/trading/customization/storage + * @returns + */ + getSuits(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handles client/trading/customization + * @returns ISuit[] + */ getTraderSuits(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; wearClothing(pmcData: IPmcData, body: IWearClothingRequestData, sessionID: string): IItemEventRouterResponse; buyClothing(pmcData: IPmcData, body: IBuyClothingRequestData, sessionID: string): IItemEventRouterResponse; diff --git a/Faupi-MunitionsExpert/server/types/callbacks/DataCallbacks.d.ts b/Faupi-MunitionsExpert/server/types/callbacks/DataCallbacks.d.ts index 04566ff..2efcf81 100644 --- a/Faupi-MunitionsExpert/server/types/callbacks/DataCallbacks.d.ts +++ b/Faupi-MunitionsExpert/server/types/callbacks/DataCallbacks.d.ts @@ -12,15 +12,42 @@ import { ILanguageBase } from "../models/spt/server/ILocaleBase"; import { ISettingsBase } from "../models/spt/server/ISettingsBase"; import { DatabaseServer } from "../servers/DatabaseServer"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; +/** + * Handle client requests + */ export declare class DataCallbacks { protected httpResponse: HttpResponseUtil; protected databaseServer: DatabaseServer; constructor(httpResponse: HttpResponseUtil, databaseServer: DatabaseServer); + /** + * Handles client/settings + * @returns ISettingsBase + */ getSettings(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handles client/globals + * @returns IGlobals + */ getGlobals(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handles client/items + * @returns string + */ getTemplateItems(url: string, info: IEmptyRequestData, sessionID: string): string; + /** + * Handles client/handbook/templates + * @returns IHandbookBase + */ getTemplateHandbook(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handles client/customization + * @returns Record>; + /** + * Handles client/account/customization + * @returns string[] + */ getTemplateCharacter(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; getTemplateQuests(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; getHideoutSettings(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; @@ -28,6 +55,6 @@ export declare class DataCallbacks { gethideoutProduction(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; getHideoutScavcase(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; getLocalesLanguages(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - getLocalesMenu(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + getLocalesMenu(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; getLocalesGlobal(url: string, info: IEmptyRequestData, sessionID: string): string; } diff --git a/Faupi-MunitionsExpert/server/types/callbacks/DialogueCallbacks.d.ts b/Faupi-MunitionsExpert/server/types/callbacks/DialogueCallbacks.d.ts index 634f90b..7b2eeae 100644 --- a/Faupi-MunitionsExpert/server/types/callbacks/DialogueCallbacks.d.ts +++ b/Faupi-MunitionsExpert/server/types/callbacks/DialogueCallbacks.d.ts @@ -26,15 +26,27 @@ export declare class DialogueCallbacks extends OnUpdate { protected httpResponse: HttpResponseUtil; protected dialogueController: DialogueController; constructor(hashUtil: HashUtil, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, dialogueController: DialogueController); + /** + * Handles client/friend/list + * @returns IGetFriendListDataResponse + */ getFriendList(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handles client/chatServer/list + * @returns + */ getChatServerList(url: string, info: IGetChatServerListRequestData, sessionID: string): IGetBodyResponseData; getMailDialogList(url: string, info: IGetMailDialogListRequestData, sessionID: string): IGetBodyResponseData; getMailDialogView(url: string, info: IGetMailDialogViewRequestData, sessionID: string): IGetBodyResponseData; - getMailDialogInfo(url: string, info: IGetMailDialogInfoRequestData, sessionID: string): IGetBodyResponseData; + getMailDialogInfo(url: string, info: IGetMailDialogInfoRequestData, sessionID: string): IGetBodyResponseData; removeDialog(url: string, info: IRemoveDialogRequestData, sessionID: string): IGetBodyResponseData; pinDialog(url: string, info: IPinDialogRequestData, sessionID: string): IGetBodyResponseData; unpinDialog(url: string, info: IPinDialogRequestData, sessionID: string): IGetBodyResponseData; setRead(url: string, info: ISetDialogReadRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handles client/mail/dialog/getAllAttachments + * @returns IGetAllAttachmentsResponse + */ getAllAttachments(url: string, info: IGetAllAttachmentsRequestData, sessionID: string): IGetBodyResponseData; listOutbox(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; listInbox(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; diff --git a/Faupi-MunitionsExpert/server/types/callbacks/GameCallbacks.d.ts b/Faupi-MunitionsExpert/server/types/callbacks/GameCallbacks.d.ts index 5e4c240..3a6b7e6 100644 --- a/Faupi-MunitionsExpert/server/types/callbacks/GameCallbacks.d.ts +++ b/Faupi-MunitionsExpert/server/types/callbacks/GameCallbacks.d.ts @@ -3,6 +3,9 @@ import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData"; import { ICheckVersionResponse } from "../models/eft/game/ICheckVersionResponse"; import { IGameConfigResponse } from "../models/eft/game/IGameConfigResponse"; import { IGameEmptyCrcRequestData } from "../models/eft/game/IGameEmptyCrcRequestData"; +import { IGameKeepAliveResponse } from "../models/eft/game/IGameKeepAliveResponse"; +import { IGameLogoutResponseData } from "../models/eft/game/IGameLogoutResponseData"; +import { IGameStartResponse } from "../models/eft/game/IGameStartResponse"; import { IReportNicknameRequestData } from "../models/eft/game/IReportNicknameRequestData"; import { IServerDetails } from "../models/eft/game/IServerDetails"; import { IVersionValidateRequestData } from "../models/eft/game/IVersionValidateRequestData"; @@ -15,13 +18,37 @@ declare class GameCallbacks { protected watermark: Watermark; protected gameController: GameController; constructor(httpResponse: HttpResponseUtil, watermark: Watermark, gameController: GameController); + /** + * Handle client/game/version/validate + * @returns INullResponseData + */ versionValidate(url: string, info: IVersionValidateRequestData, sessionID: string): INullResponseData; - gameStart(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - gameLogout(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle client/game/start + * @returns IGameStartResponse + */ + gameStart(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle client/game/logout + * @returns IGameLogoutResponseData + */ + gameLogout(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle client/game/config + * @returns IGameConfigResponse + */ getGameConfig(url: string, info: IGameEmptyCrcRequestData, sessionID: string): IGetBodyResponseData; getServer(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; validateGameVersion(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - gameKeepalive(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle client/game/keepalive + * @returns IGameKeepAliveResponse + */ + gameKeepalive(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle singleplayer/settings/version + * @returns string + */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; } diff --git a/Faupi-MunitionsExpert/server/types/callbacks/HealthCallbacks.d.ts b/Faupi-MunitionsExpert/server/types/callbacks/HealthCallbacks.d.ts index 8672be7..7edf03e 100644 --- a/Faupi-MunitionsExpert/server/types/callbacks/HealthCallbacks.d.ts +++ b/Faupi-MunitionsExpert/server/types/callbacks/HealthCallbacks.d.ts @@ -21,7 +21,19 @@ export declare class HealthCallbacks { * @returns empty response, no data sent back to client */ syncHealth(url: string, info: ISyncHealthRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle Eat + * @returns IItemEventRouterResponse + */ offraidEat(pmcData: IPmcData, body: IOffraidEatRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle Heal + * @returns IItemEventRouterResponse + */ offraidHeal(pmcData: IPmcData, body: IOffraidHealRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle RestoreHealth + * @returns IItemEventRouterResponse + */ healthTreatment(pmcData: IPmcData, info: IHealthTreatmentRequestData, sessionID: string): IItemEventRouterResponse; } diff --git a/Faupi-MunitionsExpert/server/types/callbacks/HideoutCallbacks.d.ts b/Faupi-MunitionsExpert/server/types/callbacks/HideoutCallbacks.d.ts index 99ab4c9..e39e806 100644 --- a/Faupi-MunitionsExpert/server/types/callbacks/HideoutCallbacks.d.ts +++ b/Faupi-MunitionsExpert/server/types/callbacks/HideoutCallbacks.d.ts @@ -19,14 +19,77 @@ export declare class HideoutCallbacks extends OnUpdate { protected hideoutConfig: IHideoutConfig; constructor(hideoutController: HideoutController, // TODO: delay needed configServer: ConfigServer); + /** + * Handle HideoutUpgrade + * @param pmcData + * @param body + * @param sessionID + * @returns + */ upgrade(pmcData: IPmcData, body: IHideoutUpgradeRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutUpgradeComplete + * @param pmcData + * @param body + * @param sessionID + * @returns + */ upgradeComplete(pmcData: IPmcData, body: IHideoutUpgradeCompleteRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutPutItemsInAreaSlots + * @param pmcData + * @param body + * @param sessionID + * @returns + */ putItemsInAreaSlots(pmcData: IPmcData, body: IHideoutPutItemInRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutTakeItemsFromAreaSlots + * @param pmcData + * @param body + * @param sessionID + * @returns + */ takeItemsFromAreaSlots(pmcData: IPmcData, body: IHideoutTakeItemOutRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutToggleArea + * @param pmcData + * @param body + * @param sessionID + * @returns + */ toggleArea(pmcData: IPmcData, body: IHideoutToggleAreaRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutSingleProductionStart + * @param pmcData + * @param body + * @param sessionID + * @returns + */ singleProductionStart(pmcData: IPmcData, body: IHideoutSingleProductionStartRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutScavCaseProductionStart + * @param pmcData + * @param body + * @param sessionID + * @returns + */ scavCaseProductionStart(pmcData: IPmcData, body: IHideoutScavCaseStartRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutContinuousProductionStart + * @param pmcData + * @param body + * @param sessionID + * @returns + */ continuousProductionStart(pmcData: IPmcData, body: IHideoutContinousProductionStartRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutTakeProduction + * @param pmcData + * @param body + * @param sessionID + * @returns + */ takeProduction(pmcData: IPmcData, body: IHideoutTakeProductionRequestData, sessionID: string): IItemEventRouterResponse; onUpdate(timeSinceLastRun: number): boolean; getRoute(): string; diff --git a/Faupi-MunitionsExpert/server/types/callbacks/InraidCallbacks.d.ts b/Faupi-MunitionsExpert/server/types/callbacks/InraidCallbacks.d.ts index 05bcce4..918bfaf 100644 --- a/Faupi-MunitionsExpert/server/types/callbacks/InraidCallbacks.d.ts +++ b/Faupi-MunitionsExpert/server/types/callbacks/InraidCallbacks.d.ts @@ -1,23 +1,49 @@ import { InraidController } from "../controllers/InraidController"; -import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData"; import { INullResponseData } from "../models/eft/httpResponse/INullResponseData"; import { IRegisterPlayerRequestData } from "../models/eft/inRaid/IRegisterPlayerRequestData"; import { ISaveProgressRequestData } from "../models/eft/inRaid/ISaveProgressRequestData"; -import { IAirdropConfig } from "../models/spt/config/IAirdropConfig"; -import { IInRaidConfig } from "../models/spt/config/IInRaidConfig"; -import { ConfigServer } from "../servers/ConfigServer"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; +/** + * Handle client requests + */ export declare class InraidCallbacks { protected inraidController: InraidController; protected httpResponse: HttpResponseUtil; - protected configServer: ConfigServer; - protected airdropConfig: IAirdropConfig; - protected inraidConfig: IInRaidConfig; - constructor(inraidController: InraidController, httpResponse: HttpResponseUtil, configServer: ConfigServer); + constructor(inraidController: InraidController, httpResponse: HttpResponseUtil); + /** + * Handle client/location/getLocalloot + * @param url + * @param info register player request + * @param sessionID Session id + * @returns Null http response + */ registerPlayer(url: string, info: IRegisterPlayerRequestData, sessionID: string): INullResponseData; + /** + * Handle raid/profile/save + * @param url + * @param info Save progress request + * @param sessionID Session id + * @returns Null http response + */ saveProgress(url: string, info: ISaveProgressRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/raid/endstate + * @returns + */ getRaidEndState(): string; - getRaidMenuSettings(url: string, info: IEmptyRequestData, sessionID: string): string; - getWeaponDurability(url: string, info: any, sessionID: string): string; - getAirdropConfig(url: string, info: any, sessionID: string): string; + /** + * Handle singleplayer/settings/raid/menu + * @returns JSON as string + */ + getRaidMenuSettings(): string; + /** + * Handle singleplayer/settings/weapon/durability + * @returns + */ + getWeaponDurability(): string; + /** + * Handle singleplayer/airdrop/config + * @returns JSON as string + */ + getAirdropConfig(): string; } diff --git a/Faupi-MunitionsExpert/server/types/callbacks/InsuranceCallbacks.d.ts b/Faupi-MunitionsExpert/server/types/callbacks/InsuranceCallbacks.d.ts index 8835ba2..a171e1c 100644 --- a/Faupi-MunitionsExpert/server/types/callbacks/InsuranceCallbacks.d.ts +++ b/Faupi-MunitionsExpert/server/types/callbacks/InsuranceCallbacks.d.ts @@ -17,7 +17,15 @@ export declare class InsuranceCallbacks extends OnUpdate { protected configServer: ConfigServer; protected insuranceConfig: IInsuranceConfig; constructor(insuranceController: InsuranceController, insuranceService: InsuranceService, httpResponse: HttpResponseUtil, configServer: ConfigServer); + /** + * Handle client/insurance/items/list/cost + * @returns IGetInsuranceCostResponseData + */ getInsuranceCost(url: string, info: IGetInsuranceCostRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle Insure + * @returns IItemEventRouterResponse + */ insure(pmcData: IPmcData, body: IInsureRequestData, sessionID: string): IItemEventRouterResponse; onUpdate(secondsSinceLastRun: number): boolean; getRoute(): string; diff --git a/Faupi-MunitionsExpert/server/types/callbacks/InventoryCallbacks.d.ts b/Faupi-MunitionsExpert/server/types/callbacks/InventoryCallbacks.d.ts index 9ab1486..46bf6fd 100644 --- a/Faupi-MunitionsExpert/server/types/callbacks/InventoryCallbacks.d.ts +++ b/Faupi-MunitionsExpert/server/types/callbacks/InventoryCallbacks.d.ts @@ -16,6 +16,7 @@ import { IInventorySwapRequestData } from "../models/eft/inventory/IInventorySwa import { IInventoryTagRequestData } from "../models/eft/inventory/IInventoryTagRequestData"; import { IInventoryToggleRequestData } from "../models/eft/inventory/IInventoryToggleRequestData"; import { IInventoryTransferRequestData } from "../models/eft/inventory/IInventoryTransferRequestData"; +import { IOpenRandomLootContainerRequestData } from "../models/eft/inventory/IOpenRandomLootContainerRequestData"; import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse"; export declare class InventoryCallbacks { protected inventoryController: InventoryController; @@ -36,4 +37,5 @@ export declare class InventoryCallbacks { createMapMarker(pmcData: IPmcData, body: IInventoryCreateMarkerRequestData, sessionID: string): IItemEventRouterResponse; deleteMapMarker(pmcData: IPmcData, body: IInventoryDeleteMarkerRequestData, sessionID: string): IItemEventRouterResponse; editMapMarker(pmcData: IPmcData, body: IInventoryEditMarkerRequestData, sessionID: string): IItemEventRouterResponse; + openRandomLootContainer(pmcData: IPmcData, body: IOpenRandomLootContainerRequestData, sessionID: string): IItemEventRouterResponse; } diff --git a/Faupi-MunitionsExpert/server/types/callbacks/ItemEventCallbacks.d.ts b/Faupi-MunitionsExpert/server/types/callbacks/ItemEventCallbacks.d.ts index f4f04f9..fbb0b5f 100644 --- a/Faupi-MunitionsExpert/server/types/callbacks/ItemEventCallbacks.d.ts +++ b/Faupi-MunitionsExpert/server/types/callbacks/ItemEventCallbacks.d.ts @@ -1,4 +1,5 @@ import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData"; +import { Warning } from "../models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterRequest } from "../models/eft/itemEvent/IItemEventRouterRequest"; import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse"; import { ItemEventRouter } from "../routers/ItemEventRouter"; @@ -8,4 +9,5 @@ export declare class ItemEventCallbacks { protected itemEventRouter: ItemEventRouter; constructor(httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter); handleEvents(url: string, info: IItemEventRouterRequest, sessionID: string): IGetBodyResponseData; + protected getErrorCode(warnings: Warning[]): number; } diff --git a/Faupi-MunitionsExpert/server/types/callbacks/MatchCallbacks.d.ts b/Faupi-MunitionsExpert/server/types/callbacks/MatchCallbacks.d.ts index 2a92ef5..10fbc44 100644 --- a/Faupi-MunitionsExpert/server/types/callbacks/MatchCallbacks.d.ts +++ b/Faupi-MunitionsExpert/server/types/callbacks/MatchCallbacks.d.ts @@ -34,6 +34,10 @@ export declare class MatchCallbacks { serverAvailable(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData | IGetBodyResponseData; joinMatch(url: string, info: IJoinMatchRequestData, sessionID: string): IGetBodyResponseData; getMetrics(url: string, info: any, sessionID: string): IGetBodyResponseData; + /** + * Handle client/match/group/status + * @returns + */ getGroupStatus(url: string, info: IGetGroupStatusRequestData, sessionID: string): IGetBodyResponseData; createGroup(url: string, info: ICreateGroupRequestData, sessionID: string): IGetBodyResponseData; deleteGroup(url: string, info: any, sessionID: string): INullResponseData; diff --git a/Faupi-MunitionsExpert/server/types/callbacks/NotifierCallbacks.d.ts b/Faupi-MunitionsExpert/server/types/callbacks/NotifierCallbacks.d.ts index c42058f..fab325b 100644 --- a/Faupi-MunitionsExpert/server/types/callbacks/NotifierCallbacks.d.ts +++ b/Faupi-MunitionsExpert/server/types/callbacks/NotifierCallbacks.d.ts @@ -4,6 +4,7 @@ import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData"; import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData"; import { INotifierChannel } from "../models/eft/notifier/INotifier"; import { ISelectProfileRequestData } from "../models/eft/notifier/ISelectProfileRequestData"; +import { ISelectProfileResponse } from "../models/eft/notifier/ISelectProfileResponse"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; export declare class NotifierCallbacks { protected httpServerHelper: HttpServerHelper; @@ -19,6 +20,10 @@ export declare class NotifierCallbacks { sendNotification(sessionID: string, req: any, resp: any, data: any): void; getNotifier(url: string, info: any, sessionID: string): IGetBodyResponseData; createNotifierChannel(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - selectProfile(url: string, info: ISelectProfileRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle client/game/profile/select + * @returns ISelectProfileResponse + */ + selectProfile(url: string, info: ISelectProfileRequestData, sessionID: string): IGetBodyResponseData; notify(url: string, info: any, sessionID: string): string; } diff --git a/Faupi-MunitionsExpert/server/types/callbacks/QuestCallbacks.d.ts b/Faupi-MunitionsExpert/server/types/callbacks/QuestCallbacks.d.ts index 559c29e..2a3eb20 100644 --- a/Faupi-MunitionsExpert/server/types/callbacks/QuestCallbacks.d.ts +++ b/Faupi-MunitionsExpert/server/types/callbacks/QuestCallbacks.d.ts @@ -21,6 +21,13 @@ export declare class QuestCallbacks { acceptQuest(pmcData: IPmcData, body: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; completeQuest(pmcData: IPmcData, body: ICompleteQuestRequestData, sessionID: string): IItemEventRouterResponse; handoverQuest(pmcData: IPmcData, body: IHandoverQuestRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle client/quest/list + * @param url + * @param info + * @param sessionID + * @returns + */ listQuests(url: string, info: IListQuestsRequestData, sessionID: string): IGetBodyResponseData; activityPeriods(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; } diff --git a/Faupi-MunitionsExpert/server/types/callbacks/RagfairCallbacks.d.ts b/Faupi-MunitionsExpert/server/types/callbacks/RagfairCallbacks.d.ts index c609f2f..37f3807 100644 --- a/Faupi-MunitionsExpert/server/types/callbacks/RagfairCallbacks.d.ts +++ b/Faupi-MunitionsExpert/server/types/callbacks/RagfairCallbacks.d.ts @@ -35,7 +35,7 @@ export declare class RagfairCallbacks extends OnLoadOnUpdate { getRoute(): string; search(url: string, info: ISearchRequestData, sessionID: string): IGetBodyResponseData; getMarketPrice(url: string, info: IGetMarketPriceRequestData, sessionID: string): IGetBodyResponseData; - getItemPrices(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + getItemPrices(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData>; addOffer(pmcData: IPmcData, info: IAddOfferRequestData, sessionID: string): IItemEventRouterResponse; removeOffer(pmcData: IPmcData, info: IRemoveOfferRequestData, sessionID: string): IItemEventRouterResponse; extendOffer(pmcData: IPmcData, info: IExtendOfferRequestData, sessionID: string): IItemEventRouterResponse; diff --git a/Faupi-MunitionsExpert/server/types/callbacks/TraderCallbacks.d.ts b/Faupi-MunitionsExpert/server/types/callbacks/TraderCallbacks.d.ts index e4fd099..40a1455 100644 --- a/Faupi-MunitionsExpert/server/types/callbacks/TraderCallbacks.d.ts +++ b/Faupi-MunitionsExpert/server/types/callbacks/TraderCallbacks.d.ts @@ -12,6 +12,10 @@ export declare class TraderCallbacks extends OnLoadOnUpdate { onUpdate(): boolean; getRoute(): string; getTraderSettings(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle client/trading/api/getUserAssortPrice/trader + * @returns + */ getProfilePurchases(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData>; getTrader(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; getAssort(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; diff --git a/Faupi-MunitionsExpert/server/types/callbacks/WeatherCallbacks.d.ts b/Faupi-MunitionsExpert/server/types/callbacks/WeatherCallbacks.d.ts index ae784c8..f9d2002 100644 --- a/Faupi-MunitionsExpert/server/types/callbacks/WeatherCallbacks.d.ts +++ b/Faupi-MunitionsExpert/server/types/callbacks/WeatherCallbacks.d.ts @@ -1,10 +1,15 @@ import { WeatherController } from "../controllers/WeatherController"; import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData"; import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData"; +import { IWeatherData } from "../models/eft/weather/IWeatherData"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; export declare class WeatherCallbacks { protected httpResponse: HttpResponseUtil; protected weatherController: WeatherController; constructor(httpResponse: HttpResponseUtil, weatherController: WeatherController); - getWeather(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle client/weather + * @returns IWeatherData + */ + getWeather(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; } diff --git a/Faupi-MunitionsExpert/server/types/context/ContextVariableType.d.ts b/Faupi-MunitionsExpert/server/types/context/ContextVariableType.d.ts index 5fc1704..a7dd9b5 100644 --- a/Faupi-MunitionsExpert/server/types/context/ContextVariableType.d.ts +++ b/Faupi-MunitionsExpert/server/types/context/ContextVariableType.d.ts @@ -1,4 +1,8 @@ export declare enum ContextVariableType { + /** Logged in users session id */ SESSION_ID = 0, - MATCH_INFO = 1 + /** Currently acive raid information */ + MATCH_INFO = 1, + /** Timestamp when client first connected */ + CLIENT_START_TIMESTAMP = 2 } diff --git a/Faupi-MunitionsExpert/server/types/controllers/BotController.d.ts b/Faupi-MunitionsExpert/server/types/controllers/BotController.d.ts index a5111d5..51c0c68 100644 --- a/Faupi-MunitionsExpert/server/types/controllers/BotController.d.ts +++ b/Faupi-MunitionsExpert/server/types/controllers/BotController.d.ts @@ -1,6 +1,9 @@ import { ApplicationContext } from "../context/ApplicationContext"; import { BotGenerator } from "../generators/BotGenerator"; +import { BotDifficultyHelper } from "../helpers/BotDifficultyHelper"; import { BotHelper } from "../helpers/BotHelper"; +import { ProfileHelper } from "../helpers/ProfileHelper"; +import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper"; import { IGenerateBotsRequestData } from "../models/eft/bot/IGenerateBotsRequestData"; import { IBotBase } from "../models/eft/common/tables/IBotBase"; import { IBotCore } from "../models/eft/common/tables/IBotCore"; @@ -10,24 +13,34 @@ import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { BotGenerationCacheService } from "../services/BotGenerationCacheService"; -import { PmcAiService } from "../services/PmcAiService"; +import { LocalisationService } from "../services/LocalisationService"; +import { JsonUtil } from "../utils/JsonUtil"; export declare class BotController { protected logger: ILogger; protected databaseServer: DatabaseServer; protected botGenerator: BotGenerator; protected botHelper: BotHelper; - protected pmcAiService: PmcAiService; + protected botDifficultyHelper: BotDifficultyHelper; protected botGenerationCacheService: BotGenerationCacheService; + protected localisationService: LocalisationService; + protected weightedRandomHelper: WeightedRandomHelper; + protected profileHelper: ProfileHelper; protected configServer: ConfigServer; protected applicationContext: ApplicationContext; + protected jsonUtil: JsonUtil; protected botConfig: IBotConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, botGenerator: BotGenerator, botHelper: BotHelper, pmcAiService: PmcAiService, botGenerationCacheService: BotGenerationCacheService, configServer: ConfigServer, applicationContext: ApplicationContext); + static readonly pmcTypeLabel = "PMC"; + constructor(logger: ILogger, databaseServer: DatabaseServer, botGenerator: BotGenerator, botHelper: BotHelper, botDifficultyHelper: BotDifficultyHelper, botGenerationCacheService: BotGenerationCacheService, localisationService: LocalisationService, weightedRandomHelper: WeightedRandomHelper, profileHelper: ProfileHelper, configServer: ConfigServer, applicationContext: ApplicationContext, jsonUtil: JsonUtil); /** * Return the number of bot loadout varieties to be generated * @param type bot Type we want the loadout gen count for - * @returns + * @returns number of bots to generate */ getBotPresetGenerationLimit(type: string): number; + /** + * Get the core.json difficulty settings from database\bots + * @returns IBotCore + */ getBotCoreDifficulty(): IBotCore; /** * Get bot difficulty settings @@ -37,7 +50,6 @@ export declare class BotController { * @returns Difficulty object */ getBotDifficulty(type: string, difficulty: string): Difficulty; - protected getPmcDifficultySettings(pmcType: "bear" | "usec", difficulty: string, usecType: string, bearType: string): Difficulty; /** * Generate bot profiles and store in cache * @param sessionId Session id @@ -51,4 +63,5 @@ export declare class BotController { * @returns cap number */ getBotCap(): number; + getPmcBotTypes(): Record>>; } diff --git a/Faupi-MunitionsExpert/server/types/controllers/DialogueController.d.ts b/Faupi-MunitionsExpert/server/types/controllers/DialogueController.d.ts index 1b72522..9c8b728 100644 --- a/Faupi-MunitionsExpert/server/types/controllers/DialogueController.d.ts +++ b/Faupi-MunitionsExpert/server/types/controllers/DialogueController.d.ts @@ -23,7 +23,7 @@ export declare class DialogueController { * Get the content of a dialogue * @param dialogueID Dialog id * @param sessionID Session Id - * @returns + * @returns DialogueInfo */ getDialogueInfo(dialogueID: string, sessionID: string): DialogueInfo; /** diff --git a/Faupi-MunitionsExpert/server/types/controllers/GameController.d.ts b/Faupi-MunitionsExpert/server/types/controllers/GameController.d.ts index 3bfbdb1..f4f5849 100644 --- a/Faupi-MunitionsExpert/server/types/controllers/GameController.d.ts +++ b/Faupi-MunitionsExpert/server/types/controllers/GameController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "../context/ApplicationContext"; import { GameEventHelper } from "../helpers/GameEventHelper"; import { HttpServerHelper } from "../helpers/HttpServerHelper"; import { ProfileHelper } from "../helpers/ProfileHelper"; @@ -14,6 +15,7 @@ import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { LocaleService } from "../services/LocaleService"; +import { LocalisationService } from "../services/LocalisationService"; import { ProfileFixerService } from "../services/ProfileFixerService"; import { Watermark } from "../utils/Watermark"; export declare class GameController { @@ -24,14 +26,33 @@ export declare class GameController { protected localeService: LocaleService; protected profileHelper: ProfileHelper; protected profileFixerService: ProfileFixerService; + protected localisationService: LocalisationService; protected gameEventHelper: GameEventHelper; + protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; protected coreConfig: ICoreConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, watermark: Watermark, httpServerHelper: HttpServerHelper, localeService: LocaleService, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, gameEventHelper: GameEventHelper, configServer: ConfigServer); - gameStart(_url: string, _info: IEmptyRequestData, sessionID: string): void; + constructor(logger: ILogger, databaseServer: DatabaseServer, watermark: Watermark, httpServerHelper: HttpServerHelper, localeService: LocaleService, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, gameEventHelper: GameEventHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + gameStart(_url: string, _info: IEmptyRequestData, sessionID: string, startTimeStampMS: number): void; + /** + * Check if current date falls inside any of the seasons events pased in, if so, handle them + * @param seasonalEvents events to check for + */ protected checkForAndEnableSeasonalEvents(seasonalEvents: ISeasonalEvent[]): void; + /** + * Make adjusted to server code based on the name of the event passed in + * @param globalConfig globals.json + * @param eventName Name of the event to enable. e.g. Christmas + */ protected updateGlobalEvents(globalConfig: Config, eventName: string): void; + /** + * Read in data from seasonalEvents.json and add found equipment items to bots + * @param eventName Name of the event to read equipment in from config + */ + protected addEventGearToScavs(eventName: string): void; + /** + * Set Khorovod(dancing tree) chance to 100% on all maps that support it + */ protected enableDancingTree(): void; /** * Make non-trigger-spawned raiders spawn earlier + always @@ -40,5 +61,6 @@ export declare class GameController { protected logProfileDetails(fullProfile: IAkiProfile): void; getGameConfig(sessionID: string): IGameConfigResponse; getServer(): IServerDetails[]; + protected addPumpkinsToScavBackpacks(): void; getValidGameVersion(): ICheckVersionResponse; } diff --git a/Faupi-MunitionsExpert/server/types/controllers/HideoutController.d.ts b/Faupi-MunitionsExpert/server/types/controllers/HideoutController.d.ts index ada5bd9..5b6507b 100644 --- a/Faupi-MunitionsExpert/server/types/controllers/HideoutController.d.ts +++ b/Faupi-MunitionsExpert/server/types/controllers/HideoutController.d.ts @@ -23,12 +23,13 @@ import { EventOutputHolder } from "../routers/EventOutputHolder"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { SaveServer } from "../servers/SaveServer"; +import { LocalisationService } from "../services/LocalisationService"; import { PlayerService } from "../services/PlayerService"; import { HashUtil } from "../utils/HashUtil"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; +import { JsonUtil } from "../utils/JsonUtil"; import { RandomUtil } from "../utils/RandomUtil"; import { TimeUtil } from "../utils/TimeUtil"; -import { JsonUtil } from "../utils/JsonUtil"; export declare class HideoutController { protected logger: ILogger; protected hashUtil: HashUtil; @@ -45,11 +46,12 @@ export declare class HideoutController { protected profileHelper: ProfileHelper; protected hideoutHelper: HideoutHelper; protected scavCaseRewardGenerator: ScavCaseRewardGenerator; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected jsonUtil: JsonUtil; protected static nameBackendCountersCrafting: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, randomUtil: RandomUtil, inventoryHelper: InventoryHelper, saveServer: SaveServer, playerService: PlayerService, presetHelper: PresetHelper, paymentHelper: PaymentHelper, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, profileHelper: ProfileHelper, hideoutHelper: HideoutHelper, scavCaseRewardGenerator: ScavCaseRewardGenerator, configServer: ConfigServer, jsonUtil: JsonUtil); + constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, randomUtil: RandomUtil, inventoryHelper: InventoryHelper, saveServer: SaveServer, playerService: PlayerService, presetHelper: PresetHelper, paymentHelper: PaymentHelper, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, profileHelper: ProfileHelper, hideoutHelper: HideoutHelper, scavCaseRewardGenerator: ScavCaseRewardGenerator, localisationService: LocalisationService, configServer: ConfigServer, jsonUtil: JsonUtil); upgrade(pmcData: IPmcData, body: IHideoutUpgradeRequestData, sessionID: string): IItemEventRouterResponse; upgradeComplete(pmcData: IPmcData, body: HideoutUpgradeCompleteRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/Faupi-MunitionsExpert/server/types/controllers/InraidController.d.ts b/Faupi-MunitionsExpert/server/types/controllers/InraidController.d.ts index e84eea1..39a6396 100644 --- a/Faupi-MunitionsExpert/server/types/controllers/InraidController.d.ts +++ b/Faupi-MunitionsExpert/server/types/controllers/InraidController.d.ts @@ -6,6 +6,7 @@ import { ProfileHelper } from "../helpers/ProfileHelper"; import { QuestHelper } from "../helpers/QuestHelper"; import { TraderHelper } from "../helpers/TraderHelper"; import { IPmcData } from "../models/eft/common/IPmcData"; +import { Item } from "../models/eft/common/tables/IItem"; import { IRegisterPlayerRequestData } from "../models/eft/inRaid/IRegisterPlayerRequestData"; import { ISaveProgressRequestData } from "../models/eft/inRaid/ISaveProgressRequestData"; import { IAirdropConfig } from "../models/spt/config/IAirdropConfig"; @@ -17,6 +18,9 @@ import { SaveServer } from "../servers/SaveServer"; import { InsuranceService } from "../services/InsuranceService"; import { JsonUtil } from "../utils/JsonUtil"; import { TimeUtil } from "../utils/TimeUtil"; +/** + * Logic for handling In Raid callbacks + */ export declare class InraidController { protected logger: ILogger; protected saveServer: SaveServer; @@ -35,14 +39,42 @@ export declare class InraidController { protected airdropConfig: IAirdropConfig; protected inraidConfig: IInRaidConfig; constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, questHelper: QuestHelper, itemHelper: ItemHelper, profileHelper: ProfileHelper, playerScavGenerator: PlayerScavGenerator, healthHelper: HealthHelper, traderHelper: TraderHelper, insuranceService: InsuranceService, inRaidHelper: InRaidHelper, configServer: ConfigServer); - addPlayer(sessionID: string, info: IRegisterPlayerRequestData): void; - saveProgress(offraidData: ISaveProgressRequestData, sessionID: string): void; /** - * Handle updating the profile post-pmc raid + * Save locationid to active profiles inraid object + * @param sessionID Session id + * @param info Register player request + */ + addPlayer(sessionID: string, info: IRegisterPlayerRequestData): void; + /** + * Save profile state to disk + * Handles pmc/pscav + * @param offraidData post-raid request data + * @param sessionID Session id + */ + savePostRaidProgress(offraidData: ISaveProgressRequestData, sessionID: string): void; + /** + * Handle updating player profile post-pmc raid * @param sessionID session id - * @param offraidData post-raid data of raid + * @param offraidData post-raid data */ protected savePmcProgress(sessionID: string, offraidData: ISaveProgressRequestData): void; + /** + * Make changes to pmc profile after they left raid dead, + * alter bodypart hp, handle insurance, delete inventory items, remove carried quest items + * @param postRaidSaveRequest post-raid save request + * @param pmcData pmc profile + * @param insuranceEnabled is insurance enabled + * @param preRaidGear gear player had before raid + * @param sessionID Session id + * @returns Updated profile object + */ + protected performPostRaidActionsWhenDead(postRaidSaveRequest: ISaveProgressRequestData, pmcData: IPmcData, insuranceEnabled: boolean, preRaidGear: Item[], sessionID: string): IPmcData; + /** + * Adjust player characters bodypart hp if they left raid early + * @param postRaidSaveRequest post raid data + * @param pmcData player profile + */ + protected updatePmcHealthPostRaid(postRaidSaveRequest: ISaveProgressRequestData, pmcData: IPmcData): void; /** * Reduce body part hp to % of max * @param pmcData profile to edit @@ -68,7 +100,31 @@ export declare class InraidController { * @param isPlayerScav Was the player a pScav */ protected markOrRemoveFoundInRaidItems(offraidData: ISaveProgressRequestData, pmcData: IPmcData, isPlayerScav: boolean): void; + /** + * Update profile after player completes scav raid + * @param scavData Scav profile + * @param sessionID Session id + * @param offraidData Post-raid save request + * @param pmcData Pmc profile + * @param isDead Is player dead + */ protected handlePostRaidPlayerScavProcess(scavData: IPmcData, sessionID: string, offraidData: ISaveProgressRequestData, pmcData: IPmcData, isDead: boolean): void; + /** + * Update profile with scav karma values based on in-raid actions + * @param pmcData Pmc profile + * @param offraidData Post-raid save request + * @param scavData Scav profile + * @param sessionID Session id + */ protected handlePostRaidPlayerScavKarmaChanges(pmcData: IPmcData, offraidData: ISaveProgressRequestData, scavData: IPmcData, sessionID: string): void; + /** + * Get the inraid config from configs/inraid.json + * @returns InRaid Config + */ + getInraidConfig(): IInRaidConfig; + /** + * Get airdrop config from configs/airdrop.json + * @returns Airdrop config + */ getAirdropConfig(): IAirdropConfig; } diff --git a/Faupi-MunitionsExpert/server/types/controllers/InsuranceController.d.ts b/Faupi-MunitionsExpert/server/types/controllers/InsuranceController.d.ts index 14bf129..54f31b5 100644 --- a/Faupi-MunitionsExpert/server/types/controllers/InsuranceController.d.ts +++ b/Faupi-MunitionsExpert/server/types/controllers/InsuranceController.d.ts @@ -30,8 +30,7 @@ export declare class InsuranceController { protected insuranceService: InsuranceService; protected configServer: ConfigServer; protected insuranceConfig: IInsuranceConfig; - constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, paymentService: PaymentService, // TODO: delay required - insuranceService: InsuranceService, configServer: ConfigServer); + constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, paymentService: PaymentService, insuranceService: InsuranceService, configServer: ConfigServer); processReturn(): void; insure(pmcData: IPmcData, body: IInsureRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/Faupi-MunitionsExpert/server/types/controllers/InventoryController.d.ts b/Faupi-MunitionsExpert/server/types/controllers/InventoryController.d.ts index 6a1a21e..e1c08c0 100644 --- a/Faupi-MunitionsExpert/server/types/controllers/InventoryController.d.ts +++ b/Faupi-MunitionsExpert/server/types/controllers/InventoryController.d.ts @@ -1,8 +1,8 @@ -import { EventOutputHolder } from "../routers/EventOutputHolder"; import { InventoryHelper } from "../helpers/InventoryHelper"; import { PaymentHelper } from "../helpers/PaymentHelper"; import { PresetHelper } from "../helpers/PresetHelper"; import { ProfileHelper } from "../helpers/ProfileHelper"; +import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper"; import { IPmcData } from "../models/eft/common/IPmcData"; import { IAddItemRequestData } from "../models/eft/inventory/IAddItemRequestData"; import { IInventoryBindRequestData } from "../models/eft/inventory/IInventoryBindRequestData"; @@ -21,33 +21,46 @@ import { IInventorySwapRequestData } from "../models/eft/inventory/IInventorySwa import { IInventoryTagRequestData } from "../models/eft/inventory/IInventoryTagRequestData"; import { IInventoryToggleRequestData } from "../models/eft/inventory/IInventoryToggleRequestData"; import { IInventoryTransferRequestData } from "../models/eft/inventory/IInventoryTransferRequestData"; +import { IOpenRandomLootContainerRequestData } from "../models/eft/inventory/IOpenRandomLootContainerRequestData"; import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse"; import { ILogger } from "../models/spt/utils/ILogger"; +import { EventOutputHolder } from "../routers/EventOutputHolder"; import { DatabaseServer } from "../servers/DatabaseServer"; import { FenceService } from "../services/FenceService"; +import { LocalisationService } from "../services/LocalisationService"; import { RagfairOfferService } from "../services/RagfairOfferService"; import { HashUtil } from "../utils/HashUtil"; +import { HttpResponseUtil } from "../utils/HttpResponseUtil"; import { JsonUtil } from "../utils/JsonUtil"; +import { RandomUtil } from "../utils/RandomUtil"; export declare class InventoryController { protected logger: ILogger; protected hashUtil: HashUtil; protected jsonUtil: JsonUtil; + protected randomUtil: RandomUtil; protected databaseServer: DatabaseServer; protected fenceService: FenceService; protected presetHelper: PresetHelper; protected inventoryHelper: InventoryHelper; protected ragfairOfferService: RagfairOfferService; protected profileHelper: ProfileHelper; + protected weightedRandomHelper: WeightedRandomHelper; protected paymentHelper: PaymentHelper; + protected localisationService: LocalisationService; protected eventOutputHolder: EventOutputHolder; - constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, fenceService: FenceService, presetHelper: PresetHelper, inventoryHelper: InventoryHelper, ragfairOfferService: RagfairOfferService, profileHelper: ProfileHelper, paymentHelper: PaymentHelper, eventOutputHolder: EventOutputHolder); + protected httpResponseUtil: HttpResponseUtil; + constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, fenceService: FenceService, presetHelper: PresetHelper, inventoryHelper: InventoryHelper, ragfairOfferService: RagfairOfferService, profileHelper: ProfileHelper, weightedRandomHelper: WeightedRandomHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, eventOutputHolder: EventOutputHolder, httpResponseUtil: HttpResponseUtil); /** * Move Item * change location of item with parentId and slotId * transfers items from one profile to another if fromOwner/toOwner is set in the body. * otherwise, move is contained within the same profile_f. - */ - moveItem(pmcData: IPmcData, body: IInventoryMoveRequestData, sessionID: string): IItemEventRouterResponse; + * @param pmcData Profile + * @param moveRequest Move request data + * @param sessionID Session id + * @returns IItemEventRouterResponse + */ + moveItem(pmcData: IPmcData, moveRequest: IInventoryMoveRequestData, sessionID: string): IItemEventRouterResponse; /** * Remove Item from Profile * Deep tree item deletion, also removes items from insurance list @@ -122,4 +135,12 @@ export declare class InventoryController { createMapMarker(pmcData: IPmcData, body: IInventoryCreateMarkerRequestData, sessionID: string): IItemEventRouterResponse; deleteMapMarker(pmcData: IPmcData, body: IInventoryDeleteMarkerRequestData, sessionID: string): IItemEventRouterResponse; editMapMarker(pmcData: IPmcData, body: IInventoryEditMarkerRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle event fired when a container is unpacked (currently only the halloween pumpkin) + * @param pmcData Profile data + * @param body open loot container request data + * @param sessionID Session id + * @returns IItemEventRouterResponse + */ + openRandomLootContainer(pmcData: IPmcData, body: IOpenRandomLootContainerRequestData, sessionID: string): IItemEventRouterResponse; } diff --git a/Faupi-MunitionsExpert/server/types/controllers/LocationController.d.ts b/Faupi-MunitionsExpert/server/types/controllers/LocationController.d.ts index 9db3205..b6feba8 100644 --- a/Faupi-MunitionsExpert/server/types/controllers/LocationController.d.ts +++ b/Faupi-MunitionsExpert/server/types/controllers/LocationController.d.ts @@ -7,6 +7,7 @@ import { LootItem } from "../models/spt/services/LootItem"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "../services/LocalisationService"; import { HashUtil } from "../utils/HashUtil"; import { JsonUtil } from "../utils/JsonUtil"; import { TimeUtil } from "../utils/TimeUtil"; @@ -15,12 +16,13 @@ export declare class LocationController { protected hashUtil: HashUtil; protected logger: ILogger; protected locationGenerator: LocationGenerator; + protected localisationService: LocalisationService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; protected airdropConfig: IAirdropConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger, locationGenerator: LocationGenerator, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); get(location: string): ILocationBase; generate(name: string): ILocationBase; generateAll(): ILocationsGenerateAllResponse; diff --git a/Faupi-MunitionsExpert/server/types/controllers/MatchController.d.ts b/Faupi-MunitionsExpert/server/types/controllers/MatchController.d.ts index dac6a3f..2b0d150 100644 --- a/Faupi-MunitionsExpert/server/types/controllers/MatchController.d.ts +++ b/Faupi-MunitionsExpert/server/types/controllers/MatchController.d.ts @@ -19,7 +19,6 @@ import { SaveServer } from "../servers/SaveServer"; import { BotGenerationCacheService } from "../services/BotGenerationCacheService"; import { BotLootCacheService } from "../services/BotLootCacheService"; import { MatchLocationService } from "../services/MatchLocationService"; -import { PmcAiService } from "../services/PmcAiService"; import { ProfileSnapshotService } from "../services/ProfileSnapshotService"; export declare class MatchController { protected logger: ILogger; @@ -30,13 +29,12 @@ export declare class MatchController { protected botLootCacheService: BotLootCacheService; protected configServer: ConfigServer; protected profileSnapshotService: ProfileSnapshotService; - protected pmcAiService: PmcAiService; protected botGenerationCacheService: BotGenerationCacheService; protected applicationContext: ApplicationContext; protected matchConfig: IMatchConfig; protected inraidConfig: IInRaidConfig; protected botConfig: IBotConfig; - constructor(logger: ILogger, saveServer: SaveServer, profileHelper: ProfileHelper, matchLocationService: MatchLocationService, traderHelper: TraderHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer, profileSnapshotService: ProfileSnapshotService, pmcAiService: PmcAiService, botGenerationCacheService: BotGenerationCacheService, applicationContext: ApplicationContext); + constructor(logger: ILogger, saveServer: SaveServer, profileHelper: ProfileHelper, matchLocationService: MatchLocationService, traderHelper: TraderHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer, profileSnapshotService: ProfileSnapshotService, botGenerationCacheService: BotGenerationCacheService, applicationContext: ApplicationContext); getEnabled(): boolean; getProfile(info: IGetProfileRequestData): IPmcData[]; createGroup(sessionID: string, info: ICreateGroupRequestData): any; diff --git a/Faupi-MunitionsExpert/server/types/controllers/RagfairController.d.ts b/Faupi-MunitionsExpert/server/types/controllers/RagfairController.d.ts index 5440458..95702f2 100644 --- a/Faupi-MunitionsExpert/server/types/controllers/RagfairController.d.ts +++ b/Faupi-MunitionsExpert/server/types/controllers/RagfairController.d.ts @@ -29,6 +29,7 @@ import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { RagfairServer } from "../servers/RagfairServer"; import { SaveServer } from "../servers/SaveServer"; +import { LocalisationService } from "../services/LocalisationService"; import { PaymentService } from "../services/PaymentService"; import { RagfairOfferService } from "../services/RagfairOfferService"; import { RagfairPriceService } from "../services/RagfairPriceService"; @@ -62,9 +63,10 @@ export declare class RagfairController { protected ragfairOfferService: RagfairOfferService; protected ragfairRequiredItemsService: RagfairRequiredItemsService; protected ragfairOfferGenerator: RagfairOfferGenerator; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected ragfairConfig: IRagfairConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, eventOutputHolder: EventOutputHolder, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, traderHelper: TraderHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, eventOutputHolder: EventOutputHolder, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, traderHelper: TraderHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, localisationService: LocalisationService, configServer: ConfigServer); getOffers(sessionID: string, info: ISearchRequestData): IGetOffersResult; /** * Get offers for the client based on type of search being performed @@ -103,7 +105,12 @@ export declare class RagfairController { protected isLinkedSearch(info: ISearchRequestData): boolean; protected isRequiredSearch(info: ISearchRequestData): boolean; update(): void; - getItemPrice(info: IGetMarketPriceRequestData): IGetItemPriceResult; + /** + * Called when creating an offer on flea, fills values in top right corner + * @param getPriceRequest + * @returns min/avg/max values for an item based on flea offers available + */ + getItemMinAvgMaxFleaPriceValues(getPriceRequest: IGetMarketPriceRequestData): IGetItemPriceResult; addPlayerOffer(pmcData: IPmcData, info: IAddOfferRequestData, sessionID: string): IItemEventRouterResponse; createPlayerOffer(profile: IAkiProfile, requirements: Requirement[], items: Item[], sellInOnePiece: boolean, amountToSend: number): IRagfairOffer; getAllFleaPrices(): Record; diff --git a/Faupi-MunitionsExpert/server/types/controllers/RepeatableQuestController.d.ts b/Faupi-MunitionsExpert/server/types/controllers/RepeatableQuestController.d.ts index 7db5886..333583b 100644 --- a/Faupi-MunitionsExpert/server/types/controllers/RepeatableQuestController.d.ts +++ b/Faupi-MunitionsExpert/server/types/controllers/RepeatableQuestController.d.ts @@ -17,6 +17,7 @@ import { EventOutputHolder } from "../routers/EventOutputHolder"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { ItemFilterService } from "../services/ItemFilterService"; +import { LocalisationService } from "../services/LocalisationService"; import { PaymentService } from "../services/PaymentService"; import { ProfileFixerService } from "../services/ProfileFixerService"; import { JsonUtil } from "../utils/JsonUtil"; @@ -64,12 +65,13 @@ export declare class RepeatableQuestController { protected profileFixerService: ProfileFixerService; protected ragfairServerHelper: RagfairServerHelper; protected eventOutputHolder: EventOutputHolder; + protected localisationService: LocalisationService; protected paymentService: PaymentService; protected objectId: ObjectId; protected itemFilterService: ItemFilterService; protected configServer: ConfigServer; protected questConfig: IQuestConfig; - constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, eventOutputHolder: EventOutputHolder, paymentService: PaymentService, objectId: ObjectId, itemFilterService: ItemFilterService, configServer: ConfigServer); + constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, eventOutputHolder: EventOutputHolder, localisationService: LocalisationService, paymentService: PaymentService, objectId: ObjectId, itemFilterService: ItemFilterService, configServer: ConfigServer); /** * This is the method reached by the /client/repeatalbeQuests/activityPeriods endpoint * Returns an array of objects in the format of repeatable quests to the client. diff --git a/Faupi-MunitionsExpert/server/types/controllers/WeatherController.d.ts b/Faupi-MunitionsExpert/server/types/controllers/WeatherController.d.ts index ca7f5eb..631a90c 100644 --- a/Faupi-MunitionsExpert/server/types/controllers/WeatherController.d.ts +++ b/Faupi-MunitionsExpert/server/types/controllers/WeatherController.d.ts @@ -1,11 +1,18 @@ import { WeatherGenerator } from "../generators/WeatherGenerator"; import { IWeatherData } from "../models/eft/weather/IWeatherData"; import { IWeatherConfig } from "../models/spt/config/IWeatherConfig"; +import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; export declare class WeatherController { protected weatherGenerator: WeatherGenerator; + protected logger: ILogger; protected configServer: ConfigServer; protected weatherConfig: IWeatherConfig; - constructor(weatherGenerator: WeatherGenerator, configServer: ConfigServer); + constructor(weatherGenerator: WeatherGenerator, logger: ILogger, configServer: ConfigServer); generate(): IWeatherData; + /** + * Get the current in-raid time (MUST HAVE PLAYER LOGGED INTO CLIENT TO WORK) + * @returns Date object + */ + getCurrentInRaidTime(): Date; } diff --git a/Faupi-MunitionsExpert/server/types/generators/BotGenerator.d.ts b/Faupi-MunitionsExpert/server/types/generators/BotGenerator.d.ts index 2ac51db..08ad50a 100644 --- a/Faupi-MunitionsExpert/server/types/generators/BotGenerator.d.ts +++ b/Faupi-MunitionsExpert/server/types/generators/BotGenerator.d.ts @@ -1,25 +1,21 @@ +import { BotDifficultyHelper } from "../helpers/BotDifficultyHelper"; import { BotHelper } from "../helpers/BotHelper"; import { GameEventHelper } from "../helpers/GameEventHelper"; import { ProfileHelper } from "../helpers/ProfileHelper"; -import { IGenerateBotsRequestData } from "../models/eft/bot/IGenerateBotsRequestData"; +import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper"; import { Health as PmcHealth, IBotBase, Skills } from "../models/eft/common/tables/IBotBase"; import { Health, IBotType, Inventory } from "../models/eft/common/tables/IBotType"; +import { BotGenerationDetails } from "../models/spt/bots/BotGenerationDetails"; import { IBotConfig } from "../models/spt/config/IBotConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { BotEquipmentFilterService } from "../services/BotEquipmentFilterService"; -import { PmcAiService } from "../services/PmcAiService"; import { HashUtil } from "../utils/HashUtil"; import { JsonUtil } from "../utils/JsonUtil"; import { RandomUtil } from "../utils/RandomUtil"; import { BotInventoryGenerator } from "./BotInventoryGenerator"; -declare namespace BotGenerator { - interface IRandomisedBotLevelResult { - level: number; - exp: number; - } -} +import { BotLevelGenerator } from "./BotLevelGenerator"; export declare class BotGenerator { protected logger: ILogger; protected hashUtil: HashUtil; @@ -28,13 +24,15 @@ export declare class BotGenerator { protected profileHelper: ProfileHelper; protected databaseServer: DatabaseServer; protected botInventoryGenerator: BotInventoryGenerator; + protected botLevelGenerator: BotLevelGenerator; protected botEquipmentFilterService: BotEquipmentFilterService; + protected weightedRandomHelper: WeightedRandomHelper; protected botHelper: BotHelper; + protected botDifficultyHelper: BotDifficultyHelper; protected gameEventHelper: GameEventHelper; - protected pmcAiService: PmcAiService; protected configServer: ConfigServer; protected botConfig: IBotConfig; - constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, jsonUtil: JsonUtil, profileHelper: ProfileHelper, databaseServer: DatabaseServer, botInventoryGenerator: BotInventoryGenerator, botEquipmentFilterService: BotEquipmentFilterService, botHelper: BotHelper, gameEventHelper: GameEventHelper, pmcAiService: PmcAiService, configServer: ConfigServer); + constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, jsonUtil: JsonUtil, profileHelper: ProfileHelper, databaseServer: DatabaseServer, botInventoryGenerator: BotInventoryGenerator, botLevelGenerator: BotLevelGenerator, botEquipmentFilterService: BotEquipmentFilterService, weightedRandomHelper: WeightedRandomHelper, botHelper: BotHelper, botDifficultyHelper: BotDifficultyHelper, gameEventHelper: GameEventHelper, configServer: ConfigServer); /** * Generate a player scav bot object * @param role e.g. assault / pmcbot @@ -44,12 +42,18 @@ export declare class BotGenerator { */ generatePlayerScav(sessionId: string, role: string, difficulty: string, botTemplate: IBotType): IBotBase; /** - * Generate an array of bot objects for populate a raid with + * Generate an array of bot objects based on a condition for a raid with * @param sessionId session id - * @param info request object - * @returns bot array + * @param botGenerationDetails details on how to generate the bots + * @returns Generated bots in array */ - generate(sessionId: string, info: IGenerateBotsRequestData): IBotBase[]; + generateByCondition(sessionId: string, botGenerationDetails: BotGenerationDetails): IBotBase[]; + /** + * Get the PMCs wildSpawnType value + * @param role "usec" / "bear" + * @returns wildSpawnType value as string + */ + protected getPmcRoleByDescription(role: string): string; /** * Get a randomised PMC side based on bot config value 'isUsec' * @returns pmc side as string @@ -64,26 +68,24 @@ export declare class BotGenerator { * Create a IBotBase object with equipment/loot/exp etc * @param sessionId Session id * @param bot bots base file - * @param role botRole bot will use - * @param node Bot template from db/bots/x.json - * @param isPmc Is bot to be a PMC - * @param isPlayerScav is bot to be a p scav bot + * @param botJsonTemplate Bot template from db/bots/x.json + * @param botGenerationDetails details on how to generate the bot * @returns IBotBase object */ - protected generateBot(sessionId: string, bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase; + protected generateBot(sessionId: string, bot: IBotBase, botJsonTemplate: IBotType, botGenerationDetails: BotGenerationDetails): IBotBase; + /** + * Create a bot nickname + * @param botJsonTemplate x.json from database + * @param isPlayerScav Will bot be player scav + * @param botRole role of bot e.g. assault + * @returns Nickname for bot + */ + protected generateBotNickname(botJsonTemplate: IBotType, isPlayerScav: boolean, botRole: string): string; /** * Log the number of PMCs generated to the debug console * @param output Generated bot array, ready to send to client */ protected logPmcGeneratedCount(output: IBotBase[]): void; - /** - * Return a randomised bot level and exp value - * @param role botRole being generated for - * @param min Min exp value - * @param max Max exp value - * @returns IRandomisedBotLevelResult object - */ - protected generateRandomLevel(role: string, min: number, max: number): BotGenerator.IRandomisedBotLevelResult; /** * Converts health object to the required format * @param healthObj health object from bot json @@ -117,4 +119,3 @@ export declare class BotGenerator { */ protected generateDogtag(bot: IBotBase): IBotBase; } -export {}; diff --git a/Faupi-MunitionsExpert/server/types/generators/BotInventoryGenerator.d.ts b/Faupi-MunitionsExpert/server/types/generators/BotInventoryGenerator.d.ts index c5ed545..a3b5eaa 100644 --- a/Faupi-MunitionsExpert/server/types/generators/BotInventoryGenerator.d.ts +++ b/Faupi-MunitionsExpert/server/types/generators/BotInventoryGenerator.d.ts @@ -1,12 +1,14 @@ import { BotGeneratorHelper } from "../helpers/BotGeneratorHelper"; +import { BotHelper } from "../helpers/BotHelper"; import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper"; import { Inventory as PmcInventory } from "../models/eft/common/tables/IBotBase"; -import { Chances, Generation, Inventory, Mods } from "../models/eft/common/tables/IBotType"; +import { Chances, Generation, IBotType, Inventory, Mods } from "../models/eft/common/tables/IBotType"; import { EquipmentSlots } from "../models/enums/EquipmentSlots"; -import { IBotConfig } from "../models/spt/config/IBotConfig"; +import { IBotConfig, RandomisationDetails } from "../models/spt/config/IBotConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "../services/LocalisationService"; import { HashUtil } from "../utils/HashUtil"; import { RandomUtil } from "../utils/RandomUtil"; import { BotLootGenerator } from "./BotLootGenerator"; @@ -19,15 +21,81 @@ export declare class BotInventoryGenerator { protected botWeaponGenerator: BotWeaponGenerator; protected botLootGenerator: BotLootGenerator; protected botGeneratorHelper: BotGeneratorHelper; + protected botHelper: BotHelper; protected weightedRandomHelper: WeightedRandomHelper; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected botConfig: IBotConfig; - constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, botWeaponGenerator: BotWeaponGenerator, botLootGenerator: BotLootGenerator, botGeneratorHelper: BotGeneratorHelper, weightedRandomHelper: WeightedRandomHelper, configServer: ConfigServer); - generateInventory(sessionId: string, templateInventory: Inventory, equipmentChances: Chances, itemGenerationLimitsMinMax: Generation, botRole: string, isPmc: boolean): PmcInventory; + constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, botWeaponGenerator: BotWeaponGenerator, botLootGenerator: BotLootGenerator, botGeneratorHelper: BotGeneratorHelper, botHelper: BotHelper, weightedRandomHelper: WeightedRandomHelper, localisationService: LocalisationService, configServer: ConfigServer); + /** + * Add equipment/weapons/loot to bot + * @param sessionId Session id + * @param botJsonTemplate bot/x.json data from db + * @param botRole Role bot has (assault/pmcBot) + * @param isPmc Is bot being converted into a pmc + * @param botLevel Level of bot being generated + * @returns PmcInventory object with equipment/weapons/loot + */ + generateInventory(sessionId: string, botJsonTemplate: IBotType, botRole: string, isPmc: boolean, botLevel: number): PmcInventory; + /** + * Create a pmcInventory object with all the base/generic items needed + * @returns PmcInventory object + */ + protected generateInventoryBase(): PmcInventory; + /** + * Add equipment to a bot + * @param templateInventory bot/x.json data from db + * @param equipmentChances Chances items will be added to bot + * @param botRole Role bot has (assault/pmcBot) + * @param botInventory Inventory to add equipment to + * @param botLevel Level of bot + */ + protected generateAndAddEquipmentToBot(templateInventory: Inventory, equipmentChances: Chances, botRole: string, botInventory: PmcInventory, botLevel: number): void; + /** + * Add a piece of equipment with mods to inventory from the provided pools + * @param equipmentSlot Slot to select an item for + * @param equipmentPool Possible items to choose from + * @param modPool Possible mods to apply to item chosen + * @param spawnChances Chances items will be chosen to be added + * @param botRole Role of bot e.g. assault + * @param inventory Inventory to add item into + * @param randomisationDetails settings from bot.json to adjust how item is generated + */ + protected generateEquipment(equipmentSlot: string, equipmentPool: Record, modPool: Mods, spawnChances: Chances, botRole: string, inventory: PmcInventory, randomisationDetails: RandomisationDetails): void; + /** + * Work out what weapons bot should have equipped and add them to bot inventory + * @param templateInventory bot/x.json data from db + * @param equipmentChances Chances bot can have equipment equipped + * @param sessionId Session id + * @param botInventory Inventory to add weapons to + * @param botRole assault/pmcBot/bossTagilla etc + * @param isPmc Is the bot being generated as a pmc + * @param botLevel level of bot having weapon generated + * @param itemGenerationLimitsMinMax Limits for items the bot can have + */ + protected generateAndAddWeaponsToBot(templateInventory: Inventory, equipmentChances: Chances, sessionId: string, botInventory: PmcInventory, botRole: string, isPmc: boolean, itemGenerationLimitsMinMax: Generation, botLevel: number): void; + /** + * Calculate if the bot should have weapons in Primary/Secondary/Holster slots + * @param equipmentChances Chances bot has certain equipment + * @returns What slots bot should have weapons generated for + */ + protected getDesiredWeaponsForBot(equipmentChances: Chances): { + slot: EquipmentSlots; + shouldSpawn: boolean; + }[]; + /** + * Add weapon + spare mags/ammo to bots inventory + * @param sessionId Session id + * @param weaponSlot Weapon slot being generated + * @param templateInventory bot/x.json data from db + * @param botInventory Inventory to add weapon+mags/ammo to + * @param equipmentChances Chances bot can have equipment equipped + * @param botRole assault/pmcBot/bossTagilla etc + * @param isPmc Is the bot being generated as a pmc + * @param itemGenerationLimitsMinMax + */ protected addWeaponAndMagazinesToInventory(sessionId: string, weaponSlot: { slot: EquipmentSlots; shouldSpawn: boolean; - }, templateInventory: Inventory, botInventory: PmcInventory, equipmentChances: Chances, botRole: string, isPmc: boolean, itemGenerationLimitsMinMax: Generation): void; - protected generateEquipment(equipmentSlot: string, equipmentPool: Record, modPool: Mods, spawnChances: Chances, botRole: string, inventory: PmcInventory): void; - protected generateInventoryBase(): PmcInventory; + }, templateInventory: Inventory, botInventory: PmcInventory, equipmentChances: Chances, botRole: string, isPmc: boolean, itemGenerationLimitsMinMax: Generation, botLevel: number): void; } diff --git a/Faupi-MunitionsExpert/server/types/generators/BotLevelGenerator.d.ts b/Faupi-MunitionsExpert/server/types/generators/BotLevelGenerator.d.ts new file mode 100644 index 0000000..751e6e6 --- /dev/null +++ b/Faupi-MunitionsExpert/server/types/generators/BotLevelGenerator.d.ts @@ -0,0 +1,29 @@ +import { MinMax } from "../models/common/MinMax"; +import { IRandomisedBotLevelResult } from "../models/eft/bot/IRandomisedBotLevelResult"; +import { ExpTable } from "../models/eft/common/IGlobals"; +import { IBotBase } from "../models/eft/common/tables/IBotBase"; +import { BotGenerationDetails } from "../models/spt/bots/BotGenerationDetails"; +import { ILogger } from "../models/spt/utils/ILogger"; +import { DatabaseServer } from "../servers/DatabaseServer"; +import { RandomUtil } from "../utils/RandomUtil"; +export declare class BotLevelGenerator { + protected logger: ILogger; + protected randomUtil: RandomUtil; + protected databaseServer: DatabaseServer; + constructor(logger: ILogger, randomUtil: RandomUtil, databaseServer: DatabaseServer); + /** + * Return a randomised bot level and exp value + * @param levelDetails min and max of level for bot + * @param botGenerationDetails Deatils to help generate a bot + * @param bot being level is being generated for + * @returns IRandomisedBotLevelResult object + */ + generateBotLevel(levelDetails: MinMax, botGenerationDetails: BotGenerationDetails, bot: IBotBase): IRandomisedBotLevelResult; + /** + * Get the highest level a bot can be relative to the players level, but no futher than the max size from globals.exp_table + * @param playerLevel Players current level + * @param relativeDeltaMax max delta above player level to go + * @returns highest level possible for bot + */ + protected getHighestRelativeBotLevel(playerLevel: number, relativeDeltaMax: number, levelDetails: MinMax, expTable: ExpTable[]): number; +} diff --git a/Faupi-MunitionsExpert/server/types/generators/BotLootGenerator.d.ts b/Faupi-MunitionsExpert/server/types/generators/BotLootGenerator.d.ts index c1f5310..6273a11 100644 --- a/Faupi-MunitionsExpert/server/types/generators/BotLootGenerator.d.ts +++ b/Faupi-MunitionsExpert/server/types/generators/BotLootGenerator.d.ts @@ -10,6 +10,7 @@ import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { BotLootCacheService } from "../services/BotLootCacheService"; +import { LocalisationService } from "../services/LocalisationService"; import { HashUtil } from "../utils/HashUtil"; import { RandomUtil } from "../utils/RandomUtil"; import { BotWeaponGenerator } from "./BotWeaponGenerator"; @@ -23,10 +24,22 @@ export declare class BotLootGenerator { protected botWeaponGenerator: BotWeaponGenerator; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; protected botLootCacheService: BotLootCacheService; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected botConfig: IBotConfig; - constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, botGeneratorHelper: BotGeneratorHelper, botWeaponGenerator: BotWeaponGenerator, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer); - generateLoot(sessionId: string, templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void; + constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, botGeneratorHelper: BotGeneratorHelper, botWeaponGenerator: BotWeaponGenerator, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, botLootCacheService: BotLootCacheService, localisationService: LocalisationService, configServer: ConfigServer); + /** + * Add loot to bots containers + * @param sessionId Session id + * @param templateInventory x.json from database/bots + * @param itemCounts Liits on item types to be added as loot + * @param isPmc Will bot be a pmc + * @param botRole Role of bot, e.g. asssult + * @param botInventory Inventory to add loot to + * @param equipmentChances + * @param botLevel Level of bot + */ + generateLoot(sessionId: string, templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances, botLevel: number): void; protected getRandomisedCount(min: number, max: number, nValue: number): number; /** * Take random items from a pool and add to an inventory until totalItemCount or totalValueLimit is reached @@ -49,7 +62,7 @@ export declare class BotLootGenerator { * @param botRole bots role, .e.g. pmcBot * @param isPmc are we generating for a pmc */ - protected addLooseWeaponsToInventorySlot(sessionId: string, botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void; + protected addLooseWeaponsToInventorySlot(sessionId: string, botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): void; /** * Get a random item from the pool parameter using the biasedRandomNumber system * @param pool pool of items to pick an item from @@ -113,7 +126,7 @@ export declare class BotLootGenerator { * If no limit found for a non pmc bot, fall back to defaults * @param isPmc is the bot we want limits for a pmc * @param botRole what role does the bot have - * @returns dictionary of tplIds and limit + * @returns Dictionary of tplIds and limit */ protected getItemSpawnLimitsForBotType(isPmc: boolean, botRole: string): Record; /** diff --git a/Faupi-MunitionsExpert/server/types/generators/BotWeaponGenerator.d.ts b/Faupi-MunitionsExpert/server/types/generators/BotWeaponGenerator.d.ts index 487901b..b2eaf3b 100644 --- a/Faupi-MunitionsExpert/server/types/generators/BotWeaponGenerator.d.ts +++ b/Faupi-MunitionsExpert/server/types/generators/BotWeaponGenerator.d.ts @@ -12,6 +12,7 @@ import { IBotConfig } from "../models/spt/config/IBotConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "../services/LocalisationService"; import { HashUtil } from "../utils/HashUtil"; import { JsonUtil } from "../utils/JsonUtil"; import { RandomUtil } from "../utils/RandomUtil"; @@ -27,10 +28,11 @@ export declare class BotWeaponGenerator { protected randomUtil: RandomUtil; protected configServer: ConfigServer; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; + protected localisationService: LocalisationService; protected inventoryMagGenComponents: IInventoryMagGen[]; protected readonly modMagazineSlotId = "mod_magazine"; protected botConfig: IBotConfig; - constructor(jsonUtil: JsonUtil, logger: ILogger, hashUtil: HashUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, weightedRandomHelper: WeightedRandomHelper, botGeneratorHelper: BotGeneratorHelper, randomUtil: RandomUtil, configServer: ConfigServer, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, inventoryMagGenComponents: IInventoryMagGen[]); + constructor(jsonUtil: JsonUtil, logger: ILogger, hashUtil: HashUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, weightedRandomHelper: WeightedRandomHelper, botGeneratorHelper: BotGeneratorHelper, randomUtil: RandomUtil, configServer: ConfigServer, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, localisationService: LocalisationService, inventoryMagGenComponents: IInventoryMagGen[]); /** * Pick a random weapon based on weightings and generate a functional weapon * @param equipmentSlot Primary/secondary/holster @@ -41,7 +43,7 @@ export declare class BotWeaponGenerator { * @param isPmc Is weapon generated for a pmc * @returns GenerateWeaponResult object */ - generateRandomWeapon(sessionId: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult; + generateRandomWeapon(sessionId: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** * Get a random weighted weapon from a bots pool of weapons * @param equipmentSlot Primary/secondary/holster @@ -60,7 +62,7 @@ export declare class BotWeaponGenerator { * @param isPmc * @returns GenerateWeaponResult object */ - generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult; + generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/Faupi-MunitionsExpert/server/types/generators/RagfairOfferGenerator.d.ts b/Faupi-MunitionsExpert/server/types/generators/RagfairOfferGenerator.d.ts index b64a7e7..23882d2 100644 --- a/Faupi-MunitionsExpert/server/types/generators/RagfairOfferGenerator.d.ts +++ b/Faupi-MunitionsExpert/server/types/generators/RagfairOfferGenerator.d.ts @@ -1,16 +1,19 @@ +import { HandbookHelper } from "../helpers/HandbookHelper"; import { ItemHelper } from "../helpers/ItemHelper"; +import { PaymentHelper } from "../helpers/PaymentHelper"; import { PresetHelper } from "../helpers/PresetHelper"; import { RagfairServerHelper } from "../helpers/RagfairServerHelper"; import { Item } from "../models/eft/common/tables/IItem"; import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem"; import { IBarterScheme } from "../models/eft/common/tables/ITrader"; -import { IRagfairOffer } from "../models/eft/ragfair/IRagfairOffer"; +import { IRagfairOffer, OfferRequirement } from "../models/eft/ragfair/IRagfairOffer"; import { IRagfairConfig } from "../models/spt/config/IRagfairConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { SaveServer } from "../servers/SaveServer"; import { FenceService } from "../services/FenceService"; +import { LocalisationService } from "../services/LocalisationService"; import { RagfairCategoriesService } from "../services/RagfairCategoriesService"; import { RagfairOfferService } from "../services/RagfairOfferService"; import { RagfairPriceService } from "../services/RagfairPriceService"; @@ -27,18 +30,31 @@ export declare class RagfairOfferGenerator { protected timeUtil: TimeUtil; protected databaseServer: DatabaseServer; protected ragfairServerHelper: RagfairServerHelper; + protected handbookHelper: HandbookHelper; protected saveServer: SaveServer; protected presetHelper: PresetHelper; protected ragfairAssortGenerator: RagfairAssortGenerator; protected ragfairOfferService: RagfairOfferService; protected ragfairPriceService: RagfairPriceService; + protected localisationService: LocalisationService; + protected paymentHelper: PaymentHelper; protected ragfairCategoriesService: RagfairCategoriesService; protected fenceService: FenceService; protected itemHelper: ItemHelper; protected configServer: ConfigServer; protected ragfairConfig: IRagfairConfig; - constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, ragfairServerHelper: RagfairServerHelper, saveServer: SaveServer, presetHelper: PresetHelper, ragfairAssortGenerator: RagfairAssortGenerator, ragfairOfferService: RagfairOfferService, ragfairPriceService: RagfairPriceService, ragfairCategoriesService: RagfairCategoriesService, fenceService: FenceService, itemHelper: ItemHelper, configServer: ConfigServer); + protected allowedFleaPriceItemsForBarter: { + tpl: string; + price: number; + }[]; + constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, ragfairServerHelper: RagfairServerHelper, handbookHelper: HandbookHelper, saveServer: SaveServer, presetHelper: PresetHelper, ragfairAssortGenerator: RagfairAssortGenerator, ragfairOfferService: RagfairOfferService, ragfairPriceService: RagfairPriceService, localisationService: LocalisationService, paymentHelper: PaymentHelper, ragfairCategoriesService: RagfairCategoriesService, fenceService: FenceService, itemHelper: ItemHelper, configServer: ConfigServer); createOffer(userID: string, time: number, items: Item[], barterScheme: IBarterScheme[], loyalLevel: number, price: number, sellInOnePiece?: boolean): IRagfairOffer; + /** + * Calculate the offer price that's listed on the flea listing + * @param offerRequirements barter requirements for offer + * @returns rouble cost of offer + */ + protected calculateOfferListingPrice(offerRequirements: OfferRequirement[]): number; /** * Get avatar url from trader table in db * @param isTrader Is user we're getting avatar for a trader @@ -87,20 +103,36 @@ export declare class RagfairOfferGenerator { * @returns Item with conditions added */ protected addMissingCondition(item: Item): Item; - protected getOfferRequirements(items: Item[]): { - count: number; - _tpl: string; + /** + * Create a barter-based barter scheme, if not possible, fall back to making barter scheme currency based + * @param offerItems Items for sale in offer + * @returns barter scheme + */ + protected createBarterRequirement(offerItems: Item[]): IBarterScheme[]; + /** + * Get an array of flea prices + item tpl, cached in generator class + * @returns array with tpl/price values + */ + protected getFleaPricesAsArray(): { + tpl: string; + price: number; }[]; + /** + * Create a random currency-based barter scheme for an array of items + * @param offerItems Items on offer + * @returns Barter scheme for offer + */ + protected createCurrencyRequirement(offerItems: Item[]): IBarterScheme[]; /** * Create a flea offer and store it in the Ragfair server offers array * @param userID owner of the offer * @param time time offer is put up * @param items items in the offer - * @param barterScheme - * @param loyalLevel + * @param barterScheme cost of item (currency or barter) + * @param loyalLevel Loyalty level needed to buy item * @param price price of offer * @param sellInOnePiece - * @returns + * @returns Ragfair offer */ createFleaOffer(userID: string, time: number, items: Item[], barterScheme: IBarterScheme[], loyalLevel: number, price: number, sellInOnePiece?: boolean): IRagfairOffer; } diff --git a/Faupi-MunitionsExpert/server/types/generators/WeatherGenerator.d.ts b/Faupi-MunitionsExpert/server/types/generators/WeatherGenerator.d.ts index 8ddbe49..65d2c76 100644 --- a/Faupi-MunitionsExpert/server/types/generators/WeatherGenerator.d.ts +++ b/Faupi-MunitionsExpert/server/types/generators/WeatherGenerator.d.ts @@ -1,38 +1,54 @@ +import { ApplicationContext } from "../context/ApplicationContext"; import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper"; -import { IWeatherData } from "../models/eft/weather/IWeatherData"; +import { IWeather, IWeatherData } from "../models/eft/weather/IWeatherData"; +import { WindDirection } from "../models/enums/WindDirection"; import { IWeatherConfig } from "../models/spt/config/IWeatherConfig"; +import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { RandomUtil } from "../utils/RandomUtil"; import { TimeUtil } from "../utils/TimeUtil"; export declare class WeatherGenerator { protected weightedRandomHelper: WeightedRandomHelper; + protected logger: ILogger; protected randomUtil: RandomUtil; protected timeUtil: TimeUtil; + protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected weatherConfig: IWeatherConfig; - constructor(weightedRandomHelper: WeightedRandomHelper, randomUtil: RandomUtil, timeUtil: TimeUtil, configServer: ConfigServer); - calculateTime(data: IWeatherData): IWeatherData; + constructor(weightedRandomHelper: WeightedRandomHelper, logger: ILogger, randomUtil: RandomUtil, timeUtil: TimeUtil, applicationContext: ApplicationContext, configServer: ConfigServer); + calculateGameTime(data: IWeatherData): IWeatherData; /** * Get server uptime seconds multiplied by a multiplier and add to current time as seconds * Format to BSGs requirements - * @param computedDate current date + * @param currentDate current date * @returns formatted time */ - protected getAcceleratedTime(computedDate: Date): string; + protected getBsgFormattedInRaidTime(currentDate: Date): string; + /** + * Get the current in-raid time + * @param currentDate (new Date()) + * @returns Date object of current in-raid time + */ + getInRaidTime(currentDate: Date): Date; /** * Get current time formatted to fit BSGs requirement - * @param computedDate date to format into bsg style + * @param date date to format into bsg style * @returns */ - protected getNormalTime(computedDate: Date): string; + protected getBSGFormattedTime(date: Date): string; /** - * Return randomised Weather data - * @param weatherData weather input data + * Return randomised Weather data with help of config/weather.json * @returns Randomised weather data */ - generateWeather(weatherData: IWeatherData): IWeatherData; - protected getWeightedFog(): string; + generateWeather(): IWeather; + /** + * Set IWeather date/time/timestamp values to now + * @param weather Object to update + */ + protected setCurrentDateTime(weather: IWeather): void; + protected getWeightedWindDirection(): WindDirection; + protected getWeightedWindSpeed(): number; + protected getWeightedFog(): number; protected getWeightedRain(): number; protected getRandomFloat(node: string): number; - protected getRandomInt(node: string): number; } diff --git a/Faupi-MunitionsExpert/server/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/Faupi-MunitionsExpert/server/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index 4fcb1e2..1589707 100644 --- a/Faupi-MunitionsExpert/server/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/Faupi-MunitionsExpert/server/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -1,13 +1,15 @@ import { BotWeaponGeneratorHelper } from "../../../helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "../../../helpers/ItemHelper"; import { ILogger } from "../../../models/spt/utils/ILogger"; +import { LocalisationService } from "../../../services/LocalisationService"; import { IInventoryMagGen } from "../IInventoryMagGen"; import { InventoryMagGen } from "../InventoryMagGen"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; + protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; diff --git a/Faupi-MunitionsExpert/server/types/helpers/BotDifficultyHelper.d.ts b/Faupi-MunitionsExpert/server/types/helpers/BotDifficultyHelper.d.ts new file mode 100644 index 0000000..a58ebdb --- /dev/null +++ b/Faupi-MunitionsExpert/server/types/helpers/BotDifficultyHelper.d.ts @@ -0,0 +1,46 @@ +import { Difficulty } from "../models/eft/common/tables/IBotType"; +import { IBotConfig } from "../models/spt/config/IBotConfig"; +import { ILogger } from "../models/spt/utils/ILogger"; +import { ConfigServer } from "../servers/ConfigServer"; +import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "../services/LocalisationService"; +import { JsonUtil } from "../utils/JsonUtil"; +import { RandomUtil } from "../utils/RandomUtil"; +import { BotHelper } from "./BotHelper"; +export declare class BotDifficultyHelper { + protected logger: ILogger; + protected jsonUtil: JsonUtil; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected localisationService: LocalisationService; + protected botHelper: BotHelper; + protected configServer: ConfigServer; + protected botConfig: IBotConfig; + constructor(logger: ILogger, jsonUtil: JsonUtil, databaseServer: DatabaseServer, randomUtil: RandomUtil, localisationService: LocalisationService, botHelper: BotHelper, configServer: ConfigServer); + getPmcDifficultySettings(pmcType: "bear" | "usec", difficulty: string, usecType: string, bearType: string): Difficulty; + /** + * Get difficulty settings for desired bot type, if not found use assault bot types + * @param type bot type to retreive difficulty of + * @param difficulty difficulty to get settings for (easy/normal etc) + * @returns Difficulty object + */ + getBotDifficultySettings(type: string, difficulty: string): Difficulty; + /** + * Get difficulty settings for a PMC + * @param type "usec" / "bear" + * @param difficulty what difficulty to retrieve + * @returns Difficulty object + */ + protected getDifficultySettings(type: string, difficulty: string): Difficulty; + /** + * Translate chosen value from pre-raid difficulty dropdown into bot difficulty value + * @param dropDownDifficulty Dropdown difficulty value to convert + * @returns bot difficulty + */ + convertBotDifficultyDropdownToBotDifficulty(dropDownDifficulty: string): string; + /** + * Choose a random difficulty from - easy/normal/hard/impossible + * @returns random difficulty + */ + chooseRandomDifficulty(): string; +} diff --git a/Faupi-MunitionsExpert/server/types/helpers/BotGeneratorHelper.d.ts b/Faupi-MunitionsExpert/server/types/helpers/BotGeneratorHelper.d.ts index 5e3e501..9ee017f 100644 --- a/Faupi-MunitionsExpert/server/types/helpers/BotGeneratorHelper.d.ts +++ b/Faupi-MunitionsExpert/server/types/helpers/BotGeneratorHelper.d.ts @@ -8,9 +8,11 @@ import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { BotEquipmentFilterService } from "../services/BotEquipmentFilterService"; import { ItemFilterService } from "../services/ItemFilterService"; +import { LocalisationService } from "../services/LocalisationService"; import { HashUtil } from "../utils/HashUtil"; import { JsonUtil } from "../utils/JsonUtil"; import { RandomUtil } from "../utils/RandomUtil"; +import { BotHelper } from "./BotHelper"; import { BotWeaponGeneratorHelper } from "./BotWeaponGeneratorHelper"; import { ContainerHelper } from "./ContainerHelper"; import { InventoryHelper } from "./InventoryHelper"; @@ -43,9 +45,11 @@ export declare class BotGeneratorHelper { protected itemFilterService: ItemFilterService; protected profileHelper: ProfileHelper; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; + protected botHelper: BotHelper; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected botConfig: IBotConfig; - constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, botEquipmentFilterService: BotEquipmentFilterService, itemFilterService: ItemFilterService, profileHelper: ProfileHelper, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, configServer: ConfigServer); + constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, botEquipmentFilterService: BotEquipmentFilterService, itemFilterService: ItemFilterService, profileHelper: ProfileHelper, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, botHelper: BotHelper, localisationService: LocalisationService, configServer: ConfigServer); /** * Check mods are compatible and add to array * @param equipment Equipment item to add mods to @@ -53,10 +57,13 @@ export declare class BotGeneratorHelper { * @param parentId parentid of item to add mod to * @param parentTemplate template objet of item to add mods to * @param modSpawnChances dictionary of mod items and their chance to spawn for this bot type + * @param botRole the bot role being generated for + * @param forceSpawn should this mod be forced to spawn * @returns Item + compatible mods as an array */ - generateModsForEquipment(equipment: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[]; + generateModsForEquipment(equipment: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances, botRole: string, forceSpawn?: boolean): Item[]; /** + * Add mods to a weapon using the provided mod pool * @param sessionId session id * @param weapon Weapon to add mods to * @param modPool Pool of compatible mods to attach to weapon @@ -67,18 +74,18 @@ export declare class BotGeneratorHelper { * @param botRole Role of bot weapon is generated for * @returns Weapon + mods array */ - generateModsForWeapon(sessionId: string, weapon: Item[], modPool: Mods, weaponParentId: string, parentWeaponTemplate: ITemplateItem, modSpawnChances: ModsChances, ammoTpl: string, botRole: string): Item[]; + generateModsForWeapon(sessionId: string, weapon: Item[], modPool: Mods, weaponParentId: string, parentWeaponTemplate: ITemplateItem, modSpawnChances: ModsChances, ammoTpl: string, botRole: string, botLevel: number): Item[]; /** * - * @param modSlot - * @param isRandomisableSlot - * @param modsParent - * @param botEquipBlacklist - * @param itemModPool + * @param modSlot Slot mod will fit into + * @param isRandomisableSlot Will generate a randomised mod pool if true + * @param modsParent Parent slot the item will be a part of + * @param botEquipBlacklist Blacklist to prevent mods from being picked + * @param itemModPool Pool of items to pick from * @param weapon array with only weapon tpl in it, ready for mods to be added * @param ammoTpl ammo tpl to use if slot requires a cartridge to be added (e.g. mod_magazine) - * @param parentTemplate - * @returns + * @param parentTemplate Parent item the mod will go into + * @returns ITemplateItem */ protected chooseModToPutIntoSlot(modSlot: string, isRandomisableSlot: boolean, modsParent: Slot, botEquipBlacklist: EquipmentFilterDetails, itemModPool: Record, weapon: Item[], ammoTpl: string, parentTemplate: ITemplateItem): [boolean, ITemplateItem]; /** @@ -114,8 +121,10 @@ export declare class BotGeneratorHelper { * Find all compatible mods for equipment item and add to modPool * @param itemDetails item to find mods for * @param modPool ModPool to add mods to + * @param equipmentBlacklist equipment not allowed to be used by the bot + * @param botEquipmentRole bot type to generate pool for (e.g. assault, pmcBot, pmc for usec/bear) */ - generateDynamicModPool(itemDetails: ITemplateItem, modPool: Mods): void; + generateDynamicModPool(itemDetails: ITemplateItem, modPool: Mods, equipmentBlacklist: EquipmentFilterDetails[], botEquipmentRole: string): void; /** * Take a list of tpls and filter out blacklisted values using itemFilterService + botEquipmentBlacklist * @param allowedMods base mods to filter @@ -153,7 +162,7 @@ export declare class BotGeneratorHelper { * @param modTemplate Used to add additional properites in the upd object * @returns Item object */ - protected createModItem(modId: string, modTpl: string, parentId: string, modSlot: string, modTemplate: ITemplateItem): Item; + protected createModItem(modId: string, modTpl: string, parentId: string, modSlot: string, modTemplate: ITemplateItem, botRole: string): Item; /** * randomly choose if a mod should be spawned, 100% for required mods OR mod is ammo slot * never return true for an item that has 0% spawn chance @@ -170,10 +179,10 @@ export declare class BotGeneratorHelper { */ protected getAmmoContainers(): string[]; /** - * Get the slot details for an item (chamber/cartridge/slot) + * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon * @param parentTemplate item template - * @returns + * @returns Slot item */ protected getModItemSlot(modSlot: string, parentTemplate: ITemplateItem): Slot; /** @@ -185,7 +194,6 @@ export declare class BotGeneratorHelper { * @param modPool modPool which should include available cartrigdes * @param parentId The CylinderMagazine's UID * @param parentTemplate The CylinderMagazine's template - * @returns */ protected fillCamora(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem): void; /** @@ -197,11 +205,11 @@ export declare class BotGeneratorHelper { /** * Adds properties to an item * e.g. Repairable / HasHinge / Foldable / MaxDurability - * @param itemTemplate - * @param botRole Used by weapons to randomise the durability values + * @param itemTemplate Item extra properties are being generated for + * @param botRole Used by weapons to randomise the durability values. Null for non-equipped items * @returns Item Upd object with extra properties */ - generateExtraPropertiesForItem(itemTemplate: ITemplateItem, botRole?: any): { + generateExtraPropertiesForItem(itemTemplate: ITemplateItem, botRole?: string): { upd?: Upd; }; /** @@ -220,21 +228,27 @@ export declare class BotGeneratorHelper { protected generateArmorRepairableProperties(itemTemplate: ITemplateItem, botRole: string): Repairable; /** * Get a random mod from an items compatible mods Filter array - * @param modTpl - * @param parentSlot - * @param modSlot - * @param items + * @param modTpl ???? + * @param parentSlot item mod will go into, used to get combatible items + * @param modSlot Slot to get mod to fill + * @param items items to ensure picked mod is compatible with * @returns item tpl */ protected getModTplFromItemDb(modTpl: string, parentSlot: Slot, modSlot: string, items: Item[]): string; /** * Can an item be added to an item without issue - * @param items - * @param tplToCheck - * @param equipmentSlot - * @returns true if possible + * @param items items to check compatiblilities with + * @param tplToCheck tpl of the item to check for incompatibilities + * @param equipmentSlot Slot the item will be placed into + * @returns false if no incompatibilties */ isItemIncompatibleWithCurrentItems(items: Item[], tplToCheck: string, equipmentSlot: string): boolean; + /** + * Convert a bots role to the equipment role used in config/bot.json + * @param botRole Role to convert + * @returns Equipment role (e.g. pmc / assault / bossTagilla) + */ + getBotEquipmentRole(botRole: string): string; } /** TODO - move into own class */ export declare class ExhaustableArray { diff --git a/Faupi-MunitionsExpert/server/types/helpers/BotHelper.d.ts b/Faupi-MunitionsExpert/server/types/helpers/BotHelper.d.ts index 67a6384..2752a0e 100644 --- a/Faupi-MunitionsExpert/server/types/helpers/BotHelper.d.ts +++ b/Faupi-MunitionsExpert/server/types/helpers/BotHelper.d.ts @@ -1,8 +1,9 @@ import { Difficulty, IBotType } from "../models/eft/common/tables/IBotType"; -import { IBotConfig } from "../models/spt/config/IBotConfig"; +import { EquipmentFilters, IBotConfig, RandomisationDetails } from "../models/spt/config/IBotConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "../services/LocalisationService"; import { JsonUtil } from "../utils/JsonUtil"; import { RandomUtil } from "../utils/RandomUtil"; export declare class BotHelper { @@ -10,46 +11,27 @@ export declare class BotHelper { protected jsonUtil: JsonUtil; protected databaseServer: DatabaseServer; protected randomUtil: RandomUtil; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected botConfig: IBotConfig; - constructor(logger: ILogger, jsonUtil: JsonUtil, databaseServer: DatabaseServer, randomUtil: RandomUtil, configServer: ConfigServer); - /** - * Get difficulty settings for desired bot type, if not found use assault bot types - * @param type bot type to retreive difficulty of - * @param difficulty difficulty to get settings for (easy/normal etc) - * @returns Difficulty object - */ - getBotDifficultySettings(type: string, difficulty: string): Difficulty; + constructor(logger: ILogger, jsonUtil: JsonUtil, databaseServer: DatabaseServer, randomUtil: RandomUtil, localisationService: LocalisationService, configServer: ConfigServer); /** * Get a template object for the specified botRole from bots.types db * @param role botRole to get template for * @returns IBotType object */ getBotTemplate(role: string): IBotType; - /** - * Get difficulty settings for a PMC - * @param type "usec" / "bear" - * @param difficulty what difficulty to retrieve - * @returns Difficulty object - */ - getPmcDifficultySettings(type: string, difficulty: string): Difficulty; - /** - * Translate chosen value from pre-raid difficulty dropdown into bot difficulty value - * @param dropDownDifficulty Dropdown difficulty value to convert - * @returns bot difficulty - */ - convertBotDifficultyDropdownToBotDifficulty(dropDownDifficulty: string): string; - /** - * Choose a random difficulty from - easy/normal/hard/impossible - * @returns random difficulty - */ - chooseRandomDifficulty(): string; /** * Randomise the chance the PMC will attack their own side * Look up value in bot.json/chanceSameSideIsHostilePercent * @param difficultySettings pmc difficulty settings */ randomisePmcHostility(difficultySettings: Difficulty): void; + /** + * Is the passed in bot role a PMC (usec/bear/pmc) + * @param botRole bot role to check + * @returns true if is pmc + */ isBotPmc(botRole: string): boolean; isBotBoss(botRole: string): boolean; isBotFollower(botRole: string): boolean; @@ -77,4 +59,11 @@ export declare class BotHelper { * @returns true if should be a pmc */ shouldBotBePmc(botRole: string): boolean; + /** + * Get randomisation settings for bot from config/bot.json + * @param botLevel level of bot + * @param botEquipConfig bot equipment json + * @returns RandomisationDetails + */ + getBotRandomisationDetails(botLevel: number, botEquipConfig: EquipmentFilters): RandomisationDetails; } diff --git a/Faupi-MunitionsExpert/server/types/helpers/GameEventHelper.d.ts b/Faupi-MunitionsExpert/server/types/helpers/GameEventHelper.d.ts index fca87be..fa25eff 100644 --- a/Faupi-MunitionsExpert/server/types/helpers/GameEventHelper.d.ts +++ b/Faupi-MunitionsExpert/server/types/helpers/GameEventHelper.d.ts @@ -15,4 +15,15 @@ export declare class GameEventHelper { * @returns Record with event name + start/end date */ getEventDetails(): ISeasonalEvent[]; + /** + * Is detection of seasonal events enabled (halloween / christmas) + * @returns true if seasonal events should be checked for + */ + isAutomaticEventDetectionEnabled(): boolean; + /** + * Get a dictionary of gear changes to apply to bots for a specific event e.g. Christmas/Halloween + * @param eventName Name of event to get gear changes for + * @returns bots with equipment changes + */ + getEventBotGear(eventName: string): Record>>; } diff --git a/Faupi-MunitionsExpert/server/types/helpers/HideoutHelper.d.ts b/Faupi-MunitionsExpert/server/types/helpers/HideoutHelper.d.ts index 5f7e3b7..9d51fed 100644 --- a/Faupi-MunitionsExpert/server/types/helpers/HideoutHelper.d.ts +++ b/Faupi-MunitionsExpert/server/types/helpers/HideoutHelper.d.ts @@ -11,6 +11,7 @@ import { ILogger } from "../models/spt/utils/ILogger"; import { EventOutputHolder } from "../routers/EventOutputHolder"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "../services/LocalisationService"; import { PlayerService } from "../services/PlayerService"; import { HashUtil } from "../utils/HashUtil"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; @@ -29,13 +30,14 @@ export declare class HideoutHelper { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected playerService: PlayerService; + protected localisationService: LocalisationService; protected configServer: ConfigServer; static bitcoinFarm: string; static waterCollector: string; static bitcoin: string; static expeditionaryFuelTank: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, playerService: PlayerService, configServer: ConfigServer); + constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, playerService: PlayerService, localisationService: LocalisationService, configServer: ConfigServer); registerProduction(pmcData: IPmcData, body: IHideoutSingleProductionStartRequestData | IHideoutContinousProductionStartRequestData, sessionID: string): IItemEventRouterResponse; /** * This convinience function intialies new Production Object diff --git a/Faupi-MunitionsExpert/server/types/helpers/InventoryHelper.d.ts b/Faupi-MunitionsExpert/server/types/helpers/InventoryHelper.d.ts index b8e5c9d..6419f93 100644 --- a/Faupi-MunitionsExpert/server/types/helpers/InventoryHelper.d.ts +++ b/Faupi-MunitionsExpert/server/types/helpers/InventoryHelper.d.ts @@ -5,11 +5,12 @@ import { IInventoryMergeRequestData } from "../models/eft/inventory/IInventoryMe import { IInventoryMoveRequestData } from "../models/eft/inventory/IInventoryMoveRequestData"; import { IInventorySplitRequestData } from "../models/eft/inventory/IInventorySplitRequestData"; import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse"; -import { IInventoryConfig } from "../models/spt/config/IInventoryConfig"; +import { IInventoryConfig, RewardDetails } from "../models/spt/config/IInventoryConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { FenceService } from "../services/FenceService"; +import { LocalisationService } from "../services/LocalisationService"; import { HashUtil } from "../utils/HashUtil"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; import { JsonUtil } from "../utils/JsonUtil"; @@ -38,9 +39,10 @@ export declare class InventoryHelper { protected itemHelper: ItemHelper; protected containerHelper: ContainerHelper; protected profileHelper: ProfileHelper; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected inventoryConfig: IInventoryConfig; - constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, httpResponse: HttpResponseUtil, fenceService: FenceService, databaseServer: DatabaseServer, paymentHelper: PaymentHelper, traderAssortHelper: TraderAssortHelper, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, containerHelper: ContainerHelper, profileHelper: ProfileHelper, configServer: ConfigServer); + constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, httpResponse: HttpResponseUtil, fenceService: FenceService, databaseServer: DatabaseServer, paymentHelper: PaymentHelper, traderAssortHelper: TraderAssortHelper, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, containerHelper: ContainerHelper, profileHelper: ProfileHelper, localisationService: LocalisationService, configServer: ConfigServer); addItem(pmcData: IPmcData, body: IAddItemRequestData, output: IItemEventRouterResponse, sessionID: string, callback: any, foundInRaid?: boolean, addUpd?: any): IItemEventRouterResponse; removeItem(pmcData: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse; removeItemByCount(pmcData: IPmcData, itemId: string, count: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse; @@ -76,6 +78,12 @@ export declare class InventoryHelper { * Internal helper function to handle cartridges in inventory if any of them exist. */ protected handleCartridges(items: Item[], body: IInventoryMoveRequestData): void; + /** + * Get details for how a random loot container should be handled, max rewards, possible reward tpls + * @param itemTpl Container being opened + * @returns Reward details + */ + getRandomLootContainerRewardDetails(itemTpl: string): RewardDetails; } declare namespace InventoryHelper { interface InventoryItemHash { diff --git a/Faupi-MunitionsExpert/server/types/helpers/ItemHelper.d.ts b/Faupi-MunitionsExpert/server/types/helpers/ItemHelper.d.ts index 0effaf2..fc88a46 100644 --- a/Faupi-MunitionsExpert/server/types/helpers/ItemHelper.d.ts +++ b/Faupi-MunitionsExpert/server/types/helpers/ItemHelper.d.ts @@ -5,6 +5,7 @@ import { IStaticAmmoDetails } from "../models/eft/common/tables/ILootBase"; import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem"; import { ILogger } from "../models/spt/utils/ILogger"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocaleService } from "../services/LocaleService"; import { HashUtil } from "../utils/HashUtil"; import { JsonUtil } from "../utils/JsonUtil"; import { MathUtil } from "../utils/MathUtil"; @@ -18,7 +19,8 @@ declare class ItemHelper { protected objectId: ObjectId; protected mathUtil: MathUtil; protected databaseServer: DatabaseServer; - constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, randomUtil: RandomUtil, objectId: ObjectId, mathUtil: MathUtil, databaseServer: DatabaseServer); + protected localeService: LocaleService; + constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, randomUtil: RandomUtil, objectId: ObjectId, mathUtil: MathUtil, databaseServer: DatabaseServer, localeService: LocaleService); /** * Checks if an id is a valid item. Valid meaning that it's an item that be stored in stash * @param {string} tpl the template id / tpl @@ -212,6 +214,12 @@ declare class ItemHelper { * @returns size of stack */ getItemStackSize(item: Item): number; + /** + * Get the name of an item from the locale file using the item tpl + * @param itemTpl Tpl of item to get name of + * @returns Name of item + */ + getItemName(itemTpl: string): string; } declare namespace ItemHelper { interface ItemSize { diff --git a/Faupi-MunitionsExpert/server/types/helpers/QuestHelper.d.ts b/Faupi-MunitionsExpert/server/types/helpers/QuestHelper.d.ts index a6b4892..edbd2e1 100644 --- a/Faupi-MunitionsExpert/server/types/helpers/QuestHelper.d.ts +++ b/Faupi-MunitionsExpert/server/types/helpers/QuestHelper.d.ts @@ -50,6 +50,12 @@ export declare class QuestHelper { * @returns true if player level is greater than or equal to quest */ doesPlayerLevelFulfilCondition(playerLevel: number, condition: AvailableForConditions): boolean; + /** + * Get the quests found in both arrays (inner join) + * @param before Array of qeusts #1 + * @param after Array of quests #2 + * @returns Reduction of cartesian product between two quest arrays + */ getDeltaQuests(before: IQuest[], after: IQuest[]): IQuest[]; /** * Increase skill points of a skill on player profile @@ -66,38 +72,85 @@ export declare class QuestHelper { * quest list in question. */ dumpQuests(quests: any): void; - loyaltyRequirementCheck(loyaltyRequirementProperties: AvailableForProps, profile: IPmcData): boolean; - protected processReward(reward: Reward): any[]; + /** + * Check if trader has sufficient loyalty to fullfill quest requirement + * @param questProperties Quest props + * @param profile Player profile + * @returns true if loyalty is high enough to fulfil quest requirement + */ + traderStandingRequirementCheck(questProperties: AvailableForProps, profile: IPmcData): boolean; + protected processReward(reward: Reward): Reward[]; + /** + * Gets a flat list of reward items for the given quest at a specific state (e.g. Fail/Success) + * @param quest quest to get rewards for + * @param state Quest status that holds the items (Started, Success, Fail) + * @returns array of items with the correct maxStack + */ getQuestRewardItems(quest: IQuest, state: QuestStatus): Reward[]; /** - * Add quest with new state value to pmc profile + * Update player profile with quest status (e.g. Fail/Success) * @param pmcData profile to add quest to * @param newState state the new quest should be in when added * @param acceptedQuest Details of quest being added */ addQuestToPMCData(pmcData: IPmcData, newState: QuestStatus, acceptedQuest: IAcceptQuestRequestData): void; - acceptedUnlocked(acceptedQuestId: string, sessionID: string): IQuest[]; - failedUnlocked(failedQuestId: string, sessionID: string): IQuest[]; - applyMoneyBoost(quest: IQuest, moneyBoost: number): IQuest; - changeItemStack(pmcData: IPmcData, id: string, value: number, sessionID: string, output: any): void; /** - * Get List of All Quests as an array + * TODO: what is going on here + * @param acceptedQuestId Quest to add to profile + * @param sessionID Session id + * @returns Array of quests in profile + quest passed in as param + */ + acceptedUnlocked(acceptedQuestId: string, sessionID: string): IQuest[]; + /** + * TODO: what is going on here + * @param failedQuestId + * @param sessionID Session id + * @returns + */ + failedUnlocked(failedQuestId: string, sessionID: string): IQuest[]; + /** + * Adjust quest money rewards by passed in multipler + * @param quest Quest to multiple money rewards + * @param multipler Value to adjust money rewards by + * @returns Updated quest + */ + applyMoneyBoost(quest: IQuest, multipler: number): IQuest; + /** + * Sets the item stack to new value, or delete the item if value <= 0 + * // TODO maybe merge this function and the one from customization + * @param pmcData Profile + * @param itemId id of item to adjust stack size of + * @param newStackSize Stack size to adjust to + * @param sessionID Session id + * @param output ItemEvent router response + */ + changeItemStack(pmcData: IPmcData, itemId: string, newStackSize: number, sessionID: string, output: IItemEventRouterResponse): void; + /** + * Get List of All Quests from db + * NOT CLONED * @returns Array of IQuest objects */ - questValues(): IQuest[]; + getQuestsFromDb(): IQuest[]; /** - * Reest AvailableForStart conditions for quests - * @param quests queststo clean + * Get quests, strip all requirement conditions except level + * @param quests quests to process * @returns quest array without conditions */ - protected cleanQuestList(quests: IQuest[]): IQuest[]; + protected getQuestsWithOnlyLevelRequirementStartCondition(quests: IQuest[]): IQuest[]; /** - * Reset AvailableForStart conditions on a quest + * Remove all quest conditions except for level requirement * @param quest quest to clean * @returns reset IQuest object */ - cleanQuestConditions(quest: IQuest): IQuest; - failQuest(pmcData: IPmcData, body: any, sessionID: string): any; + getQuestWithOnlyLevelRequirementStartCondition(quest: IQuest): IQuest; + /** + * Fail a quest in a player profile + * @param pmcData Profile + * @param failRequest fail quest request data + * @param sessionID Session id + * @returns Item event router response + */ + failQuest(pmcData: IPmcData, failRequest: any, sessionID: string): IItemEventRouterResponse; /** * Get quest by id from database * @param questId questid to look for @@ -105,7 +158,12 @@ export declare class QuestHelper { * @returns IQuest object */ getQuestFromDb(questId: string, pmcData: IPmcData): IQuest; - getQuestLocaleIdFromDb(messageId: string): string; + /** + * Get the locale Id from locale db for a quest message + * @param questMessageId Quest mesage id to look up + * @returns Locale Id from locale db + */ + getQuestLocaleIdFromDb(questMessageId: string): string; /** * Alter a quests state + Add a record to tis status timers object * @param pmcData Profile to update @@ -128,5 +186,10 @@ export declare class QuestHelper { * @returns bonus in percent */ protected getIntelCenterRewardBonus(pmcData: IPmcData): number; - getFindItemIdForQuestItem(itemTpl: string): string; + /** + * Find quest with 'findItem' requirement that needs the item tpl be handed in + * @param itemTpl item tpl to look for + * @returns 'FindItem' condition id + */ + getFindItemIdForQuestHandIn(itemTpl: string): string; } diff --git a/Faupi-MunitionsExpert/server/types/helpers/RagfairServerHelper.d.ts b/Faupi-MunitionsExpert/server/types/helpers/RagfairServerHelper.d.ts index a03cdda..ec388d8 100644 --- a/Faupi-MunitionsExpert/server/types/helpers/RagfairServerHelper.d.ts +++ b/Faupi-MunitionsExpert/server/types/helpers/RagfairServerHelper.d.ts @@ -44,10 +44,20 @@ export declare class RagfairServerHelper { isPlayer(userID: string): boolean; returnItems(sessionID: string, items: any[]): void; calculateDynamicStackCount(tplId: string, isWeaponPreset: boolean): number; + /** + * Choose a currency at random with bias + * @returns currency tpl + */ getDynamicOfferCurrency(): string; getMemberType(userID: string): MemberCategory; getNickname(userID: string): string; getPresetItems(item: any): Item[]; getPresetItemsByTpl(item: Item): Item[]; + /** + * Generate new unique ids for the children while preserving hierarchy + * @param item base item + * @param preset + * @returns Item array with new IDs + */ reparentPresets(item: Item, preset: Item[]): Item[]; } diff --git a/Faupi-MunitionsExpert/server/types/helpers/RagfairSortHelper.d.ts b/Faupi-MunitionsExpert/server/types/helpers/RagfairSortHelper.d.ts index 28d1d38..4669ce6 100644 --- a/Faupi-MunitionsExpert/server/types/helpers/RagfairSortHelper.d.ts +++ b/Faupi-MunitionsExpert/server/types/helpers/RagfairSortHelper.d.ts @@ -18,7 +18,7 @@ export declare class RagfairSortHelper { protected sortOffersByRating(a: IRagfairOffer, b: IRagfairOffer): number; protected sortOffersByName(a: IRagfairOffer, b: IRagfairOffer): number; /** - * Order two offers by price value + * Order two offers by rouble price value * @param a Offer a * @param b Offer b * @returns diff --git a/Faupi-MunitionsExpert/server/types/loaders/PreAkiModLoader.d.ts b/Faupi-MunitionsExpert/server/types/loaders/PreAkiModLoader.d.ts index 7a687a5..f486a28 100644 --- a/Faupi-MunitionsExpert/server/types/loaders/PreAkiModLoader.d.ts +++ b/Faupi-MunitionsExpert/server/types/loaders/PreAkiModLoader.d.ts @@ -1,29 +1,31 @@ import { DependencyContainer } from "tsyringe"; +import { IPostAkiLoadMod } from "../models/external/IPostAkiLoadMod"; +import { IPostDBLoadMod } from "../models/external/IPostDBLoadMod"; +import { IPreAkiLoadMod } from "../models/external/IPreAkiLoadMod"; import { ICoreConfig } from "../models/spt/config/ICoreConfig"; import { ModLoader } from "../models/spt/mod/IMod"; import { IModLoader } from "../models/spt/mod/IModLoader"; import { IPackageJsonData } from "../models/spt/mod/IPackageJsonData"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; +import { LocalisationService } from "../services/LocalisationService"; import { ModCompilerService } from "../services/ModCompilerService"; import { JsonUtil } from "../utils/JsonUtil"; import { VFS } from "../utils/VFS"; import { BundleLoader } from "./BundleLoader"; -import { IPostAkiLoadMod } from "../models/external/IPostAkiLoadMod"; -import { IPreAkiLoadMod } from "../models/external/IPreAkiLoadMod"; -import { IPostDBLoadMod } from "../models/external/IPostDBLoadMod"; export declare class PreAkiModLoader implements IModLoader { protected logger: ILogger; protected vfs: VFS; protected jsonUtil: JsonUtil; protected modCompilerService: ModCompilerService; protected bundleLoader: BundleLoader; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected static container: DependencyContainer; protected readonly basepath = "user/mods/"; protected imported: Record; protected akiConfig: ICoreConfig; - constructor(logger: ILogger, vfs: VFS, jsonUtil: JsonUtil, modCompilerService: ModCompilerService, bundleLoader: BundleLoader, configServer: ConfigServer); + constructor(logger: ILogger, vfs: VFS, jsonUtil: JsonUtil, modCompilerService: ModCompilerService, bundleLoader: BundleLoader, localisationService: LocalisationService, configServer: ConfigServer); load(container: DependencyContainer): Promise; getBundles(local: boolean): string; getBundle(key: string, local: boolean): void; diff --git a/Faupi-MunitionsExpert/server/types/models/eft/bot/IGenerateBotsRequestData.d.ts b/Faupi-MunitionsExpert/server/types/models/eft/bot/IGenerateBotsRequestData.d.ts index c49cef7..f1f7013 100644 --- a/Faupi-MunitionsExpert/server/types/models/eft/bot/IGenerateBotsRequestData.d.ts +++ b/Faupi-MunitionsExpert/server/types/models/eft/bot/IGenerateBotsRequestData.d.ts @@ -2,6 +2,7 @@ export interface IGenerateBotsRequestData { conditions: Condition[]; } export interface Condition { + /** e.g. assault/pmcBot/bossKilla */ Role: string; Limit: number; Difficulty: string; diff --git a/Faupi-MunitionsExpert/server/types/models/eft/bot/IRandomisedBotLevelResult.d.ts b/Faupi-MunitionsExpert/server/types/models/eft/bot/IRandomisedBotLevelResult.d.ts new file mode 100644 index 0000000..75bd936 --- /dev/null +++ b/Faupi-MunitionsExpert/server/types/models/eft/bot/IRandomisedBotLevelResult.d.ts @@ -0,0 +1,4 @@ +export interface IRandomisedBotLevelResult { + level: number; + exp: number; +} diff --git a/Faupi-MunitionsExpert/server/types/models/eft/common/IGlobals.d.ts b/Faupi-MunitionsExpert/server/types/models/eft/common/IGlobals.d.ts index 81e2023..b53f106 100644 --- a/Faupi-MunitionsExpert/server/types/models/eft/common/IGlobals.d.ts +++ b/Faupi-MunitionsExpert/server/types/models/eft/common/IGlobals.d.ts @@ -591,6 +591,7 @@ export interface HealPrice { export interface ProfileHealthSettings { BodyPartsSettings: BodyPartsSettings; HealthFactorsSettings: HealthFactorsSettings; + DefaultStimulatorBuff: string; } export interface BodyPartsSettings { Head: BodyPartsSetting; diff --git a/Faupi-MunitionsExpert/server/types/models/eft/common/tables/IBotType.d.ts b/Faupi-MunitionsExpert/server/types/models/eft/common/tables/IBotType.d.ts index c1fe579..55b4bd9 100644 --- a/Faupi-MunitionsExpert/server/types/models/eft/common/tables/IBotType.d.ts +++ b/Faupi-MunitionsExpert/server/types/models/eft/common/tables/IBotType.d.ts @@ -13,8 +13,8 @@ export interface IBotType { skills: Skills; } export interface Appearance { - body: string[]; - feet: string[]; + body: Record; + feet: Record; hands: string[]; head: string[]; voice: string[]; diff --git a/Faupi-MunitionsExpert/server/types/models/eft/common/tables/ITemplateItem.d.ts b/Faupi-MunitionsExpert/server/types/models/eft/common/tables/ITemplateItem.d.ts index 8569e61..0fa7e18 100644 --- a/Faupi-MunitionsExpert/server/types/models/eft/common/tables/ITemplateItem.d.ts +++ b/Faupi-MunitionsExpert/server/types/models/eft/common/tables/ITemplateItem.d.ts @@ -254,7 +254,7 @@ export interface Props { foodUseTime?: number; foodEffectType?: string; StimulatorBuffs?: string; - effects_health?: any; + effects_health?: IHealthEffect[] | Record>; effects_damage?: any; MaximumNumberOfUsage?: number; knifeHitDelay?: number; @@ -366,6 +366,10 @@ export interface Props { MinTimeToContactExplode?: number; ExplosionEffectType?: string; } +export interface IHealthEffect { + type: string; + value: number; +} export interface Prefab { path: string; rcid: string; diff --git a/Faupi-MunitionsExpert/server/types/models/eft/customization/IGetSuitsResponse.d.ts b/Faupi-MunitionsExpert/server/types/models/eft/customization/IGetSuitsResponse.d.ts new file mode 100644 index 0000000..cbb909d --- /dev/null +++ b/Faupi-MunitionsExpert/server/types/models/eft/customization/IGetSuitsResponse.d.ts @@ -0,0 +1,4 @@ +export interface IGetSuitsResponse { + _id: string; + suites: string[]; +} diff --git a/Faupi-MunitionsExpert/server/types/models/eft/game/IGameKeepAliveResponse.d.ts b/Faupi-MunitionsExpert/server/types/models/eft/game/IGameKeepAliveResponse.d.ts new file mode 100644 index 0000000..170ce6a --- /dev/null +++ b/Faupi-MunitionsExpert/server/types/models/eft/game/IGameKeepAliveResponse.d.ts @@ -0,0 +1,4 @@ +export interface IGameKeepAliveResponse { + msg: string; + utc_time: number; +} diff --git a/Faupi-MunitionsExpert/server/types/models/eft/game/IGameLogoutResponseData.d.ts b/Faupi-MunitionsExpert/server/types/models/eft/game/IGameLogoutResponseData.d.ts new file mode 100644 index 0000000..0f52050 --- /dev/null +++ b/Faupi-MunitionsExpert/server/types/models/eft/game/IGameLogoutResponseData.d.ts @@ -0,0 +1,3 @@ +export interface IGameLogoutResponseData { + status: string; +} diff --git a/Faupi-MunitionsExpert/server/types/models/eft/game/IGameStartResponse.d.ts b/Faupi-MunitionsExpert/server/types/models/eft/game/IGameStartResponse.d.ts new file mode 100644 index 0000000..9f0ab6d --- /dev/null +++ b/Faupi-MunitionsExpert/server/types/models/eft/game/IGameStartResponse.d.ts @@ -0,0 +1,3 @@ +export interface IGameStartResponse { + utc_time: number; +} diff --git a/Faupi-MunitionsExpert/server/types/models/eft/inventory/IOpenRandomLootContainerRequestData.d.ts b/Faupi-MunitionsExpert/server/types/models/eft/inventory/IOpenRandomLootContainerRequestData.d.ts new file mode 100644 index 0000000..3c45124 --- /dev/null +++ b/Faupi-MunitionsExpert/server/types/models/eft/inventory/IOpenRandomLootContainerRequestData.d.ts @@ -0,0 +1,11 @@ +import { IInventoryBaseActionRequestData } from "./IInventoryBaseActionRequestData"; +export interface IOpenRandomLootContainerRequestData extends IInventoryBaseActionRequestData { + Action: "OpenRandomLootContainer"; + /** Container item opened */ + item: string; + to: To[]; +} +export interface To { + /** Player character (pmc/scav) id items will be sent to */ + id: string; +} diff --git a/Faupi-MunitionsExpert/server/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/Faupi-MunitionsExpert/server/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index 4841cfd..60ab284 100644 --- a/Faupi-MunitionsExpert/server/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/Faupi-MunitionsExpert/server/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -10,8 +10,9 @@ export interface IItemEventRouterBase { export declare type TProfileChanges = Record; export interface Warning { index: number; - err: string; errmsg: string; + code?: string; + data?: any; } export interface ProfileChange { _id: string; diff --git a/Faupi-MunitionsExpert/server/types/models/eft/match/IStartOffineRaidRequestData.d.ts b/Faupi-MunitionsExpert/server/types/models/eft/match/IStartOffineRaidRequestData.d.ts index af0625e..1983728 100644 --- a/Faupi-MunitionsExpert/server/types/models/eft/match/IStartOffineRaidRequestData.d.ts +++ b/Faupi-MunitionsExpert/server/types/models/eft/match/IStartOffineRaidRequestData.d.ts @@ -2,8 +2,10 @@ import { BotAmount } from "../../enums/BotAmount"; import { BotDifficulty } from "../../enums/BotDifficulty"; export interface IStartOfflineRaidRequestData { locationName: string; + /** Current time, not in-game time */ startTime: number; - dateTime: string; + /** CURR = am, past = pm */ + dateTime: "CURR" | "PAST"; gameSettings: GameSettings; } export interface GameSettings { diff --git a/Faupi-MunitionsExpert/server/types/models/eft/notifier/ISelectProfileResponse.d.ts b/Faupi-MunitionsExpert/server/types/models/eft/notifier/ISelectProfileResponse.d.ts new file mode 100644 index 0000000..ecb668a --- /dev/null +++ b/Faupi-MunitionsExpert/server/types/models/eft/notifier/ISelectProfileResponse.d.ts @@ -0,0 +1,6 @@ +import { INotifierChannel } from "./INotifier"; +export interface ISelectProfileResponse { + status: string; + notifier: INotifierChannel; + notifierServer: string; +} diff --git a/Faupi-MunitionsExpert/server/types/models/eft/ragfair/IRagfairOffer.d.ts b/Faupi-MunitionsExpert/server/types/models/eft/ragfair/IRagfairOffer.d.ts index 3251a37..792ec7d 100644 --- a/Faupi-MunitionsExpert/server/types/models/eft/ragfair/IRagfairOffer.d.ts +++ b/Faupi-MunitionsExpert/server/types/models/eft/ragfair/IRagfairOffer.d.ts @@ -7,19 +7,19 @@ export interface IRagfairOffer { requirements: OfferRequirement[]; root: string; intId: number; + /** Handbook price */ itemsCost: number; + /** Rouble price */ requirementsCost: number; - sptRequirementsCostRouble: number; startTime: number; endTime: number; sellInOnePiece: boolean; - name?: string; - shortName?: string; loyaltyLevel: number; buyRestrictionMax?: number; buyRestrictionCurrent?: number; locked: boolean; unlimitedCount: boolean; + /** Rouble price */ summaryCost: number; user: IRagfairOfferUser; notAvailable: boolean; @@ -33,11 +33,11 @@ export interface OfferRequirement { } export interface IRagfairOfferUser { id: string; - nickname: string; - rating: number; + nickname?: string; + rating?: number; memberType: MemberCategory; - avatar: string; - isRatingGrowing: boolean; + avatar?: string; + isRatingGrowing?: boolean; } export interface SellResult { sellTime: number; diff --git a/Faupi-MunitionsExpert/server/types/models/eft/weather/IWeatherData.d.ts b/Faupi-MunitionsExpert/server/types/models/eft/weather/IWeatherData.d.ts index ecc96ce..1f5d5b5 100644 --- a/Faupi-MunitionsExpert/server/types/models/eft/weather/IWeatherData.d.ts +++ b/Faupi-MunitionsExpert/server/types/models/eft/weather/IWeatherData.d.ts @@ -1,17 +1,18 @@ +import { WindDirection } from "../../../models/enums/WindDirection"; export interface IWeatherData { acceleration: number; time: string; date: string; - weather: IWeather; + weather?: IWeather; } export interface IWeather { pressure: number; temp: number; - fog: string; + fog: number; rain_intensity: number; - rain: any; + rain: number; wind_gustiness: number; - wind_direction: any; + wind_direction: WindDirection; wind_speed: number; cloud: number; time: string; diff --git a/Faupi-MunitionsExpert/server/types/models/enums/BackendErrorCodes.d.ts b/Faupi-MunitionsExpert/server/types/models/enums/BackendErrorCodes.d.ts new file mode 100644 index 0000000..6614b75 --- /dev/null +++ b/Faupi-MunitionsExpert/server/types/models/enums/BackendErrorCodes.d.ts @@ -0,0 +1,67 @@ +export declare enum BackendErrorCodes { + NONE = 0, + UNKNOWN_ERROR = 200, + NOT_AUTHORIZED = 201, + NEED_AUTHORIZATION_CODE = 209, + WRONG_AUTHORIZATION_CODE = 211, + NEED_CAPTCHA = 214, + NO_NEED_CAPTCHA = 215, + CAPTCHA_FAILED = 218, + CAPTCHA_BRUTE_FORCED = 219, + NO_ROOM_IN_STASH = 223, + NICKNAME_NOT_UNIQUE = 225, + NICKNAME_NOT_VALID = 226, + UNSUPPORTED_CLIENT_VERSION = 232, + REPORT_NOT_ALLOWED = 238, + NICKNAME_IS_ABUSIVE = 241, + NICKNAME_CHANGE_TIMEOUT = 242, + NOT_MODIFIED = 304, + HTTP_BAD_REQUEST = 400, + HTTP_NOT_AUTHORIZED = 401, + HTTP_FORBIDDEN = 403, + HTTP_NOT_FOUND = 404, + HTTP_METHOD_NOT_ALLOWED = 405, + UNKNOWN_TRADING_ERROR = 500, + HTTPNOTIMPLEMENTED = 501, + HTTPBADGATEWAY = 502, + HTTPSERVICEUNAVAILABLE = 503, + HTTPGATEWAYTIMEOUT = 504, + TRADEROUTOFMONEY = 505, + HTTPVARIANTALSONEGOTIATES = 506, + PRICECHANGED = 509, + TRADERDISABLED = 512, + ITEMHASBEENSOLD = 513, + NOTENOUGHSPACEFORMONEY = 518, + HTTPINVALIDSSLCERTIFICATE = 526, + UNKNOWNRAGFAIRERROR = 550, + UNKNOWNRAGFAIRERROR2 = 551, + UNKNOWNMATCHMAKERERROR = 600, + SESSIONPARAMETERSERROR = 601, + SESSIONLOST = 602, + SERVERNOTREGISTERED = 604, + UNKNOWNQUESTERROR = 700, + QUESTBADPARAM = 702, + QUESTNOTFOUND = 703, + QUESTISUNAVAILABLE = 704, + NOFREESPACEFORREWARDS = 705, + WRONGQUESTSTATUS = 706, + CANTCOMPLETEQUEST = 707, + UNKNOWNMAILERROR = 900, + TOOMANYFRIENDREQUESTS = 925, + UNKNOWNSCRIPTEXECUTIONERROR = 1000, + UNKNOWNREPAIRINGERROR = 1200, + UNKNOWNINSURANCEERROR = 1300, + UNKNOWNCURRENCYEXCHANGEERROR = 1400, + OFFERNOTFOUND = 1503, + NOTENOUGHSPACE = 1505, + OFFEROUTOFSTOCK = 1506, + OFFERSOLD = 1507, + RAGFAIRUNAVAILABLE = 1511, + BANNEDERRORCODE = 1513, + INSUFFICIENTNUMBERINSTOCK = 1516, + TOOMANYITEMSTOSELL = 1517, + EXAMINATIONFAILED = 22001, + ITEMALREADYEXAMINED = 22002, + UNKNOWNNGINXERROR = 9000, + PARSERESPONSEERROR = 9001 +} diff --git a/Faupi-MunitionsExpert/server/types/models/enums/HideoutEventActions.d.ts b/Faupi-MunitionsExpert/server/types/models/enums/HideoutEventActions.d.ts new file mode 100644 index 0000000..e441477 --- /dev/null +++ b/Faupi-MunitionsExpert/server/types/models/enums/HideoutEventActions.d.ts @@ -0,0 +1,11 @@ +export declare enum HideoutEventActions { + HIDEOUT_UPGRADE = "HideoutUpgrade", + HIDEOUT_UPGRADE_COMPLETE = "HideoutUpgradeComplete", + HIDEOUT_PUT_ITEMS_IN_AREA_SLOTS = "HideoutPutItemsInAreaSlots", + HIDEOUT_TAKE_ITEMS_FROM_AREA_SLOTS = "HideoutTakeItemsFromAreaSlots", + HIDEOUT_TOGGLE_AREA = "HideoutToggleArea", + HIDEOUT_SINGLE_PRODUCTION_START = "HideoutSingleProductionStart", + HIDEOUT_SCAV_CASE_PRODUCTION_START = "HideoutScavCaseProductionStart", + HIDEOUT_CONTINUOUS_PRODUCTION_START = "HideoutContinuousProductionStart", + HIDEOUT_TAKE_PRODUCTION = "HideoutTakeProduction" +} diff --git a/Faupi-MunitionsExpert/server/types/models/enums/ItemEventActions.d.ts b/Faupi-MunitionsExpert/server/types/models/enums/ItemEventActions.d.ts new file mode 100644 index 0000000..0e65453 --- /dev/null +++ b/Faupi-MunitionsExpert/server/types/models/enums/ItemEventActions.d.ts @@ -0,0 +1,19 @@ +export declare enum ItemEventActions { + MOVE = "Move", + REMOVE = "Remove", + SPLIT = "Split", + MERGE = "Merge", + TRANSFER = "Transfer", + SWAP = "Swap", + FOLD = "Fold", + TOGGLE = "Toggle", + TAG = "Tag", + BIND = "Bind", + EXAMINE = "Examine", + READ_ENCYCLOPEDIA = "ReadEncyclopedia", + APPLY_INVENTORY_CHANGES = "ApplyInventoryChanges", + CREATE_MAP_MARKER = "CreateMapMarker", + DELETE_MAP_MARKER = "DeleteMapMarker", + EDIT_MAP_MARKER = "EditMapMarker", + OPEN_RANDOM_LOOT_CONTAINER = "OpenRandomLootContainer" +} diff --git a/Faupi-MunitionsExpert/server/types/models/enums/WeatherType.d.ts b/Faupi-MunitionsExpert/server/types/models/enums/WeatherType.d.ts new file mode 100644 index 0000000..d31fefe --- /dev/null +++ b/Faupi-MunitionsExpert/server/types/models/enums/WeatherType.d.ts @@ -0,0 +1,19 @@ +export declare enum WeatherType { + CLEAR_DAY = 1, + CLEAR_WIND = 2, + CLEAR_NIGHT = 3, + PARTLY_CLOUD_DAY = 4, + PARTLY_CLOUD_NIGHT = 5, + CLEAR_FOG_DAY = 6, + CLEAR_FOG_NIGHT = 7, + CLOUDFOG = 8, + FOG = 9, + MOSTLY_CLOUD = 10, + LIGHT_RAIN = 11, + RAIN = 12, + CLOUD_WIND = 13, + CLOUD_WIND_RAIN = 14, + FULL_CLOUD = 15, + THUNDER_CLOUD = 16, + NONE = 0 +} diff --git a/Faupi-MunitionsExpert/server/types/models/enums/WildSpawnTypeNumber.d.ts b/Faupi-MunitionsExpert/server/types/models/enums/WildSpawnTypeNumber.d.ts new file mode 100644 index 0000000..ff806fe --- /dev/null +++ b/Faupi-MunitionsExpert/server/types/models/enums/WildSpawnTypeNumber.d.ts @@ -0,0 +1,33 @@ +export declare enum WildSpawnTypeNumber { + ASSAULT = 1, + MARKSMAN = 2, + BOSSTEST = 4, + BOSSBULLY = 8, + FOLLOWERTEST = 16, + FOLLOWERBULLY = 32, + BOSSKILLA = 64, + BOSSKOJANIY = 128, + FOLLOWERKOJANIY = 256, + PMCBOT = 512, + CURSEDASSAULT = 1024, + BOSSGLUHAR = 2048, + FOLLOWERGLUHARASSAULT = 4096, + FOLLOWERGLUHARSECURITY = 8192, + FOLLOWERGLUHARSCOUT = 16384, + FOLLOWERGLUHARSNIPE = 32768, + FOLLOWERSANITAR = 65536, + BOSSSANITAR = 131072, + TEST = 262144, + ASSAULTGROUP = 524288, + SECTANTWARRIOR = 1048576, + SECTANTPRIEST = 2097152, + BOSSTAGILLA = 4194304, + FOLLOWERTAGILLA = 8388608, + EXUSEC = 16777216, + GIFTER = 33554432, + BOSSKNIGHT = 67108864, + FOLLOWERBIGPIPE = 134217728, + FOLLOWERBIRDEYE = 268435456, + SPTUSEC = 536870912, + SPTBEAR = 1073741824 +} diff --git a/Faupi-MunitionsExpert/server/types/models/enums/WindDirection.d.ts b/Faupi-MunitionsExpert/server/types/models/enums/WindDirection.d.ts new file mode 100644 index 0000000..fb30b20 --- /dev/null +++ b/Faupi-MunitionsExpert/server/types/models/enums/WindDirection.d.ts @@ -0,0 +1,10 @@ +export declare enum WindDirection { + EAST = 1, + NORTH = 2, + WEST = 3, + SOUTH = 4, + SE = 5, + SW = 6, + NW = 7, + NE = 8 +} diff --git a/Faupi-MunitionsExpert/server/types/models/spt/bots/BotGenerationDetails.d.ts b/Faupi-MunitionsExpert/server/types/models/spt/bots/BotGenerationDetails.d.ts new file mode 100644 index 0000000..256de03 --- /dev/null +++ b/Faupi-MunitionsExpert/server/types/models/spt/bots/BotGenerationDetails.d.ts @@ -0,0 +1,16 @@ +export interface BotGenerationDetails { + /** Should the bot be generated as a PMC */ + isPmc: boolean; + /** assault/pmcBot etc */ + role: string; + /** Active players current level */ + playerLevel: number; + /** Delta of highest level of bot */ + botRelativeLevelDeltaMax: number; + /** How many to create and store */ + botCountToGenerate: number; + /** Desired difficulty of the bot */ + botDifficulty: string; + /** Will the generated bot be a player scav */ + isPlayerScav: boolean; +} diff --git a/Faupi-MunitionsExpert/server/types/models/spt/config/IBotConfig.d.ts b/Faupi-MunitionsExpert/server/types/models/spt/config/IBotConfig.d.ts index af8ceba..83897db 100644 --- a/Faupi-MunitionsExpert/server/types/models/spt/config/IBotConfig.d.ts +++ b/Faupi-MunitionsExpert/server/types/models/spt/config/IBotConfig.d.ts @@ -27,6 +27,8 @@ export interface IBotConfig extends IBaseConfig { maxBotCap: Record; /** How many stacks of secret ammo should a bot have in its bot secure container */ secureContainerAmmoStackCount: number; + /** Batch generation size when type not available in cache */ + botGenerationBatchSizePerType: number; } export interface PresetBatch { assault: number; @@ -64,10 +66,13 @@ export interface LootNvalue { } export interface EquipmentFilters { weaponModLimits: ModLimits; - randomisedWeaponModSlots?: string[]; - randomisedArmorSlots?: string[]; + faceShieldIsActiveChancePercent?: number; + lightLaserIsActiveChancePercent?: number; + randomisation: RandomisationDetails[]; blacklist: EquipmentFilterDetails[]; whitelist: EquipmentFilterDetails[]; + clothing: WeightingAdjustmentDetails[]; + weightingAdjustments: WeightingAdjustmentDetails[]; } export interface ModLimits { /** How many scopes are allowed on a weapon - hard coded to work with OPTIC_SCOPE, ASSAULT_SCOPE, COLLIMATOR, COMPACT_COLLIMATOR */ @@ -75,8 +80,27 @@ export interface ModLimits { /** How many lasers or lights are allowed on a weapon - hard coded to work with TACTICAL_COMBO, and FLASHLIGHT */ lightLaserLimit?: number; } +export interface RandomisationDetails { + levelRange: MinMax; + randomisedWeaponModSlots?: string[]; + randomisedArmorSlots?: string[]; + /** Equipment chances */ + equipment?: Record; + /** Modc chances */ + mods?: Record; +} export interface EquipmentFilterDetails { levelRange: MinMax; equipment: Record; cartridge: Record; } +export interface WeightingAdjustmentDetails { + levelRange: MinMax; + ammo?: AdjustmentDetails; + equipment?: AdjustmentDetails; + clothing?: AdjustmentDetails; +} +export interface AdjustmentDetails { + add: Record>; + edit: Record>; +} diff --git a/Faupi-MunitionsExpert/server/types/models/spt/config/IInventoryConfig.d.ts b/Faupi-MunitionsExpert/server/types/models/spt/config/IInventoryConfig.d.ts index ffffa41..4642b9b 100644 --- a/Faupi-MunitionsExpert/server/types/models/spt/config/IInventoryConfig.d.ts +++ b/Faupi-MunitionsExpert/server/types/models/spt/config/IInventoryConfig.d.ts @@ -2,4 +2,10 @@ import { IBaseConfig } from "./IBaseConfig"; export interface IInventoryConfig extends IBaseConfig { kind: "aki-inventory"; newItemsMarkedFound: boolean; + randomLootContainers: Record; +} +export interface RewardDetails { + rewardCount: number; + foundInRaid: boolean; + rewardTplPool: Record; } diff --git a/Faupi-MunitionsExpert/server/types/models/spt/config/ILocaleConfig.d.ts b/Faupi-MunitionsExpert/server/types/models/spt/config/ILocaleConfig.d.ts index fe9abf7..0a8955c 100644 --- a/Faupi-MunitionsExpert/server/types/models/spt/config/ILocaleConfig.d.ts +++ b/Faupi-MunitionsExpert/server/types/models/spt/config/ILocaleConfig.d.ts @@ -1,5 +1,10 @@ import { IBaseConfig } from "./IBaseConfig"; export interface ILocaleConfig extends IBaseConfig { kind: "aki-locale"; - desiredLocale: string; + /** e.g. ru/en/cn/fr etc, or 'system', will take computer locale setting */ + gameLocale: string; + /** e.g. ru/en/cn/fr etc, or 'system', will take computer locale setting */ + serverLocale: string; + /** Languages server can be translated into */ + serverSupportedLocales: string[]; } diff --git a/Faupi-MunitionsExpert/server/types/models/spt/config/IPmcConfig.d.ts b/Faupi-MunitionsExpert/server/types/models/spt/config/IPmcConfig.d.ts index 9db2ba1..979122c 100644 --- a/Faupi-MunitionsExpert/server/types/models/spt/config/IPmcConfig.d.ts +++ b/Faupi-MunitionsExpert/server/types/models/spt/config/IPmcConfig.d.ts @@ -6,14 +6,17 @@ export interface IPmcConfig { looseWeaponInBackpackChancePercent: number; looseWeaponInBackpackLootMinMax: MinMax; isUsec: number; + usecType: string; + bearType: string; chanceSameSideIsHostilePercent: number; /** key: location, value: type for usec/bear */ - pmcType: Record; + pmcType: Record>>; maxBackpackLootTotalRub: number; maxPocketLootTotalRub: number; maxVestLootTotalRub: number; convertIntoPmcChance: Record; enemyTypes: string[]; + botRelativeLevelDeltaMax: number; } export interface PmcTypes { usec: string; diff --git a/Faupi-MunitionsExpert/server/types/models/spt/config/IRagfairConfig.d.ts b/Faupi-MunitionsExpert/server/types/models/spt/config/IRagfairConfig.d.ts index c1b8763..6786417 100644 --- a/Faupi-MunitionsExpert/server/types/models/spt/config/IRagfairConfig.d.ts +++ b/Faupi-MunitionsExpert/server/types/models/spt/config/IRagfairConfig.d.ts @@ -28,12 +28,8 @@ export interface Reputation { gain: number; loss: number; } -export declare class OfferAdjustment { - maxPriceDifferenceBelowHandbookPercent: number; - handbookPriceMultipier: number; - priceThreshholdRub: number; -} export interface Dynamic { + barter: Barter; offerAdjustment: OfferAdjustment; expiredOfferThreshold: number; offerItemCount: MinMax; @@ -49,6 +45,20 @@ export interface Dynamic { showAsSingleStack: string[]; blacklist: Blacklist; } +export declare class Barter { + enable: boolean; + chancePercent: number; + itemCountMin: number; + itemCountMax: number; + priceRangeVariancePercent: number; + minRoubleCostToBecomeBarter: number; + itemTypeBlacklist: string[]; +} +export declare class OfferAdjustment { + maxPriceDifferenceBelowHandbookPercent: number; + handbookPriceMultipier: number; + priceThreshholdRub: number; +} export interface Condition { conditionChance: number; min: number; diff --git a/Faupi-MunitionsExpert/server/types/models/spt/config/ISeasonalEventConfig.d.ts b/Faupi-MunitionsExpert/server/types/models/spt/config/ISeasonalEventConfig.d.ts index bc60618..e410925 100644 --- a/Faupi-MunitionsExpert/server/types/models/spt/config/ISeasonalEventConfig.d.ts +++ b/Faupi-MunitionsExpert/server/types/models/spt/config/ISeasonalEventConfig.d.ts @@ -1,6 +1,9 @@ import { IBaseConfig } from "./IBaseConfig"; export interface ISeasonalEventConfig extends IBaseConfig { kind: "aki-seasonalevents"; + enableSeasonalEventDetection: boolean; + /** event / botType / equipSlot / itemid */ + eventGear: Record>>>; events: ISeasonalEvent[]; } export interface ISeasonalEvent { diff --git a/Faupi-MunitionsExpert/server/types/models/spt/config/IWeatherConfig.d.ts b/Faupi-MunitionsExpert/server/types/models/spt/config/IWeatherConfig.d.ts index bbdc43e..41a1c83 100644 --- a/Faupi-MunitionsExpert/server/types/models/spt/config/IWeatherConfig.d.ts +++ b/Faupi-MunitionsExpert/server/types/models/spt/config/IWeatherConfig.d.ts @@ -1,3 +1,4 @@ +import { WindDirection } from "../../../models/enums/WindDirection"; import { MinMax } from "../../common/MinMax"; import { IBaseConfig } from "./IBaseConfig"; export interface IWeatherConfig extends IBaseConfig { @@ -7,12 +8,16 @@ export interface IWeatherConfig extends IBaseConfig { } export interface Weather { clouds: MinMax; - windSpeed: MinMax; - windDirection: MinMax; + windSpeed: WeatherSettings; + windDirection: WeatherSettings; windGustiness: MinMax; - rain: MinMax; + rain: WeatherSettings; rainIntensity: MinMax; - fog: MinMax; + fog: WeatherSettings; temp: MinMax; pressure: MinMax; } +export interface WeatherSettings { + values: T[]; + weights: number[]; +} diff --git a/Faupi-MunitionsExpert/server/types/routers/item_events/HideoutItemEventRouter.d.ts b/Faupi-MunitionsExpert/server/types/routers/item_events/HideoutItemEventRouter.d.ts index e1e98af..44bd1cd 100644 --- a/Faupi-MunitionsExpert/server/types/routers/item_events/HideoutItemEventRouter.d.ts +++ b/Faupi-MunitionsExpert/server/types/routers/item_events/HideoutItemEventRouter.d.ts @@ -1,7 +1,7 @@ -import { IPmcData } from "../../models/eft/common/IPmcData"; -import { IItemEventRouterResponse } from "../../models/eft/itemEvent/IItemEventRouterResponse"; import { HideoutCallbacks } from "../../callbacks/HideoutCallbacks"; import { HandledRoute, ItemEventRouterDefinition } from "../../di/Router"; +import { IPmcData } from "../../models/eft/common/IPmcData"; +import { IItemEventRouterResponse } from "../../models/eft/itemEvent/IItemEventRouterResponse"; export declare class HideoutItemEventRouter extends ItemEventRouterDefinition { protected hideoutCallbacks: HideoutCallbacks; constructor(hideoutCallbacks: HideoutCallbacks); diff --git a/Faupi-MunitionsExpert/server/types/routers/item_events/InventoryItemEventRouter.d.ts b/Faupi-MunitionsExpert/server/types/routers/item_events/InventoryItemEventRouter.d.ts index 2619bb9..953d322 100644 --- a/Faupi-MunitionsExpert/server/types/routers/item_events/InventoryItemEventRouter.d.ts +++ b/Faupi-MunitionsExpert/server/types/routers/item_events/InventoryItemEventRouter.d.ts @@ -1,7 +1,7 @@ -import { IPmcData } from "../../models/eft/common/IPmcData"; -import { IItemEventRouterResponse } from "../../models/eft/itemEvent/IItemEventRouterResponse"; import { InventoryCallbacks } from "../../callbacks/InventoryCallbacks"; import { HandledRoute, ItemEventRouterDefinition } from "../../di/Router"; +import { IPmcData } from "../../models/eft/common/IPmcData"; +import { IItemEventRouterResponse } from "../../models/eft/itemEvent/IItemEventRouterResponse"; export declare class InventoryItemEventRouter extends ItemEventRouterDefinition { protected inventoryCallbacks: InventoryCallbacks; constructor(inventoryCallbacks: InventoryCallbacks); diff --git a/Faupi-MunitionsExpert/server/types/servers/HttpServer.d.ts b/Faupi-MunitionsExpert/server/types/servers/HttpServer.d.ts index bbca8af..80c1d48 100644 --- a/Faupi-MunitionsExpert/server/types/servers/HttpServer.d.ts +++ b/Faupi-MunitionsExpert/server/types/servers/HttpServer.d.ts @@ -4,6 +4,7 @@ import { ApplicationContext } from "../context/ApplicationContext"; import { HttpServerHelper } from "../helpers/HttpServerHelper"; import { IHttpConfig } from "../models/spt/config/IHttpConfig"; import { ILogger } from "../models/spt/utils/ILogger"; +import { LocalisationService } from "../services/LocalisationService"; import { ConfigServer } from "./ConfigServer"; import { DatabaseServer } from "./DatabaseServer"; import { IHttpListener } from "./http/IHttpListener"; @@ -12,11 +13,12 @@ export declare class HttpServer { protected logger: ILogger; protected databaseServer: DatabaseServer; protected httpServerHelper: HttpServerHelper; + protected localisationService: LocalisationService; protected httpListeners: IHttpListener[]; protected configServer: ConfigServer; protected applicationContext: ApplicationContext; protected webSocketServer: WebSocketServer; - constructor(logger: ILogger, databaseServer: DatabaseServer, httpServerHelper: HttpServerHelper, httpListeners: IHttpListener[], configServer: ConfigServer, applicationContext: ApplicationContext, webSocketServer: WebSocketServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, httpServerHelper: HttpServerHelper, localisationService: LocalisationService, httpListeners: IHttpListener[], configServer: ConfigServer, applicationContext: ApplicationContext, webSocketServer: WebSocketServer); protected httpConfig: IHttpConfig; getCookies(req: http.IncomingMessage): any; handleRequest(req: IncomingMessage, resp: ServerResponse): void; diff --git a/Faupi-MunitionsExpert/server/types/servers/SaveServer.d.ts b/Faupi-MunitionsExpert/server/types/servers/SaveServer.d.ts index cb28f49..4dca514 100644 --- a/Faupi-MunitionsExpert/server/types/servers/SaveServer.d.ts +++ b/Faupi-MunitionsExpert/server/types/servers/SaveServer.d.ts @@ -1,20 +1,22 @@ +import { SaveLoadRouter } from "../di/Router"; import { IAkiProfile, Info } from "../models/eft/profile/IAkiProfile"; +import { ILogger } from "../models/spt/utils/ILogger"; +import { LocalisationService } from "../services/LocalisationService"; import { HashUtil } from "../utils/HashUtil"; import { JsonUtil } from "../utils/JsonUtil"; import { VFS } from "../utils/VFS"; -import { SaveLoadRouter } from "../di/Router"; -import { ILogger } from "../models/spt/utils/ILogger"; export declare class SaveServer { protected vfs: VFS; protected saveLoadRouters: SaveLoadRouter[]; protected jsonUtil: JsonUtil; protected hashUtil: HashUtil; + protected localisationService: LocalisationService; protected logger: ILogger; protected profileFilepath: string; protected profiles: {}; protected onSave: {}; protected saveMd5: {}; - constructor(vfs: VFS, saveLoadRouters: SaveLoadRouter[], jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger); + constructor(vfs: VFS, saveLoadRouters: SaveLoadRouter[], jsonUtil: JsonUtil, hashUtil: HashUtil, localisationService: LocalisationService, logger: ILogger); load(): void; save(): void; getProfile(sessionId: string): IAkiProfile; diff --git a/Faupi-MunitionsExpert/server/types/servers/WebSocketServer.d.ts b/Faupi-MunitionsExpert/server/types/servers/WebSocketServer.d.ts index f33d214..5d40e6e 100644 --- a/Faupi-MunitionsExpert/server/types/servers/WebSocketServer.d.ts +++ b/Faupi-MunitionsExpert/server/types/servers/WebSocketServer.d.ts @@ -1,18 +1,20 @@ /// -import { HttpServerHelper } from "../helpers/HttpServerHelper"; -import WebSocket from "ws"; import http, { IncomingMessage } from "http"; -import { ILogger } from "../models/spt/utils/ILogger"; -import { RandomUtil } from "../utils/RandomUtil"; +import WebSocket from "ws"; +import { HttpServerHelper } from "../helpers/HttpServerHelper"; import { INotification } from "../models/eft/notifier/INotifier"; -import { ConfigServer } from "./ConfigServer"; import { IHttpConfig } from "../models/spt/config/IHttpConfig"; +import { ILogger } from "../models/spt/utils/ILogger"; +import { LocalisationService } from "../services/LocalisationService"; +import { RandomUtil } from "../utils/RandomUtil"; +import { ConfigServer } from "./ConfigServer"; export declare class WebSocketServer { protected logger: ILogger; protected randomUtil: RandomUtil; protected configServer: ConfigServer; + protected localisationService: LocalisationService; protected httpServerHelper: HttpServerHelper; - constructor(logger: ILogger, randomUtil: RandomUtil, configServer: ConfigServer, httpServerHelper: HttpServerHelper); + constructor(logger: ILogger, randomUtil: RandomUtil, configServer: ConfigServer, localisationService: LocalisationService, httpServerHelper: HttpServerHelper); protected httpConfig: IHttpConfig; protected defaultNotification: INotification; protected webSockets: Record; diff --git a/Faupi-MunitionsExpert/server/types/servers/http/AkiHttpListener.d.ts b/Faupi-MunitionsExpert/server/types/servers/http/AkiHttpListener.d.ts index 6f78939..acf92aa 100644 --- a/Faupi-MunitionsExpert/server/types/servers/http/AkiHttpListener.d.ts +++ b/Faupi-MunitionsExpert/server/types/servers/http/AkiHttpListener.d.ts @@ -1,22 +1,24 @@ /// /// import { IncomingMessage, ServerResponse } from "http"; -import { IHttpListener } from "./IHttpListener"; import { Serializer } from "../../di/Serializer"; import { ILogger } from "../../models/spt/utils/ILogger"; import { HttpRouter } from "../../routers/HttpRouter"; +import { LocalisationService } from "../../services/LocalisationService"; import { HttpResponseUtil } from "../../utils/HttpResponseUtil"; import { JsonUtil } from "../../utils/JsonUtil"; import { HttpBufferHandler } from "./HttpBufferHandler"; +import { IHttpListener } from "./IHttpListener"; export declare class AkiHttpListener implements IHttpListener { protected httpRouter: HttpRouter; protected serializers: Serializer[]; protected logger: ILogger; protected jsonUtil: JsonUtil; protected httpResponse: HttpResponseUtil; + protected localisationService: LocalisationService; protected httpBufferHandler: HttpBufferHandler; constructor(httpRouter: HttpRouter, // TODO: delay required - serializers: Serializer[], logger: ILogger, jsonUtil: JsonUtil, httpResponse: HttpResponseUtil, httpBufferHandler: HttpBufferHandler); + serializers: Serializer[], logger: ILogger, jsonUtil: JsonUtil, httpResponse: HttpResponseUtil, localisationService: LocalisationService, httpBufferHandler: HttpBufferHandler); canHandle(_: string, req: IncomingMessage): boolean; handle(sessionId: string, req: IncomingMessage, resp: ServerResponse): void; sendResponse(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: Buffer, output: string): void; diff --git a/Faupi-MunitionsExpert/server/types/services/BotEquipmentFilterService.d.ts b/Faupi-MunitionsExpert/server/types/services/BotEquipmentFilterService.d.ts index 632f961..43e64b0 100644 --- a/Faupi-MunitionsExpert/server/types/services/BotEquipmentFilterService.d.ts +++ b/Faupi-MunitionsExpert/server/types/services/BotEquipmentFilterService.d.ts @@ -1,21 +1,29 @@ -import { IBotType } from "../models/eft/common/tables/IBotType"; -import { EquipmentFilters, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig"; +import { BotHelper } from "../helpers/BotHelper"; +import { EquipmentChances, IBotType, ModsChances } from "../models/eft/common/tables/IBotType"; +import { BotGenerationDetails } from "../models/spt/bots/BotGenerationDetails"; +import { AdjustmentDetails, EquipmentFilterDetails, EquipmentFilters, IBotConfig, WeightingAdjustmentDetails } from "../models/spt/config/IBotConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; export declare class BotEquipmentFilterService { protected logger: ILogger; + protected botHelper: BotHelper; protected configServer: ConfigServer; protected botConfig: IBotConfig; - protected botEquipmentFilterlists: Record; - constructor(logger: ILogger, configServer: ConfigServer); + protected botEquipmentConfig: Record; + constructor(logger: ILogger, botHelper: BotHelper, configServer: ConfigServer); /** * Filter a bots data to exclude equipment and cartridges defines in the botConfig * @param baseBotNode bots json data to filter - * @param playerLevel Level of the currently playing player - * @param isPmc Is the bot we're filtering a PMC - * @param role Role of the bot we're filtering + * @param botLevel Level of the bot + * @param botGenerationDetails details on how to generate a bot */ - filterBotEquipment(baseBotNode: IBotType, playerLevel: number, isPmc: boolean, role: string): void; + filterBotEquipment(baseBotNode: IBotType, botLevel: number, botGenerationDetails: BotGenerationDetails): void; + /** + * Iterate over the changes passed in and alter data in baseValues + * @param equipmentChanges Changes to apply + * @param baseValues Values to update + */ + protected adjustChances(equipmentChanges: Record, baseValues: EquipmentChances | ModsChances): void; /** * Get an object that contains equipment and cartridge blacklists for a specified bot type * @param botRole Role of the bot we want the blacklist for @@ -30,6 +38,20 @@ export declare class BotEquipmentFilterService { * @returns EquipmentFilterDetails object */ protected getBotEquipmentWhitelist(botRole: string, playerLevel: number): EquipmentFilterDetails; + /** + * Retreive clothing weighting adjustments from bot.json config + * @param botRole Bot type to get adjustments for + * @param playerLevel level of player + * @returns Weighting adjustments for bots clothing + */ + protected getBotClothingAdjustments(botRole: string, playerLevel: number): WeightingAdjustmentDetails; + /** + * Retreive item weighting adjustments from bot.json config + * @param botRole Bot type to get adjustments for + * @param playerLevel level of player + * @returns Weighting adjustments for bot items + */ + protected getBotWeightingAdjustments(botRole: string, playerLevel: number): WeightingAdjustmentDetails; /** * Filter bot equipment based on blacklist and whitelist from config/bot.json * Prioritises whitelist first, if one is found blacklist is ignored @@ -47,4 +69,10 @@ export declare class BotEquipmentFilterService { * @returns Filtered bot file */ protected filterCartridges(baseBotNode: IBotType, blacklist: EquipmentFilterDetails, whitelist: EquipmentFilterDetails): void; + /** + * Add/Edit weighting changes to bot items using values from config/bot.json/equipment + * @param weightingAdjustments Weighting change to apply to bot + * @param botItemPool Bot item dictionary to adjust + */ + protected adjustWeighting(weightingAdjustments: AdjustmentDetails, botItemPool: Record, showEditWarnings?: boolean): void; } diff --git a/Faupi-MunitionsExpert/server/types/services/BotGenerationCacheService.d.ts b/Faupi-MunitionsExpert/server/types/services/BotGenerationCacheService.d.ts index ba53fec..0be0576 100644 --- a/Faupi-MunitionsExpert/server/types/services/BotGenerationCacheService.d.ts +++ b/Faupi-MunitionsExpert/server/types/services/BotGenerationCacheService.d.ts @@ -8,11 +8,11 @@ export declare class BotGenerationCacheService { protected randomUtil: RandomUtil; protected jsonUtil: JsonUtil; protected botHelper: BotHelper; - protected storedBots: IBotBase[]; + protected storedBots: Map; constructor(logger: ILogger, randomUtil: RandomUtil, jsonUtil: JsonUtil, botHelper: BotHelper); /** * Store array of bots in cache, shuffle results before storage - * @param botsToStore + * @param botsToStore Bots we want to store in the cache */ storeBots(botsToStore: IBotBase[]): void; /** @@ -21,25 +21,7 @@ export declare class BotGenerationCacheService { * @param role role to retreive (assault/bossTagilla etc) * @returns IBotBase object */ - getBot(role: string): IBotBase[]; - /** - * Find a bot by its index from cache - * @param indexOfBotToReturn index to find bot by - * @returns bot profile - */ - protected getBotFromCache(indexOfBotToReturn: number): IBotBase; - /** - * Remove bot profile by index from cache - * @param indexOfBotToReturn Index of bot profile to remove - */ - protected removeBotFromCache(indexOfBotToReturn: number): void; - /** - * Get index of bot profile that matches criteria - * @param role Role of bot wanted - * @param getPmc Requested bot a pmc - * @returns index of found bot, -1 if not found - */ - protected getIndexOfBotToReturn(role: string, getPmc: boolean): number; + getBot(role: string): IBotBase; /** * Remove all cached bot profiles */ @@ -48,5 +30,5 @@ export declare class BotGenerationCacheService { * Does cache have bots * @returns true if empty */ - cacheIsEmpty(): boolean; + cacheHasBotOfRole(role: string): boolean; } diff --git a/Faupi-MunitionsExpert/server/types/services/LocaleService.d.ts b/Faupi-MunitionsExpert/server/types/services/LocaleService.d.ts index 33bea7b..8275b75 100644 --- a/Faupi-MunitionsExpert/server/types/services/LocaleService.d.ts +++ b/Faupi-MunitionsExpert/server/types/services/LocaleService.d.ts @@ -1,14 +1,42 @@ import { ILocaleConfig } from "../models/spt/config/ILocaleConfig"; +import { ILocaleGlobalBase } from "../models/spt/server/ILocaleBase"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; +import { DatabaseServer } from "../servers/DatabaseServer"; +/** + * Handles getting locales from config or users machine + */ export declare class LocaleService { protected logger: ILogger; + protected databaseServer: DatabaseServer; protected configServer: ConfigServer; protected localeConfig: ILocaleConfig; - constructor(logger: ILogger, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, configServer: ConfigServer); /** - * Gets the locale key from the locale.json file + * Get the eft globals db file based on the configured locale in config/locale.json, if not found, fall back to 'en' + * @returns ILocaleGlobalBase + */ + getLocaleDb(): ILocaleGlobalBase; + /** + * Gets the game locale key from the locale.json file, + * if value is 'system' get system locale * @returns locale e.g en/ge/cz/cn */ - getDesiredLocale(): string; + getDesiredGameLocale(): string; + /** + * Gets the game locale key from the locale.json file, + * if value is 'system' get system locale + * @returns locale e.g en/ge/cz/cn + */ + getDesiredServerLocale(): string; + /** + * Get array of languages supported for localisation + * @returns array of locales e.g. en/fr/cn + */ + getServerSupportedLocales(): string[]; + /** + * Get the locale of the computer running the server + * @returns langage part of locale e.g. 'en' part of 'en-US' + */ + protected getPlatformLocale(): string; } diff --git a/Faupi-MunitionsExpert/server/types/services/LocalisationService.d.ts b/Faupi-MunitionsExpert/server/types/services/LocalisationService.d.ts new file mode 100644 index 0000000..519325d --- /dev/null +++ b/Faupi-MunitionsExpert/server/types/services/LocalisationService.d.ts @@ -0,0 +1,21 @@ +import { I18n } from "i18n"; +import { ILocaleConfig } from "../models/spt/config/ILocaleConfig"; +import { ILogger } from "../models/spt/utils/ILogger"; +import { LocaleService } from "./LocaleService"; +/** + * Handles translating server text into different langauges + */ +export declare class LocalisationService { + protected logger: ILogger; + protected localeService: LocaleService; + protected localeConfig: ILocaleConfig; + protected i18n: I18n; + constructor(logger: ILogger, localeService: LocaleService); + /** + * Get a localised value using the passed in key + * @param key Key to loop up locale for + * @param args optional arguments + * @returns Localised string + */ + getText(key: string, args?: any): string; +} diff --git a/Faupi-MunitionsExpert/server/types/services/PaymentService.d.ts b/Faupi-MunitionsExpert/server/types/services/PaymentService.d.ts index a5e538f..c9ce95a 100644 --- a/Faupi-MunitionsExpert/server/types/services/PaymentService.d.ts +++ b/Faupi-MunitionsExpert/server/types/services/PaymentService.d.ts @@ -11,6 +11,7 @@ import { IProcessSellTradeRequestData } from "../models/eft/trade/IProcessSellTr import { ILogger } from "../models/spt/utils/ILogger"; import { DatabaseServer } from "../servers/DatabaseServer"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; +import { LocalisationService } from "./LocalisationService"; export declare class PaymentService { protected logger: ILogger; protected httpResponse: HttpResponseUtil; @@ -19,8 +20,9 @@ export declare class PaymentService { protected traderHelper: TraderHelper; protected itemHelper: ItemHelper; protected inventoryHelper: InventoryHelper; + protected localisationService: LocalisationService; protected paymentHelper: PaymentHelper; - constructor(logger: ILogger, httpResponse: HttpResponseUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, traderHelper: TraderHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, paymentHelper: PaymentHelper); + constructor(logger: ILogger, httpResponse: HttpResponseUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, traderHelper: TraderHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, localisationService: LocalisationService, paymentHelper: PaymentHelper); /** * Take money and insert items into return to server request * @param {Object} pmcData @@ -50,7 +52,7 @@ export declare class PaymentService { * @param pmcData Player profile to find and remove currency from * @param currencyTpl Type of currency to pay * @param amountToPay money value to pay - * @param sessionID Sessino id + * @param sessionID Session id * @param output output object to send to client * @returns IItemEventRouterResponse */ diff --git a/Faupi-MunitionsExpert/server/types/services/PlayerService.d.ts b/Faupi-MunitionsExpert/server/types/services/PlayerService.d.ts index 519b7e5..2f364d5 100644 --- a/Faupi-MunitionsExpert/server/types/services/PlayerService.d.ts +++ b/Faupi-MunitionsExpert/server/types/services/PlayerService.d.ts @@ -2,10 +2,12 @@ import { IPmcData } from "../models/eft/common/IPmcData"; import { IPlayerIncrementSkillLevelRequestData } from "../models/eft/player/IPlayerIncrementSkillLevelRequestData"; import { ILogger } from "../models/spt/utils/ILogger"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "./LocalisationService"; export declare class PlayerService { protected logger: ILogger; + protected localisationService: LocalisationService; protected databaseServer: DatabaseServer; - constructor(logger: ILogger, databaseServer: DatabaseServer); + constructor(logger: ILogger, localisationService: LocalisationService, databaseServer: DatabaseServer); /** * increases the profile skill and updates any output * @param {Object} pmcData diff --git a/Faupi-MunitionsExpert/server/types/services/PmcAiService.d.ts b/Faupi-MunitionsExpert/server/types/services/PmcAiService.d.ts deleted file mode 100644 index 0690f1f..0000000 --- a/Faupi-MunitionsExpert/server/types/services/PmcAiService.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { IBotConfig } from "../models/spt/config/IBotConfig"; -import { ILogger } from "../models/spt/utils/ILogger"; -import { ConfigServer } from "../servers/ConfigServer"; -/** Storing/retreving pmcRoles set at the start of a raid - its done at that point as we know what location the player is heading to */ -export declare class PmcAiService { - protected logger: ILogger; - protected configServer: ConfigServer; - protected botConfig: IBotConfig; - protected usecRole: string; - protected bearRole: string; - constructor(logger: ILogger, configServer: ConfigServer); - /** - * Convert from pmc side (usec/bear) to the side as defined in the bot config (usecType/bearType) - * @param pmcSide eft side (usec/bear) - * @returns pmc side as defined in config - */ - getPmcRole(pmcSide: "usec" | "bear" | string): string; - /** - * Set the roles for pmcs - * @param location map location to look up and use as pmc types - */ - setPmcRolesByLocation(location: string): void; - /** - * Clear the saved role from usec/bear PMCs - */ - clearPmcRoles(): void; -} diff --git a/Faupi-MunitionsExpert/server/types/services/ProfileFixerService.d.ts b/Faupi-MunitionsExpert/server/types/services/ProfileFixerService.d.ts index e772919..86a6af8 100644 --- a/Faupi-MunitionsExpert/server/types/services/ProfileFixerService.d.ts +++ b/Faupi-MunitionsExpert/server/types/services/ProfileFixerService.d.ts @@ -8,12 +8,14 @@ import { HideoutAreas } from "../models/enums/HideoutAreas"; import { ILogger } from "../models/spt/utils/ILogger"; import { DatabaseServer } from "../servers/DatabaseServer"; import { Watermark } from "../utils/Watermark"; +import { LocalisationService } from "./LocalisationService"; export declare class ProfileFixerService { protected logger: ILogger; protected watermark: Watermark; protected hideoutHelper: HideoutHelper; + protected localisationService: LocalisationService; protected databaseServer: DatabaseServer; - constructor(logger: ILogger, watermark: Watermark, hideoutHelper: HideoutHelper, databaseServer: DatabaseServer); + constructor(logger: ILogger, watermark: Watermark, hideoutHelper: HideoutHelper, localisationService: LocalisationService, databaseServer: DatabaseServer); /** * Find issues in the pmc profile data that may cause issues and fix them * @param pmcProfile profile to check and fix diff --git a/Faupi-MunitionsExpert/server/types/services/RagfairOfferService.d.ts b/Faupi-MunitionsExpert/server/types/services/RagfairOfferService.d.ts index a6f6b6d..86c1e52 100644 --- a/Faupi-MunitionsExpert/server/types/services/RagfairOfferService.d.ts +++ b/Faupi-MunitionsExpert/server/types/services/RagfairOfferService.d.ts @@ -11,6 +11,7 @@ import { DatabaseServer } from "../servers/DatabaseServer"; import { SaveServer } from "../servers/SaveServer"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; import { TimeUtil } from "../utils/TimeUtil"; +import { LocalisationService } from "./LocalisationService"; import { RagfairCategoriesService } from "./RagfairCategoriesService"; export declare class RagfairOfferService { protected logger: ILogger; @@ -22,12 +23,14 @@ export declare class RagfairOfferService { protected profileHelper: ProfileHelper; protected eventOutputHolder: EventOutputHolder; protected httpResponse: HttpResponseUtil; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected playerOffersLoaded: boolean; protected expiredOffers: Item[]; - protected offers: IRagfairOffer[]; + /** offerId, offer */ + protected offers: Record; protected ragfairConfig: IRagfairConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, databaseServer: DatabaseServer, saveServer: SaveServer, ragfairServerHelper: RagfairServerHelper, ragfairCategoriesService: RagfairCategoriesService, profileHelper: ProfileHelper, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, databaseServer: DatabaseServer, saveServer: SaveServer, ragfairServerHelper: RagfairServerHelper, ragfairCategoriesService: RagfairCategoriesService, profileHelper: ProfileHelper, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, localisationService: LocalisationService, configServer: ConfigServer); /** * Get all offers * @returns IRagfairOffer array diff --git a/Faupi-MunitionsExpert/server/types/utils/App.d.ts b/Faupi-MunitionsExpert/server/types/utils/App.d.ts index dcc2669..cc8a5af 100644 --- a/Faupi-MunitionsExpert/server/types/utils/App.d.ts +++ b/Faupi-MunitionsExpert/server/types/utils/App.d.ts @@ -1,14 +1,16 @@ -import { TimeUtil } from "./TimeUtil"; import { OnLoad } from "../di/OnLoad"; import { OnUpdate } from "../di/OnUpdate"; import { ILogger } from "../models/spt/utils/ILogger"; +import { LocalisationService } from "../services/LocalisationService"; +import { TimeUtil } from "./TimeUtil"; export declare class App { protected logger: ILogger; protected timeUtil: TimeUtil; + protected localisationService: LocalisationService; protected onLoadComponents: OnLoad[]; protected onUpdateComponents: OnUpdate[]; protected onUpdateLastRun: {}; - constructor(logger: ILogger, timeUtil: TimeUtil, onLoadComponents: OnLoad[], onUpdateComponents: OnUpdate[]); + constructor(logger: ILogger, timeUtil: TimeUtil, localisationService: LocalisationService, onLoadComponents: OnLoad[], onUpdateComponents: OnUpdate[]); load(): void; protected update(onUpdateComponents: OnUpdate[]): void; protected logUpdateException(err: any, updateable: OnUpdate): void; diff --git a/Faupi-MunitionsExpert/server/types/utils/DatabaseImporter.d.ts b/Faupi-MunitionsExpert/server/types/utils/DatabaseImporter.d.ts index 483e135..31670ae 100644 --- a/Faupi-MunitionsExpert/server/types/utils/DatabaseImporter.d.ts +++ b/Faupi-MunitionsExpert/server/types/utils/DatabaseImporter.d.ts @@ -3,15 +3,17 @@ import { IDatabaseTables } from "../models/spt/server/IDatabaseTables"; import { ILogger } from "../models/spt/utils/ILogger"; import { ImageRouter } from "../routers/ImageRouter"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "../services/LocalisationService"; import { JsonUtil } from "./JsonUtil"; import { VFS } from "./VFS"; export declare class DatabaseImporter extends OnLoad { protected logger: ILogger; protected vfs: VFS; protected jsonUtil: JsonUtil; + protected localisationService: LocalisationService; protected databaseServer: DatabaseServer; protected imageRouter: ImageRouter; - constructor(logger: ILogger, vfs: VFS, jsonUtil: JsonUtil, databaseServer: DatabaseServer, imageRouter: ImageRouter); + constructor(logger: ILogger, vfs: VFS, jsonUtil: JsonUtil, localisationService: LocalisationService, databaseServer: DatabaseServer, imageRouter: ImageRouter); onLoad(): void; /** * Read all json files in database folder and map into a json object diff --git a/Faupi-MunitionsExpert/server/types/utils/HttpResponseUtil.d.ts b/Faupi-MunitionsExpert/server/types/utils/HttpResponseUtil.d.ts index 29502be..3a78618 100644 --- a/Faupi-MunitionsExpert/server/types/utils/HttpResponseUtil.d.ts +++ b/Faupi-MunitionsExpert/server/types/utils/HttpResponseUtil.d.ts @@ -1,10 +1,13 @@ -import { JsonUtil } from "./JsonUtil"; import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData"; import { INullResponseData } from "../models/eft/httpResponse/INullResponseData"; import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse"; +import { BackendErrorCodes } from "../models/enums/BackendErrorCodes"; +import { LocalisationService } from "../services/LocalisationService"; +import { JsonUtil } from "./JsonUtil"; export declare class HttpResponseUtil { protected jsonUtil: JsonUtil; - constructor(jsonUtil: JsonUtil); + protected localisationService: LocalisationService; + constructor(jsonUtil: JsonUtil, localisationService: LocalisationService); protected clearString(s: string): any; noBody(data: any): any; getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; @@ -12,5 +15,5 @@ export declare class HttpResponseUtil { emptyResponse(): IGetBodyResponseData; nullResponse(): INullResponseData; emptyArrayResponse(): IGetBodyResponseData; - appendErrorToOutput(output: IItemEventRouterResponse, message?: string, title?: string): IItemEventRouterResponse; + appendErrorToOutput(output: IItemEventRouterResponse, message?: string, errorCode?: BackendErrorCodes): IItemEventRouterResponse; } diff --git a/Faupi-MunitionsExpert/server/types/utils/Logger.d.ts b/Faupi-MunitionsExpert/server/types/utils/Logger.d.ts index 3d9013f..1088701 100644 --- a/Faupi-MunitionsExpert/server/types/utils/Logger.d.ts +++ b/Faupi-MunitionsExpert/server/types/utils/Logger.d.ts @@ -53,6 +53,12 @@ export declare class WinstonLogger implements ILogger { warning(data: string | Record): Promise; success(data: string | Record): Promise; info(data: string | Record): Promise; + /** + * Log to console text with a customisable text and background color. Background defaults to black + * @param data text to log + * @param textColor color of text + * @param backgroundColor color of background + */ logWithColor(data: string | Record, textColor: LogTextColor, backgroundColor?: LogBackgroundColor): Promise; debug(data: string | Record, onlyShowInConsole?: boolean): Promise; } diff --git a/Faupi-MunitionsExpert/server/types/utils/RandomUtil.d.ts b/Faupi-MunitionsExpert/server/types/utils/RandomUtil.d.ts index 633e472..aa556e3 100644 --- a/Faupi-MunitionsExpert/server/types/utils/RandomUtil.d.ts +++ b/Faupi-MunitionsExpert/server/types/utils/RandomUtil.d.ts @@ -110,6 +110,12 @@ export declare class RandomUtil { getIntEx(max: number): number; getFloat(min: number, max: number): number; getBool(): boolean; + /** + * Check if number passes a check out of 100 + * @param chancePercent value check needs to be above + * @returns true if value passes check + */ + getChance100(chancePercent: number): boolean; getStringArrayValue(arr: string[]): string; getArrayValue(arr: T[]): T; getKey(node: any): string; diff --git a/Faupi-MunitionsExpert/server/types/utils/Watermark.d.ts b/Faupi-MunitionsExpert/server/types/utils/Watermark.d.ts index c6dc120..e02eba2 100644 --- a/Faupi-MunitionsExpert/server/types/utils/Watermark.d.ts +++ b/Faupi-MunitionsExpert/server/types/utils/Watermark.d.ts @@ -1,20 +1,15 @@ import { ICoreConfig } from "../models/spt/config/ICoreConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; +import { LocalisationService } from "../services/LocalisationService"; export declare class WatermarkLocale { - protected locales: { - "en-US": { - description: string[]; - warning: string[]; - modding: string[]; - }; - "zh-CN": { - description: string[]; - warning: string[]; - modding: string[]; - }; + protected localisationService: LocalisationService; + constructor(localisationService: LocalisationService); + protected watermark: { + description: string[]; + warning: string[]; + modding: string[]; }; - getLocale(): string; getDescription(): string[]; getWarning(): string[]; getModding(): string[]; @@ -22,9 +17,10 @@ export declare class WatermarkLocale { export declare class Watermark { protected logger: ILogger; protected configServer: ConfigServer; + protected localisationService: LocalisationService; protected watermarkLocale?: WatermarkLocale; protected akiConfig: ICoreConfig; - constructor(logger: ILogger, configServer: ConfigServer, watermarkLocale?: WatermarkLocale); + constructor(logger: ILogger, configServer: ConfigServer, localisationService: LocalisationService, watermarkLocale?: WatermarkLocale); protected text: string[]; protected versionLabel: string; initialize(): void; diff --git a/KcY-SeeItemValue/itemValue/Built/KcY-SeeItemValue 1.4.8/bepInEx/plugins/KcY-SeeItemValue.dll b/KcY-SeeItemValue/itemValue/Built/KcY-SeeItemValue 1.5.0/bepInEx/plugins/KcY-SeeItemValue.dll similarity index 76% rename from KcY-SeeItemValue/itemValue/Built/KcY-SeeItemValue 1.4.8/bepInEx/plugins/KcY-SeeItemValue.dll rename to KcY-SeeItemValue/itemValue/Built/KcY-SeeItemValue 1.5.0/bepInEx/plugins/KcY-SeeItemValue.dll index ac6f45fdf3ecb9752fbb45d109f4905f71ad70c8..d587e610d06a3a8a9519c565e106ed5ffa94dcac 100644 GIT binary patch delta 479 zcmZq3Xvmn*!6N(O!MBY)HoTH?49^+37#JBC7}yv*84TFC7_^zM0NL4-AM!f-SAfM2 zv2AA%VmQcJ%*w{#%3KCi^Ov0gsB1n@mW#m@OtyhZEg&hxu%D%vm5U(@XpR_z4cj{o zF$NDH$;J>cxscDAF?I4iW6@7`?#?-h#l=QOh6W5ac9!w+2Jt|KV@ir=NosCbVoqtQT@pkPs?fmH zkO9WDG@SfNOwGkJuf*7h!6h@fBr`uRv8Xb^h`}8wmRgjSn4D^4Xbe+tXkvmaVPFZD zu(aGs8z-9+cRc1a*Jp*8vFfyY3MS}%yGu}$BJ;|l1G+9D7QvoWd76BCmsrKAC wuQbHIt-z-KP|M_nx^Fo-8Cbwk#kqO9UMM5bC2#fZfz)JOLt`K((QrN!080volK=n! delta 453 zcmZq3Xvmn*!E&Q_%8!jbHoTIy49^+37z!8|7}yvz7!26B7_^zM0NKftAM!f-yMV`X61tfRP{EqRP(h&T#IFi%CJXP@e^L0gy?XLO-M5^q3@i+c eAfq-<*9&E2G~N7G-yTR!)-^N+auN;aGXVfG#)Dn} diff --git a/KcY-SeeItemValue/itemValue/Built/KcY-SeeItemValue 1.4.8/user/mods/KcY-SeeItemValue 1.4.8/LICENSE.txt b/KcY-SeeItemValue/itemValue/Built/KcY-SeeItemValue 1.5.0/user/mods/KcY-SeeItemValue 1.5.0/LICENSE.txt similarity index 100% rename from KcY-SeeItemValue/itemValue/Built/KcY-SeeItemValue 1.4.8/user/mods/KcY-SeeItemValue 1.4.8/LICENSE.txt rename to KcY-SeeItemValue/itemValue/Built/KcY-SeeItemValue 1.5.0/user/mods/KcY-SeeItemValue 1.5.0/LICENSE.txt diff --git a/KcY-SeeItemValue/itemValue/Built/KcY-SeeItemValue 1.4.8/user/mods/KcY-SeeItemValue 1.4.8/package.json b/KcY-SeeItemValue/itemValue/Built/KcY-SeeItemValue 1.5.0/user/mods/KcY-SeeItemValue 1.5.0/package.json similarity index 91% rename from KcY-SeeItemValue/itemValue/Built/KcY-SeeItemValue 1.4.8/user/mods/KcY-SeeItemValue 1.4.8/package.json rename to KcY-SeeItemValue/itemValue/Built/KcY-SeeItemValue 1.5.0/user/mods/KcY-SeeItemValue 1.5.0/package.json index 8c61770..f799ae4 100644 --- a/KcY-SeeItemValue/itemValue/Built/KcY-SeeItemValue 1.4.8/user/mods/KcY-SeeItemValue 1.4.8/package.json +++ b/KcY-SeeItemValue/itemValue/Built/KcY-SeeItemValue 1.5.0/user/mods/KcY-SeeItemValue 1.5.0/package.json @@ -1,10 +1,10 @@ { "name": "SeeItemValue", "author": "KcY", - "version": "1.4.8", + "version": "1.5.0", "license": "NCSA Open Source", "main": "src/mod.js", - "akiVersion": "3.2.5", + "akiVersion": "3.3.0", "UpdatedBy": "CWX", "scripts": { "setup": "npm i", diff --git a/KcY-SeeItemValue/itemValue/Built/KcY-SeeItemValue 1.4.8/user/mods/KcY-SeeItemValue 1.4.8/src/config.json b/KcY-SeeItemValue/itemValue/Built/KcY-SeeItemValue 1.5.0/user/mods/KcY-SeeItemValue 1.5.0/src/config.json similarity index 100% rename from KcY-SeeItemValue/itemValue/Built/KcY-SeeItemValue 1.4.8/user/mods/KcY-SeeItemValue 1.4.8/src/config.json rename to KcY-SeeItemValue/itemValue/Built/KcY-SeeItemValue 1.5.0/user/mods/KcY-SeeItemValue 1.5.0/src/config.json diff --git a/KcY-SeeItemValue/itemValue/Built/KcY-SeeItemValue 1.4.8/user/mods/KcY-SeeItemValue 1.4.8/src/mod.ts b/KcY-SeeItemValue/itemValue/Built/KcY-SeeItemValue 1.5.0/user/mods/KcY-SeeItemValue 1.5.0/src/mod.ts similarity index 100% rename from KcY-SeeItemValue/itemValue/Built/KcY-SeeItemValue 1.4.8/user/mods/KcY-SeeItemValue 1.4.8/src/mod.ts rename to KcY-SeeItemValue/itemValue/Built/KcY-SeeItemValue 1.5.0/user/mods/KcY-SeeItemValue 1.5.0/src/mod.ts diff --git a/KcY-SeeItemValue/itemValue/Patches.cs b/KcY-SeeItemValue/itemValue/Patches.cs index cd2303e..4d71330 100644 --- a/KcY-SeeItemValue/itemValue/Patches.cs +++ b/KcY-SeeItemValue/itemValue/Patches.cs @@ -3,10 +3,10 @@ using System.Reflection; using Aki.Reflection.Patching; using EFT.InventoryLogic; using Ammo = BulletClass; -using Grenade = GClass2192; -using GrenadeTemplate = GClass2085; -using SecureContainer = GClass2138; -using SecureContainerTemplate = GClass2046; +using Grenade = GClass2199; +using GrenadeTemplate = GClass2091; +using SecureContainer = GClass2144; +using SecureContainerTemplate = GClass2051; namespace itemValueMod { diff --git a/KcY-SeeItemValue/itemValue/Program.cs b/KcY-SeeItemValue/itemValue/Program.cs index a6066c4..64c50ba 100644 --- a/KcY-SeeItemValue/itemValue/Program.cs +++ b/KcY-SeeItemValue/itemValue/Program.cs @@ -2,7 +2,7 @@ namespace itemValueMod { - [BepInPlugin("com.KcY.SeeItemValue", "KcY-SeeItemValue", "1.4.8")] + [BepInPlugin("com.KcY.SeeItemValue", "KcY-SeeItemValue", "1.4.9")] public class Plugin : BaseUnityPlugin { private void Awake() diff --git a/KcY-SeeItemValue/itemValue/itemValueMod.cs b/KcY-SeeItemValue/itemValue/itemValueMod.cs index da4adbd..ab4d18b 100644 --- a/KcY-SeeItemValue/itemValue/itemValueMod.cs +++ b/KcY-SeeItemValue/itemValue/itemValueMod.cs @@ -4,7 +4,7 @@ using EFT.InventoryLogic; using System; using System.Collections.Generic; using System.Reflection; -using ItemAttribute = GClass2203; +using ItemAttribute = GClass2210; using System.Net; using System.Threading; using UnityEngine; @@ -197,12 +197,12 @@ namespace itemValueMod var foodDrink = item.GetItemComponent(); if (foodDrink != null && foodDrink.HpPercent != 0) { - GInterface208 ginterface208_0 = (GInterface208)foodDrink.GetType().GetField("ginterface208_0", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(foodDrink); + GInterface209 ginterface209_0 = (GInterface209)foodDrink.GetType().GetField("ginterface209_0", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(foodDrink); DebugMode($" foodDrink Check - HpPercent is: {foodDrink.HpPercent}"); - DebugMode($" foodDrink Check - MaxResource is: {ginterface208_0.MaxResource}"); + DebugMode($" foodDrink Check - MaxResource is: {ginterface209_0.MaxResource}"); - editedPrice *= foodDrink.HpPercent / ginterface208_0.MaxResource; + editedPrice *= foodDrink.HpPercent / ginterface209_0.MaxResource; } DebugMode($" After foodDrink Check - price is: {editedPrice}"); @@ -210,12 +210,12 @@ namespace itemValueMod var keys = item.GetItemComponent(); if (keys != null) { - GInterface212 ginterface212_0 = (GInterface212)keys.GetType().GetField("Template", BindingFlags.Public | BindingFlags.Instance).GetValue(keys); + GInterface213 gInterface213_0 = (GInterface213)keys.GetType().GetField("Template", BindingFlags.Public | BindingFlags.Instance).GetValue(keys); if (keys.NumberOfUsages > 0) { - double totalMinusUsed = Convert.ToDouble(ginterface212_0.MaximumNumberOfUsage - keys.NumberOfUsages); - double multi = totalMinusUsed / ginterface212_0.MaximumNumberOfUsage; + double totalMinusUsed = Convert.ToDouble(gInterface213_0.MaximumNumberOfUsage - keys.NumberOfUsages); + double multi = totalMinusUsed / gInterface213_0.MaximumNumberOfUsage; DebugMode($" foodDrink Check - totalMinusUsed is: {totalMinusUsed}"); DebugMode($" foodDrink Check - multi is: {multi}"); diff --git a/KcY-SeeItemValue/itemValue/itemValueMod.csproj b/KcY-SeeItemValue/itemValue/itemValueMod.csproj index f2ed16c..a65d17f 100644 --- a/KcY-SeeItemValue/itemValue/itemValueMod.csproj +++ b/KcY-SeeItemValue/itemValue/itemValueMod.csproj @@ -2,7 +2,7 @@ net472 - 1.4.5 + 1.4.9 KcY-SeeItemValue diff --git a/KcY-SeeItemValue/itemValue/server/dist/package.json b/KcY-SeeItemValue/itemValue/server/dist/package.json index 8c61770..dde6f29 100644 --- a/KcY-SeeItemValue/itemValue/server/dist/package.json +++ b/KcY-SeeItemValue/itemValue/server/dist/package.json @@ -1,10 +1,10 @@ { "name": "SeeItemValue", "author": "KcY", - "version": "1.4.8", + "version": "1.4.9", "license": "NCSA Open Source", "main": "src/mod.js", - "akiVersion": "3.2.5", + "akiVersion": "3.3.0", "UpdatedBy": "CWX", "scripts": { "setup": "npm i", diff --git a/KcY-SeeItemValue/itemValue/server/package.json b/KcY-SeeItemValue/itemValue/server/package.json index 8c61770..dde6f29 100644 --- a/KcY-SeeItemValue/itemValue/server/package.json +++ b/KcY-SeeItemValue/itemValue/server/package.json @@ -1,10 +1,10 @@ { "name": "SeeItemValue", "author": "KcY", - "version": "1.4.8", + "version": "1.4.9", "license": "NCSA Open Source", "main": "src/mod.js", - "akiVersion": "3.2.5", + "akiVersion": "3.3.0", "UpdatedBy": "CWX", "scripts": { "setup": "npm i", diff --git a/KcY-SeeItemValue/itemValue/server/types/callbacks/BotCallbacks.d.ts b/KcY-SeeItemValue/itemValue/server/types/callbacks/BotCallbacks.d.ts index 2db60dc..827015e 100644 --- a/KcY-SeeItemValue/itemValue/server/types/callbacks/BotCallbacks.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/callbacks/BotCallbacks.d.ts @@ -8,8 +8,29 @@ export declare class BotCallbacks { protected botController: BotController; protected httpResponse: HttpResponseUtil; constructor(botController: BotController, httpResponse: HttpResponseUtil); + /** + * Handle singleplayer/settings/bot/limit + * @returns string + */ getBotLimit(url: string, info: IEmptyRequestData, sessionID: string): string; + /** + * Handle singleplayer/settings/bot/difficulty + * @returns string + */ getBotDifficulty(url: string, info: IEmptyRequestData, sessionID: string): string; + /** + * Handle client/game/bot/generate + * @returns IGetBodyResponseData + */ generateBots(url: string, info: IGenerateBotsRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle singleplayer/settings/bot/maxCap + * @returns string + */ getBotCap(): string; + /** + * Handle singleplayer/settings/bot/getBotBehaviours + * @returns string + */ + getBotBehaviours(): string; } diff --git a/KcY-SeeItemValue/itemValue/server/types/callbacks/CustomizationCallbacks.d.ts b/KcY-SeeItemValue/itemValue/server/types/callbacks/CustomizationCallbacks.d.ts index 3bab8c0..75d5701 100644 --- a/KcY-SeeItemValue/itemValue/server/types/callbacks/CustomizationCallbacks.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/callbacks/CustomizationCallbacks.d.ts @@ -3,6 +3,7 @@ import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData"; import { IPmcData } from "../models/eft/common/IPmcData"; import { ISuit } from "../models/eft/common/tables/ITrader"; import { IBuyClothingRequestData } from "../models/eft/customization/IBuyClothingRequestData"; +import { IGetSuitsResponse } from "../models/eft/customization/IGetSuitsResponse"; import { IWearClothingRequestData } from "../models/eft/customization/IWearClothingRequestData"; import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData"; import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse"; @@ -13,10 +14,15 @@ export declare class CustomizationCallbacks { protected saveServer: SaveServer; protected httpResponse: HttpResponseUtil; constructor(customizationController: CustomizationController, saveServer: SaveServer, httpResponse: HttpResponseUtil); - getSuits(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<{ - _id: string; - suites: string[]; - }>; + /** + * Handles client/trading/customization/storage + * @returns + */ + getSuits(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handles client/trading/customization + * @returns ISuit[] + */ getTraderSuits(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; wearClothing(pmcData: IPmcData, body: IWearClothingRequestData, sessionID: string): IItemEventRouterResponse; buyClothing(pmcData: IPmcData, body: IBuyClothingRequestData, sessionID: string): IItemEventRouterResponse; diff --git a/KcY-SeeItemValue/itemValue/server/types/callbacks/DataCallbacks.d.ts b/KcY-SeeItemValue/itemValue/server/types/callbacks/DataCallbacks.d.ts index 04566ff..2efcf81 100644 --- a/KcY-SeeItemValue/itemValue/server/types/callbacks/DataCallbacks.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/callbacks/DataCallbacks.d.ts @@ -12,15 +12,42 @@ import { ILanguageBase } from "../models/spt/server/ILocaleBase"; import { ISettingsBase } from "../models/spt/server/ISettingsBase"; import { DatabaseServer } from "../servers/DatabaseServer"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; +/** + * Handle client requests + */ export declare class DataCallbacks { protected httpResponse: HttpResponseUtil; protected databaseServer: DatabaseServer; constructor(httpResponse: HttpResponseUtil, databaseServer: DatabaseServer); + /** + * Handles client/settings + * @returns ISettingsBase + */ getSettings(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handles client/globals + * @returns IGlobals + */ getGlobals(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handles client/items + * @returns string + */ getTemplateItems(url: string, info: IEmptyRequestData, sessionID: string): string; + /** + * Handles client/handbook/templates + * @returns IHandbookBase + */ getTemplateHandbook(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handles client/customization + * @returns Record>; + /** + * Handles client/account/customization + * @returns string[] + */ getTemplateCharacter(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; getTemplateQuests(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; getHideoutSettings(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; @@ -28,6 +55,6 @@ export declare class DataCallbacks { gethideoutProduction(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; getHideoutScavcase(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; getLocalesLanguages(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - getLocalesMenu(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + getLocalesMenu(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; getLocalesGlobal(url: string, info: IEmptyRequestData, sessionID: string): string; } diff --git a/KcY-SeeItemValue/itemValue/server/types/callbacks/DialogueCallbacks.d.ts b/KcY-SeeItemValue/itemValue/server/types/callbacks/DialogueCallbacks.d.ts index 634f90b..7b2eeae 100644 --- a/KcY-SeeItemValue/itemValue/server/types/callbacks/DialogueCallbacks.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/callbacks/DialogueCallbacks.d.ts @@ -26,15 +26,27 @@ export declare class DialogueCallbacks extends OnUpdate { protected httpResponse: HttpResponseUtil; protected dialogueController: DialogueController; constructor(hashUtil: HashUtil, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, dialogueController: DialogueController); + /** + * Handles client/friend/list + * @returns IGetFriendListDataResponse + */ getFriendList(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handles client/chatServer/list + * @returns + */ getChatServerList(url: string, info: IGetChatServerListRequestData, sessionID: string): IGetBodyResponseData; getMailDialogList(url: string, info: IGetMailDialogListRequestData, sessionID: string): IGetBodyResponseData; getMailDialogView(url: string, info: IGetMailDialogViewRequestData, sessionID: string): IGetBodyResponseData; - getMailDialogInfo(url: string, info: IGetMailDialogInfoRequestData, sessionID: string): IGetBodyResponseData; + getMailDialogInfo(url: string, info: IGetMailDialogInfoRequestData, sessionID: string): IGetBodyResponseData; removeDialog(url: string, info: IRemoveDialogRequestData, sessionID: string): IGetBodyResponseData; pinDialog(url: string, info: IPinDialogRequestData, sessionID: string): IGetBodyResponseData; unpinDialog(url: string, info: IPinDialogRequestData, sessionID: string): IGetBodyResponseData; setRead(url: string, info: ISetDialogReadRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handles client/mail/dialog/getAllAttachments + * @returns IGetAllAttachmentsResponse + */ getAllAttachments(url: string, info: IGetAllAttachmentsRequestData, sessionID: string): IGetBodyResponseData; listOutbox(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; listInbox(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; diff --git a/KcY-SeeItemValue/itemValue/server/types/callbacks/GameCallbacks.d.ts b/KcY-SeeItemValue/itemValue/server/types/callbacks/GameCallbacks.d.ts index 5e4c240..3a6b7e6 100644 --- a/KcY-SeeItemValue/itemValue/server/types/callbacks/GameCallbacks.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/callbacks/GameCallbacks.d.ts @@ -3,6 +3,9 @@ import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData"; import { ICheckVersionResponse } from "../models/eft/game/ICheckVersionResponse"; import { IGameConfigResponse } from "../models/eft/game/IGameConfigResponse"; import { IGameEmptyCrcRequestData } from "../models/eft/game/IGameEmptyCrcRequestData"; +import { IGameKeepAliveResponse } from "../models/eft/game/IGameKeepAliveResponse"; +import { IGameLogoutResponseData } from "../models/eft/game/IGameLogoutResponseData"; +import { IGameStartResponse } from "../models/eft/game/IGameStartResponse"; import { IReportNicknameRequestData } from "../models/eft/game/IReportNicknameRequestData"; import { IServerDetails } from "../models/eft/game/IServerDetails"; import { IVersionValidateRequestData } from "../models/eft/game/IVersionValidateRequestData"; @@ -15,13 +18,37 @@ declare class GameCallbacks { protected watermark: Watermark; protected gameController: GameController; constructor(httpResponse: HttpResponseUtil, watermark: Watermark, gameController: GameController); + /** + * Handle client/game/version/validate + * @returns INullResponseData + */ versionValidate(url: string, info: IVersionValidateRequestData, sessionID: string): INullResponseData; - gameStart(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - gameLogout(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle client/game/start + * @returns IGameStartResponse + */ + gameStart(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle client/game/logout + * @returns IGameLogoutResponseData + */ + gameLogout(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle client/game/config + * @returns IGameConfigResponse + */ getGameConfig(url: string, info: IGameEmptyCrcRequestData, sessionID: string): IGetBodyResponseData; getServer(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; validateGameVersion(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - gameKeepalive(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle client/game/keepalive + * @returns IGameKeepAliveResponse + */ + gameKeepalive(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle singleplayer/settings/version + * @returns string + */ getVersion(url: string, info: IEmptyRequestData, sessionID: string): string; reportNickname(url: string, info: IReportNicknameRequestData, sessionID: string): INullResponseData; } diff --git a/KcY-SeeItemValue/itemValue/server/types/callbacks/HealthCallbacks.d.ts b/KcY-SeeItemValue/itemValue/server/types/callbacks/HealthCallbacks.d.ts index 8672be7..7edf03e 100644 --- a/KcY-SeeItemValue/itemValue/server/types/callbacks/HealthCallbacks.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/callbacks/HealthCallbacks.d.ts @@ -21,7 +21,19 @@ export declare class HealthCallbacks { * @returns empty response, no data sent back to client */ syncHealth(url: string, info: ISyncHealthRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle Eat + * @returns IItemEventRouterResponse + */ offraidEat(pmcData: IPmcData, body: IOffraidEatRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle Heal + * @returns IItemEventRouterResponse + */ offraidHeal(pmcData: IPmcData, body: IOffraidHealRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle RestoreHealth + * @returns IItemEventRouterResponse + */ healthTreatment(pmcData: IPmcData, info: IHealthTreatmentRequestData, sessionID: string): IItemEventRouterResponse; } diff --git a/KcY-SeeItemValue/itemValue/server/types/callbacks/HideoutCallbacks.d.ts b/KcY-SeeItemValue/itemValue/server/types/callbacks/HideoutCallbacks.d.ts index 99ab4c9..e39e806 100644 --- a/KcY-SeeItemValue/itemValue/server/types/callbacks/HideoutCallbacks.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/callbacks/HideoutCallbacks.d.ts @@ -19,14 +19,77 @@ export declare class HideoutCallbacks extends OnUpdate { protected hideoutConfig: IHideoutConfig; constructor(hideoutController: HideoutController, // TODO: delay needed configServer: ConfigServer); + /** + * Handle HideoutUpgrade + * @param pmcData + * @param body + * @param sessionID + * @returns + */ upgrade(pmcData: IPmcData, body: IHideoutUpgradeRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutUpgradeComplete + * @param pmcData + * @param body + * @param sessionID + * @returns + */ upgradeComplete(pmcData: IPmcData, body: IHideoutUpgradeCompleteRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutPutItemsInAreaSlots + * @param pmcData + * @param body + * @param sessionID + * @returns + */ putItemsInAreaSlots(pmcData: IPmcData, body: IHideoutPutItemInRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutTakeItemsFromAreaSlots + * @param pmcData + * @param body + * @param sessionID + * @returns + */ takeItemsFromAreaSlots(pmcData: IPmcData, body: IHideoutTakeItemOutRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutToggleArea + * @param pmcData + * @param body + * @param sessionID + * @returns + */ toggleArea(pmcData: IPmcData, body: IHideoutToggleAreaRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutSingleProductionStart + * @param pmcData + * @param body + * @param sessionID + * @returns + */ singleProductionStart(pmcData: IPmcData, body: IHideoutSingleProductionStartRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutScavCaseProductionStart + * @param pmcData + * @param body + * @param sessionID + * @returns + */ scavCaseProductionStart(pmcData: IPmcData, body: IHideoutScavCaseStartRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutContinuousProductionStart + * @param pmcData + * @param body + * @param sessionID + * @returns + */ continuousProductionStart(pmcData: IPmcData, body: IHideoutContinousProductionStartRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle HideoutTakeProduction + * @param pmcData + * @param body + * @param sessionID + * @returns + */ takeProduction(pmcData: IPmcData, body: IHideoutTakeProductionRequestData, sessionID: string): IItemEventRouterResponse; onUpdate(timeSinceLastRun: number): boolean; getRoute(): string; diff --git a/KcY-SeeItemValue/itemValue/server/types/callbacks/InraidCallbacks.d.ts b/KcY-SeeItemValue/itemValue/server/types/callbacks/InraidCallbacks.d.ts index 05bcce4..918bfaf 100644 --- a/KcY-SeeItemValue/itemValue/server/types/callbacks/InraidCallbacks.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/callbacks/InraidCallbacks.d.ts @@ -1,23 +1,49 @@ import { InraidController } from "../controllers/InraidController"; -import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData"; import { INullResponseData } from "../models/eft/httpResponse/INullResponseData"; import { IRegisterPlayerRequestData } from "../models/eft/inRaid/IRegisterPlayerRequestData"; import { ISaveProgressRequestData } from "../models/eft/inRaid/ISaveProgressRequestData"; -import { IAirdropConfig } from "../models/spt/config/IAirdropConfig"; -import { IInRaidConfig } from "../models/spt/config/IInRaidConfig"; -import { ConfigServer } from "../servers/ConfigServer"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; +/** + * Handle client requests + */ export declare class InraidCallbacks { protected inraidController: InraidController; protected httpResponse: HttpResponseUtil; - protected configServer: ConfigServer; - protected airdropConfig: IAirdropConfig; - protected inraidConfig: IInRaidConfig; - constructor(inraidController: InraidController, httpResponse: HttpResponseUtil, configServer: ConfigServer); + constructor(inraidController: InraidController, httpResponse: HttpResponseUtil); + /** + * Handle client/location/getLocalloot + * @param url + * @param info register player request + * @param sessionID Session id + * @returns Null http response + */ registerPlayer(url: string, info: IRegisterPlayerRequestData, sessionID: string): INullResponseData; + /** + * Handle raid/profile/save + * @param url + * @param info Save progress request + * @param sessionID Session id + * @returns Null http response + */ saveProgress(url: string, info: ISaveProgressRequestData, sessionID: string): INullResponseData; + /** + * Handle singleplayer/settings/raid/endstate + * @returns + */ getRaidEndState(): string; - getRaidMenuSettings(url: string, info: IEmptyRequestData, sessionID: string): string; - getWeaponDurability(url: string, info: any, sessionID: string): string; - getAirdropConfig(url: string, info: any, sessionID: string): string; + /** + * Handle singleplayer/settings/raid/menu + * @returns JSON as string + */ + getRaidMenuSettings(): string; + /** + * Handle singleplayer/settings/weapon/durability + * @returns + */ + getWeaponDurability(): string; + /** + * Handle singleplayer/airdrop/config + * @returns JSON as string + */ + getAirdropConfig(): string; } diff --git a/KcY-SeeItemValue/itemValue/server/types/callbacks/InsuranceCallbacks.d.ts b/KcY-SeeItemValue/itemValue/server/types/callbacks/InsuranceCallbacks.d.ts index 8835ba2..a171e1c 100644 --- a/KcY-SeeItemValue/itemValue/server/types/callbacks/InsuranceCallbacks.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/callbacks/InsuranceCallbacks.d.ts @@ -17,7 +17,15 @@ export declare class InsuranceCallbacks extends OnUpdate { protected configServer: ConfigServer; protected insuranceConfig: IInsuranceConfig; constructor(insuranceController: InsuranceController, insuranceService: InsuranceService, httpResponse: HttpResponseUtil, configServer: ConfigServer); + /** + * Handle client/insurance/items/list/cost + * @returns IGetInsuranceCostResponseData + */ getInsuranceCost(url: string, info: IGetInsuranceCostRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle Insure + * @returns IItemEventRouterResponse + */ insure(pmcData: IPmcData, body: IInsureRequestData, sessionID: string): IItemEventRouterResponse; onUpdate(secondsSinceLastRun: number): boolean; getRoute(): string; diff --git a/KcY-SeeItemValue/itemValue/server/types/callbacks/InventoryCallbacks.d.ts b/KcY-SeeItemValue/itemValue/server/types/callbacks/InventoryCallbacks.d.ts index 9ab1486..46bf6fd 100644 --- a/KcY-SeeItemValue/itemValue/server/types/callbacks/InventoryCallbacks.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/callbacks/InventoryCallbacks.d.ts @@ -16,6 +16,7 @@ import { IInventorySwapRequestData } from "../models/eft/inventory/IInventorySwa import { IInventoryTagRequestData } from "../models/eft/inventory/IInventoryTagRequestData"; import { IInventoryToggleRequestData } from "../models/eft/inventory/IInventoryToggleRequestData"; import { IInventoryTransferRequestData } from "../models/eft/inventory/IInventoryTransferRequestData"; +import { IOpenRandomLootContainerRequestData } from "../models/eft/inventory/IOpenRandomLootContainerRequestData"; import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse"; export declare class InventoryCallbacks { protected inventoryController: InventoryController; @@ -36,4 +37,5 @@ export declare class InventoryCallbacks { createMapMarker(pmcData: IPmcData, body: IInventoryCreateMarkerRequestData, sessionID: string): IItemEventRouterResponse; deleteMapMarker(pmcData: IPmcData, body: IInventoryDeleteMarkerRequestData, sessionID: string): IItemEventRouterResponse; editMapMarker(pmcData: IPmcData, body: IInventoryEditMarkerRequestData, sessionID: string): IItemEventRouterResponse; + openRandomLootContainer(pmcData: IPmcData, body: IOpenRandomLootContainerRequestData, sessionID: string): IItemEventRouterResponse; } diff --git a/KcY-SeeItemValue/itemValue/server/types/callbacks/ItemEventCallbacks.d.ts b/KcY-SeeItemValue/itemValue/server/types/callbacks/ItemEventCallbacks.d.ts index f4f04f9..fbb0b5f 100644 --- a/KcY-SeeItemValue/itemValue/server/types/callbacks/ItemEventCallbacks.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/callbacks/ItemEventCallbacks.d.ts @@ -1,4 +1,5 @@ import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData"; +import { Warning } from "../models/eft/itemEvent/IItemEventRouterBase"; import { IItemEventRouterRequest } from "../models/eft/itemEvent/IItemEventRouterRequest"; import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse"; import { ItemEventRouter } from "../routers/ItemEventRouter"; @@ -8,4 +9,5 @@ export declare class ItemEventCallbacks { protected itemEventRouter: ItemEventRouter; constructor(httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter); handleEvents(url: string, info: IItemEventRouterRequest, sessionID: string): IGetBodyResponseData; + protected getErrorCode(warnings: Warning[]): number; } diff --git a/KcY-SeeItemValue/itemValue/server/types/callbacks/MatchCallbacks.d.ts b/KcY-SeeItemValue/itemValue/server/types/callbacks/MatchCallbacks.d.ts index 2a92ef5..10fbc44 100644 --- a/KcY-SeeItemValue/itemValue/server/types/callbacks/MatchCallbacks.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/callbacks/MatchCallbacks.d.ts @@ -34,6 +34,10 @@ export declare class MatchCallbacks { serverAvailable(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData | IGetBodyResponseData; joinMatch(url: string, info: IJoinMatchRequestData, sessionID: string): IGetBodyResponseData; getMetrics(url: string, info: any, sessionID: string): IGetBodyResponseData; + /** + * Handle client/match/group/status + * @returns + */ getGroupStatus(url: string, info: IGetGroupStatusRequestData, sessionID: string): IGetBodyResponseData; createGroup(url: string, info: ICreateGroupRequestData, sessionID: string): IGetBodyResponseData; deleteGroup(url: string, info: any, sessionID: string): INullResponseData; diff --git a/KcY-SeeItemValue/itemValue/server/types/callbacks/NotifierCallbacks.d.ts b/KcY-SeeItemValue/itemValue/server/types/callbacks/NotifierCallbacks.d.ts index c42058f..fab325b 100644 --- a/KcY-SeeItemValue/itemValue/server/types/callbacks/NotifierCallbacks.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/callbacks/NotifierCallbacks.d.ts @@ -4,6 +4,7 @@ import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData"; import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData"; import { INotifierChannel } from "../models/eft/notifier/INotifier"; import { ISelectProfileRequestData } from "../models/eft/notifier/ISelectProfileRequestData"; +import { ISelectProfileResponse } from "../models/eft/notifier/ISelectProfileResponse"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; export declare class NotifierCallbacks { protected httpServerHelper: HttpServerHelper; @@ -19,6 +20,10 @@ export declare class NotifierCallbacks { sendNotification(sessionID: string, req: any, resp: any, data: any): void; getNotifier(url: string, info: any, sessionID: string): IGetBodyResponseData; createNotifierChannel(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; - selectProfile(url: string, info: ISelectProfileRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle client/game/profile/select + * @returns ISelectProfileResponse + */ + selectProfile(url: string, info: ISelectProfileRequestData, sessionID: string): IGetBodyResponseData; notify(url: string, info: any, sessionID: string): string; } diff --git a/KcY-SeeItemValue/itemValue/server/types/callbacks/QuestCallbacks.d.ts b/KcY-SeeItemValue/itemValue/server/types/callbacks/QuestCallbacks.d.ts index 559c29e..2a3eb20 100644 --- a/KcY-SeeItemValue/itemValue/server/types/callbacks/QuestCallbacks.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/callbacks/QuestCallbacks.d.ts @@ -21,6 +21,13 @@ export declare class QuestCallbacks { acceptQuest(pmcData: IPmcData, body: IAcceptQuestRequestData, sessionID: string): IItemEventRouterResponse; completeQuest(pmcData: IPmcData, body: ICompleteQuestRequestData, sessionID: string): IItemEventRouterResponse; handoverQuest(pmcData: IPmcData, body: IHandoverQuestRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle client/quest/list + * @param url + * @param info + * @param sessionID + * @returns + */ listQuests(url: string, info: IListQuestsRequestData, sessionID: string): IGetBodyResponseData; activityPeriods(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; } diff --git a/KcY-SeeItemValue/itemValue/server/types/callbacks/RagfairCallbacks.d.ts b/KcY-SeeItemValue/itemValue/server/types/callbacks/RagfairCallbacks.d.ts index c609f2f..37f3807 100644 --- a/KcY-SeeItemValue/itemValue/server/types/callbacks/RagfairCallbacks.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/callbacks/RagfairCallbacks.d.ts @@ -35,7 +35,7 @@ export declare class RagfairCallbacks extends OnLoadOnUpdate { getRoute(): string; search(url: string, info: ISearchRequestData, sessionID: string): IGetBodyResponseData; getMarketPrice(url: string, info: IGetMarketPriceRequestData, sessionID: string): IGetBodyResponseData; - getItemPrices(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + getItemPrices(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData>; addOffer(pmcData: IPmcData, info: IAddOfferRequestData, sessionID: string): IItemEventRouterResponse; removeOffer(pmcData: IPmcData, info: IRemoveOfferRequestData, sessionID: string): IItemEventRouterResponse; extendOffer(pmcData: IPmcData, info: IExtendOfferRequestData, sessionID: string): IItemEventRouterResponse; diff --git a/KcY-SeeItemValue/itemValue/server/types/callbacks/TraderCallbacks.d.ts b/KcY-SeeItemValue/itemValue/server/types/callbacks/TraderCallbacks.d.ts index e4fd099..40a1455 100644 --- a/KcY-SeeItemValue/itemValue/server/types/callbacks/TraderCallbacks.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/callbacks/TraderCallbacks.d.ts @@ -12,6 +12,10 @@ export declare class TraderCallbacks extends OnLoadOnUpdate { onUpdate(): boolean; getRoute(): string; getTraderSettings(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle client/trading/api/getUserAssortPrice/trader + * @returns + */ getProfilePurchases(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData>; getTrader(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; getAssort(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; diff --git a/KcY-SeeItemValue/itemValue/server/types/callbacks/WeatherCallbacks.d.ts b/KcY-SeeItemValue/itemValue/server/types/callbacks/WeatherCallbacks.d.ts index ae784c8..f9d2002 100644 --- a/KcY-SeeItemValue/itemValue/server/types/callbacks/WeatherCallbacks.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/callbacks/WeatherCallbacks.d.ts @@ -1,10 +1,15 @@ import { WeatherController } from "../controllers/WeatherController"; import { IEmptyRequestData } from "../models/eft/common/IEmptyRequestData"; import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData"; +import { IWeatherData } from "../models/eft/weather/IWeatherData"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; export declare class WeatherCallbacks { protected httpResponse: HttpResponseUtil; protected weatherController: WeatherController; constructor(httpResponse: HttpResponseUtil, weatherController: WeatherController); - getWeather(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; + /** + * Handle client/weather + * @returns IWeatherData + */ + getWeather(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData; } diff --git a/KcY-SeeItemValue/itemValue/server/types/context/ContextVariableType.d.ts b/KcY-SeeItemValue/itemValue/server/types/context/ContextVariableType.d.ts index 5fc1704..a7dd9b5 100644 --- a/KcY-SeeItemValue/itemValue/server/types/context/ContextVariableType.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/context/ContextVariableType.d.ts @@ -1,4 +1,8 @@ export declare enum ContextVariableType { + /** Logged in users session id */ SESSION_ID = 0, - MATCH_INFO = 1 + /** Currently acive raid information */ + MATCH_INFO = 1, + /** Timestamp when client first connected */ + CLIENT_START_TIMESTAMP = 2 } diff --git a/KcY-SeeItemValue/itemValue/server/types/controllers/BotController.d.ts b/KcY-SeeItemValue/itemValue/server/types/controllers/BotController.d.ts index a5111d5..51c0c68 100644 --- a/KcY-SeeItemValue/itemValue/server/types/controllers/BotController.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/controllers/BotController.d.ts @@ -1,6 +1,9 @@ import { ApplicationContext } from "../context/ApplicationContext"; import { BotGenerator } from "../generators/BotGenerator"; +import { BotDifficultyHelper } from "../helpers/BotDifficultyHelper"; import { BotHelper } from "../helpers/BotHelper"; +import { ProfileHelper } from "../helpers/ProfileHelper"; +import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper"; import { IGenerateBotsRequestData } from "../models/eft/bot/IGenerateBotsRequestData"; import { IBotBase } from "../models/eft/common/tables/IBotBase"; import { IBotCore } from "../models/eft/common/tables/IBotCore"; @@ -10,24 +13,34 @@ import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { BotGenerationCacheService } from "../services/BotGenerationCacheService"; -import { PmcAiService } from "../services/PmcAiService"; +import { LocalisationService } from "../services/LocalisationService"; +import { JsonUtil } from "../utils/JsonUtil"; export declare class BotController { protected logger: ILogger; protected databaseServer: DatabaseServer; protected botGenerator: BotGenerator; protected botHelper: BotHelper; - protected pmcAiService: PmcAiService; + protected botDifficultyHelper: BotDifficultyHelper; protected botGenerationCacheService: BotGenerationCacheService; + protected localisationService: LocalisationService; + protected weightedRandomHelper: WeightedRandomHelper; + protected profileHelper: ProfileHelper; protected configServer: ConfigServer; protected applicationContext: ApplicationContext; + protected jsonUtil: JsonUtil; protected botConfig: IBotConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, botGenerator: BotGenerator, botHelper: BotHelper, pmcAiService: PmcAiService, botGenerationCacheService: BotGenerationCacheService, configServer: ConfigServer, applicationContext: ApplicationContext); + static readonly pmcTypeLabel = "PMC"; + constructor(logger: ILogger, databaseServer: DatabaseServer, botGenerator: BotGenerator, botHelper: BotHelper, botDifficultyHelper: BotDifficultyHelper, botGenerationCacheService: BotGenerationCacheService, localisationService: LocalisationService, weightedRandomHelper: WeightedRandomHelper, profileHelper: ProfileHelper, configServer: ConfigServer, applicationContext: ApplicationContext, jsonUtil: JsonUtil); /** * Return the number of bot loadout varieties to be generated * @param type bot Type we want the loadout gen count for - * @returns + * @returns number of bots to generate */ getBotPresetGenerationLimit(type: string): number; + /** + * Get the core.json difficulty settings from database\bots + * @returns IBotCore + */ getBotCoreDifficulty(): IBotCore; /** * Get bot difficulty settings @@ -37,7 +50,6 @@ export declare class BotController { * @returns Difficulty object */ getBotDifficulty(type: string, difficulty: string): Difficulty; - protected getPmcDifficultySettings(pmcType: "bear" | "usec", difficulty: string, usecType: string, bearType: string): Difficulty; /** * Generate bot profiles and store in cache * @param sessionId Session id @@ -51,4 +63,5 @@ export declare class BotController { * @returns cap number */ getBotCap(): number; + getPmcBotTypes(): Record>>; } diff --git a/KcY-SeeItemValue/itemValue/server/types/controllers/DialogueController.d.ts b/KcY-SeeItemValue/itemValue/server/types/controllers/DialogueController.d.ts index 1b72522..9c8b728 100644 --- a/KcY-SeeItemValue/itemValue/server/types/controllers/DialogueController.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/controllers/DialogueController.d.ts @@ -23,7 +23,7 @@ export declare class DialogueController { * Get the content of a dialogue * @param dialogueID Dialog id * @param sessionID Session Id - * @returns + * @returns DialogueInfo */ getDialogueInfo(dialogueID: string, sessionID: string): DialogueInfo; /** diff --git a/KcY-SeeItemValue/itemValue/server/types/controllers/GameController.d.ts b/KcY-SeeItemValue/itemValue/server/types/controllers/GameController.d.ts index 3bfbdb1..f4f5849 100644 --- a/KcY-SeeItemValue/itemValue/server/types/controllers/GameController.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/controllers/GameController.d.ts @@ -1,3 +1,4 @@ +import { ApplicationContext } from "../context/ApplicationContext"; import { GameEventHelper } from "../helpers/GameEventHelper"; import { HttpServerHelper } from "../helpers/HttpServerHelper"; import { ProfileHelper } from "../helpers/ProfileHelper"; @@ -14,6 +15,7 @@ import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { LocaleService } from "../services/LocaleService"; +import { LocalisationService } from "../services/LocalisationService"; import { ProfileFixerService } from "../services/ProfileFixerService"; import { Watermark } from "../utils/Watermark"; export declare class GameController { @@ -24,14 +26,33 @@ export declare class GameController { protected localeService: LocaleService; protected profileHelper: ProfileHelper; protected profileFixerService: ProfileFixerService; + protected localisationService: LocalisationService; protected gameEventHelper: GameEventHelper; + protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected httpConfig: IHttpConfig; protected coreConfig: ICoreConfig; - constructor(logger: ILogger, databaseServer: DatabaseServer, watermark: Watermark, httpServerHelper: HttpServerHelper, localeService: LocaleService, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, gameEventHelper: GameEventHelper, configServer: ConfigServer); - gameStart(_url: string, _info: IEmptyRequestData, sessionID: string): void; + constructor(logger: ILogger, databaseServer: DatabaseServer, watermark: Watermark, httpServerHelper: HttpServerHelper, localeService: LocaleService, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, localisationService: LocalisationService, gameEventHelper: GameEventHelper, applicationContext: ApplicationContext, configServer: ConfigServer); + gameStart(_url: string, _info: IEmptyRequestData, sessionID: string, startTimeStampMS: number): void; + /** + * Check if current date falls inside any of the seasons events pased in, if so, handle them + * @param seasonalEvents events to check for + */ protected checkForAndEnableSeasonalEvents(seasonalEvents: ISeasonalEvent[]): void; + /** + * Make adjusted to server code based on the name of the event passed in + * @param globalConfig globals.json + * @param eventName Name of the event to enable. e.g. Christmas + */ protected updateGlobalEvents(globalConfig: Config, eventName: string): void; + /** + * Read in data from seasonalEvents.json and add found equipment items to bots + * @param eventName Name of the event to read equipment in from config + */ + protected addEventGearToScavs(eventName: string): void; + /** + * Set Khorovod(dancing tree) chance to 100% on all maps that support it + */ protected enableDancingTree(): void; /** * Make non-trigger-spawned raiders spawn earlier + always @@ -40,5 +61,6 @@ export declare class GameController { protected logProfileDetails(fullProfile: IAkiProfile): void; getGameConfig(sessionID: string): IGameConfigResponse; getServer(): IServerDetails[]; + protected addPumpkinsToScavBackpacks(): void; getValidGameVersion(): ICheckVersionResponse; } diff --git a/KcY-SeeItemValue/itemValue/server/types/controllers/HideoutController.d.ts b/KcY-SeeItemValue/itemValue/server/types/controllers/HideoutController.d.ts index ada5bd9..5b6507b 100644 --- a/KcY-SeeItemValue/itemValue/server/types/controllers/HideoutController.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/controllers/HideoutController.d.ts @@ -23,12 +23,13 @@ import { EventOutputHolder } from "../routers/EventOutputHolder"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { SaveServer } from "../servers/SaveServer"; +import { LocalisationService } from "../services/LocalisationService"; import { PlayerService } from "../services/PlayerService"; import { HashUtil } from "../utils/HashUtil"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; +import { JsonUtil } from "../utils/JsonUtil"; import { RandomUtil } from "../utils/RandomUtil"; import { TimeUtil } from "../utils/TimeUtil"; -import { JsonUtil } from "../utils/JsonUtil"; export declare class HideoutController { protected logger: ILogger; protected hashUtil: HashUtil; @@ -45,11 +46,12 @@ export declare class HideoutController { protected profileHelper: ProfileHelper; protected hideoutHelper: HideoutHelper; protected scavCaseRewardGenerator: ScavCaseRewardGenerator; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected jsonUtil: JsonUtil; protected static nameBackendCountersCrafting: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, randomUtil: RandomUtil, inventoryHelper: InventoryHelper, saveServer: SaveServer, playerService: PlayerService, presetHelper: PresetHelper, paymentHelper: PaymentHelper, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, profileHelper: ProfileHelper, hideoutHelper: HideoutHelper, scavCaseRewardGenerator: ScavCaseRewardGenerator, configServer: ConfigServer, jsonUtil: JsonUtil); + constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, randomUtil: RandomUtil, inventoryHelper: InventoryHelper, saveServer: SaveServer, playerService: PlayerService, presetHelper: PresetHelper, paymentHelper: PaymentHelper, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, profileHelper: ProfileHelper, hideoutHelper: HideoutHelper, scavCaseRewardGenerator: ScavCaseRewardGenerator, localisationService: LocalisationService, configServer: ConfigServer, jsonUtil: JsonUtil); upgrade(pmcData: IPmcData, body: IHideoutUpgradeRequestData, sessionID: string): IItemEventRouterResponse; upgradeComplete(pmcData: IPmcData, body: HideoutUpgradeCompleteRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/KcY-SeeItemValue/itemValue/server/types/controllers/InraidController.d.ts b/KcY-SeeItemValue/itemValue/server/types/controllers/InraidController.d.ts index e84eea1..39a6396 100644 --- a/KcY-SeeItemValue/itemValue/server/types/controllers/InraidController.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/controllers/InraidController.d.ts @@ -6,6 +6,7 @@ import { ProfileHelper } from "../helpers/ProfileHelper"; import { QuestHelper } from "../helpers/QuestHelper"; import { TraderHelper } from "../helpers/TraderHelper"; import { IPmcData } from "../models/eft/common/IPmcData"; +import { Item } from "../models/eft/common/tables/IItem"; import { IRegisterPlayerRequestData } from "../models/eft/inRaid/IRegisterPlayerRequestData"; import { ISaveProgressRequestData } from "../models/eft/inRaid/ISaveProgressRequestData"; import { IAirdropConfig } from "../models/spt/config/IAirdropConfig"; @@ -17,6 +18,9 @@ import { SaveServer } from "../servers/SaveServer"; import { InsuranceService } from "../services/InsuranceService"; import { JsonUtil } from "../utils/JsonUtil"; import { TimeUtil } from "../utils/TimeUtil"; +/** + * Logic for handling In Raid callbacks + */ export declare class InraidController { protected logger: ILogger; protected saveServer: SaveServer; @@ -35,14 +39,42 @@ export declare class InraidController { protected airdropConfig: IAirdropConfig; protected inraidConfig: IInRaidConfig; constructor(logger: ILogger, saveServer: SaveServer, jsonUtil: JsonUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, questHelper: QuestHelper, itemHelper: ItemHelper, profileHelper: ProfileHelper, playerScavGenerator: PlayerScavGenerator, healthHelper: HealthHelper, traderHelper: TraderHelper, insuranceService: InsuranceService, inRaidHelper: InRaidHelper, configServer: ConfigServer); - addPlayer(sessionID: string, info: IRegisterPlayerRequestData): void; - saveProgress(offraidData: ISaveProgressRequestData, sessionID: string): void; /** - * Handle updating the profile post-pmc raid + * Save locationid to active profiles inraid object + * @param sessionID Session id + * @param info Register player request + */ + addPlayer(sessionID: string, info: IRegisterPlayerRequestData): void; + /** + * Save profile state to disk + * Handles pmc/pscav + * @param offraidData post-raid request data + * @param sessionID Session id + */ + savePostRaidProgress(offraidData: ISaveProgressRequestData, sessionID: string): void; + /** + * Handle updating player profile post-pmc raid * @param sessionID session id - * @param offraidData post-raid data of raid + * @param offraidData post-raid data */ protected savePmcProgress(sessionID: string, offraidData: ISaveProgressRequestData): void; + /** + * Make changes to pmc profile after they left raid dead, + * alter bodypart hp, handle insurance, delete inventory items, remove carried quest items + * @param postRaidSaveRequest post-raid save request + * @param pmcData pmc profile + * @param insuranceEnabled is insurance enabled + * @param preRaidGear gear player had before raid + * @param sessionID Session id + * @returns Updated profile object + */ + protected performPostRaidActionsWhenDead(postRaidSaveRequest: ISaveProgressRequestData, pmcData: IPmcData, insuranceEnabled: boolean, preRaidGear: Item[], sessionID: string): IPmcData; + /** + * Adjust player characters bodypart hp if they left raid early + * @param postRaidSaveRequest post raid data + * @param pmcData player profile + */ + protected updatePmcHealthPostRaid(postRaidSaveRequest: ISaveProgressRequestData, pmcData: IPmcData): void; /** * Reduce body part hp to % of max * @param pmcData profile to edit @@ -68,7 +100,31 @@ export declare class InraidController { * @param isPlayerScav Was the player a pScav */ protected markOrRemoveFoundInRaidItems(offraidData: ISaveProgressRequestData, pmcData: IPmcData, isPlayerScav: boolean): void; + /** + * Update profile after player completes scav raid + * @param scavData Scav profile + * @param sessionID Session id + * @param offraidData Post-raid save request + * @param pmcData Pmc profile + * @param isDead Is player dead + */ protected handlePostRaidPlayerScavProcess(scavData: IPmcData, sessionID: string, offraidData: ISaveProgressRequestData, pmcData: IPmcData, isDead: boolean): void; + /** + * Update profile with scav karma values based on in-raid actions + * @param pmcData Pmc profile + * @param offraidData Post-raid save request + * @param scavData Scav profile + * @param sessionID Session id + */ protected handlePostRaidPlayerScavKarmaChanges(pmcData: IPmcData, offraidData: ISaveProgressRequestData, scavData: IPmcData, sessionID: string): void; + /** + * Get the inraid config from configs/inraid.json + * @returns InRaid Config + */ + getInraidConfig(): IInRaidConfig; + /** + * Get airdrop config from configs/airdrop.json + * @returns Airdrop config + */ getAirdropConfig(): IAirdropConfig; } diff --git a/KcY-SeeItemValue/itemValue/server/types/controllers/InsuranceController.d.ts b/KcY-SeeItemValue/itemValue/server/types/controllers/InsuranceController.d.ts index 14bf129..54f31b5 100644 --- a/KcY-SeeItemValue/itemValue/server/types/controllers/InsuranceController.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/controllers/InsuranceController.d.ts @@ -30,8 +30,7 @@ export declare class InsuranceController { protected insuranceService: InsuranceService; protected configServer: ConfigServer; protected insuranceConfig: IInsuranceConfig; - constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, paymentService: PaymentService, // TODO: delay required - insuranceService: InsuranceService, configServer: ConfigServer); + constructor(logger: ILogger, randomUtil: RandomUtil, eventOutputHolder: EventOutputHolder, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileHelper: ProfileHelper, dialogueHelper: DialogueHelper, paymentService: PaymentService, insuranceService: InsuranceService, configServer: ConfigServer); processReturn(): void; insure(pmcData: IPmcData, body: IInsureRequestData, sessionID: string): IItemEventRouterResponse; /** diff --git a/KcY-SeeItemValue/itemValue/server/types/controllers/InventoryController.d.ts b/KcY-SeeItemValue/itemValue/server/types/controllers/InventoryController.d.ts index 6a1a21e..e1c08c0 100644 --- a/KcY-SeeItemValue/itemValue/server/types/controllers/InventoryController.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/controllers/InventoryController.d.ts @@ -1,8 +1,8 @@ -import { EventOutputHolder } from "../routers/EventOutputHolder"; import { InventoryHelper } from "../helpers/InventoryHelper"; import { PaymentHelper } from "../helpers/PaymentHelper"; import { PresetHelper } from "../helpers/PresetHelper"; import { ProfileHelper } from "../helpers/ProfileHelper"; +import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper"; import { IPmcData } from "../models/eft/common/IPmcData"; import { IAddItemRequestData } from "../models/eft/inventory/IAddItemRequestData"; import { IInventoryBindRequestData } from "../models/eft/inventory/IInventoryBindRequestData"; @@ -21,33 +21,46 @@ import { IInventorySwapRequestData } from "../models/eft/inventory/IInventorySwa import { IInventoryTagRequestData } from "../models/eft/inventory/IInventoryTagRequestData"; import { IInventoryToggleRequestData } from "../models/eft/inventory/IInventoryToggleRequestData"; import { IInventoryTransferRequestData } from "../models/eft/inventory/IInventoryTransferRequestData"; +import { IOpenRandomLootContainerRequestData } from "../models/eft/inventory/IOpenRandomLootContainerRequestData"; import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse"; import { ILogger } from "../models/spt/utils/ILogger"; +import { EventOutputHolder } from "../routers/EventOutputHolder"; import { DatabaseServer } from "../servers/DatabaseServer"; import { FenceService } from "../services/FenceService"; +import { LocalisationService } from "../services/LocalisationService"; import { RagfairOfferService } from "../services/RagfairOfferService"; import { HashUtil } from "../utils/HashUtil"; +import { HttpResponseUtil } from "../utils/HttpResponseUtil"; import { JsonUtil } from "../utils/JsonUtil"; +import { RandomUtil } from "../utils/RandomUtil"; export declare class InventoryController { protected logger: ILogger; protected hashUtil: HashUtil; protected jsonUtil: JsonUtil; + protected randomUtil: RandomUtil; protected databaseServer: DatabaseServer; protected fenceService: FenceService; protected presetHelper: PresetHelper; protected inventoryHelper: InventoryHelper; protected ragfairOfferService: RagfairOfferService; protected profileHelper: ProfileHelper; + protected weightedRandomHelper: WeightedRandomHelper; protected paymentHelper: PaymentHelper; + protected localisationService: LocalisationService; protected eventOutputHolder: EventOutputHolder; - constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, fenceService: FenceService, presetHelper: PresetHelper, inventoryHelper: InventoryHelper, ragfairOfferService: RagfairOfferService, profileHelper: ProfileHelper, paymentHelper: PaymentHelper, eventOutputHolder: EventOutputHolder); + protected httpResponseUtil: HttpResponseUtil; + constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, fenceService: FenceService, presetHelper: PresetHelper, inventoryHelper: InventoryHelper, ragfairOfferService: RagfairOfferService, profileHelper: ProfileHelper, weightedRandomHelper: WeightedRandomHelper, paymentHelper: PaymentHelper, localisationService: LocalisationService, eventOutputHolder: EventOutputHolder, httpResponseUtil: HttpResponseUtil); /** * Move Item * change location of item with parentId and slotId * transfers items from one profile to another if fromOwner/toOwner is set in the body. * otherwise, move is contained within the same profile_f. - */ - moveItem(pmcData: IPmcData, body: IInventoryMoveRequestData, sessionID: string): IItemEventRouterResponse; + * @param pmcData Profile + * @param moveRequest Move request data + * @param sessionID Session id + * @returns IItemEventRouterResponse + */ + moveItem(pmcData: IPmcData, moveRequest: IInventoryMoveRequestData, sessionID: string): IItemEventRouterResponse; /** * Remove Item from Profile * Deep tree item deletion, also removes items from insurance list @@ -122,4 +135,12 @@ export declare class InventoryController { createMapMarker(pmcData: IPmcData, body: IInventoryCreateMarkerRequestData, sessionID: string): IItemEventRouterResponse; deleteMapMarker(pmcData: IPmcData, body: IInventoryDeleteMarkerRequestData, sessionID: string): IItemEventRouterResponse; editMapMarker(pmcData: IPmcData, body: IInventoryEditMarkerRequestData, sessionID: string): IItemEventRouterResponse; + /** + * Handle event fired when a container is unpacked (currently only the halloween pumpkin) + * @param pmcData Profile data + * @param body open loot container request data + * @param sessionID Session id + * @returns IItemEventRouterResponse + */ + openRandomLootContainer(pmcData: IPmcData, body: IOpenRandomLootContainerRequestData, sessionID: string): IItemEventRouterResponse; } diff --git a/KcY-SeeItemValue/itemValue/server/types/controllers/LocationController.d.ts b/KcY-SeeItemValue/itemValue/server/types/controllers/LocationController.d.ts index 9db3205..b6feba8 100644 --- a/KcY-SeeItemValue/itemValue/server/types/controllers/LocationController.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/controllers/LocationController.d.ts @@ -7,6 +7,7 @@ import { LootItem } from "../models/spt/services/LootItem"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "../services/LocalisationService"; import { HashUtil } from "../utils/HashUtil"; import { JsonUtil } from "../utils/JsonUtil"; import { TimeUtil } from "../utils/TimeUtil"; @@ -15,12 +16,13 @@ export declare class LocationController { protected hashUtil: HashUtil; protected logger: ILogger; protected locationGenerator: LocationGenerator; + protected localisationService: LocalisationService; protected lootGenerator: LootGenerator; protected databaseServer: DatabaseServer; protected timeUtil: TimeUtil; protected configServer: ConfigServer; protected airdropConfig: IAirdropConfig; - constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger, locationGenerator: LocationGenerator, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); + constructor(jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger, locationGenerator: LocationGenerator, localisationService: LocalisationService, lootGenerator: LootGenerator, databaseServer: DatabaseServer, timeUtil: TimeUtil, configServer: ConfigServer); get(location: string): ILocationBase; generate(name: string): ILocationBase; generateAll(): ILocationsGenerateAllResponse; diff --git a/KcY-SeeItemValue/itemValue/server/types/controllers/MatchController.d.ts b/KcY-SeeItemValue/itemValue/server/types/controllers/MatchController.d.ts index dac6a3f..2b0d150 100644 --- a/KcY-SeeItemValue/itemValue/server/types/controllers/MatchController.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/controllers/MatchController.d.ts @@ -19,7 +19,6 @@ import { SaveServer } from "../servers/SaveServer"; import { BotGenerationCacheService } from "../services/BotGenerationCacheService"; import { BotLootCacheService } from "../services/BotLootCacheService"; import { MatchLocationService } from "../services/MatchLocationService"; -import { PmcAiService } from "../services/PmcAiService"; import { ProfileSnapshotService } from "../services/ProfileSnapshotService"; export declare class MatchController { protected logger: ILogger; @@ -30,13 +29,12 @@ export declare class MatchController { protected botLootCacheService: BotLootCacheService; protected configServer: ConfigServer; protected profileSnapshotService: ProfileSnapshotService; - protected pmcAiService: PmcAiService; protected botGenerationCacheService: BotGenerationCacheService; protected applicationContext: ApplicationContext; protected matchConfig: IMatchConfig; protected inraidConfig: IInRaidConfig; protected botConfig: IBotConfig; - constructor(logger: ILogger, saveServer: SaveServer, profileHelper: ProfileHelper, matchLocationService: MatchLocationService, traderHelper: TraderHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer, profileSnapshotService: ProfileSnapshotService, pmcAiService: PmcAiService, botGenerationCacheService: BotGenerationCacheService, applicationContext: ApplicationContext); + constructor(logger: ILogger, saveServer: SaveServer, profileHelper: ProfileHelper, matchLocationService: MatchLocationService, traderHelper: TraderHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer, profileSnapshotService: ProfileSnapshotService, botGenerationCacheService: BotGenerationCacheService, applicationContext: ApplicationContext); getEnabled(): boolean; getProfile(info: IGetProfileRequestData): IPmcData[]; createGroup(sessionID: string, info: ICreateGroupRequestData): any; diff --git a/KcY-SeeItemValue/itemValue/server/types/controllers/RagfairController.d.ts b/KcY-SeeItemValue/itemValue/server/types/controllers/RagfairController.d.ts index 5440458..95702f2 100644 --- a/KcY-SeeItemValue/itemValue/server/types/controllers/RagfairController.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/controllers/RagfairController.d.ts @@ -29,6 +29,7 @@ import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { RagfairServer } from "../servers/RagfairServer"; import { SaveServer } from "../servers/SaveServer"; +import { LocalisationService } from "../services/LocalisationService"; import { PaymentService } from "../services/PaymentService"; import { RagfairOfferService } from "../services/RagfairOfferService"; import { RagfairPriceService } from "../services/RagfairPriceService"; @@ -62,9 +63,10 @@ export declare class RagfairController { protected ragfairOfferService: RagfairOfferService; protected ragfairRequiredItemsService: RagfairRequiredItemsService; protected ragfairOfferGenerator: RagfairOfferGenerator; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected ragfairConfig: IRagfairConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, eventOutputHolder: EventOutputHolder, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, traderHelper: TraderHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, httpResponse: HttpResponseUtil, eventOutputHolder: EventOutputHolder, ragfairServer: RagfairServer, ragfairPriceService: RagfairPriceService, databaseServer: DatabaseServer, itemHelper: ItemHelper, saveServer: SaveServer, ragfairSellHelper: RagfairSellHelper, ragfairTaxHelper: RagfairTaxHelper, ragfairSortHelper: RagfairSortHelper, ragfairOfferHelper: RagfairOfferHelper, profileHelper: ProfileHelper, paymentService: PaymentService, handbookHelper: HandbookHelper, paymentHelper: PaymentHelper, inventoryHelper: InventoryHelper, traderHelper: TraderHelper, ragfairHelper: RagfairHelper, ragfairOfferService: RagfairOfferService, ragfairRequiredItemsService: RagfairRequiredItemsService, ragfairOfferGenerator: RagfairOfferGenerator, localisationService: LocalisationService, configServer: ConfigServer); getOffers(sessionID: string, info: ISearchRequestData): IGetOffersResult; /** * Get offers for the client based on type of search being performed @@ -103,7 +105,12 @@ export declare class RagfairController { protected isLinkedSearch(info: ISearchRequestData): boolean; protected isRequiredSearch(info: ISearchRequestData): boolean; update(): void; - getItemPrice(info: IGetMarketPriceRequestData): IGetItemPriceResult; + /** + * Called when creating an offer on flea, fills values in top right corner + * @param getPriceRequest + * @returns min/avg/max values for an item based on flea offers available + */ + getItemMinAvgMaxFleaPriceValues(getPriceRequest: IGetMarketPriceRequestData): IGetItemPriceResult; addPlayerOffer(pmcData: IPmcData, info: IAddOfferRequestData, sessionID: string): IItemEventRouterResponse; createPlayerOffer(profile: IAkiProfile, requirements: Requirement[], items: Item[], sellInOnePiece: boolean, amountToSend: number): IRagfairOffer; getAllFleaPrices(): Record; diff --git a/KcY-SeeItemValue/itemValue/server/types/controllers/RepeatableQuestController.d.ts b/KcY-SeeItemValue/itemValue/server/types/controllers/RepeatableQuestController.d.ts index 7db5886..333583b 100644 --- a/KcY-SeeItemValue/itemValue/server/types/controllers/RepeatableQuestController.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/controllers/RepeatableQuestController.d.ts @@ -17,6 +17,7 @@ import { EventOutputHolder } from "../routers/EventOutputHolder"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { ItemFilterService } from "../services/ItemFilterService"; +import { LocalisationService } from "../services/LocalisationService"; import { PaymentService } from "../services/PaymentService"; import { ProfileFixerService } from "../services/ProfileFixerService"; import { JsonUtil } from "../utils/JsonUtil"; @@ -64,12 +65,13 @@ export declare class RepeatableQuestController { protected profileFixerService: ProfileFixerService; protected ragfairServerHelper: RagfairServerHelper; protected eventOutputHolder: EventOutputHolder; + protected localisationService: LocalisationService; protected paymentService: PaymentService; protected objectId: ObjectId; protected itemFilterService: ItemFilterService; protected configServer: ConfigServer; protected questConfig: IQuestConfig; - constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, eventOutputHolder: EventOutputHolder, paymentService: PaymentService, objectId: ObjectId, itemFilterService: ItemFilterService, configServer: ConfigServer); + constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, eventOutputHolder: EventOutputHolder, localisationService: LocalisationService, paymentService: PaymentService, objectId: ObjectId, itemFilterService: ItemFilterService, configServer: ConfigServer); /** * This is the method reached by the /client/repeatalbeQuests/activityPeriods endpoint * Returns an array of objects in the format of repeatable quests to the client. diff --git a/KcY-SeeItemValue/itemValue/server/types/controllers/WeatherController.d.ts b/KcY-SeeItemValue/itemValue/server/types/controllers/WeatherController.d.ts index ca7f5eb..631a90c 100644 --- a/KcY-SeeItemValue/itemValue/server/types/controllers/WeatherController.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/controllers/WeatherController.d.ts @@ -1,11 +1,18 @@ import { WeatherGenerator } from "../generators/WeatherGenerator"; import { IWeatherData } from "../models/eft/weather/IWeatherData"; import { IWeatherConfig } from "../models/spt/config/IWeatherConfig"; +import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; export declare class WeatherController { protected weatherGenerator: WeatherGenerator; + protected logger: ILogger; protected configServer: ConfigServer; protected weatherConfig: IWeatherConfig; - constructor(weatherGenerator: WeatherGenerator, configServer: ConfigServer); + constructor(weatherGenerator: WeatherGenerator, logger: ILogger, configServer: ConfigServer); generate(): IWeatherData; + /** + * Get the current in-raid time (MUST HAVE PLAYER LOGGED INTO CLIENT TO WORK) + * @returns Date object + */ + getCurrentInRaidTime(): Date; } diff --git a/KcY-SeeItemValue/itemValue/server/types/generators/BotGenerator.d.ts b/KcY-SeeItemValue/itemValue/server/types/generators/BotGenerator.d.ts index 2ac51db..08ad50a 100644 --- a/KcY-SeeItemValue/itemValue/server/types/generators/BotGenerator.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/generators/BotGenerator.d.ts @@ -1,25 +1,21 @@ +import { BotDifficultyHelper } from "../helpers/BotDifficultyHelper"; import { BotHelper } from "../helpers/BotHelper"; import { GameEventHelper } from "../helpers/GameEventHelper"; import { ProfileHelper } from "../helpers/ProfileHelper"; -import { IGenerateBotsRequestData } from "../models/eft/bot/IGenerateBotsRequestData"; +import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper"; import { Health as PmcHealth, IBotBase, Skills } from "../models/eft/common/tables/IBotBase"; import { Health, IBotType, Inventory } from "../models/eft/common/tables/IBotType"; +import { BotGenerationDetails } from "../models/spt/bots/BotGenerationDetails"; import { IBotConfig } from "../models/spt/config/IBotConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { BotEquipmentFilterService } from "../services/BotEquipmentFilterService"; -import { PmcAiService } from "../services/PmcAiService"; import { HashUtil } from "../utils/HashUtil"; import { JsonUtil } from "../utils/JsonUtil"; import { RandomUtil } from "../utils/RandomUtil"; import { BotInventoryGenerator } from "./BotInventoryGenerator"; -declare namespace BotGenerator { - interface IRandomisedBotLevelResult { - level: number; - exp: number; - } -} +import { BotLevelGenerator } from "./BotLevelGenerator"; export declare class BotGenerator { protected logger: ILogger; protected hashUtil: HashUtil; @@ -28,13 +24,15 @@ export declare class BotGenerator { protected profileHelper: ProfileHelper; protected databaseServer: DatabaseServer; protected botInventoryGenerator: BotInventoryGenerator; + protected botLevelGenerator: BotLevelGenerator; protected botEquipmentFilterService: BotEquipmentFilterService; + protected weightedRandomHelper: WeightedRandomHelper; protected botHelper: BotHelper; + protected botDifficultyHelper: BotDifficultyHelper; protected gameEventHelper: GameEventHelper; - protected pmcAiService: PmcAiService; protected configServer: ConfigServer; protected botConfig: IBotConfig; - constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, jsonUtil: JsonUtil, profileHelper: ProfileHelper, databaseServer: DatabaseServer, botInventoryGenerator: BotInventoryGenerator, botEquipmentFilterService: BotEquipmentFilterService, botHelper: BotHelper, gameEventHelper: GameEventHelper, pmcAiService: PmcAiService, configServer: ConfigServer); + constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, jsonUtil: JsonUtil, profileHelper: ProfileHelper, databaseServer: DatabaseServer, botInventoryGenerator: BotInventoryGenerator, botLevelGenerator: BotLevelGenerator, botEquipmentFilterService: BotEquipmentFilterService, weightedRandomHelper: WeightedRandomHelper, botHelper: BotHelper, botDifficultyHelper: BotDifficultyHelper, gameEventHelper: GameEventHelper, configServer: ConfigServer); /** * Generate a player scav bot object * @param role e.g. assault / pmcbot @@ -44,12 +42,18 @@ export declare class BotGenerator { */ generatePlayerScav(sessionId: string, role: string, difficulty: string, botTemplate: IBotType): IBotBase; /** - * Generate an array of bot objects for populate a raid with + * Generate an array of bot objects based on a condition for a raid with * @param sessionId session id - * @param info request object - * @returns bot array + * @param botGenerationDetails details on how to generate the bots + * @returns Generated bots in array */ - generate(sessionId: string, info: IGenerateBotsRequestData): IBotBase[]; + generateByCondition(sessionId: string, botGenerationDetails: BotGenerationDetails): IBotBase[]; + /** + * Get the PMCs wildSpawnType value + * @param role "usec" / "bear" + * @returns wildSpawnType value as string + */ + protected getPmcRoleByDescription(role: string): string; /** * Get a randomised PMC side based on bot config value 'isUsec' * @returns pmc side as string @@ -64,26 +68,24 @@ export declare class BotGenerator { * Create a IBotBase object with equipment/loot/exp etc * @param sessionId Session id * @param bot bots base file - * @param role botRole bot will use - * @param node Bot template from db/bots/x.json - * @param isPmc Is bot to be a PMC - * @param isPlayerScav is bot to be a p scav bot + * @param botJsonTemplate Bot template from db/bots/x.json + * @param botGenerationDetails details on how to generate the bot * @returns IBotBase object */ - protected generateBot(sessionId: string, bot: IBotBase, role: string, node: IBotType, isPmc: boolean, isPlayerScav?: boolean): IBotBase; + protected generateBot(sessionId: string, bot: IBotBase, botJsonTemplate: IBotType, botGenerationDetails: BotGenerationDetails): IBotBase; + /** + * Create a bot nickname + * @param botJsonTemplate x.json from database + * @param isPlayerScav Will bot be player scav + * @param botRole role of bot e.g. assault + * @returns Nickname for bot + */ + protected generateBotNickname(botJsonTemplate: IBotType, isPlayerScav: boolean, botRole: string): string; /** * Log the number of PMCs generated to the debug console * @param output Generated bot array, ready to send to client */ protected logPmcGeneratedCount(output: IBotBase[]): void; - /** - * Return a randomised bot level and exp value - * @param role botRole being generated for - * @param min Min exp value - * @param max Max exp value - * @returns IRandomisedBotLevelResult object - */ - protected generateRandomLevel(role: string, min: number, max: number): BotGenerator.IRandomisedBotLevelResult; /** * Converts health object to the required format * @param healthObj health object from bot json @@ -117,4 +119,3 @@ export declare class BotGenerator { */ protected generateDogtag(bot: IBotBase): IBotBase; } -export {}; diff --git a/KcY-SeeItemValue/itemValue/server/types/generators/BotInventoryGenerator.d.ts b/KcY-SeeItemValue/itemValue/server/types/generators/BotInventoryGenerator.d.ts index c5ed545..a3b5eaa 100644 --- a/KcY-SeeItemValue/itemValue/server/types/generators/BotInventoryGenerator.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/generators/BotInventoryGenerator.d.ts @@ -1,12 +1,14 @@ import { BotGeneratorHelper } from "../helpers/BotGeneratorHelper"; +import { BotHelper } from "../helpers/BotHelper"; import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper"; import { Inventory as PmcInventory } from "../models/eft/common/tables/IBotBase"; -import { Chances, Generation, Inventory, Mods } from "../models/eft/common/tables/IBotType"; +import { Chances, Generation, IBotType, Inventory, Mods } from "../models/eft/common/tables/IBotType"; import { EquipmentSlots } from "../models/enums/EquipmentSlots"; -import { IBotConfig } from "../models/spt/config/IBotConfig"; +import { IBotConfig, RandomisationDetails } from "../models/spt/config/IBotConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "../services/LocalisationService"; import { HashUtil } from "../utils/HashUtil"; import { RandomUtil } from "../utils/RandomUtil"; import { BotLootGenerator } from "./BotLootGenerator"; @@ -19,15 +21,81 @@ export declare class BotInventoryGenerator { protected botWeaponGenerator: BotWeaponGenerator; protected botLootGenerator: BotLootGenerator; protected botGeneratorHelper: BotGeneratorHelper; + protected botHelper: BotHelper; protected weightedRandomHelper: WeightedRandomHelper; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected botConfig: IBotConfig; - constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, botWeaponGenerator: BotWeaponGenerator, botLootGenerator: BotLootGenerator, botGeneratorHelper: BotGeneratorHelper, weightedRandomHelper: WeightedRandomHelper, configServer: ConfigServer); - generateInventory(sessionId: string, templateInventory: Inventory, equipmentChances: Chances, itemGenerationLimitsMinMax: Generation, botRole: string, isPmc: boolean): PmcInventory; + constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, botWeaponGenerator: BotWeaponGenerator, botLootGenerator: BotLootGenerator, botGeneratorHelper: BotGeneratorHelper, botHelper: BotHelper, weightedRandomHelper: WeightedRandomHelper, localisationService: LocalisationService, configServer: ConfigServer); + /** + * Add equipment/weapons/loot to bot + * @param sessionId Session id + * @param botJsonTemplate bot/x.json data from db + * @param botRole Role bot has (assault/pmcBot) + * @param isPmc Is bot being converted into a pmc + * @param botLevel Level of bot being generated + * @returns PmcInventory object with equipment/weapons/loot + */ + generateInventory(sessionId: string, botJsonTemplate: IBotType, botRole: string, isPmc: boolean, botLevel: number): PmcInventory; + /** + * Create a pmcInventory object with all the base/generic items needed + * @returns PmcInventory object + */ + protected generateInventoryBase(): PmcInventory; + /** + * Add equipment to a bot + * @param templateInventory bot/x.json data from db + * @param equipmentChances Chances items will be added to bot + * @param botRole Role bot has (assault/pmcBot) + * @param botInventory Inventory to add equipment to + * @param botLevel Level of bot + */ + protected generateAndAddEquipmentToBot(templateInventory: Inventory, equipmentChances: Chances, botRole: string, botInventory: PmcInventory, botLevel: number): void; + /** + * Add a piece of equipment with mods to inventory from the provided pools + * @param equipmentSlot Slot to select an item for + * @param equipmentPool Possible items to choose from + * @param modPool Possible mods to apply to item chosen + * @param spawnChances Chances items will be chosen to be added + * @param botRole Role of bot e.g. assault + * @param inventory Inventory to add item into + * @param randomisationDetails settings from bot.json to adjust how item is generated + */ + protected generateEquipment(equipmentSlot: string, equipmentPool: Record, modPool: Mods, spawnChances: Chances, botRole: string, inventory: PmcInventory, randomisationDetails: RandomisationDetails): void; + /** + * Work out what weapons bot should have equipped and add them to bot inventory + * @param templateInventory bot/x.json data from db + * @param equipmentChances Chances bot can have equipment equipped + * @param sessionId Session id + * @param botInventory Inventory to add weapons to + * @param botRole assault/pmcBot/bossTagilla etc + * @param isPmc Is the bot being generated as a pmc + * @param botLevel level of bot having weapon generated + * @param itemGenerationLimitsMinMax Limits for items the bot can have + */ + protected generateAndAddWeaponsToBot(templateInventory: Inventory, equipmentChances: Chances, sessionId: string, botInventory: PmcInventory, botRole: string, isPmc: boolean, itemGenerationLimitsMinMax: Generation, botLevel: number): void; + /** + * Calculate if the bot should have weapons in Primary/Secondary/Holster slots + * @param equipmentChances Chances bot has certain equipment + * @returns What slots bot should have weapons generated for + */ + protected getDesiredWeaponsForBot(equipmentChances: Chances): { + slot: EquipmentSlots; + shouldSpawn: boolean; + }[]; + /** + * Add weapon + spare mags/ammo to bots inventory + * @param sessionId Session id + * @param weaponSlot Weapon slot being generated + * @param templateInventory bot/x.json data from db + * @param botInventory Inventory to add weapon+mags/ammo to + * @param equipmentChances Chances bot can have equipment equipped + * @param botRole assault/pmcBot/bossTagilla etc + * @param isPmc Is the bot being generated as a pmc + * @param itemGenerationLimitsMinMax + */ protected addWeaponAndMagazinesToInventory(sessionId: string, weaponSlot: { slot: EquipmentSlots; shouldSpawn: boolean; - }, templateInventory: Inventory, botInventory: PmcInventory, equipmentChances: Chances, botRole: string, isPmc: boolean, itemGenerationLimitsMinMax: Generation): void; - protected generateEquipment(equipmentSlot: string, equipmentPool: Record, modPool: Mods, spawnChances: Chances, botRole: string, inventory: PmcInventory): void; - protected generateInventoryBase(): PmcInventory; + }, templateInventory: Inventory, botInventory: PmcInventory, equipmentChances: Chances, botRole: string, isPmc: boolean, itemGenerationLimitsMinMax: Generation, botLevel: number): void; } diff --git a/KcY-SeeItemValue/itemValue/server/types/generators/BotLevelGenerator.d.ts b/KcY-SeeItemValue/itemValue/server/types/generators/BotLevelGenerator.d.ts new file mode 100644 index 0000000..751e6e6 --- /dev/null +++ b/KcY-SeeItemValue/itemValue/server/types/generators/BotLevelGenerator.d.ts @@ -0,0 +1,29 @@ +import { MinMax } from "../models/common/MinMax"; +import { IRandomisedBotLevelResult } from "../models/eft/bot/IRandomisedBotLevelResult"; +import { ExpTable } from "../models/eft/common/IGlobals"; +import { IBotBase } from "../models/eft/common/tables/IBotBase"; +import { BotGenerationDetails } from "../models/spt/bots/BotGenerationDetails"; +import { ILogger } from "../models/spt/utils/ILogger"; +import { DatabaseServer } from "../servers/DatabaseServer"; +import { RandomUtil } from "../utils/RandomUtil"; +export declare class BotLevelGenerator { + protected logger: ILogger; + protected randomUtil: RandomUtil; + protected databaseServer: DatabaseServer; + constructor(logger: ILogger, randomUtil: RandomUtil, databaseServer: DatabaseServer); + /** + * Return a randomised bot level and exp value + * @param levelDetails min and max of level for bot + * @param botGenerationDetails Deatils to help generate a bot + * @param bot being level is being generated for + * @returns IRandomisedBotLevelResult object + */ + generateBotLevel(levelDetails: MinMax, botGenerationDetails: BotGenerationDetails, bot: IBotBase): IRandomisedBotLevelResult; + /** + * Get the highest level a bot can be relative to the players level, but no futher than the max size from globals.exp_table + * @param playerLevel Players current level + * @param relativeDeltaMax max delta above player level to go + * @returns highest level possible for bot + */ + protected getHighestRelativeBotLevel(playerLevel: number, relativeDeltaMax: number, levelDetails: MinMax, expTable: ExpTable[]): number; +} diff --git a/KcY-SeeItemValue/itemValue/server/types/generators/BotLootGenerator.d.ts b/KcY-SeeItemValue/itemValue/server/types/generators/BotLootGenerator.d.ts index c1f5310..6273a11 100644 --- a/KcY-SeeItemValue/itemValue/server/types/generators/BotLootGenerator.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/generators/BotLootGenerator.d.ts @@ -10,6 +10,7 @@ import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { BotLootCacheService } from "../services/BotLootCacheService"; +import { LocalisationService } from "../services/LocalisationService"; import { HashUtil } from "../utils/HashUtil"; import { RandomUtil } from "../utils/RandomUtil"; import { BotWeaponGenerator } from "./BotWeaponGenerator"; @@ -23,10 +24,22 @@ export declare class BotLootGenerator { protected botWeaponGenerator: BotWeaponGenerator; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; protected botLootCacheService: BotLootCacheService; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected botConfig: IBotConfig; - constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, botGeneratorHelper: BotGeneratorHelper, botWeaponGenerator: BotWeaponGenerator, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer); - generateLoot(sessionId: string, templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances): void; + constructor(logger: ILogger, hashUtil: HashUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, botGeneratorHelper: BotGeneratorHelper, botWeaponGenerator: BotWeaponGenerator, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, botLootCacheService: BotLootCacheService, localisationService: LocalisationService, configServer: ConfigServer); + /** + * Add loot to bots containers + * @param sessionId Session id + * @param templateInventory x.json from database/bots + * @param itemCounts Liits on item types to be added as loot + * @param isPmc Will bot be a pmc + * @param botRole Role of bot, e.g. asssult + * @param botInventory Inventory to add loot to + * @param equipmentChances + * @param botLevel Level of bot + */ + generateLoot(sessionId: string, templateInventory: Inventory, itemCounts: ItemMinMax, isPmc: boolean, botRole: string, botInventory: PmcInventory, equipmentChances: Chances, botLevel: number): void; protected getRandomisedCount(min: number, max: number, nValue: number): number; /** * Take random items from a pool and add to an inventory until totalItemCount or totalValueLimit is reached @@ -49,7 +62,7 @@ export declare class BotLootGenerator { * @param botRole bots role, .e.g. pmcBot * @param isPmc are we generating for a pmc */ - protected addLooseWeaponsToInventorySlot(sessionId: string, botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean): void; + protected addLooseWeaponsToInventorySlot(sessionId: string, botInventory: PmcInventory, equipmentSlot: string, templateInventory: Inventory, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): void; /** * Get a random item from the pool parameter using the biasedRandomNumber system * @param pool pool of items to pick an item from @@ -113,7 +126,7 @@ export declare class BotLootGenerator { * If no limit found for a non pmc bot, fall back to defaults * @param isPmc is the bot we want limits for a pmc * @param botRole what role does the bot have - * @returns dictionary of tplIds and limit + * @returns Dictionary of tplIds and limit */ protected getItemSpawnLimitsForBotType(isPmc: boolean, botRole: string): Record; /** diff --git a/KcY-SeeItemValue/itemValue/server/types/generators/BotWeaponGenerator.d.ts b/KcY-SeeItemValue/itemValue/server/types/generators/BotWeaponGenerator.d.ts index 487901b..b2eaf3b 100644 --- a/KcY-SeeItemValue/itemValue/server/types/generators/BotWeaponGenerator.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/generators/BotWeaponGenerator.d.ts @@ -12,6 +12,7 @@ import { IBotConfig } from "../models/spt/config/IBotConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "../services/LocalisationService"; import { HashUtil } from "../utils/HashUtil"; import { JsonUtil } from "../utils/JsonUtil"; import { RandomUtil } from "../utils/RandomUtil"; @@ -27,10 +28,11 @@ export declare class BotWeaponGenerator { protected randomUtil: RandomUtil; protected configServer: ConfigServer; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; + protected localisationService: LocalisationService; protected inventoryMagGenComponents: IInventoryMagGen[]; protected readonly modMagazineSlotId = "mod_magazine"; protected botConfig: IBotConfig; - constructor(jsonUtil: JsonUtil, logger: ILogger, hashUtil: HashUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, weightedRandomHelper: WeightedRandomHelper, botGeneratorHelper: BotGeneratorHelper, randomUtil: RandomUtil, configServer: ConfigServer, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, inventoryMagGenComponents: IInventoryMagGen[]); + constructor(jsonUtil: JsonUtil, logger: ILogger, hashUtil: HashUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, weightedRandomHelper: WeightedRandomHelper, botGeneratorHelper: BotGeneratorHelper, randomUtil: RandomUtil, configServer: ConfigServer, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, localisationService: LocalisationService, inventoryMagGenComponents: IInventoryMagGen[]); /** * Pick a random weapon based on weightings and generate a functional weapon * @param equipmentSlot Primary/secondary/holster @@ -41,7 +43,7 @@ export declare class BotWeaponGenerator { * @param isPmc Is weapon generated for a pmc * @returns GenerateWeaponResult object */ - generateRandomWeapon(sessionId: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult; + generateRandomWeapon(sessionId: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** * Get a random weighted weapon from a bots pool of weapons * @param equipmentSlot Primary/secondary/holster @@ -60,7 +62,7 @@ export declare class BotWeaponGenerator { * @param isPmc * @returns GenerateWeaponResult object */ - generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean): GenerateWeaponResult; + generateWeaponByTpl(sessionId: string, weaponTpl: string, equipmentSlot: string, botTemplateInventory: Inventory, weaponParentId: string, modChances: ModsChances, botRole: string, isPmc: boolean, botLevel: number): GenerateWeaponResult; /** * Create array with weapon base as only element and * add additional properties based on weapon type diff --git a/KcY-SeeItemValue/itemValue/server/types/generators/RagfairOfferGenerator.d.ts b/KcY-SeeItemValue/itemValue/server/types/generators/RagfairOfferGenerator.d.ts index b64a7e7..23882d2 100644 --- a/KcY-SeeItemValue/itemValue/server/types/generators/RagfairOfferGenerator.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/generators/RagfairOfferGenerator.d.ts @@ -1,16 +1,19 @@ +import { HandbookHelper } from "../helpers/HandbookHelper"; import { ItemHelper } from "../helpers/ItemHelper"; +import { PaymentHelper } from "../helpers/PaymentHelper"; import { PresetHelper } from "../helpers/PresetHelper"; import { RagfairServerHelper } from "../helpers/RagfairServerHelper"; import { Item } from "../models/eft/common/tables/IItem"; import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem"; import { IBarterScheme } from "../models/eft/common/tables/ITrader"; -import { IRagfairOffer } from "../models/eft/ragfair/IRagfairOffer"; +import { IRagfairOffer, OfferRequirement } from "../models/eft/ragfair/IRagfairOffer"; import { IRagfairConfig } from "../models/spt/config/IRagfairConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { SaveServer } from "../servers/SaveServer"; import { FenceService } from "../services/FenceService"; +import { LocalisationService } from "../services/LocalisationService"; import { RagfairCategoriesService } from "../services/RagfairCategoriesService"; import { RagfairOfferService } from "../services/RagfairOfferService"; import { RagfairPriceService } from "../services/RagfairPriceService"; @@ -27,18 +30,31 @@ export declare class RagfairOfferGenerator { protected timeUtil: TimeUtil; protected databaseServer: DatabaseServer; protected ragfairServerHelper: RagfairServerHelper; + protected handbookHelper: HandbookHelper; protected saveServer: SaveServer; protected presetHelper: PresetHelper; protected ragfairAssortGenerator: RagfairAssortGenerator; protected ragfairOfferService: RagfairOfferService; protected ragfairPriceService: RagfairPriceService; + protected localisationService: LocalisationService; + protected paymentHelper: PaymentHelper; protected ragfairCategoriesService: RagfairCategoriesService; protected fenceService: FenceService; protected itemHelper: ItemHelper; protected configServer: ConfigServer; protected ragfairConfig: IRagfairConfig; - constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, ragfairServerHelper: RagfairServerHelper, saveServer: SaveServer, presetHelper: PresetHelper, ragfairAssortGenerator: RagfairAssortGenerator, ragfairOfferService: RagfairOfferService, ragfairPriceService: RagfairPriceService, ragfairCategoriesService: RagfairCategoriesService, fenceService: FenceService, itemHelper: ItemHelper, configServer: ConfigServer); + protected allowedFleaPriceItemsForBarter: { + tpl: string; + price: number; + }[]; + constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, ragfairServerHelper: RagfairServerHelper, handbookHelper: HandbookHelper, saveServer: SaveServer, presetHelper: PresetHelper, ragfairAssortGenerator: RagfairAssortGenerator, ragfairOfferService: RagfairOfferService, ragfairPriceService: RagfairPriceService, localisationService: LocalisationService, paymentHelper: PaymentHelper, ragfairCategoriesService: RagfairCategoriesService, fenceService: FenceService, itemHelper: ItemHelper, configServer: ConfigServer); createOffer(userID: string, time: number, items: Item[], barterScheme: IBarterScheme[], loyalLevel: number, price: number, sellInOnePiece?: boolean): IRagfairOffer; + /** + * Calculate the offer price that's listed on the flea listing + * @param offerRequirements barter requirements for offer + * @returns rouble cost of offer + */ + protected calculateOfferListingPrice(offerRequirements: OfferRequirement[]): number; /** * Get avatar url from trader table in db * @param isTrader Is user we're getting avatar for a trader @@ -87,20 +103,36 @@ export declare class RagfairOfferGenerator { * @returns Item with conditions added */ protected addMissingCondition(item: Item): Item; - protected getOfferRequirements(items: Item[]): { - count: number; - _tpl: string; + /** + * Create a barter-based barter scheme, if not possible, fall back to making barter scheme currency based + * @param offerItems Items for sale in offer + * @returns barter scheme + */ + protected createBarterRequirement(offerItems: Item[]): IBarterScheme[]; + /** + * Get an array of flea prices + item tpl, cached in generator class + * @returns array with tpl/price values + */ + protected getFleaPricesAsArray(): { + tpl: string; + price: number; }[]; + /** + * Create a random currency-based barter scheme for an array of items + * @param offerItems Items on offer + * @returns Barter scheme for offer + */ + protected createCurrencyRequirement(offerItems: Item[]): IBarterScheme[]; /** * Create a flea offer and store it in the Ragfair server offers array * @param userID owner of the offer * @param time time offer is put up * @param items items in the offer - * @param barterScheme - * @param loyalLevel + * @param barterScheme cost of item (currency or barter) + * @param loyalLevel Loyalty level needed to buy item * @param price price of offer * @param sellInOnePiece - * @returns + * @returns Ragfair offer */ createFleaOffer(userID: string, time: number, items: Item[], barterScheme: IBarterScheme[], loyalLevel: number, price: number, sellInOnePiece?: boolean): IRagfairOffer; } diff --git a/KcY-SeeItemValue/itemValue/server/types/generators/WeatherGenerator.d.ts b/KcY-SeeItemValue/itemValue/server/types/generators/WeatherGenerator.d.ts index 8ddbe49..65d2c76 100644 --- a/KcY-SeeItemValue/itemValue/server/types/generators/WeatherGenerator.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/generators/WeatherGenerator.d.ts @@ -1,38 +1,54 @@ +import { ApplicationContext } from "../context/ApplicationContext"; import { WeightedRandomHelper } from "../helpers/WeightedRandomHelper"; -import { IWeatherData } from "../models/eft/weather/IWeatherData"; +import { IWeather, IWeatherData } from "../models/eft/weather/IWeatherData"; +import { WindDirection } from "../models/enums/WindDirection"; import { IWeatherConfig } from "../models/spt/config/IWeatherConfig"; +import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { RandomUtil } from "../utils/RandomUtil"; import { TimeUtil } from "../utils/TimeUtil"; export declare class WeatherGenerator { protected weightedRandomHelper: WeightedRandomHelper; + protected logger: ILogger; protected randomUtil: RandomUtil; protected timeUtil: TimeUtil; + protected applicationContext: ApplicationContext; protected configServer: ConfigServer; protected weatherConfig: IWeatherConfig; - constructor(weightedRandomHelper: WeightedRandomHelper, randomUtil: RandomUtil, timeUtil: TimeUtil, configServer: ConfigServer); - calculateTime(data: IWeatherData): IWeatherData; + constructor(weightedRandomHelper: WeightedRandomHelper, logger: ILogger, randomUtil: RandomUtil, timeUtil: TimeUtil, applicationContext: ApplicationContext, configServer: ConfigServer); + calculateGameTime(data: IWeatherData): IWeatherData; /** * Get server uptime seconds multiplied by a multiplier and add to current time as seconds * Format to BSGs requirements - * @param computedDate current date + * @param currentDate current date * @returns formatted time */ - protected getAcceleratedTime(computedDate: Date): string; + protected getBsgFormattedInRaidTime(currentDate: Date): string; + /** + * Get the current in-raid time + * @param currentDate (new Date()) + * @returns Date object of current in-raid time + */ + getInRaidTime(currentDate: Date): Date; /** * Get current time formatted to fit BSGs requirement - * @param computedDate date to format into bsg style + * @param date date to format into bsg style * @returns */ - protected getNormalTime(computedDate: Date): string; + protected getBSGFormattedTime(date: Date): string; /** - * Return randomised Weather data - * @param weatherData weather input data + * Return randomised Weather data with help of config/weather.json * @returns Randomised weather data */ - generateWeather(weatherData: IWeatherData): IWeatherData; - protected getWeightedFog(): string; + generateWeather(): IWeather; + /** + * Set IWeather date/time/timestamp values to now + * @param weather Object to update + */ + protected setCurrentDateTime(weather: IWeather): void; + protected getWeightedWindDirection(): WindDirection; + protected getWeightedWindSpeed(): number; + protected getWeightedFog(): number; protected getWeightedRain(): number; protected getRandomFloat(node: string): number; - protected getRandomInt(node: string): number; } diff --git a/KcY-SeeItemValue/itemValue/server/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts b/KcY-SeeItemValue/itemValue/server/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts index 4fcb1e2..1589707 100644 --- a/KcY-SeeItemValue/itemValue/server/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/generators/weapongen/implementations/ExternalInventoryMagGen.d.ts @@ -1,13 +1,15 @@ import { BotWeaponGeneratorHelper } from "../../../helpers/BotWeaponGeneratorHelper"; import { ItemHelper } from "../../../helpers/ItemHelper"; import { ILogger } from "../../../models/spt/utils/ILogger"; +import { LocalisationService } from "../../../services/LocalisationService"; import { IInventoryMagGen } from "../IInventoryMagGen"; import { InventoryMagGen } from "../InventoryMagGen"; export declare class ExternalInventoryMagGen implements IInventoryMagGen { protected logger: ILogger; protected itemHelper: ItemHelper; + protected localisationService: LocalisationService; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; - constructor(logger: ILogger, itemHelper: ItemHelper, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); + constructor(logger: ILogger, itemHelper: ItemHelper, localisationService: LocalisationService, botWeaponGeneratorHelper: BotWeaponGeneratorHelper); getPriority(): number; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; process(inventoryMagGen: InventoryMagGen): void; diff --git a/KcY-SeeItemValue/itemValue/server/types/helpers/BotDifficultyHelper.d.ts b/KcY-SeeItemValue/itemValue/server/types/helpers/BotDifficultyHelper.d.ts new file mode 100644 index 0000000..a58ebdb --- /dev/null +++ b/KcY-SeeItemValue/itemValue/server/types/helpers/BotDifficultyHelper.d.ts @@ -0,0 +1,46 @@ +import { Difficulty } from "../models/eft/common/tables/IBotType"; +import { IBotConfig } from "../models/spt/config/IBotConfig"; +import { ILogger } from "../models/spt/utils/ILogger"; +import { ConfigServer } from "../servers/ConfigServer"; +import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "../services/LocalisationService"; +import { JsonUtil } from "../utils/JsonUtil"; +import { RandomUtil } from "../utils/RandomUtil"; +import { BotHelper } from "./BotHelper"; +export declare class BotDifficultyHelper { + protected logger: ILogger; + protected jsonUtil: JsonUtil; + protected databaseServer: DatabaseServer; + protected randomUtil: RandomUtil; + protected localisationService: LocalisationService; + protected botHelper: BotHelper; + protected configServer: ConfigServer; + protected botConfig: IBotConfig; + constructor(logger: ILogger, jsonUtil: JsonUtil, databaseServer: DatabaseServer, randomUtil: RandomUtil, localisationService: LocalisationService, botHelper: BotHelper, configServer: ConfigServer); + getPmcDifficultySettings(pmcType: "bear" | "usec", difficulty: string, usecType: string, bearType: string): Difficulty; + /** + * Get difficulty settings for desired bot type, if not found use assault bot types + * @param type bot type to retreive difficulty of + * @param difficulty difficulty to get settings for (easy/normal etc) + * @returns Difficulty object + */ + getBotDifficultySettings(type: string, difficulty: string): Difficulty; + /** + * Get difficulty settings for a PMC + * @param type "usec" / "bear" + * @param difficulty what difficulty to retrieve + * @returns Difficulty object + */ + protected getDifficultySettings(type: string, difficulty: string): Difficulty; + /** + * Translate chosen value from pre-raid difficulty dropdown into bot difficulty value + * @param dropDownDifficulty Dropdown difficulty value to convert + * @returns bot difficulty + */ + convertBotDifficultyDropdownToBotDifficulty(dropDownDifficulty: string): string; + /** + * Choose a random difficulty from - easy/normal/hard/impossible + * @returns random difficulty + */ + chooseRandomDifficulty(): string; +} diff --git a/KcY-SeeItemValue/itemValue/server/types/helpers/BotGeneratorHelper.d.ts b/KcY-SeeItemValue/itemValue/server/types/helpers/BotGeneratorHelper.d.ts index 5e3e501..9ee017f 100644 --- a/KcY-SeeItemValue/itemValue/server/types/helpers/BotGeneratorHelper.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/helpers/BotGeneratorHelper.d.ts @@ -8,9 +8,11 @@ import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { BotEquipmentFilterService } from "../services/BotEquipmentFilterService"; import { ItemFilterService } from "../services/ItemFilterService"; +import { LocalisationService } from "../services/LocalisationService"; import { HashUtil } from "../utils/HashUtil"; import { JsonUtil } from "../utils/JsonUtil"; import { RandomUtil } from "../utils/RandomUtil"; +import { BotHelper } from "./BotHelper"; import { BotWeaponGeneratorHelper } from "./BotWeaponGeneratorHelper"; import { ContainerHelper } from "./ContainerHelper"; import { InventoryHelper } from "./InventoryHelper"; @@ -43,9 +45,11 @@ export declare class BotGeneratorHelper { protected itemFilterService: ItemFilterService; protected profileHelper: ProfileHelper; protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper; + protected botHelper: BotHelper; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected botConfig: IBotConfig; - constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, botEquipmentFilterService: BotEquipmentFilterService, itemFilterService: ItemFilterService, profileHelper: ProfileHelper, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, configServer: ConfigServer); + constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, randomUtil: RandomUtil, probabilityHelper: ProbabilityHelper, databaseServer: DatabaseServer, durabilityLimitsHelper: DurabilityLimitsHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, containerHelper: ContainerHelper, botEquipmentFilterService: BotEquipmentFilterService, itemFilterService: ItemFilterService, profileHelper: ProfileHelper, botWeaponGeneratorHelper: BotWeaponGeneratorHelper, botHelper: BotHelper, localisationService: LocalisationService, configServer: ConfigServer); /** * Check mods are compatible and add to array * @param equipment Equipment item to add mods to @@ -53,10 +57,13 @@ export declare class BotGeneratorHelper { * @param parentId parentid of item to add mod to * @param parentTemplate template objet of item to add mods to * @param modSpawnChances dictionary of mod items and their chance to spawn for this bot type + * @param botRole the bot role being generated for + * @param forceSpawn should this mod be forced to spawn * @returns Item + compatible mods as an array */ - generateModsForEquipment(equipment: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances): Item[]; + generateModsForEquipment(equipment: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem, modSpawnChances: ModsChances, botRole: string, forceSpawn?: boolean): Item[]; /** + * Add mods to a weapon using the provided mod pool * @param sessionId session id * @param weapon Weapon to add mods to * @param modPool Pool of compatible mods to attach to weapon @@ -67,18 +74,18 @@ export declare class BotGeneratorHelper { * @param botRole Role of bot weapon is generated for * @returns Weapon + mods array */ - generateModsForWeapon(sessionId: string, weapon: Item[], modPool: Mods, weaponParentId: string, parentWeaponTemplate: ITemplateItem, modSpawnChances: ModsChances, ammoTpl: string, botRole: string): Item[]; + generateModsForWeapon(sessionId: string, weapon: Item[], modPool: Mods, weaponParentId: string, parentWeaponTemplate: ITemplateItem, modSpawnChances: ModsChances, ammoTpl: string, botRole: string, botLevel: number): Item[]; /** * - * @param modSlot - * @param isRandomisableSlot - * @param modsParent - * @param botEquipBlacklist - * @param itemModPool + * @param modSlot Slot mod will fit into + * @param isRandomisableSlot Will generate a randomised mod pool if true + * @param modsParent Parent slot the item will be a part of + * @param botEquipBlacklist Blacklist to prevent mods from being picked + * @param itemModPool Pool of items to pick from * @param weapon array with only weapon tpl in it, ready for mods to be added * @param ammoTpl ammo tpl to use if slot requires a cartridge to be added (e.g. mod_magazine) - * @param parentTemplate - * @returns + * @param parentTemplate Parent item the mod will go into + * @returns ITemplateItem */ protected chooseModToPutIntoSlot(modSlot: string, isRandomisableSlot: boolean, modsParent: Slot, botEquipBlacklist: EquipmentFilterDetails, itemModPool: Record, weapon: Item[], ammoTpl: string, parentTemplate: ITemplateItem): [boolean, ITemplateItem]; /** @@ -114,8 +121,10 @@ export declare class BotGeneratorHelper { * Find all compatible mods for equipment item and add to modPool * @param itemDetails item to find mods for * @param modPool ModPool to add mods to + * @param equipmentBlacklist equipment not allowed to be used by the bot + * @param botEquipmentRole bot type to generate pool for (e.g. assault, pmcBot, pmc for usec/bear) */ - generateDynamicModPool(itemDetails: ITemplateItem, modPool: Mods): void; + generateDynamicModPool(itemDetails: ITemplateItem, modPool: Mods, equipmentBlacklist: EquipmentFilterDetails[], botEquipmentRole: string): void; /** * Take a list of tpls and filter out blacklisted values using itemFilterService + botEquipmentBlacklist * @param allowedMods base mods to filter @@ -153,7 +162,7 @@ export declare class BotGeneratorHelper { * @param modTemplate Used to add additional properites in the upd object * @returns Item object */ - protected createModItem(modId: string, modTpl: string, parentId: string, modSlot: string, modTemplate: ITemplateItem): Item; + protected createModItem(modId: string, modTpl: string, parentId: string, modSlot: string, modTemplate: ITemplateItem, botRole: string): Item; /** * randomly choose if a mod should be spawned, 100% for required mods OR mod is ammo slot * never return true for an item that has 0% spawn chance @@ -170,10 +179,10 @@ export declare class BotGeneratorHelper { */ protected getAmmoContainers(): string[]; /** - * Get the slot details for an item (chamber/cartridge/slot) + * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon * @param parentTemplate item template - * @returns + * @returns Slot item */ protected getModItemSlot(modSlot: string, parentTemplate: ITemplateItem): Slot; /** @@ -185,7 +194,6 @@ export declare class BotGeneratorHelper { * @param modPool modPool which should include available cartrigdes * @param parentId The CylinderMagazine's UID * @param parentTemplate The CylinderMagazine's template - * @returns */ protected fillCamora(items: Item[], modPool: Mods, parentId: string, parentTemplate: ITemplateItem): void; /** @@ -197,11 +205,11 @@ export declare class BotGeneratorHelper { /** * Adds properties to an item * e.g. Repairable / HasHinge / Foldable / MaxDurability - * @param itemTemplate - * @param botRole Used by weapons to randomise the durability values + * @param itemTemplate Item extra properties are being generated for + * @param botRole Used by weapons to randomise the durability values. Null for non-equipped items * @returns Item Upd object with extra properties */ - generateExtraPropertiesForItem(itemTemplate: ITemplateItem, botRole?: any): { + generateExtraPropertiesForItem(itemTemplate: ITemplateItem, botRole?: string): { upd?: Upd; }; /** @@ -220,21 +228,27 @@ export declare class BotGeneratorHelper { protected generateArmorRepairableProperties(itemTemplate: ITemplateItem, botRole: string): Repairable; /** * Get a random mod from an items compatible mods Filter array - * @param modTpl - * @param parentSlot - * @param modSlot - * @param items + * @param modTpl ???? + * @param parentSlot item mod will go into, used to get combatible items + * @param modSlot Slot to get mod to fill + * @param items items to ensure picked mod is compatible with * @returns item tpl */ protected getModTplFromItemDb(modTpl: string, parentSlot: Slot, modSlot: string, items: Item[]): string; /** * Can an item be added to an item without issue - * @param items - * @param tplToCheck - * @param equipmentSlot - * @returns true if possible + * @param items items to check compatiblilities with + * @param tplToCheck tpl of the item to check for incompatibilities + * @param equipmentSlot Slot the item will be placed into + * @returns false if no incompatibilties */ isItemIncompatibleWithCurrentItems(items: Item[], tplToCheck: string, equipmentSlot: string): boolean; + /** + * Convert a bots role to the equipment role used in config/bot.json + * @param botRole Role to convert + * @returns Equipment role (e.g. pmc / assault / bossTagilla) + */ + getBotEquipmentRole(botRole: string): string; } /** TODO - move into own class */ export declare class ExhaustableArray { diff --git a/KcY-SeeItemValue/itemValue/server/types/helpers/BotHelper.d.ts b/KcY-SeeItemValue/itemValue/server/types/helpers/BotHelper.d.ts index 67a6384..2752a0e 100644 --- a/KcY-SeeItemValue/itemValue/server/types/helpers/BotHelper.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/helpers/BotHelper.d.ts @@ -1,8 +1,9 @@ import { Difficulty, IBotType } from "../models/eft/common/tables/IBotType"; -import { IBotConfig } from "../models/spt/config/IBotConfig"; +import { EquipmentFilters, IBotConfig, RandomisationDetails } from "../models/spt/config/IBotConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "../services/LocalisationService"; import { JsonUtil } from "../utils/JsonUtil"; import { RandomUtil } from "../utils/RandomUtil"; export declare class BotHelper { @@ -10,46 +11,27 @@ export declare class BotHelper { protected jsonUtil: JsonUtil; protected databaseServer: DatabaseServer; protected randomUtil: RandomUtil; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected botConfig: IBotConfig; - constructor(logger: ILogger, jsonUtil: JsonUtil, databaseServer: DatabaseServer, randomUtil: RandomUtil, configServer: ConfigServer); - /** - * Get difficulty settings for desired bot type, if not found use assault bot types - * @param type bot type to retreive difficulty of - * @param difficulty difficulty to get settings for (easy/normal etc) - * @returns Difficulty object - */ - getBotDifficultySettings(type: string, difficulty: string): Difficulty; + constructor(logger: ILogger, jsonUtil: JsonUtil, databaseServer: DatabaseServer, randomUtil: RandomUtil, localisationService: LocalisationService, configServer: ConfigServer); /** * Get a template object for the specified botRole from bots.types db * @param role botRole to get template for * @returns IBotType object */ getBotTemplate(role: string): IBotType; - /** - * Get difficulty settings for a PMC - * @param type "usec" / "bear" - * @param difficulty what difficulty to retrieve - * @returns Difficulty object - */ - getPmcDifficultySettings(type: string, difficulty: string): Difficulty; - /** - * Translate chosen value from pre-raid difficulty dropdown into bot difficulty value - * @param dropDownDifficulty Dropdown difficulty value to convert - * @returns bot difficulty - */ - convertBotDifficultyDropdownToBotDifficulty(dropDownDifficulty: string): string; - /** - * Choose a random difficulty from - easy/normal/hard/impossible - * @returns random difficulty - */ - chooseRandomDifficulty(): string; /** * Randomise the chance the PMC will attack their own side * Look up value in bot.json/chanceSameSideIsHostilePercent * @param difficultySettings pmc difficulty settings */ randomisePmcHostility(difficultySettings: Difficulty): void; + /** + * Is the passed in bot role a PMC (usec/bear/pmc) + * @param botRole bot role to check + * @returns true if is pmc + */ isBotPmc(botRole: string): boolean; isBotBoss(botRole: string): boolean; isBotFollower(botRole: string): boolean; @@ -77,4 +59,11 @@ export declare class BotHelper { * @returns true if should be a pmc */ shouldBotBePmc(botRole: string): boolean; + /** + * Get randomisation settings for bot from config/bot.json + * @param botLevel level of bot + * @param botEquipConfig bot equipment json + * @returns RandomisationDetails + */ + getBotRandomisationDetails(botLevel: number, botEquipConfig: EquipmentFilters): RandomisationDetails; } diff --git a/KcY-SeeItemValue/itemValue/server/types/helpers/GameEventHelper.d.ts b/KcY-SeeItemValue/itemValue/server/types/helpers/GameEventHelper.d.ts index fca87be..fa25eff 100644 --- a/KcY-SeeItemValue/itemValue/server/types/helpers/GameEventHelper.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/helpers/GameEventHelper.d.ts @@ -15,4 +15,15 @@ export declare class GameEventHelper { * @returns Record with event name + start/end date */ getEventDetails(): ISeasonalEvent[]; + /** + * Is detection of seasonal events enabled (halloween / christmas) + * @returns true if seasonal events should be checked for + */ + isAutomaticEventDetectionEnabled(): boolean; + /** + * Get a dictionary of gear changes to apply to bots for a specific event e.g. Christmas/Halloween + * @param eventName Name of event to get gear changes for + * @returns bots with equipment changes + */ + getEventBotGear(eventName: string): Record>>; } diff --git a/KcY-SeeItemValue/itemValue/server/types/helpers/HideoutHelper.d.ts b/KcY-SeeItemValue/itemValue/server/types/helpers/HideoutHelper.d.ts index 5f7e3b7..9d51fed 100644 --- a/KcY-SeeItemValue/itemValue/server/types/helpers/HideoutHelper.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/helpers/HideoutHelper.d.ts @@ -11,6 +11,7 @@ import { ILogger } from "../models/spt/utils/ILogger"; import { EventOutputHolder } from "../routers/EventOutputHolder"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "../services/LocalisationService"; import { PlayerService } from "../services/PlayerService"; import { HashUtil } from "../utils/HashUtil"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; @@ -29,13 +30,14 @@ export declare class HideoutHelper { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected playerService: PlayerService; + protected localisationService: LocalisationService; protected configServer: ConfigServer; static bitcoinFarm: string; static waterCollector: string; static bitcoin: string; static expeditionaryFuelTank: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, playerService: PlayerService, configServer: ConfigServer); + constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, playerService: PlayerService, localisationService: LocalisationService, configServer: ConfigServer); registerProduction(pmcData: IPmcData, body: IHideoutSingleProductionStartRequestData | IHideoutContinousProductionStartRequestData, sessionID: string): IItemEventRouterResponse; /** * This convinience function intialies new Production Object diff --git a/KcY-SeeItemValue/itemValue/server/types/helpers/InventoryHelper.d.ts b/KcY-SeeItemValue/itemValue/server/types/helpers/InventoryHelper.d.ts index b8e5c9d..6419f93 100644 --- a/KcY-SeeItemValue/itemValue/server/types/helpers/InventoryHelper.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/helpers/InventoryHelper.d.ts @@ -5,11 +5,12 @@ import { IInventoryMergeRequestData } from "../models/eft/inventory/IInventoryMe import { IInventoryMoveRequestData } from "../models/eft/inventory/IInventoryMoveRequestData"; import { IInventorySplitRequestData } from "../models/eft/inventory/IInventorySplitRequestData"; import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse"; -import { IInventoryConfig } from "../models/spt/config/IInventoryConfig"; +import { IInventoryConfig, RewardDetails } from "../models/spt/config/IInventoryConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { FenceService } from "../services/FenceService"; +import { LocalisationService } from "../services/LocalisationService"; import { HashUtil } from "../utils/HashUtil"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; import { JsonUtil } from "../utils/JsonUtil"; @@ -38,9 +39,10 @@ export declare class InventoryHelper { protected itemHelper: ItemHelper; protected containerHelper: ContainerHelper; protected profileHelper: ProfileHelper; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected inventoryConfig: IInventoryConfig; - constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, httpResponse: HttpResponseUtil, fenceService: FenceService, databaseServer: DatabaseServer, paymentHelper: PaymentHelper, traderAssortHelper: TraderAssortHelper, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, containerHelper: ContainerHelper, profileHelper: ProfileHelper, configServer: ConfigServer); + constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, httpResponse: HttpResponseUtil, fenceService: FenceService, databaseServer: DatabaseServer, paymentHelper: PaymentHelper, traderAssortHelper: TraderAssortHelper, dialogueHelper: DialogueHelper, itemHelper: ItemHelper, containerHelper: ContainerHelper, profileHelper: ProfileHelper, localisationService: LocalisationService, configServer: ConfigServer); addItem(pmcData: IPmcData, body: IAddItemRequestData, output: IItemEventRouterResponse, sessionID: string, callback: any, foundInRaid?: boolean, addUpd?: any): IItemEventRouterResponse; removeItem(pmcData: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse; removeItemByCount(pmcData: IPmcData, itemId: string, count: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse; @@ -76,6 +78,12 @@ export declare class InventoryHelper { * Internal helper function to handle cartridges in inventory if any of them exist. */ protected handleCartridges(items: Item[], body: IInventoryMoveRequestData): void; + /** + * Get details for how a random loot container should be handled, max rewards, possible reward tpls + * @param itemTpl Container being opened + * @returns Reward details + */ + getRandomLootContainerRewardDetails(itemTpl: string): RewardDetails; } declare namespace InventoryHelper { interface InventoryItemHash { diff --git a/KcY-SeeItemValue/itemValue/server/types/helpers/ItemHelper.d.ts b/KcY-SeeItemValue/itemValue/server/types/helpers/ItemHelper.d.ts index 0effaf2..fc88a46 100644 --- a/KcY-SeeItemValue/itemValue/server/types/helpers/ItemHelper.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/helpers/ItemHelper.d.ts @@ -5,6 +5,7 @@ import { IStaticAmmoDetails } from "../models/eft/common/tables/ILootBase"; import { ITemplateItem } from "../models/eft/common/tables/ITemplateItem"; import { ILogger } from "../models/spt/utils/ILogger"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocaleService } from "../services/LocaleService"; import { HashUtil } from "../utils/HashUtil"; import { JsonUtil } from "../utils/JsonUtil"; import { MathUtil } from "../utils/MathUtil"; @@ -18,7 +19,8 @@ declare class ItemHelper { protected objectId: ObjectId; protected mathUtil: MathUtil; protected databaseServer: DatabaseServer; - constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, randomUtil: RandomUtil, objectId: ObjectId, mathUtil: MathUtil, databaseServer: DatabaseServer); + protected localeService: LocaleService; + constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, randomUtil: RandomUtil, objectId: ObjectId, mathUtil: MathUtil, databaseServer: DatabaseServer, localeService: LocaleService); /** * Checks if an id is a valid item. Valid meaning that it's an item that be stored in stash * @param {string} tpl the template id / tpl @@ -212,6 +214,12 @@ declare class ItemHelper { * @returns size of stack */ getItemStackSize(item: Item): number; + /** + * Get the name of an item from the locale file using the item tpl + * @param itemTpl Tpl of item to get name of + * @returns Name of item + */ + getItemName(itemTpl: string): string; } declare namespace ItemHelper { interface ItemSize { diff --git a/KcY-SeeItemValue/itemValue/server/types/helpers/QuestHelper.d.ts b/KcY-SeeItemValue/itemValue/server/types/helpers/QuestHelper.d.ts index a6b4892..edbd2e1 100644 --- a/KcY-SeeItemValue/itemValue/server/types/helpers/QuestHelper.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/helpers/QuestHelper.d.ts @@ -50,6 +50,12 @@ export declare class QuestHelper { * @returns true if player level is greater than or equal to quest */ doesPlayerLevelFulfilCondition(playerLevel: number, condition: AvailableForConditions): boolean; + /** + * Get the quests found in both arrays (inner join) + * @param before Array of qeusts #1 + * @param after Array of quests #2 + * @returns Reduction of cartesian product between two quest arrays + */ getDeltaQuests(before: IQuest[], after: IQuest[]): IQuest[]; /** * Increase skill points of a skill on player profile @@ -66,38 +72,85 @@ export declare class QuestHelper { * quest list in question. */ dumpQuests(quests: any): void; - loyaltyRequirementCheck(loyaltyRequirementProperties: AvailableForProps, profile: IPmcData): boolean; - protected processReward(reward: Reward): any[]; + /** + * Check if trader has sufficient loyalty to fullfill quest requirement + * @param questProperties Quest props + * @param profile Player profile + * @returns true if loyalty is high enough to fulfil quest requirement + */ + traderStandingRequirementCheck(questProperties: AvailableForProps, profile: IPmcData): boolean; + protected processReward(reward: Reward): Reward[]; + /** + * Gets a flat list of reward items for the given quest at a specific state (e.g. Fail/Success) + * @param quest quest to get rewards for + * @param state Quest status that holds the items (Started, Success, Fail) + * @returns array of items with the correct maxStack + */ getQuestRewardItems(quest: IQuest, state: QuestStatus): Reward[]; /** - * Add quest with new state value to pmc profile + * Update player profile with quest status (e.g. Fail/Success) * @param pmcData profile to add quest to * @param newState state the new quest should be in when added * @param acceptedQuest Details of quest being added */ addQuestToPMCData(pmcData: IPmcData, newState: QuestStatus, acceptedQuest: IAcceptQuestRequestData): void; - acceptedUnlocked(acceptedQuestId: string, sessionID: string): IQuest[]; - failedUnlocked(failedQuestId: string, sessionID: string): IQuest[]; - applyMoneyBoost(quest: IQuest, moneyBoost: number): IQuest; - changeItemStack(pmcData: IPmcData, id: string, value: number, sessionID: string, output: any): void; /** - * Get List of All Quests as an array + * TODO: what is going on here + * @param acceptedQuestId Quest to add to profile + * @param sessionID Session id + * @returns Array of quests in profile + quest passed in as param + */ + acceptedUnlocked(acceptedQuestId: string, sessionID: string): IQuest[]; + /** + * TODO: what is going on here + * @param failedQuestId + * @param sessionID Session id + * @returns + */ + failedUnlocked(failedQuestId: string, sessionID: string): IQuest[]; + /** + * Adjust quest money rewards by passed in multipler + * @param quest Quest to multiple money rewards + * @param multipler Value to adjust money rewards by + * @returns Updated quest + */ + applyMoneyBoost(quest: IQuest, multipler: number): IQuest; + /** + * Sets the item stack to new value, or delete the item if value <= 0 + * // TODO maybe merge this function and the one from customization + * @param pmcData Profile + * @param itemId id of item to adjust stack size of + * @param newStackSize Stack size to adjust to + * @param sessionID Session id + * @param output ItemEvent router response + */ + changeItemStack(pmcData: IPmcData, itemId: string, newStackSize: number, sessionID: string, output: IItemEventRouterResponse): void; + /** + * Get List of All Quests from db + * NOT CLONED * @returns Array of IQuest objects */ - questValues(): IQuest[]; + getQuestsFromDb(): IQuest[]; /** - * Reest AvailableForStart conditions for quests - * @param quests queststo clean + * Get quests, strip all requirement conditions except level + * @param quests quests to process * @returns quest array without conditions */ - protected cleanQuestList(quests: IQuest[]): IQuest[]; + protected getQuestsWithOnlyLevelRequirementStartCondition(quests: IQuest[]): IQuest[]; /** - * Reset AvailableForStart conditions on a quest + * Remove all quest conditions except for level requirement * @param quest quest to clean * @returns reset IQuest object */ - cleanQuestConditions(quest: IQuest): IQuest; - failQuest(pmcData: IPmcData, body: any, sessionID: string): any; + getQuestWithOnlyLevelRequirementStartCondition(quest: IQuest): IQuest; + /** + * Fail a quest in a player profile + * @param pmcData Profile + * @param failRequest fail quest request data + * @param sessionID Session id + * @returns Item event router response + */ + failQuest(pmcData: IPmcData, failRequest: any, sessionID: string): IItemEventRouterResponse; /** * Get quest by id from database * @param questId questid to look for @@ -105,7 +158,12 @@ export declare class QuestHelper { * @returns IQuest object */ getQuestFromDb(questId: string, pmcData: IPmcData): IQuest; - getQuestLocaleIdFromDb(messageId: string): string; + /** + * Get the locale Id from locale db for a quest message + * @param questMessageId Quest mesage id to look up + * @returns Locale Id from locale db + */ + getQuestLocaleIdFromDb(questMessageId: string): string; /** * Alter a quests state + Add a record to tis status timers object * @param pmcData Profile to update @@ -128,5 +186,10 @@ export declare class QuestHelper { * @returns bonus in percent */ protected getIntelCenterRewardBonus(pmcData: IPmcData): number; - getFindItemIdForQuestItem(itemTpl: string): string; + /** + * Find quest with 'findItem' requirement that needs the item tpl be handed in + * @param itemTpl item tpl to look for + * @returns 'FindItem' condition id + */ + getFindItemIdForQuestHandIn(itemTpl: string): string; } diff --git a/KcY-SeeItemValue/itemValue/server/types/helpers/RagfairServerHelper.d.ts b/KcY-SeeItemValue/itemValue/server/types/helpers/RagfairServerHelper.d.ts index a03cdda..ec388d8 100644 --- a/KcY-SeeItemValue/itemValue/server/types/helpers/RagfairServerHelper.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/helpers/RagfairServerHelper.d.ts @@ -44,10 +44,20 @@ export declare class RagfairServerHelper { isPlayer(userID: string): boolean; returnItems(sessionID: string, items: any[]): void; calculateDynamicStackCount(tplId: string, isWeaponPreset: boolean): number; + /** + * Choose a currency at random with bias + * @returns currency tpl + */ getDynamicOfferCurrency(): string; getMemberType(userID: string): MemberCategory; getNickname(userID: string): string; getPresetItems(item: any): Item[]; getPresetItemsByTpl(item: Item): Item[]; + /** + * Generate new unique ids for the children while preserving hierarchy + * @param item base item + * @param preset + * @returns Item array with new IDs + */ reparentPresets(item: Item, preset: Item[]): Item[]; } diff --git a/KcY-SeeItemValue/itemValue/server/types/helpers/RagfairSortHelper.d.ts b/KcY-SeeItemValue/itemValue/server/types/helpers/RagfairSortHelper.d.ts index 28d1d38..4669ce6 100644 --- a/KcY-SeeItemValue/itemValue/server/types/helpers/RagfairSortHelper.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/helpers/RagfairSortHelper.d.ts @@ -18,7 +18,7 @@ export declare class RagfairSortHelper { protected sortOffersByRating(a: IRagfairOffer, b: IRagfairOffer): number; protected sortOffersByName(a: IRagfairOffer, b: IRagfairOffer): number; /** - * Order two offers by price value + * Order two offers by rouble price value * @param a Offer a * @param b Offer b * @returns diff --git a/KcY-SeeItemValue/itemValue/server/types/loaders/PreAkiModLoader.d.ts b/KcY-SeeItemValue/itemValue/server/types/loaders/PreAkiModLoader.d.ts index 7a687a5..f486a28 100644 --- a/KcY-SeeItemValue/itemValue/server/types/loaders/PreAkiModLoader.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/loaders/PreAkiModLoader.d.ts @@ -1,29 +1,31 @@ import { DependencyContainer } from "tsyringe"; +import { IPostAkiLoadMod } from "../models/external/IPostAkiLoadMod"; +import { IPostDBLoadMod } from "../models/external/IPostDBLoadMod"; +import { IPreAkiLoadMod } from "../models/external/IPreAkiLoadMod"; import { ICoreConfig } from "../models/spt/config/ICoreConfig"; import { ModLoader } from "../models/spt/mod/IMod"; import { IModLoader } from "../models/spt/mod/IModLoader"; import { IPackageJsonData } from "../models/spt/mod/IPackageJsonData"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; +import { LocalisationService } from "../services/LocalisationService"; import { ModCompilerService } from "../services/ModCompilerService"; import { JsonUtil } from "../utils/JsonUtil"; import { VFS } from "../utils/VFS"; import { BundleLoader } from "./BundleLoader"; -import { IPostAkiLoadMod } from "../models/external/IPostAkiLoadMod"; -import { IPreAkiLoadMod } from "../models/external/IPreAkiLoadMod"; -import { IPostDBLoadMod } from "../models/external/IPostDBLoadMod"; export declare class PreAkiModLoader implements IModLoader { protected logger: ILogger; protected vfs: VFS; protected jsonUtil: JsonUtil; protected modCompilerService: ModCompilerService; protected bundleLoader: BundleLoader; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected static container: DependencyContainer; protected readonly basepath = "user/mods/"; protected imported: Record; protected akiConfig: ICoreConfig; - constructor(logger: ILogger, vfs: VFS, jsonUtil: JsonUtil, modCompilerService: ModCompilerService, bundleLoader: BundleLoader, configServer: ConfigServer); + constructor(logger: ILogger, vfs: VFS, jsonUtil: JsonUtil, modCompilerService: ModCompilerService, bundleLoader: BundleLoader, localisationService: LocalisationService, configServer: ConfigServer); load(container: DependencyContainer): Promise; getBundles(local: boolean): string; getBundle(key: string, local: boolean): void; diff --git a/KcY-SeeItemValue/itemValue/server/types/models/eft/bot/IGenerateBotsRequestData.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/eft/bot/IGenerateBotsRequestData.d.ts index c49cef7..f1f7013 100644 --- a/KcY-SeeItemValue/itemValue/server/types/models/eft/bot/IGenerateBotsRequestData.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/models/eft/bot/IGenerateBotsRequestData.d.ts @@ -2,6 +2,7 @@ export interface IGenerateBotsRequestData { conditions: Condition[]; } export interface Condition { + /** e.g. assault/pmcBot/bossKilla */ Role: string; Limit: number; Difficulty: string; diff --git a/KcY-SeeItemValue/itemValue/server/types/models/eft/bot/IRandomisedBotLevelResult.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/eft/bot/IRandomisedBotLevelResult.d.ts new file mode 100644 index 0000000..75bd936 --- /dev/null +++ b/KcY-SeeItemValue/itemValue/server/types/models/eft/bot/IRandomisedBotLevelResult.d.ts @@ -0,0 +1,4 @@ +export interface IRandomisedBotLevelResult { + level: number; + exp: number; +} diff --git a/KcY-SeeItemValue/itemValue/server/types/models/eft/common/IGlobals.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/eft/common/IGlobals.d.ts index 81e2023..b53f106 100644 --- a/KcY-SeeItemValue/itemValue/server/types/models/eft/common/IGlobals.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/models/eft/common/IGlobals.d.ts @@ -591,6 +591,7 @@ export interface HealPrice { export interface ProfileHealthSettings { BodyPartsSettings: BodyPartsSettings; HealthFactorsSettings: HealthFactorsSettings; + DefaultStimulatorBuff: string; } export interface BodyPartsSettings { Head: BodyPartsSetting; diff --git a/KcY-SeeItemValue/itemValue/server/types/models/eft/common/tables/IBotType.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/eft/common/tables/IBotType.d.ts index c1fe579..55b4bd9 100644 --- a/KcY-SeeItemValue/itemValue/server/types/models/eft/common/tables/IBotType.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/models/eft/common/tables/IBotType.d.ts @@ -13,8 +13,8 @@ export interface IBotType { skills: Skills; } export interface Appearance { - body: string[]; - feet: string[]; + body: Record; + feet: Record; hands: string[]; head: string[]; voice: string[]; diff --git a/KcY-SeeItemValue/itemValue/server/types/models/eft/common/tables/ITemplateItem.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/eft/common/tables/ITemplateItem.d.ts index 8569e61..0fa7e18 100644 --- a/KcY-SeeItemValue/itemValue/server/types/models/eft/common/tables/ITemplateItem.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/models/eft/common/tables/ITemplateItem.d.ts @@ -254,7 +254,7 @@ export interface Props { foodUseTime?: number; foodEffectType?: string; StimulatorBuffs?: string; - effects_health?: any; + effects_health?: IHealthEffect[] | Record>; effects_damage?: any; MaximumNumberOfUsage?: number; knifeHitDelay?: number; @@ -366,6 +366,10 @@ export interface Props { MinTimeToContactExplode?: number; ExplosionEffectType?: string; } +export interface IHealthEffect { + type: string; + value: number; +} export interface Prefab { path: string; rcid: string; diff --git a/KcY-SeeItemValue/itemValue/server/types/models/eft/customization/IGetSuitsResponse.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/eft/customization/IGetSuitsResponse.d.ts new file mode 100644 index 0000000..cbb909d --- /dev/null +++ b/KcY-SeeItemValue/itemValue/server/types/models/eft/customization/IGetSuitsResponse.d.ts @@ -0,0 +1,4 @@ +export interface IGetSuitsResponse { + _id: string; + suites: string[]; +} diff --git a/KcY-SeeItemValue/itemValue/server/types/models/eft/game/IGameKeepAliveResponse.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/eft/game/IGameKeepAliveResponse.d.ts new file mode 100644 index 0000000..170ce6a --- /dev/null +++ b/KcY-SeeItemValue/itemValue/server/types/models/eft/game/IGameKeepAliveResponse.d.ts @@ -0,0 +1,4 @@ +export interface IGameKeepAliveResponse { + msg: string; + utc_time: number; +} diff --git a/KcY-SeeItemValue/itemValue/server/types/models/eft/game/IGameLogoutResponseData.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/eft/game/IGameLogoutResponseData.d.ts new file mode 100644 index 0000000..0f52050 --- /dev/null +++ b/KcY-SeeItemValue/itemValue/server/types/models/eft/game/IGameLogoutResponseData.d.ts @@ -0,0 +1,3 @@ +export interface IGameLogoutResponseData { + status: string; +} diff --git a/KcY-SeeItemValue/itemValue/server/types/models/eft/game/IGameStartResponse.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/eft/game/IGameStartResponse.d.ts new file mode 100644 index 0000000..9f0ab6d --- /dev/null +++ b/KcY-SeeItemValue/itemValue/server/types/models/eft/game/IGameStartResponse.d.ts @@ -0,0 +1,3 @@ +export interface IGameStartResponse { + utc_time: number; +} diff --git a/KcY-SeeItemValue/itemValue/server/types/models/eft/inventory/IOpenRandomLootContainerRequestData.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/eft/inventory/IOpenRandomLootContainerRequestData.d.ts new file mode 100644 index 0000000..3c45124 --- /dev/null +++ b/KcY-SeeItemValue/itemValue/server/types/models/eft/inventory/IOpenRandomLootContainerRequestData.d.ts @@ -0,0 +1,11 @@ +import { IInventoryBaseActionRequestData } from "./IInventoryBaseActionRequestData"; +export interface IOpenRandomLootContainerRequestData extends IInventoryBaseActionRequestData { + Action: "OpenRandomLootContainer"; + /** Container item opened */ + item: string; + to: To[]; +} +export interface To { + /** Player character (pmc/scav) id items will be sent to */ + id: string; +} diff --git a/KcY-SeeItemValue/itemValue/server/types/models/eft/itemEvent/IItemEventRouterBase.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/eft/itemEvent/IItemEventRouterBase.d.ts index 4841cfd..60ab284 100644 --- a/KcY-SeeItemValue/itemValue/server/types/models/eft/itemEvent/IItemEventRouterBase.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/models/eft/itemEvent/IItemEventRouterBase.d.ts @@ -10,8 +10,9 @@ export interface IItemEventRouterBase { export declare type TProfileChanges = Record; export interface Warning { index: number; - err: string; errmsg: string; + code?: string; + data?: any; } export interface ProfileChange { _id: string; diff --git a/KcY-SeeItemValue/itemValue/server/types/models/eft/match/IStartOffineRaidRequestData.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/eft/match/IStartOffineRaidRequestData.d.ts index af0625e..1983728 100644 --- a/KcY-SeeItemValue/itemValue/server/types/models/eft/match/IStartOffineRaidRequestData.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/models/eft/match/IStartOffineRaidRequestData.d.ts @@ -2,8 +2,10 @@ import { BotAmount } from "../../enums/BotAmount"; import { BotDifficulty } from "../../enums/BotDifficulty"; export interface IStartOfflineRaidRequestData { locationName: string; + /** Current time, not in-game time */ startTime: number; - dateTime: string; + /** CURR = am, past = pm */ + dateTime: "CURR" | "PAST"; gameSettings: GameSettings; } export interface GameSettings { diff --git a/KcY-SeeItemValue/itemValue/server/types/models/eft/notifier/ISelectProfileResponse.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/eft/notifier/ISelectProfileResponse.d.ts new file mode 100644 index 0000000..ecb668a --- /dev/null +++ b/KcY-SeeItemValue/itemValue/server/types/models/eft/notifier/ISelectProfileResponse.d.ts @@ -0,0 +1,6 @@ +import { INotifierChannel } from "./INotifier"; +export interface ISelectProfileResponse { + status: string; + notifier: INotifierChannel; + notifierServer: string; +} diff --git a/KcY-SeeItemValue/itemValue/server/types/models/eft/ragfair/IRagfairOffer.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/eft/ragfair/IRagfairOffer.d.ts index 3251a37..792ec7d 100644 --- a/KcY-SeeItemValue/itemValue/server/types/models/eft/ragfair/IRagfairOffer.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/models/eft/ragfair/IRagfairOffer.d.ts @@ -7,19 +7,19 @@ export interface IRagfairOffer { requirements: OfferRequirement[]; root: string; intId: number; + /** Handbook price */ itemsCost: number; + /** Rouble price */ requirementsCost: number; - sptRequirementsCostRouble: number; startTime: number; endTime: number; sellInOnePiece: boolean; - name?: string; - shortName?: string; loyaltyLevel: number; buyRestrictionMax?: number; buyRestrictionCurrent?: number; locked: boolean; unlimitedCount: boolean; + /** Rouble price */ summaryCost: number; user: IRagfairOfferUser; notAvailable: boolean; @@ -33,11 +33,11 @@ export interface OfferRequirement { } export interface IRagfairOfferUser { id: string; - nickname: string; - rating: number; + nickname?: string; + rating?: number; memberType: MemberCategory; - avatar: string; - isRatingGrowing: boolean; + avatar?: string; + isRatingGrowing?: boolean; } export interface SellResult { sellTime: number; diff --git a/KcY-SeeItemValue/itemValue/server/types/models/eft/weather/IWeatherData.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/eft/weather/IWeatherData.d.ts index ecc96ce..1f5d5b5 100644 --- a/KcY-SeeItemValue/itemValue/server/types/models/eft/weather/IWeatherData.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/models/eft/weather/IWeatherData.d.ts @@ -1,17 +1,18 @@ +import { WindDirection } from "../../../models/enums/WindDirection"; export interface IWeatherData { acceleration: number; time: string; date: string; - weather: IWeather; + weather?: IWeather; } export interface IWeather { pressure: number; temp: number; - fog: string; + fog: number; rain_intensity: number; - rain: any; + rain: number; wind_gustiness: number; - wind_direction: any; + wind_direction: WindDirection; wind_speed: number; cloud: number; time: string; diff --git a/KcY-SeeItemValue/itemValue/server/types/models/enums/BackendErrorCodes.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/enums/BackendErrorCodes.d.ts new file mode 100644 index 0000000..6614b75 --- /dev/null +++ b/KcY-SeeItemValue/itemValue/server/types/models/enums/BackendErrorCodes.d.ts @@ -0,0 +1,67 @@ +export declare enum BackendErrorCodes { + NONE = 0, + UNKNOWN_ERROR = 200, + NOT_AUTHORIZED = 201, + NEED_AUTHORIZATION_CODE = 209, + WRONG_AUTHORIZATION_CODE = 211, + NEED_CAPTCHA = 214, + NO_NEED_CAPTCHA = 215, + CAPTCHA_FAILED = 218, + CAPTCHA_BRUTE_FORCED = 219, + NO_ROOM_IN_STASH = 223, + NICKNAME_NOT_UNIQUE = 225, + NICKNAME_NOT_VALID = 226, + UNSUPPORTED_CLIENT_VERSION = 232, + REPORT_NOT_ALLOWED = 238, + NICKNAME_IS_ABUSIVE = 241, + NICKNAME_CHANGE_TIMEOUT = 242, + NOT_MODIFIED = 304, + HTTP_BAD_REQUEST = 400, + HTTP_NOT_AUTHORIZED = 401, + HTTP_FORBIDDEN = 403, + HTTP_NOT_FOUND = 404, + HTTP_METHOD_NOT_ALLOWED = 405, + UNKNOWN_TRADING_ERROR = 500, + HTTPNOTIMPLEMENTED = 501, + HTTPBADGATEWAY = 502, + HTTPSERVICEUNAVAILABLE = 503, + HTTPGATEWAYTIMEOUT = 504, + TRADEROUTOFMONEY = 505, + HTTPVARIANTALSONEGOTIATES = 506, + PRICECHANGED = 509, + TRADERDISABLED = 512, + ITEMHASBEENSOLD = 513, + NOTENOUGHSPACEFORMONEY = 518, + HTTPINVALIDSSLCERTIFICATE = 526, + UNKNOWNRAGFAIRERROR = 550, + UNKNOWNRAGFAIRERROR2 = 551, + UNKNOWNMATCHMAKERERROR = 600, + SESSIONPARAMETERSERROR = 601, + SESSIONLOST = 602, + SERVERNOTREGISTERED = 604, + UNKNOWNQUESTERROR = 700, + QUESTBADPARAM = 702, + QUESTNOTFOUND = 703, + QUESTISUNAVAILABLE = 704, + NOFREESPACEFORREWARDS = 705, + WRONGQUESTSTATUS = 706, + CANTCOMPLETEQUEST = 707, + UNKNOWNMAILERROR = 900, + TOOMANYFRIENDREQUESTS = 925, + UNKNOWNSCRIPTEXECUTIONERROR = 1000, + UNKNOWNREPAIRINGERROR = 1200, + UNKNOWNINSURANCEERROR = 1300, + UNKNOWNCURRENCYEXCHANGEERROR = 1400, + OFFERNOTFOUND = 1503, + NOTENOUGHSPACE = 1505, + OFFEROUTOFSTOCK = 1506, + OFFERSOLD = 1507, + RAGFAIRUNAVAILABLE = 1511, + BANNEDERRORCODE = 1513, + INSUFFICIENTNUMBERINSTOCK = 1516, + TOOMANYITEMSTOSELL = 1517, + EXAMINATIONFAILED = 22001, + ITEMALREADYEXAMINED = 22002, + UNKNOWNNGINXERROR = 9000, + PARSERESPONSEERROR = 9001 +} diff --git a/KcY-SeeItemValue/itemValue/server/types/models/enums/HideoutEventActions.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/enums/HideoutEventActions.d.ts new file mode 100644 index 0000000..e441477 --- /dev/null +++ b/KcY-SeeItemValue/itemValue/server/types/models/enums/HideoutEventActions.d.ts @@ -0,0 +1,11 @@ +export declare enum HideoutEventActions { + HIDEOUT_UPGRADE = "HideoutUpgrade", + HIDEOUT_UPGRADE_COMPLETE = "HideoutUpgradeComplete", + HIDEOUT_PUT_ITEMS_IN_AREA_SLOTS = "HideoutPutItemsInAreaSlots", + HIDEOUT_TAKE_ITEMS_FROM_AREA_SLOTS = "HideoutTakeItemsFromAreaSlots", + HIDEOUT_TOGGLE_AREA = "HideoutToggleArea", + HIDEOUT_SINGLE_PRODUCTION_START = "HideoutSingleProductionStart", + HIDEOUT_SCAV_CASE_PRODUCTION_START = "HideoutScavCaseProductionStart", + HIDEOUT_CONTINUOUS_PRODUCTION_START = "HideoutContinuousProductionStart", + HIDEOUT_TAKE_PRODUCTION = "HideoutTakeProduction" +} diff --git a/KcY-SeeItemValue/itemValue/server/types/models/enums/ItemEventActions.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/enums/ItemEventActions.d.ts new file mode 100644 index 0000000..0e65453 --- /dev/null +++ b/KcY-SeeItemValue/itemValue/server/types/models/enums/ItemEventActions.d.ts @@ -0,0 +1,19 @@ +export declare enum ItemEventActions { + MOVE = "Move", + REMOVE = "Remove", + SPLIT = "Split", + MERGE = "Merge", + TRANSFER = "Transfer", + SWAP = "Swap", + FOLD = "Fold", + TOGGLE = "Toggle", + TAG = "Tag", + BIND = "Bind", + EXAMINE = "Examine", + READ_ENCYCLOPEDIA = "ReadEncyclopedia", + APPLY_INVENTORY_CHANGES = "ApplyInventoryChanges", + CREATE_MAP_MARKER = "CreateMapMarker", + DELETE_MAP_MARKER = "DeleteMapMarker", + EDIT_MAP_MARKER = "EditMapMarker", + OPEN_RANDOM_LOOT_CONTAINER = "OpenRandomLootContainer" +} diff --git a/KcY-SeeItemValue/itemValue/server/types/models/enums/WeatherType.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/enums/WeatherType.d.ts new file mode 100644 index 0000000..d31fefe --- /dev/null +++ b/KcY-SeeItemValue/itemValue/server/types/models/enums/WeatherType.d.ts @@ -0,0 +1,19 @@ +export declare enum WeatherType { + CLEAR_DAY = 1, + CLEAR_WIND = 2, + CLEAR_NIGHT = 3, + PARTLY_CLOUD_DAY = 4, + PARTLY_CLOUD_NIGHT = 5, + CLEAR_FOG_DAY = 6, + CLEAR_FOG_NIGHT = 7, + CLOUDFOG = 8, + FOG = 9, + MOSTLY_CLOUD = 10, + LIGHT_RAIN = 11, + RAIN = 12, + CLOUD_WIND = 13, + CLOUD_WIND_RAIN = 14, + FULL_CLOUD = 15, + THUNDER_CLOUD = 16, + NONE = 0 +} diff --git a/KcY-SeeItemValue/itemValue/server/types/models/enums/WildSpawnTypeNumber.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/enums/WildSpawnTypeNumber.d.ts new file mode 100644 index 0000000..ff806fe --- /dev/null +++ b/KcY-SeeItemValue/itemValue/server/types/models/enums/WildSpawnTypeNumber.d.ts @@ -0,0 +1,33 @@ +export declare enum WildSpawnTypeNumber { + ASSAULT = 1, + MARKSMAN = 2, + BOSSTEST = 4, + BOSSBULLY = 8, + FOLLOWERTEST = 16, + FOLLOWERBULLY = 32, + BOSSKILLA = 64, + BOSSKOJANIY = 128, + FOLLOWERKOJANIY = 256, + PMCBOT = 512, + CURSEDASSAULT = 1024, + BOSSGLUHAR = 2048, + FOLLOWERGLUHARASSAULT = 4096, + FOLLOWERGLUHARSECURITY = 8192, + FOLLOWERGLUHARSCOUT = 16384, + FOLLOWERGLUHARSNIPE = 32768, + FOLLOWERSANITAR = 65536, + BOSSSANITAR = 131072, + TEST = 262144, + ASSAULTGROUP = 524288, + SECTANTWARRIOR = 1048576, + SECTANTPRIEST = 2097152, + BOSSTAGILLA = 4194304, + FOLLOWERTAGILLA = 8388608, + EXUSEC = 16777216, + GIFTER = 33554432, + BOSSKNIGHT = 67108864, + FOLLOWERBIGPIPE = 134217728, + FOLLOWERBIRDEYE = 268435456, + SPTUSEC = 536870912, + SPTBEAR = 1073741824 +} diff --git a/KcY-SeeItemValue/itemValue/server/types/models/enums/WindDirection.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/enums/WindDirection.d.ts new file mode 100644 index 0000000..fb30b20 --- /dev/null +++ b/KcY-SeeItemValue/itemValue/server/types/models/enums/WindDirection.d.ts @@ -0,0 +1,10 @@ +export declare enum WindDirection { + EAST = 1, + NORTH = 2, + WEST = 3, + SOUTH = 4, + SE = 5, + SW = 6, + NW = 7, + NE = 8 +} diff --git a/KcY-SeeItemValue/itemValue/server/types/models/spt/bots/BotGenerationDetails.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/spt/bots/BotGenerationDetails.d.ts new file mode 100644 index 0000000..256de03 --- /dev/null +++ b/KcY-SeeItemValue/itemValue/server/types/models/spt/bots/BotGenerationDetails.d.ts @@ -0,0 +1,16 @@ +export interface BotGenerationDetails { + /** Should the bot be generated as a PMC */ + isPmc: boolean; + /** assault/pmcBot etc */ + role: string; + /** Active players current level */ + playerLevel: number; + /** Delta of highest level of bot */ + botRelativeLevelDeltaMax: number; + /** How many to create and store */ + botCountToGenerate: number; + /** Desired difficulty of the bot */ + botDifficulty: string; + /** Will the generated bot be a player scav */ + isPlayerScav: boolean; +} diff --git a/KcY-SeeItemValue/itemValue/server/types/models/spt/config/IBotConfig.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/spt/config/IBotConfig.d.ts index af8ceba..83897db 100644 --- a/KcY-SeeItemValue/itemValue/server/types/models/spt/config/IBotConfig.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/models/spt/config/IBotConfig.d.ts @@ -27,6 +27,8 @@ export interface IBotConfig extends IBaseConfig { maxBotCap: Record; /** How many stacks of secret ammo should a bot have in its bot secure container */ secureContainerAmmoStackCount: number; + /** Batch generation size when type not available in cache */ + botGenerationBatchSizePerType: number; } export interface PresetBatch { assault: number; @@ -64,10 +66,13 @@ export interface LootNvalue { } export interface EquipmentFilters { weaponModLimits: ModLimits; - randomisedWeaponModSlots?: string[]; - randomisedArmorSlots?: string[]; + faceShieldIsActiveChancePercent?: number; + lightLaserIsActiveChancePercent?: number; + randomisation: RandomisationDetails[]; blacklist: EquipmentFilterDetails[]; whitelist: EquipmentFilterDetails[]; + clothing: WeightingAdjustmentDetails[]; + weightingAdjustments: WeightingAdjustmentDetails[]; } export interface ModLimits { /** How many scopes are allowed on a weapon - hard coded to work with OPTIC_SCOPE, ASSAULT_SCOPE, COLLIMATOR, COMPACT_COLLIMATOR */ @@ -75,8 +80,27 @@ export interface ModLimits { /** How many lasers or lights are allowed on a weapon - hard coded to work with TACTICAL_COMBO, and FLASHLIGHT */ lightLaserLimit?: number; } +export interface RandomisationDetails { + levelRange: MinMax; + randomisedWeaponModSlots?: string[]; + randomisedArmorSlots?: string[]; + /** Equipment chances */ + equipment?: Record; + /** Modc chances */ + mods?: Record; +} export interface EquipmentFilterDetails { levelRange: MinMax; equipment: Record; cartridge: Record; } +export interface WeightingAdjustmentDetails { + levelRange: MinMax; + ammo?: AdjustmentDetails; + equipment?: AdjustmentDetails; + clothing?: AdjustmentDetails; +} +export interface AdjustmentDetails { + add: Record>; + edit: Record>; +} diff --git a/KcY-SeeItemValue/itemValue/server/types/models/spt/config/IInventoryConfig.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/spt/config/IInventoryConfig.d.ts index ffffa41..4642b9b 100644 --- a/KcY-SeeItemValue/itemValue/server/types/models/spt/config/IInventoryConfig.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/models/spt/config/IInventoryConfig.d.ts @@ -2,4 +2,10 @@ import { IBaseConfig } from "./IBaseConfig"; export interface IInventoryConfig extends IBaseConfig { kind: "aki-inventory"; newItemsMarkedFound: boolean; + randomLootContainers: Record; +} +export interface RewardDetails { + rewardCount: number; + foundInRaid: boolean; + rewardTplPool: Record; } diff --git a/KcY-SeeItemValue/itemValue/server/types/models/spt/config/ILocaleConfig.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/spt/config/ILocaleConfig.d.ts index fe9abf7..0a8955c 100644 --- a/KcY-SeeItemValue/itemValue/server/types/models/spt/config/ILocaleConfig.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/models/spt/config/ILocaleConfig.d.ts @@ -1,5 +1,10 @@ import { IBaseConfig } from "./IBaseConfig"; export interface ILocaleConfig extends IBaseConfig { kind: "aki-locale"; - desiredLocale: string; + /** e.g. ru/en/cn/fr etc, or 'system', will take computer locale setting */ + gameLocale: string; + /** e.g. ru/en/cn/fr etc, or 'system', will take computer locale setting */ + serverLocale: string; + /** Languages server can be translated into */ + serverSupportedLocales: string[]; } diff --git a/KcY-SeeItemValue/itemValue/server/types/models/spt/config/IPmcConfig.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/spt/config/IPmcConfig.d.ts index 9db2ba1..979122c 100644 --- a/KcY-SeeItemValue/itemValue/server/types/models/spt/config/IPmcConfig.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/models/spt/config/IPmcConfig.d.ts @@ -6,14 +6,17 @@ export interface IPmcConfig { looseWeaponInBackpackChancePercent: number; looseWeaponInBackpackLootMinMax: MinMax; isUsec: number; + usecType: string; + bearType: string; chanceSameSideIsHostilePercent: number; /** key: location, value: type for usec/bear */ - pmcType: Record; + pmcType: Record>>; maxBackpackLootTotalRub: number; maxPocketLootTotalRub: number; maxVestLootTotalRub: number; convertIntoPmcChance: Record; enemyTypes: string[]; + botRelativeLevelDeltaMax: number; } export interface PmcTypes { usec: string; diff --git a/KcY-SeeItemValue/itemValue/server/types/models/spt/config/IRagfairConfig.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/spt/config/IRagfairConfig.d.ts index c1b8763..6786417 100644 --- a/KcY-SeeItemValue/itemValue/server/types/models/spt/config/IRagfairConfig.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/models/spt/config/IRagfairConfig.d.ts @@ -28,12 +28,8 @@ export interface Reputation { gain: number; loss: number; } -export declare class OfferAdjustment { - maxPriceDifferenceBelowHandbookPercent: number; - handbookPriceMultipier: number; - priceThreshholdRub: number; -} export interface Dynamic { + barter: Barter; offerAdjustment: OfferAdjustment; expiredOfferThreshold: number; offerItemCount: MinMax; @@ -49,6 +45,20 @@ export interface Dynamic { showAsSingleStack: string[]; blacklist: Blacklist; } +export declare class Barter { + enable: boolean; + chancePercent: number; + itemCountMin: number; + itemCountMax: number; + priceRangeVariancePercent: number; + minRoubleCostToBecomeBarter: number; + itemTypeBlacklist: string[]; +} +export declare class OfferAdjustment { + maxPriceDifferenceBelowHandbookPercent: number; + handbookPriceMultipier: number; + priceThreshholdRub: number; +} export interface Condition { conditionChance: number; min: number; diff --git a/KcY-SeeItemValue/itemValue/server/types/models/spt/config/ISeasonalEventConfig.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/spt/config/ISeasonalEventConfig.d.ts index bc60618..e410925 100644 --- a/KcY-SeeItemValue/itemValue/server/types/models/spt/config/ISeasonalEventConfig.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/models/spt/config/ISeasonalEventConfig.d.ts @@ -1,6 +1,9 @@ import { IBaseConfig } from "./IBaseConfig"; export interface ISeasonalEventConfig extends IBaseConfig { kind: "aki-seasonalevents"; + enableSeasonalEventDetection: boolean; + /** event / botType / equipSlot / itemid */ + eventGear: Record>>>; events: ISeasonalEvent[]; } export interface ISeasonalEvent { diff --git a/KcY-SeeItemValue/itemValue/server/types/models/spt/config/IWeatherConfig.d.ts b/KcY-SeeItemValue/itemValue/server/types/models/spt/config/IWeatherConfig.d.ts index bbdc43e..41a1c83 100644 --- a/KcY-SeeItemValue/itemValue/server/types/models/spt/config/IWeatherConfig.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/models/spt/config/IWeatherConfig.d.ts @@ -1,3 +1,4 @@ +import { WindDirection } from "../../../models/enums/WindDirection"; import { MinMax } from "../../common/MinMax"; import { IBaseConfig } from "./IBaseConfig"; export interface IWeatherConfig extends IBaseConfig { @@ -7,12 +8,16 @@ export interface IWeatherConfig extends IBaseConfig { } export interface Weather { clouds: MinMax; - windSpeed: MinMax; - windDirection: MinMax; + windSpeed: WeatherSettings; + windDirection: WeatherSettings; windGustiness: MinMax; - rain: MinMax; + rain: WeatherSettings; rainIntensity: MinMax; - fog: MinMax; + fog: WeatherSettings; temp: MinMax; pressure: MinMax; } +export interface WeatherSettings { + values: T[]; + weights: number[]; +} diff --git a/KcY-SeeItemValue/itemValue/server/types/routers/item_events/HideoutItemEventRouter.d.ts b/KcY-SeeItemValue/itemValue/server/types/routers/item_events/HideoutItemEventRouter.d.ts index e1e98af..44bd1cd 100644 --- a/KcY-SeeItemValue/itemValue/server/types/routers/item_events/HideoutItemEventRouter.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/routers/item_events/HideoutItemEventRouter.d.ts @@ -1,7 +1,7 @@ -import { IPmcData } from "../../models/eft/common/IPmcData"; -import { IItemEventRouterResponse } from "../../models/eft/itemEvent/IItemEventRouterResponse"; import { HideoutCallbacks } from "../../callbacks/HideoutCallbacks"; import { HandledRoute, ItemEventRouterDefinition } from "../../di/Router"; +import { IPmcData } from "../../models/eft/common/IPmcData"; +import { IItemEventRouterResponse } from "../../models/eft/itemEvent/IItemEventRouterResponse"; export declare class HideoutItemEventRouter extends ItemEventRouterDefinition { protected hideoutCallbacks: HideoutCallbacks; constructor(hideoutCallbacks: HideoutCallbacks); diff --git a/KcY-SeeItemValue/itemValue/server/types/routers/item_events/InventoryItemEventRouter.d.ts b/KcY-SeeItemValue/itemValue/server/types/routers/item_events/InventoryItemEventRouter.d.ts index 2619bb9..953d322 100644 --- a/KcY-SeeItemValue/itemValue/server/types/routers/item_events/InventoryItemEventRouter.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/routers/item_events/InventoryItemEventRouter.d.ts @@ -1,7 +1,7 @@ -import { IPmcData } from "../../models/eft/common/IPmcData"; -import { IItemEventRouterResponse } from "../../models/eft/itemEvent/IItemEventRouterResponse"; import { InventoryCallbacks } from "../../callbacks/InventoryCallbacks"; import { HandledRoute, ItemEventRouterDefinition } from "../../di/Router"; +import { IPmcData } from "../../models/eft/common/IPmcData"; +import { IItemEventRouterResponse } from "../../models/eft/itemEvent/IItemEventRouterResponse"; export declare class InventoryItemEventRouter extends ItemEventRouterDefinition { protected inventoryCallbacks: InventoryCallbacks; constructor(inventoryCallbacks: InventoryCallbacks); diff --git a/KcY-SeeItemValue/itemValue/server/types/servers/HttpServer.d.ts b/KcY-SeeItemValue/itemValue/server/types/servers/HttpServer.d.ts index bbca8af..80c1d48 100644 --- a/KcY-SeeItemValue/itemValue/server/types/servers/HttpServer.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/servers/HttpServer.d.ts @@ -4,6 +4,7 @@ import { ApplicationContext } from "../context/ApplicationContext"; import { HttpServerHelper } from "../helpers/HttpServerHelper"; import { IHttpConfig } from "../models/spt/config/IHttpConfig"; import { ILogger } from "../models/spt/utils/ILogger"; +import { LocalisationService } from "../services/LocalisationService"; import { ConfigServer } from "./ConfigServer"; import { DatabaseServer } from "./DatabaseServer"; import { IHttpListener } from "./http/IHttpListener"; @@ -12,11 +13,12 @@ export declare class HttpServer { protected logger: ILogger; protected databaseServer: DatabaseServer; protected httpServerHelper: HttpServerHelper; + protected localisationService: LocalisationService; protected httpListeners: IHttpListener[]; protected configServer: ConfigServer; protected applicationContext: ApplicationContext; protected webSocketServer: WebSocketServer; - constructor(logger: ILogger, databaseServer: DatabaseServer, httpServerHelper: HttpServerHelper, httpListeners: IHttpListener[], configServer: ConfigServer, applicationContext: ApplicationContext, webSocketServer: WebSocketServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, httpServerHelper: HttpServerHelper, localisationService: LocalisationService, httpListeners: IHttpListener[], configServer: ConfigServer, applicationContext: ApplicationContext, webSocketServer: WebSocketServer); protected httpConfig: IHttpConfig; getCookies(req: http.IncomingMessage): any; handleRequest(req: IncomingMessage, resp: ServerResponse): void; diff --git a/KcY-SeeItemValue/itemValue/server/types/servers/SaveServer.d.ts b/KcY-SeeItemValue/itemValue/server/types/servers/SaveServer.d.ts index cb28f49..4dca514 100644 --- a/KcY-SeeItemValue/itemValue/server/types/servers/SaveServer.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/servers/SaveServer.d.ts @@ -1,20 +1,22 @@ +import { SaveLoadRouter } from "../di/Router"; import { IAkiProfile, Info } from "../models/eft/profile/IAkiProfile"; +import { ILogger } from "../models/spt/utils/ILogger"; +import { LocalisationService } from "../services/LocalisationService"; import { HashUtil } from "../utils/HashUtil"; import { JsonUtil } from "../utils/JsonUtil"; import { VFS } from "../utils/VFS"; -import { SaveLoadRouter } from "../di/Router"; -import { ILogger } from "../models/spt/utils/ILogger"; export declare class SaveServer { protected vfs: VFS; protected saveLoadRouters: SaveLoadRouter[]; protected jsonUtil: JsonUtil; protected hashUtil: HashUtil; + protected localisationService: LocalisationService; protected logger: ILogger; protected profileFilepath: string; protected profiles: {}; protected onSave: {}; protected saveMd5: {}; - constructor(vfs: VFS, saveLoadRouters: SaveLoadRouter[], jsonUtil: JsonUtil, hashUtil: HashUtil, logger: ILogger); + constructor(vfs: VFS, saveLoadRouters: SaveLoadRouter[], jsonUtil: JsonUtil, hashUtil: HashUtil, localisationService: LocalisationService, logger: ILogger); load(): void; save(): void; getProfile(sessionId: string): IAkiProfile; diff --git a/KcY-SeeItemValue/itemValue/server/types/servers/WebSocketServer.d.ts b/KcY-SeeItemValue/itemValue/server/types/servers/WebSocketServer.d.ts index f33d214..5d40e6e 100644 --- a/KcY-SeeItemValue/itemValue/server/types/servers/WebSocketServer.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/servers/WebSocketServer.d.ts @@ -1,18 +1,20 @@ /// -import { HttpServerHelper } from "../helpers/HttpServerHelper"; -import WebSocket from "ws"; import http, { IncomingMessage } from "http"; -import { ILogger } from "../models/spt/utils/ILogger"; -import { RandomUtil } from "../utils/RandomUtil"; +import WebSocket from "ws"; +import { HttpServerHelper } from "../helpers/HttpServerHelper"; import { INotification } from "../models/eft/notifier/INotifier"; -import { ConfigServer } from "./ConfigServer"; import { IHttpConfig } from "../models/spt/config/IHttpConfig"; +import { ILogger } from "../models/spt/utils/ILogger"; +import { LocalisationService } from "../services/LocalisationService"; +import { RandomUtil } from "../utils/RandomUtil"; +import { ConfigServer } from "./ConfigServer"; export declare class WebSocketServer { protected logger: ILogger; protected randomUtil: RandomUtil; protected configServer: ConfigServer; + protected localisationService: LocalisationService; protected httpServerHelper: HttpServerHelper; - constructor(logger: ILogger, randomUtil: RandomUtil, configServer: ConfigServer, httpServerHelper: HttpServerHelper); + constructor(logger: ILogger, randomUtil: RandomUtil, configServer: ConfigServer, localisationService: LocalisationService, httpServerHelper: HttpServerHelper); protected httpConfig: IHttpConfig; protected defaultNotification: INotification; protected webSockets: Record; diff --git a/KcY-SeeItemValue/itemValue/server/types/servers/http/AkiHttpListener.d.ts b/KcY-SeeItemValue/itemValue/server/types/servers/http/AkiHttpListener.d.ts index 6f78939..acf92aa 100644 --- a/KcY-SeeItemValue/itemValue/server/types/servers/http/AkiHttpListener.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/servers/http/AkiHttpListener.d.ts @@ -1,22 +1,24 @@ /// /// import { IncomingMessage, ServerResponse } from "http"; -import { IHttpListener } from "./IHttpListener"; import { Serializer } from "../../di/Serializer"; import { ILogger } from "../../models/spt/utils/ILogger"; import { HttpRouter } from "../../routers/HttpRouter"; +import { LocalisationService } from "../../services/LocalisationService"; import { HttpResponseUtil } from "../../utils/HttpResponseUtil"; import { JsonUtil } from "../../utils/JsonUtil"; import { HttpBufferHandler } from "./HttpBufferHandler"; +import { IHttpListener } from "./IHttpListener"; export declare class AkiHttpListener implements IHttpListener { protected httpRouter: HttpRouter; protected serializers: Serializer[]; protected logger: ILogger; protected jsonUtil: JsonUtil; protected httpResponse: HttpResponseUtil; + protected localisationService: LocalisationService; protected httpBufferHandler: HttpBufferHandler; constructor(httpRouter: HttpRouter, // TODO: delay required - serializers: Serializer[], logger: ILogger, jsonUtil: JsonUtil, httpResponse: HttpResponseUtil, httpBufferHandler: HttpBufferHandler); + serializers: Serializer[], logger: ILogger, jsonUtil: JsonUtil, httpResponse: HttpResponseUtil, localisationService: LocalisationService, httpBufferHandler: HttpBufferHandler); canHandle(_: string, req: IncomingMessage): boolean; handle(sessionId: string, req: IncomingMessage, resp: ServerResponse): void; sendResponse(sessionID: string, req: IncomingMessage, resp: ServerResponse, body: Buffer, output: string): void; diff --git a/KcY-SeeItemValue/itemValue/server/types/services/BotEquipmentFilterService.d.ts b/KcY-SeeItemValue/itemValue/server/types/services/BotEquipmentFilterService.d.ts index 632f961..43e64b0 100644 --- a/KcY-SeeItemValue/itemValue/server/types/services/BotEquipmentFilterService.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/services/BotEquipmentFilterService.d.ts @@ -1,21 +1,29 @@ -import { IBotType } from "../models/eft/common/tables/IBotType"; -import { EquipmentFilters, EquipmentFilterDetails, IBotConfig } from "../models/spt/config/IBotConfig"; +import { BotHelper } from "../helpers/BotHelper"; +import { EquipmentChances, IBotType, ModsChances } from "../models/eft/common/tables/IBotType"; +import { BotGenerationDetails } from "../models/spt/bots/BotGenerationDetails"; +import { AdjustmentDetails, EquipmentFilterDetails, EquipmentFilters, IBotConfig, WeightingAdjustmentDetails } from "../models/spt/config/IBotConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; export declare class BotEquipmentFilterService { protected logger: ILogger; + protected botHelper: BotHelper; protected configServer: ConfigServer; protected botConfig: IBotConfig; - protected botEquipmentFilterlists: Record; - constructor(logger: ILogger, configServer: ConfigServer); + protected botEquipmentConfig: Record; + constructor(logger: ILogger, botHelper: BotHelper, configServer: ConfigServer); /** * Filter a bots data to exclude equipment and cartridges defines in the botConfig * @param baseBotNode bots json data to filter - * @param playerLevel Level of the currently playing player - * @param isPmc Is the bot we're filtering a PMC - * @param role Role of the bot we're filtering + * @param botLevel Level of the bot + * @param botGenerationDetails details on how to generate a bot */ - filterBotEquipment(baseBotNode: IBotType, playerLevel: number, isPmc: boolean, role: string): void; + filterBotEquipment(baseBotNode: IBotType, botLevel: number, botGenerationDetails: BotGenerationDetails): void; + /** + * Iterate over the changes passed in and alter data in baseValues + * @param equipmentChanges Changes to apply + * @param baseValues Values to update + */ + protected adjustChances(equipmentChanges: Record, baseValues: EquipmentChances | ModsChances): void; /** * Get an object that contains equipment and cartridge blacklists for a specified bot type * @param botRole Role of the bot we want the blacklist for @@ -30,6 +38,20 @@ export declare class BotEquipmentFilterService { * @returns EquipmentFilterDetails object */ protected getBotEquipmentWhitelist(botRole: string, playerLevel: number): EquipmentFilterDetails; + /** + * Retreive clothing weighting adjustments from bot.json config + * @param botRole Bot type to get adjustments for + * @param playerLevel level of player + * @returns Weighting adjustments for bots clothing + */ + protected getBotClothingAdjustments(botRole: string, playerLevel: number): WeightingAdjustmentDetails; + /** + * Retreive item weighting adjustments from bot.json config + * @param botRole Bot type to get adjustments for + * @param playerLevel level of player + * @returns Weighting adjustments for bot items + */ + protected getBotWeightingAdjustments(botRole: string, playerLevel: number): WeightingAdjustmentDetails; /** * Filter bot equipment based on blacklist and whitelist from config/bot.json * Prioritises whitelist first, if one is found blacklist is ignored @@ -47,4 +69,10 @@ export declare class BotEquipmentFilterService { * @returns Filtered bot file */ protected filterCartridges(baseBotNode: IBotType, blacklist: EquipmentFilterDetails, whitelist: EquipmentFilterDetails): void; + /** + * Add/Edit weighting changes to bot items using values from config/bot.json/equipment + * @param weightingAdjustments Weighting change to apply to bot + * @param botItemPool Bot item dictionary to adjust + */ + protected adjustWeighting(weightingAdjustments: AdjustmentDetails, botItemPool: Record, showEditWarnings?: boolean): void; } diff --git a/KcY-SeeItemValue/itemValue/server/types/services/BotGenerationCacheService.d.ts b/KcY-SeeItemValue/itemValue/server/types/services/BotGenerationCacheService.d.ts index ba53fec..0be0576 100644 --- a/KcY-SeeItemValue/itemValue/server/types/services/BotGenerationCacheService.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/services/BotGenerationCacheService.d.ts @@ -8,11 +8,11 @@ export declare class BotGenerationCacheService { protected randomUtil: RandomUtil; protected jsonUtil: JsonUtil; protected botHelper: BotHelper; - protected storedBots: IBotBase[]; + protected storedBots: Map; constructor(logger: ILogger, randomUtil: RandomUtil, jsonUtil: JsonUtil, botHelper: BotHelper); /** * Store array of bots in cache, shuffle results before storage - * @param botsToStore + * @param botsToStore Bots we want to store in the cache */ storeBots(botsToStore: IBotBase[]): void; /** @@ -21,25 +21,7 @@ export declare class BotGenerationCacheService { * @param role role to retreive (assault/bossTagilla etc) * @returns IBotBase object */ - getBot(role: string): IBotBase[]; - /** - * Find a bot by its index from cache - * @param indexOfBotToReturn index to find bot by - * @returns bot profile - */ - protected getBotFromCache(indexOfBotToReturn: number): IBotBase; - /** - * Remove bot profile by index from cache - * @param indexOfBotToReturn Index of bot profile to remove - */ - protected removeBotFromCache(indexOfBotToReturn: number): void; - /** - * Get index of bot profile that matches criteria - * @param role Role of bot wanted - * @param getPmc Requested bot a pmc - * @returns index of found bot, -1 if not found - */ - protected getIndexOfBotToReturn(role: string, getPmc: boolean): number; + getBot(role: string): IBotBase; /** * Remove all cached bot profiles */ @@ -48,5 +30,5 @@ export declare class BotGenerationCacheService { * Does cache have bots * @returns true if empty */ - cacheIsEmpty(): boolean; + cacheHasBotOfRole(role: string): boolean; } diff --git a/KcY-SeeItemValue/itemValue/server/types/services/LocaleService.d.ts b/KcY-SeeItemValue/itemValue/server/types/services/LocaleService.d.ts index 33bea7b..8275b75 100644 --- a/KcY-SeeItemValue/itemValue/server/types/services/LocaleService.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/services/LocaleService.d.ts @@ -1,14 +1,42 @@ import { ILocaleConfig } from "../models/spt/config/ILocaleConfig"; +import { ILocaleGlobalBase } from "../models/spt/server/ILocaleBase"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; +import { DatabaseServer } from "../servers/DatabaseServer"; +/** + * Handles getting locales from config or users machine + */ export declare class LocaleService { protected logger: ILogger; + protected databaseServer: DatabaseServer; protected configServer: ConfigServer; protected localeConfig: ILocaleConfig; - constructor(logger: ILogger, configServer: ConfigServer); + constructor(logger: ILogger, databaseServer: DatabaseServer, configServer: ConfigServer); /** - * Gets the locale key from the locale.json file + * Get the eft globals db file based on the configured locale in config/locale.json, if not found, fall back to 'en' + * @returns ILocaleGlobalBase + */ + getLocaleDb(): ILocaleGlobalBase; + /** + * Gets the game locale key from the locale.json file, + * if value is 'system' get system locale * @returns locale e.g en/ge/cz/cn */ - getDesiredLocale(): string; + getDesiredGameLocale(): string; + /** + * Gets the game locale key from the locale.json file, + * if value is 'system' get system locale + * @returns locale e.g en/ge/cz/cn + */ + getDesiredServerLocale(): string; + /** + * Get array of languages supported for localisation + * @returns array of locales e.g. en/fr/cn + */ + getServerSupportedLocales(): string[]; + /** + * Get the locale of the computer running the server + * @returns langage part of locale e.g. 'en' part of 'en-US' + */ + protected getPlatformLocale(): string; } diff --git a/KcY-SeeItemValue/itemValue/server/types/services/LocalisationService.d.ts b/KcY-SeeItemValue/itemValue/server/types/services/LocalisationService.d.ts new file mode 100644 index 0000000..519325d --- /dev/null +++ b/KcY-SeeItemValue/itemValue/server/types/services/LocalisationService.d.ts @@ -0,0 +1,21 @@ +import { I18n } from "i18n"; +import { ILocaleConfig } from "../models/spt/config/ILocaleConfig"; +import { ILogger } from "../models/spt/utils/ILogger"; +import { LocaleService } from "./LocaleService"; +/** + * Handles translating server text into different langauges + */ +export declare class LocalisationService { + protected logger: ILogger; + protected localeService: LocaleService; + protected localeConfig: ILocaleConfig; + protected i18n: I18n; + constructor(logger: ILogger, localeService: LocaleService); + /** + * Get a localised value using the passed in key + * @param key Key to loop up locale for + * @param args optional arguments + * @returns Localised string + */ + getText(key: string, args?: any): string; +} diff --git a/KcY-SeeItemValue/itemValue/server/types/services/PaymentService.d.ts b/KcY-SeeItemValue/itemValue/server/types/services/PaymentService.d.ts index a5e538f..c9ce95a 100644 --- a/KcY-SeeItemValue/itemValue/server/types/services/PaymentService.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/services/PaymentService.d.ts @@ -11,6 +11,7 @@ import { IProcessSellTradeRequestData } from "../models/eft/trade/IProcessSellTr import { ILogger } from "../models/spt/utils/ILogger"; import { DatabaseServer } from "../servers/DatabaseServer"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; +import { LocalisationService } from "./LocalisationService"; export declare class PaymentService { protected logger: ILogger; protected httpResponse: HttpResponseUtil; @@ -19,8 +20,9 @@ export declare class PaymentService { protected traderHelper: TraderHelper; protected itemHelper: ItemHelper; protected inventoryHelper: InventoryHelper; + protected localisationService: LocalisationService; protected paymentHelper: PaymentHelper; - constructor(logger: ILogger, httpResponse: HttpResponseUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, traderHelper: TraderHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, paymentHelper: PaymentHelper); + constructor(logger: ILogger, httpResponse: HttpResponseUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, traderHelper: TraderHelper, itemHelper: ItemHelper, inventoryHelper: InventoryHelper, localisationService: LocalisationService, paymentHelper: PaymentHelper); /** * Take money and insert items into return to server request * @param {Object} pmcData @@ -50,7 +52,7 @@ export declare class PaymentService { * @param pmcData Player profile to find and remove currency from * @param currencyTpl Type of currency to pay * @param amountToPay money value to pay - * @param sessionID Sessino id + * @param sessionID Session id * @param output output object to send to client * @returns IItemEventRouterResponse */ diff --git a/KcY-SeeItemValue/itemValue/server/types/services/PlayerService.d.ts b/KcY-SeeItemValue/itemValue/server/types/services/PlayerService.d.ts index 519b7e5..2f364d5 100644 --- a/KcY-SeeItemValue/itemValue/server/types/services/PlayerService.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/services/PlayerService.d.ts @@ -2,10 +2,12 @@ import { IPmcData } from "../models/eft/common/IPmcData"; import { IPlayerIncrementSkillLevelRequestData } from "../models/eft/player/IPlayerIncrementSkillLevelRequestData"; import { ILogger } from "../models/spt/utils/ILogger"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "./LocalisationService"; export declare class PlayerService { protected logger: ILogger; + protected localisationService: LocalisationService; protected databaseServer: DatabaseServer; - constructor(logger: ILogger, databaseServer: DatabaseServer); + constructor(logger: ILogger, localisationService: LocalisationService, databaseServer: DatabaseServer); /** * increases the profile skill and updates any output * @param {Object} pmcData diff --git a/KcY-SeeItemValue/itemValue/server/types/services/PmcAiService.d.ts b/KcY-SeeItemValue/itemValue/server/types/services/PmcAiService.d.ts deleted file mode 100644 index 0690f1f..0000000 --- a/KcY-SeeItemValue/itemValue/server/types/services/PmcAiService.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { IBotConfig } from "../models/spt/config/IBotConfig"; -import { ILogger } from "../models/spt/utils/ILogger"; -import { ConfigServer } from "../servers/ConfigServer"; -/** Storing/retreving pmcRoles set at the start of a raid - its done at that point as we know what location the player is heading to */ -export declare class PmcAiService { - protected logger: ILogger; - protected configServer: ConfigServer; - protected botConfig: IBotConfig; - protected usecRole: string; - protected bearRole: string; - constructor(logger: ILogger, configServer: ConfigServer); - /** - * Convert from pmc side (usec/bear) to the side as defined in the bot config (usecType/bearType) - * @param pmcSide eft side (usec/bear) - * @returns pmc side as defined in config - */ - getPmcRole(pmcSide: "usec" | "bear" | string): string; - /** - * Set the roles for pmcs - * @param location map location to look up and use as pmc types - */ - setPmcRolesByLocation(location: string): void; - /** - * Clear the saved role from usec/bear PMCs - */ - clearPmcRoles(): void; -} diff --git a/KcY-SeeItemValue/itemValue/server/types/services/ProfileFixerService.d.ts b/KcY-SeeItemValue/itemValue/server/types/services/ProfileFixerService.d.ts index e772919..86a6af8 100644 --- a/KcY-SeeItemValue/itemValue/server/types/services/ProfileFixerService.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/services/ProfileFixerService.d.ts @@ -8,12 +8,14 @@ import { HideoutAreas } from "../models/enums/HideoutAreas"; import { ILogger } from "../models/spt/utils/ILogger"; import { DatabaseServer } from "../servers/DatabaseServer"; import { Watermark } from "../utils/Watermark"; +import { LocalisationService } from "./LocalisationService"; export declare class ProfileFixerService { protected logger: ILogger; protected watermark: Watermark; protected hideoutHelper: HideoutHelper; + protected localisationService: LocalisationService; protected databaseServer: DatabaseServer; - constructor(logger: ILogger, watermark: Watermark, hideoutHelper: HideoutHelper, databaseServer: DatabaseServer); + constructor(logger: ILogger, watermark: Watermark, hideoutHelper: HideoutHelper, localisationService: LocalisationService, databaseServer: DatabaseServer); /** * Find issues in the pmc profile data that may cause issues and fix them * @param pmcProfile profile to check and fix diff --git a/KcY-SeeItemValue/itemValue/server/types/services/RagfairOfferService.d.ts b/KcY-SeeItemValue/itemValue/server/types/services/RagfairOfferService.d.ts index a6f6b6d..86c1e52 100644 --- a/KcY-SeeItemValue/itemValue/server/types/services/RagfairOfferService.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/services/RagfairOfferService.d.ts @@ -11,6 +11,7 @@ import { DatabaseServer } from "../servers/DatabaseServer"; import { SaveServer } from "../servers/SaveServer"; import { HttpResponseUtil } from "../utils/HttpResponseUtil"; import { TimeUtil } from "../utils/TimeUtil"; +import { LocalisationService } from "./LocalisationService"; import { RagfairCategoriesService } from "./RagfairCategoriesService"; export declare class RagfairOfferService { protected logger: ILogger; @@ -22,12 +23,14 @@ export declare class RagfairOfferService { protected profileHelper: ProfileHelper; protected eventOutputHolder: EventOutputHolder; protected httpResponse: HttpResponseUtil; + protected localisationService: LocalisationService; protected configServer: ConfigServer; protected playerOffersLoaded: boolean; protected expiredOffers: Item[]; - protected offers: IRagfairOffer[]; + /** offerId, offer */ + protected offers: Record; protected ragfairConfig: IRagfairConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, databaseServer: DatabaseServer, saveServer: SaveServer, ragfairServerHelper: RagfairServerHelper, ragfairCategoriesService: RagfairCategoriesService, profileHelper: ProfileHelper, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, databaseServer: DatabaseServer, saveServer: SaveServer, ragfairServerHelper: RagfairServerHelper, ragfairCategoriesService: RagfairCategoriesService, profileHelper: ProfileHelper, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, localisationService: LocalisationService, configServer: ConfigServer); /** * Get all offers * @returns IRagfairOffer array diff --git a/KcY-SeeItemValue/itemValue/server/types/utils/App.d.ts b/KcY-SeeItemValue/itemValue/server/types/utils/App.d.ts index dcc2669..cc8a5af 100644 --- a/KcY-SeeItemValue/itemValue/server/types/utils/App.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/utils/App.d.ts @@ -1,14 +1,16 @@ -import { TimeUtil } from "./TimeUtil"; import { OnLoad } from "../di/OnLoad"; import { OnUpdate } from "../di/OnUpdate"; import { ILogger } from "../models/spt/utils/ILogger"; +import { LocalisationService } from "../services/LocalisationService"; +import { TimeUtil } from "./TimeUtil"; export declare class App { protected logger: ILogger; protected timeUtil: TimeUtil; + protected localisationService: LocalisationService; protected onLoadComponents: OnLoad[]; protected onUpdateComponents: OnUpdate[]; protected onUpdateLastRun: {}; - constructor(logger: ILogger, timeUtil: TimeUtil, onLoadComponents: OnLoad[], onUpdateComponents: OnUpdate[]); + constructor(logger: ILogger, timeUtil: TimeUtil, localisationService: LocalisationService, onLoadComponents: OnLoad[], onUpdateComponents: OnUpdate[]); load(): void; protected update(onUpdateComponents: OnUpdate[]): void; protected logUpdateException(err: any, updateable: OnUpdate): void; diff --git a/KcY-SeeItemValue/itemValue/server/types/utils/DatabaseImporter.d.ts b/KcY-SeeItemValue/itemValue/server/types/utils/DatabaseImporter.d.ts index 483e135..31670ae 100644 --- a/KcY-SeeItemValue/itemValue/server/types/utils/DatabaseImporter.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/utils/DatabaseImporter.d.ts @@ -3,15 +3,17 @@ import { IDatabaseTables } from "../models/spt/server/IDatabaseTables"; import { ILogger } from "../models/spt/utils/ILogger"; import { ImageRouter } from "../routers/ImageRouter"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { LocalisationService } from "../services/LocalisationService"; import { JsonUtil } from "./JsonUtil"; import { VFS } from "./VFS"; export declare class DatabaseImporter extends OnLoad { protected logger: ILogger; protected vfs: VFS; protected jsonUtil: JsonUtil; + protected localisationService: LocalisationService; protected databaseServer: DatabaseServer; protected imageRouter: ImageRouter; - constructor(logger: ILogger, vfs: VFS, jsonUtil: JsonUtil, databaseServer: DatabaseServer, imageRouter: ImageRouter); + constructor(logger: ILogger, vfs: VFS, jsonUtil: JsonUtil, localisationService: LocalisationService, databaseServer: DatabaseServer, imageRouter: ImageRouter); onLoad(): void; /** * Read all json files in database folder and map into a json object diff --git a/KcY-SeeItemValue/itemValue/server/types/utils/HttpResponseUtil.d.ts b/KcY-SeeItemValue/itemValue/server/types/utils/HttpResponseUtil.d.ts index 29502be..3a78618 100644 --- a/KcY-SeeItemValue/itemValue/server/types/utils/HttpResponseUtil.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/utils/HttpResponseUtil.d.ts @@ -1,10 +1,13 @@ -import { JsonUtil } from "./JsonUtil"; import { IGetBodyResponseData } from "../models/eft/httpResponse/IGetBodyResponseData"; import { INullResponseData } from "../models/eft/httpResponse/INullResponseData"; import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse"; +import { BackendErrorCodes } from "../models/enums/BackendErrorCodes"; +import { LocalisationService } from "../services/LocalisationService"; +import { JsonUtil } from "./JsonUtil"; export declare class HttpResponseUtil { protected jsonUtil: JsonUtil; - constructor(jsonUtil: JsonUtil); + protected localisationService: LocalisationService; + constructor(jsonUtil: JsonUtil, localisationService: LocalisationService); protected clearString(s: string): any; noBody(data: any): any; getBody(data: T, err?: number, errmsg?: any): IGetBodyResponseData; @@ -12,5 +15,5 @@ export declare class HttpResponseUtil { emptyResponse(): IGetBodyResponseData; nullResponse(): INullResponseData; emptyArrayResponse(): IGetBodyResponseData; - appendErrorToOutput(output: IItemEventRouterResponse, message?: string, title?: string): IItemEventRouterResponse; + appendErrorToOutput(output: IItemEventRouterResponse, message?: string, errorCode?: BackendErrorCodes): IItemEventRouterResponse; } diff --git a/KcY-SeeItemValue/itemValue/server/types/utils/Logger.d.ts b/KcY-SeeItemValue/itemValue/server/types/utils/Logger.d.ts index 3d9013f..1088701 100644 --- a/KcY-SeeItemValue/itemValue/server/types/utils/Logger.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/utils/Logger.d.ts @@ -53,6 +53,12 @@ export declare class WinstonLogger implements ILogger { warning(data: string | Record): Promise; success(data: string | Record): Promise; info(data: string | Record): Promise; + /** + * Log to console text with a customisable text and background color. Background defaults to black + * @param data text to log + * @param textColor color of text + * @param backgroundColor color of background + */ logWithColor(data: string | Record, textColor: LogTextColor, backgroundColor?: LogBackgroundColor): Promise; debug(data: string | Record, onlyShowInConsole?: boolean): Promise; } diff --git a/KcY-SeeItemValue/itemValue/server/types/utils/RandomUtil.d.ts b/KcY-SeeItemValue/itemValue/server/types/utils/RandomUtil.d.ts index 633e472..aa556e3 100644 --- a/KcY-SeeItemValue/itemValue/server/types/utils/RandomUtil.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/utils/RandomUtil.d.ts @@ -110,6 +110,12 @@ export declare class RandomUtil { getIntEx(max: number): number; getFloat(min: number, max: number): number; getBool(): boolean; + /** + * Check if number passes a check out of 100 + * @param chancePercent value check needs to be above + * @returns true if value passes check + */ + getChance100(chancePercent: number): boolean; getStringArrayValue(arr: string[]): string; getArrayValue(arr: T[]): T; getKey(node: any): string; diff --git a/KcY-SeeItemValue/itemValue/server/types/utils/Watermark.d.ts b/KcY-SeeItemValue/itemValue/server/types/utils/Watermark.d.ts index c6dc120..e02eba2 100644 --- a/KcY-SeeItemValue/itemValue/server/types/utils/Watermark.d.ts +++ b/KcY-SeeItemValue/itemValue/server/types/utils/Watermark.d.ts @@ -1,20 +1,15 @@ import { ICoreConfig } from "../models/spt/config/ICoreConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; +import { LocalisationService } from "../services/LocalisationService"; export declare class WatermarkLocale { - protected locales: { - "en-US": { - description: string[]; - warning: string[]; - modding: string[]; - }; - "zh-CN": { - description: string[]; - warning: string[]; - modding: string[]; - }; + protected localisationService: LocalisationService; + constructor(localisationService: LocalisationService); + protected watermark: { + description: string[]; + warning: string[]; + modding: string[]; }; - getLocale(): string; getDescription(): string[]; getWarning(): string[]; getModding(): string[]; @@ -22,9 +17,10 @@ export declare class WatermarkLocale { export declare class Watermark { protected logger: ILogger; protected configServer: ConfigServer; + protected localisationService: LocalisationService; protected watermarkLocale?: WatermarkLocale; protected akiConfig: ICoreConfig; - constructor(logger: ILogger, configServer: ConfigServer, watermarkLocale?: WatermarkLocale); + constructor(logger: ILogger, configServer: ConfigServer, localisationService: LocalisationService, watermarkLocale?: WatermarkLocale); protected text: string[]; protected versionLabel: string; initialize(): void; diff --git a/Shared/EFT/Accessibility.dll b/Shared/EFT/Accessibility.dll index aeea772959e58241b8c2646dd1f11c6ff65babe9..43b0fd5c7e83fd29dbd92252d389421560915d77 100644 GIT binary patch delta 554 zcmV+_0@eM%tpUKT0g%`NmASFnfKv)EI5ILZHZ?djG?QdhRewi!o19pa!+muQR-wjc zk$zxFqZSGcI)3GI=D|(IA9K}BK<~g7_FqQF1&)Zlb5s1WAqPeacmW+>9O=OSw7~}# zsoc!$YiKR7s+pGrlpoa-*y_>LiaU2E;1yr;wV^!Y5OEm^f^uCIMj+T2U6&s7lS|+u zpy=W@*?ue;U4K!`D?C#}1(U+Khcd9pJ71G{XG|*;hb4yiYG(SX!#;#5tcE}u{3Y9Q zVfTm;%jn=igvYASDtS2q~7t8plk=-@}Y)z zVGM`SBQv;x7D!k5Yodlt@@Q%6l?#qTZg1&bT=`8nVt+wNr$qZFl*>eB-+tRTBxG3t zCXx>X62nqTMp3+}Eb^cs91DN#hJ2qiawVL(;fI1tkr4pE8UWBvu9Elo7iT&>#Q=;K z-u*Pv%Ob@KiszwoCj=b|eD?ssH-BHg5XAnR(Ke4-OE>fu$DhB31cxeH|6FmKv>6Dq znKypec7NQ{uZZ=8xIUjLoic`1zq{BW(MHinu{@D_a9smFU delta 554 zcmV+_0@eM%tpUKT0g%`NO^mVHfKv)FFflSQI503XF_UCeRey|v-KMMjnnV+ACpO9; zrPICC3ByXU?kWb*H~6TET}W%)rWC6b^xYx6VsCim0sV*UV&KAHxK;*MM)66;rDo-5(d=C57PlFpM6fB6(8iO& z8JAH|Nq=&ySb%k{t8;`rA|mHll4#Gy$+w||Gjt_B z&8;*P3lW|?S!8^-FP77!Dc`9(E6#ia29STT=@FT>CPYXdMd6`ZJ6-Ak8r%1Jh+8GMUB=pVncKYD`jPJdv zt%+C@UHB8@N|&-UEEE%>#KeUQHzp)*To_mobzxlS)))eQ_rCXLrY#cV!Uge6?|1Jx z_uO;OIrrZ4I{xDO=mwBtyLl71#9mTf;q76G(|z}U*@ug3FF$Ze8@v2KdCm&-hVRvV z)6r|D>w2MH6}sPab<5R@M@zcn%?M+|hIPAQ(-R}WnAVN-#pAChyIsSB`g$z`q$!b& zbappEXUnqz8`Zcg@>>dGHDHMh<&wHF{ialvf9*bIrHHhbc8|(I9(Y_PVkJ!jcTqM* zhs!JHZpZ6DZ^wKu`NJK&5sHP7{2M(4&Zz)mzsV`mfoa1J{2DpsTb=`XP@RU!Qk*w@ zVS7}RzG9k9+ENVrnDW3-GEVwaGOr}*TNipTp##^M2Tcn91r3#+9n#{}a{Kw5kue4{ zg9H1eu^!mO9F6y%1`MxJ}i5c`jnP~=!1UH>!3MvLsr%}}5a1j4D>i)AakmH3cliz(p;mglZs zGwRNIzGH@*H0{6D8ur{-tKRgLUfam9=QJ!^2`7bZE~rt^o=+T`@EK4oTs<-DH5PrV zK6lG0r(wE_?KP84H?$lf_vAiR%eKOf*;a;(8QVr_F$jfYOo~}s)MRWhYN6*R@}gzd zT`vf&T9Alh>qZok@Jqs^eUB^@Bg4 zjZes}X4uZ{Vrv!W=%&j1xrZ&q+LKztK?kW)-N8?miltW%p8O@X`^v~C*R_|5&JUaA zn=3w12~GcuHy;O3;fICSI;imLbDGCeX?a%hs;4W7mMg;CW7+nk(U_^Cbhwb+_b8HW zev7wZC=2@M6I(9Ke|Gx&6Hk3zic6*R&XHqXj#g7rQlptu!=7KX?Qzp`qbDbXxa;emPV*1|Fh)jdj?AgNE8;krA2X z_>M>goS{wN0PC*SvRmYAfSTH`vCN-H-{8l&siKkZCc{VFUOUCLK3BJ67-03!w3^(j zkNPqTq0)8fkKN(b>OBm;Pn$nbYb)1|aa~=ll94sAs64G>juxS!T`tp+=jDy;>d4ZY zEPs-U%9o?@dYN76OL9_@i!yaPpK>a96SU#c&nEL0c0`lpcxBGgjAQwlm6>bjjsH`r q92c0^fU!F~U7Jzsyjjb$-CiSeeut4B{hPS7?+%OW|8V|M2L1w*k;?)A diff --git a/Shared/EFT/Aki.Common.dll b/Shared/EFT/Aki.Common.dll deleted file mode 100644 index 8dbd95b51ef2ef2587bd8d7ddd38653a23da9b84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13824 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 W{MzXKu58`9-}7<&!TjIJ1OEq-UYmXZ diff --git a/Shared/EFT/Aki.Reflection.dll b/Shared/EFT/Aki.Reflection.dll deleted file mode 100644 index 2ca458f4cd21ebd7c99da81ba96dc00a371a2e36..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13824 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 VTfs)GTiA9Rf2{WZ*Z(;W{5MERJ!k*` diff --git a/Shared/EFT/AmplifyMotion.dll b/Shared/EFT/AmplifyMotion.dll index ff9f92b06d89768028ebb3314fe5622fcf0e2cd7..21176f2cdd5d004e8cd73459e670db03352ead1d 100644 GIT binary patch delta 552 zcmV+@0@wY(X~1ca*aH5?vD$z!3NSb_GBGwaI5antWHMEMFri*h3Pv>$%7Y<|KCE&e zE<#Fj)koERTOYcc^mXN%>=2$4fyW%G9?CW5-40jh^p1 zJF1ihS7U!BNMbN%4hu(Bb*q@jrncJc)buPx;KWbo9LY;^Q~9)}v4{rsWt?gsgUdx&WN!DbzT)b`6Owie+#8J&AAN;F!T1%@*IYL z(f?L&630q(iON>tW=MiLP(8V6vBB{X?Ybl)>ENNRH!kxwR&_dAn21LkRsw3f#!v>hqW{$_YA>VAB)+4?tC>#D2ay;m4Ewt!ba8-B)r@`74QH{g*yDOpq;d}G9K>Ea0! zBS75M$JC80#tIbZu()M?QQ>XIWb9wr;Tuqq3>Zg}%nv+srE{gZ8WR;+BgN;6%gJ!f zW+ysQph2xo1+aKR7(d)ob;But@Zqu5;cUCx-HR>1`nIa$X&knt*!l;C?P3B#vOyhN zi~4kz?qZj1Qpc1e>+&CP3Q%P)J=yr5pazU!tMPeB= z*8e%gtJKF^cvbO!k4vX`X}$i(^fw9WuDP)zPe8^!y_79sdY%w1q>s}ZAQymKyDw6} q=>IOAzp46dU~7E*~000000002u0taCL delta 552 zcmV+@0@wY(X~1ca*aF0yvD$z!3NbJ-GBG$XFf%lhWHMEMQGpFPK?!(`sN-z(sygN>l5L9|R0!r6Qzi&}yPRHhF|78@F!tgvy zlXEN1KB#9`W;34gFo{B;TH;dp?SdpDDXIhx(h2(FW9%=W3GUj5-n{$Ow3=}Hf`KA9 z41?z*j=bl8S}cBIf?F{->X<#-z&283Tr&h^ZmCb;ymgGAx=>|d#XE90+Us9FMP@f5U+Py9DcK;>kj@NYG`8#dy qU9jtv%1v@dnTJ06H#!Cx>SEyPyD$k#3pI8NF?d01000000002k01%A; diff --git a/Shared/EFT/AnimationSystem.Recording.dll b/Shared/EFT/AnimationSystem.Recording.dll index e0e5eedfabf0df503f380ac6ed5f92ada9d2d94d..01a9a482eb87adb75dcbdbd9ff956d0db3e625ce 100644 GIT binary patch delta 1247 zcmV<51R(psX~1cahyyaP1CfhO0`cmx+9CuH&sB8+yo8fMsXz(}bw+h{vkV1Y2^8qd zeU6sY@~MSqIXQ1qOmCb1qKF@_%NAZH{Qm z*{acXK+vQLFskZ}*W0bOKZp**uF0TPjhM5?c`BlpN;@(IV@plNZy6_w zfoKXuT-3~Fya%JKPmGmGZ7_3xjAZ9>(II+$N0Zg772Yz_oQ&Hq)svDlHO-opFW~iX za!my6*i#6*^?@}X7JnesEx(g1C>?QDDHz_-o3!xqp=H`JzS0iMGh_z7zPtLm4WFKg z*{QTJ>b1SV-bdOxPh_&RTb8r8Gn~(MoKi-1Y?liWWFd<97|RKc-l*Sy1W(pZ#)Akb z2(!Wu^qb!G2nfZRKuTY1X5DAt8sMSE>;5MVnz)z#l zhB44*$YL$~?5;_R*6+$ab4=%%R|sh9Ho&5=faPu3^mcqUmAaOs{ZfrKO3Z2LUi$qw z+NtKW>atW;UtEeB+z78L&D&_Lg|eltXTXx*huQshom^~SOU1^8QD-~+Ji3Ohc$2qF zCA1>EIGRb5X)*DCFgP+YF*Y?gH85H*KL!aZhDe6@4FL%RF){=&XYNA7gtEPh2c_5k z!nw1=p5d0wn;ktu6PG}(Fd?i*SvI)GlgI9?$hoViX;c$u#!vvw42a)V)_UZ}i!X@Q9OHHGH)UEi#O4GVmL)*pam6U_7 zM4BEGEsguL5%YcnJ601$!xXVCyShhp(5?^2Fo@a$M49XWWd$?smA)g<0_7up3VVu% zJuTBwXFc-`bKQ$lEYDA zf70&(4R95Ih3Dx{jSD{Y`(P z+eOM;|I3j5#qOp)D-pUjw(4n{9)>GK!OHt(??@fKjx0YF;Wa)*Jjxg9=^WVky@+G1vJl`ocs@k z+bBu3cjmy^E=G z%+^$D-`QrhzLo>H{S$-W`N$NfC;gswD6@Pd-mJhumY(}fxLYKvTx@x`c#|T+a)-@YfHY$O J00000002vYSEv90 delta 1247 zcmV<51R(psX~1cahy(2RMv;q60(q6O+9CuH8=tW%ue0exw2v`ohkbb}vkV1Y2^2{< zQulQUux@Ia7>@_}yfu_pp2@R)4#gmU%}-Bw*+h4Tuqj_?hNL5Xz1@<=FbxI?Duzgg z_YDC70R;dAf&u_B^3#>Nr>LV`t;z+phj8Sf^)t_6I3{>FrQCFm$OrJ2>WKiXkB2Cg zb$V$ihk^YyM>iMuhKmb)rD2BkP6}7DIwcxu-Q;a1Kq5rBRCzTb*egb|qbMAI@yDM! zQU>^Q5L{LJ!(@WV8X#j=;T`x`cI2T#Z=ptRdIfBvY>KUT=?>n(*J_eXvdUh~04a81 zf))~@^yG9)Kt5-P8#fE}P{pe$(0D6`_?F*q%vfzIwl-%FX>y9vXl|{f`ebNAO9b~{ zodaS*=>P&Aop0A0oPLtzs)(t7#%&`<(MogDO~<^);Q69@IR;VP!3**`^>V$vcpx*FbxI?Duzgg_YDC70R;dA zf&u^uF~hgBPX!bb8OwtuEzEe0u3)-)H8{lot8CXaf;J<6a%LzhqHw7nfeS92OyxYa zoAjLhsec8pcR^9N-v;K+di?2$eU^mXPbf7H8dC5d1&1T0D;HD-mp9L%ZOeZ4J7=25 zM7%-}`T^tFVeFjde@Oi8_$o>ehL=9hInm&iAoAy`50u5!Kt%pxAb0@-%{nch#198r z%f`fYcb0>H6K8&|x9wE-wv3-`KVwHgfH_PU$6JWn0AOk6JOJPSIP|TzC|7Pg;1ODD zu2YVwU(yQ_m@65#2sDmo$SW z>N=f!3IRRJ)OwDIY|<+)bU5;I;;?qrx8eWqA`Js)G(D13R;4;^?lv*|jB}gU6q9;| z@_6gV-T^lw8BcCfV4YCf&{$u_0{ J00000006wkOBnzF diff --git a/Shared/EFT/AnimationSystem.Types.dll b/Shared/EFT/AnimationSystem.Types.dll index 5dead39dda7e7dc9abe6e76658b93d9e6a4888de..646cbb273ede6fb97b01a6ad9f80fd0b3ab8f531 100644 GIT binary patch delta 1250 zcmV<81ReXpg#o~Y0g#9TGOz=Yi%kP#S^%-zi4YL6dG6(MBHBia7Y6;hs3Y04bP@Fm z6pd+oB!+u&zS5aYaAl@wOEc9g&9i+R#UOv%*TtL3{4K2}HiQ1GTWeN2YUEHb4F(A+ zhDe6@4FLfG1pows0su~~Xl=;>jdJw54^aPw9YO@S$wx$F5y zSnb24zQ|-t(8fv{#&$iGZ^cbW(On7DE>b&$93d z58ZmMHPUw|$l>T(E@Y5&sPi!K@rq<{*8>yLW;+5USh?$1(O&7xEAbferiUrl3ONhf z)~wAkuN9&jFtS@45~d9IVv?C<{OL9SD`L|1`2Ax?O7Qt zFig;`5w)AvAfxz6uzZR#`Z-p64AEWJo?jE8PU1Fo#R-2y>4j>%jkO~lU}pFG_PFFtYsto zYoC+L)YaO0L(Bk~Oh{Hdx~^pw7}j}KfCDqU-Y6E_l+1y#?Es0*GJ6UKL@WquYmj%a z7>RsU*u@&3_yQh#)5kjicX})NWTo;$Uq_jdnU8ts#<~!9M;H|$RVEW+Gwu*z%+FU6 zC1}|o+(tQih;x%^Kke|1_>&LNQU#G6XPP8Y1l9%(z^q zKGPsMFKItVBpD5{KsR~MhQB+fiq7Jh4bqh{^3xasmSOBL4F(A+hDe6@4FLfG z1pows0su7u>ikhJO|btQ5m4)IhIMw(6te#-Z@aFe7|$JO5YJ(Nfs>IIPjhV)=+-m}z8(pT{UxvKq2jOm){R3f6V zf(y}<4kTwvEN^cE)DlZwWZUlfLG-R>Hi%kQ{4gs;-i4YL@e-0CaSjk7YBsPGFH;y^8bP@Fm z6gMnF6HIWJ*FqbSPshSU!lvwTzq5TD#UOvR*yvvfOMmQ@t#EouvR?D6Y>A_+rYEZN@r~RXs0M?i@OR^MNceD8Q|7ON zEK08SBtfg~ZaR=BbOG`)=S)E|?OnVSU3Xn`j~RQR+q$fTlPAYEIr%~A<+vuob+hwZ z{Qu%W!@_IByTD32R05)1#Kjz1evm!a zC@e1sWdig42+j*Qz=me1O0*1?B1uH! zE!?!XBe}6}I3ts3Kk&LNQU#G6XOd{jjgCTADUW zKP$T)L7HQl!$7_@Pfk>7A##N0?6{1`Yv*_Tymv!@gZ_SAfPOwO4F(A+hDe6@4FLfG z1pows0sx2^!n3X9-f=u*<$&IXVWe ziE0&3|6)j-dsi# zN8BmbvNJhGvwDB&*3)_%?A?qA7m6eMiTCGc+rQIo0t3>M4PJ*mk`cId1}rRji5hbl zy>M^n*zevBW7O)kQ6I#jf%*VC5($kt-986-uHXht?=lw1e{>%0cQnZPT@*I`Qdqgc z73j%f#fzwsN)K`@9w)}?=rrx@Y_bPA#K8pqUG?!!5&(ah+~DBOK(+1~b95I3=_a^- zeC$8bLct#EK?i@kca`xLooaUhBk^ zkYd`zlRi`om_~(+NQ?yFS&R<%?wGlM0jsYs{luT4`vteujW;HU9NicwfMRc1RA>Ek z(7h)>l22;4v@9#hW3xgim6?J%r|iFqce^ii#<04AHk1%KM#HnV7^Gl(Vcdj=5{7mL zjxWB?AIWqv`fUH1&dn=G)A@E(%`c|fw^8& MYP0|V0000008<7^@Bjb+ diff --git a/Shared/EFT/Assembly-CSharp-firstpass.dll b/Shared/EFT/Assembly-CSharp-firstpass.dll index 35ba5a71725082b4498f364d8f88a39e19d4db0c..c456d57c3d75680bf7812b53e1a0640b41b31d0e 100644 GIT binary patch delta 1264 zcmVcTTP@ zWtS}VB6+u%*aXpu6kZGg*vyc!eKfZ?`*EF2n=N#0cDH?E1;rqLRyl9V0BzBv(M!I% zFe!J8Woa=fFbxI?Duzgg_YDC70R;dAf&u`6x?JW&s5{#Kd{YTxlRDsBtY9GZwBn0{ zz&J;W(Qz!UI?aM(W`@#g>8E0s^uhT$QZPNz9oPQ-iagIt;fMyYx>$O(>ImR@?-T-Z zLBH-78)csOCzF_eO8dcxoFKY3sCkyV##w_ZghEItN{f>3*Q_cMa$70u=*d}S?>dx)Z`UAB;eFar9}t4sAe=s{_IsR;!j1@**8_`gSncQMp-AR zd4UJ%1k)&g6wK4rAj6eAjU6UtJ6SL;Z3Bt7fR@^&G#`&Bj*M7T14Z<-rFL3olLcx>J50JeRs$p!WaSZ!g}5o_6c^BKL0?xw;$HEk==@Ely-lb+JU)5SOHb6% z zbwzPzKJ{WQi_2^PJly+#HHR2jz+#i*bQLh*rcMVz#pr z5vnoPUt*h@)Iw2%$xoz=f9Q~>uDDr9nhn`D?^u@o+x)~DTHKG-Hv>g+0f4xb(bmg0vloTJpP7tDc^ a(1s(x;7Pf36Im2)%aO=;000000002$hF1On delta 1264 zcmVCh9Hp3BSMey~SS&$oSI1;rqLZ)5mOJdnbPL#nY6S1V)vN zga7x1QpWT73ZS`lM^^xFlf~LE6T@vy8^|R*fkXCxOno z-%Ij9a?&196-3K>uycOr77kT}OMtl>th51F_v~(lCr0N4WW2$8GBFqbC==!kZ$|9B zj9^Efa{wZL!EoZt8ss6$nzXS@2;i}ExCkR$ADUXJ!L;3g_5&IqfbbV~wc4D+fajDV z{02GpOsd4`-?+tZ6HEMb-wteHnV1aK7gp|JI_F$}U_7Fq_uAIiCr_^lCAi$JN?IpcqmYpp z6OTFz%3I78Jse#N|{BQ6SY4KG#rj zclC>wlfs#nMFQH5X%5eSDH-~i(>=qM5}fCT7tvc+w4-WYFruUu`)t|-a39PT#@ys! zKxO}Np0h^1>g3 zYoUPEIPW0oGGiNrSB8+JF!Epg!hTzrnHI`?FEgkpDwUeST=$iGwx1GjsUp&{JlaGd zH%*{Y7WrBGNw1104Jn&p?Uy>P$c-f5eBOl9RC|$^`%I$fYzI``orA-h@Dk`5f00RE zlS1JbCPUL@j3>V$lnkv8O)8J2F2Dh;3Vvli0SyLh8f=u-j*RvK&*AjxpsVS-=XHh<%w;=A9|Dp&?Ve8 zATiY;(B2x%kOR0QLzWb1&+jBu7O)C&ZkAhpN-T<1N|RsVkdY(_YZ)8>{JwJwR!!A8 a!fl;)vc0lz+5$z&-}JmD000000001&vtNS% diff --git a/Shared/EFT/Assembly-CSharp.dll b/Shared/EFT/Assembly-CSharp.dll index 909ee759eff3aa1d4ef5bb7aee0e3f1f5f7d6db7..52df8ce6868bc72f4d87dead3826586c1a30e111 100644 GIT binary patch literal 9743872 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%0ALpbkOTm`8h|7KSY!Z_0AR5JNCJS}3_ub9 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 z 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 $a-6^7yG)09pW^`6t))b2Lot~ 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

!0j{y@OYxhCBwMPHPP@K{K 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 Wqy$W` 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

%lY5K$~GF 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