From f648f42721778321eab4af1aec2cfacc29fece8e Mon Sep 17 00:00:00 2001 From: CWX Date: Wed, 5 Feb 2025 06:56:51 +0000 Subject: [PATCH] This is just Jetbrains formatting and code syntax styling --- ExampleMods/Mods/EditConfigs.cs | 109 ++- ExampleMods/Mods/EditDatabaseValues.cs | 359 ++++----- ExampleMods/Mods/Logging.cs | 51 +- .../Mods/Override/WatermarkOverride.cs | 7 +- .../Core/Callbacks/AchievementCallbacks.cs | 3 +- .../Core/Callbacks/ClientLogCallbacks.cs | 11 +- Libraries/Core/Callbacks/DataCallbacks.cs | 11 +- Libraries/Core/Callbacks/DialogueCallbacks.cs | 26 +- Libraries/Core/Callbacks/HealthCallbacks.cs | 3 +- Libraries/Core/Callbacks/HideoutCallbacks.cs | 290 +++---- Libraries/Core/Callbacks/HttpCallbacks.cs | 4 +- Libraries/Core/Callbacks/InraidCallbacks.cs | 2 +- .../Core/Callbacks/InsuranceCallbacks.cs | 36 +- .../Core/Callbacks/ItemEventCallbacks.cs | 30 +- .../Core/Callbacks/LauncherV2Callbacks.cs | 36 +- Libraries/Core/Callbacks/MatchCallbacks.cs | 2 +- Libraries/Core/Callbacks/NoteCallbacks.cs | 1 - Libraries/Core/Callbacks/ProfileCallbacks.cs | 5 +- Libraries/Core/Callbacks/RagfairCallbacks.cs | 26 +- Libraries/Core/Callbacks/SaveCallbacks.cs | 12 +- Libraries/Core/Callbacks/TraderCallbacks.cs | 12 +- Libraries/Core/Context/ApplicationContext.cs | 5 +- Libraries/Core/Context/ContextVariable.cs | 3 +- .../Core/Controllers/AchievementController.cs | 7 +- Libraries/Core/Controllers/BotController.cs | 94 +-- Libraries/Core/Controllers/BuildController.cs | 19 +- .../Core/Controllers/ClientLogController.cs | 3 +- .../Controllers/CustomizationController.cs | 38 +- .../Core/Controllers/DialogueController.cs | 108 +-- Libraries/Core/Controllers/GameController.cs | 137 +--- .../Core/Controllers/HealthController.cs | 51 +- .../Core/Controllers/HideoutController.cs | 180 +---- .../Core/Controllers/InRaidController.cs | 4 +- .../Core/Controllers/InsuranceController.cs | 139 +--- .../Core/Controllers/InventoryController.cs | 80 +- .../Core/Controllers/LauncherController.cs | 28 +- .../Core/Controllers/LauncherV2Controller.cs | 27 +- .../Core/Controllers/LocationController.cs | 11 +- Libraries/Core/Controllers/MatchController.cs | 9 +- Libraries/Core/Controllers/NoteController.cs | 8 +- .../Core/Controllers/NotifierController.cs | 6 +- .../Core/Controllers/PrestigeController.cs | 57 +- .../Core/Controllers/ProfileController.cs | 63 +- Libraries/Core/Controllers/QuestController.cs | 43 +- .../Core/Controllers/RagfairController.cs | 243 ++---- .../Core/Controllers/RepairController.cs | 13 +- .../Controllers/RepeatableQuestController.cs | 87 +- Libraries/Core/Controllers/TradeController.cs | 53 +- .../Core/Controllers/TraderController.cs | 21 +- .../Core/Controllers/WishlistController.cs | 10 +- Libraries/Core/DI/OnLoad.cs | 2 +- Libraries/Core/DI/Router.cs | 19 +- .../Generators/BotEquipmentModGenerator.cs | 308 ++------ Libraries/Core/Generators/BotGenerator.cs | 105 +-- .../Core/Generators/BotInventoryGenerator.cs | 96 +-- .../Core/Generators/BotLevelGenerator.cs | 17 +- Libraries/Core/Generators/BotLootGenerator.cs | 118 +-- .../Core/Generators/BotWeaponGenerator.cs | 122 +-- .../Generators/FenceBaseAssortGenerator.cs | 85 +- .../Core/Generators/LocationLootGenerator.cs | 217 ++--- Libraries/Core/Generators/LootGenerator.cs | 359 ++++----- Libraries/Core/Generators/PMCLootGenerator.cs | 58 +- .../Core/Generators/PlayerScavGenerator.cs | 50 +- .../Core/Generators/RagfairAssortGenerator.cs | 16 +- .../Core/Generators/RagfairOfferGenerator.cs | 359 +++++---- .../Generators/RepeatableQuestGenerator.cs | 53 +- .../RepeatableQuestRewardGenerator.cs | 100 +-- .../Generators/ScavCaseRewardGenerator.cs | 114 +-- .../Implementations/BarrelInvetoryMagGen.cs | 4 - .../ExternalInventoryMagGen.cs | 39 +- .../Implementations/UbglExternalMagGen.cs | 1 - .../Generators/WeaponGen/InventoryMagGen.cs | 6 +- Libraries/Core/Generators/WeatherGenerator.cs | 5 +- Libraries/Core/Helpers/AssortHelper.cs | 40 +- Libraries/Core/Helpers/BotDifficultyHelper.cs | 24 +- Libraries/Core/Helpers/BotGeneratorHelper.cs | 104 +-- Libraries/Core/Helpers/BotHelper.cs | 31 +- .../Core/Helpers/BotWeaponGeneratorHelper.cs | 6 +- Libraries/Core/Helpers/ContainerHelper.cs | 44 +- .../Helpers/Dialogue/AbstractDialogChatBot.cs | 11 +- .../Dialogue/Commando/SptCommandoCommands.cs | 28 +- .../SptCommands/GiveCommand/GiveSptCommand.cs | 10 +- .../SptCommands/GiveCommand/SavedCommand.cs | 1 - .../GiveCommand/StringSimilarity.cs | 14 +- .../Commands/AreYouABotMessageHandler.cs | 44 +- .../Commands/ForceChristmasMessageHandler.cs | 55 +- .../Commands/ForceHalloweenMessageHandler.cs | 59 +- .../Commands/ForceSnowMessageHandler.cs | 47 +- .../Commands/ForceSummerMessageHandler.cs | 55 +- .../Commands/GiveMeSpaceMessageHandler.cs | 14 +- .../SPTFriend/Commands/HelloMessageHandler.cs | 140 ++-- .../Commands/LoveYouChatMessageHandler.cs | 14 +- .../Commands/NikitaMessageHandler.cs | 49 +- .../Commands/SendGiftMessageHandler.cs | 97 ++- .../Helpers/Dialogue/SptDialogueChatBot.cs | 29 +- Libraries/Core/Helpers/DialogueHelper.cs | 2 +- .../Core/Helpers/DurabilityLimitsHelper.cs | 132 +--- Libraries/Core/Helpers/GameEventHelper.cs | 1 - Libraries/Core/Helpers/HandbookHelper.cs | 87 +- Libraries/Core/Helpers/HealthHelper.cs | 90 +-- Libraries/Core/Helpers/HideoutHelper.cs | 340 +++----- Libraries/Core/Helpers/HttpServerHelper.cs | 2 +- Libraries/Core/Helpers/InRaidHelper.cs | 106 +-- Libraries/Core/Helpers/InventoryHelper.cs | 21 +- Libraries/Core/Helpers/ItemHelper.cs | 459 +++-------- .../Core/Helpers/NotificationSendHelper.cs | 14 +- Libraries/Core/Helpers/NotifierHelper.cs | 16 +- Libraries/Core/Helpers/PaymentHelper.cs | 2 +- Libraries/Core/Helpers/PresetHelper.cs | 28 +- Libraries/Core/Helpers/ProfileHelper.cs | 73 +- .../Core/Helpers/QuestConditionHelper.cs | 18 +- Libraries/Core/Helpers/QuestHelper.cs | 290 ++----- Libraries/Core/Helpers/QuestRewardHelper.cs | 11 +- Libraries/Core/Helpers/RagfairHelper.cs | 61 +- Libraries/Core/Helpers/RagfairOfferHelper.cs | 209 +---- Libraries/Core/Helpers/RagfairSellHelper.cs | 44 +- Libraries/Core/Helpers/RagfairServerHelper.cs | 68 +- Libraries/Core/Helpers/RagfairSortHelper.cs | 5 +- Libraries/Core/Helpers/RepairHelper.cs | 49 +- Libraries/Core/Helpers/RewardHelper.cs | 743 +++++++++--------- .../Core/Helpers/SecureContainerHelper.cs | 4 +- Libraries/Core/Helpers/TradeHelper.cs | 73 +- Libraries/Core/Helpers/TraderAssortHelper.cs | 47 +- Libraries/Core/Helpers/TraderHelper.cs | 151 +--- Libraries/Core/Helpers/UtilityHelper.cs | 2 +- .../Core/Helpers/WeightedRandomHelper.cs | 52 +- Libraries/Core/Loaders/PostDBModLoader.cs | 5 +- Libraries/Core/Loaders/PostSptModLoader.cs | 9 +- Libraries/Core/Models/Common/MinMax.cs | 3 +- Libraries/Core/Models/Eft/Common/Globals.cs | 6 +- .../Core/Models/Eft/Common/LocationBase.cs | 18 +- Libraries/Core/Models/Eft/Common/PmcData.cs | 4 +- .../Core/Models/Eft/Common/Tables/BotBase.cs | 32 +- .../Core/Models/Eft/Common/Tables/BotType.cs | 24 +- .../Eft/Common/Tables/CustomizationItem.cs | 1 - .../Eft/Common/Tables/GlobalTablesUsings.cs | 3 +- .../Core/Models/Eft/Common/Tables/Item.cs | 12 +- .../Eft/Common/Tables/ProfileTemplate.cs | 4 +- .../Core/Models/Eft/Common/Tables/Quest.cs | 56 +- .../Eft/Common/Tables/RepeatableQuests.cs | 2 +- .../Core/Models/Eft/Common/Tables/Reward.cs | 6 +- .../Models/Eft/Common/Tables/TemplateItem.cs | 26 +- .../Core/Models/Eft/Common/Tables/Trader.cs | 3 +- .../Models/Eft/Dialog/FriendRequestData.cs | 2 +- .../Eft/Game/SendSurveyOpinionRequest.cs | 2 +- Libraries/Core/Models/Eft/Health/Effect.cs | 2 +- .../Eft/Health/HealthTreatmentRequestData.cs | 2 +- .../Eft/Health/OffraidHealRequestData.cs | 6 +- .../Core/Models/Eft/Hideout/HideoutArea.cs | 2 +- .../HideoutCancelProductionRequestData.cs | 2 +- ...outContinuousProductionStartRequestData.cs | 2 +- .../HideoutCustomizationApplyRequestData.cs | 1 - .../Models/Eft/Hideout/HideoutProduction.cs | 2 +- .../Hideout/HideoutPutItemInRequestData.cs | 1 - .../HideoutUpgradeCompleteRequestData.cs | 1 - .../Eft/Hideout/HideoutUpgradeRequestData.cs | 1 - .../Eft/ItemEvent/ItemEventRouterRequest.cs | 12 +- .../Core/Models/Eft/Launcher/MiniProfile.cs | 2 +- .../Match/GetRaidConfigurationRequestData.cs | 2 +- .../PresetBuildActionRequestData.cs | 2 +- .../Eft/Prestige/ObtainPrestigeRequest.cs | 56 +- .../Core/Models/Eft/Profile/SptProfile.cs | 6 +- .../Models/Eft/Ws/NotificationEventType.cs | 2 +- Libraries/Core/Models/Enums/AirdropType.cs | 2 +- Libraries/Core/Models/Enums/ArmorMaterial.cs | 23 +- Libraries/Core/Models/Enums/BaseClasses.cs | 1 - Libraries/Core/Models/Enums/BonusSkillType.cs | 2 +- Libraries/Core/Models/Enums/BonusType.cs | 2 +- Libraries/Core/Models/Enums/CurrencyType.cs | 15 +- .../Core/Models/Enums/DamageEffectType.cs | 25 +- .../Core/Models/Enums/DogtagExchangeSide.cs | 2 +- Libraries/Core/Models/Enums/ELocationName.cs | 2 +- Libraries/Core/Models/Enums/EventType.cs | 15 +- .../Core/Models/Enums/ExfiltrationType.cs | 13 +- Libraries/Core/Models/Enums/ExitStatus.cs | 2 +- Libraries/Core/Models/Enums/FleaOfferType.cs | 15 +- Libraries/Core/Models/Enums/GiftSenderType.cs | 2 +- Libraries/Core/Models/Enums/GiftSentResult.cs | 2 +- Libraries/Core/Models/Enums/HealthFactor.cs | 23 +- .../Models/Enums/Hideout/CircleRewardType.cs | 2 +- .../Models/Enums/Hideout/QteActivityType.cs | 2 +- .../Models/Enums/Hideout/QteEffectType.cs | 2 +- .../Models/Enums/Hideout/QteResultType.cs | 2 +- .../Models/Enums/Hideout/QteRewardType.cs | 2 +- .../Core/Models/Enums/Hideout/QteType.cs | 2 +- .../Models/Enums/Hideout/RequirementType.cs | 2 +- Libraries/Core/Models/Enums/HideoutAreas.cs | 2 +- .../Core/Models/Enums/ItemAddedResult.cs | 2 +- .../Core/Models/Enums/ItemDropSoundType.cs | 15 +- .../Core/Models/Enums/ItemEventActions.cs | 4 +- Libraries/Core/Models/Enums/LootRarity.cs | 15 +- Libraries/Core/Models/Enums/MessageType.cs | 2 +- Libraries/Core/Models/Enums/ModSpawn.cs | 2 +- Libraries/Core/Models/Enums/PlayerSideMask.cs | 19 +- Libraries/Core/Models/Enums/ProfileStatus.cs | 2 +- Libraries/Core/Models/Enums/QuestTypeEnum.cs | 2 +- Libraries/Core/Models/Enums/RagfairSort.cs | 2 +- Libraries/Core/Models/Enums/RaidMode.cs | 2 +- .../TimeAndWeather/CloudinessType.cs | 2 +- Libraries/Core/Models/Enums/ReloadMode.cs | 15 +- .../Core/Models/Enums/RepairStrategyType.cs | 13 +- .../Core/Models/Enums/RequirementState.cs | 35 +- Libraries/Core/Models/Enums/Season.cs | 2 +- .../Core/Models/Enums/SeasonalEventType.cs | 2 +- Libraries/Core/Models/Enums/SkillTypes.cs | 2 +- Libraries/Core/Models/Enums/ThrowWeapType.cs | 21 +- .../Core/Models/Enums/TraderServiceType.cs | 2 +- Libraries/Core/Models/Enums/Traders.cs | 22 +- Libraries/Core/Models/Enums/TransitionType.cs | 2 +- Libraries/Core/Models/Enums/WindDirection.cs | 2 +- Libraries/Core/Models/RadioStationType.cs | 29 +- Libraries/Core/Models/Spt/Config/BotConfig.cs | 4 +- .../Core/Models/Spt/Config/GiftsConfig.cs | 4 +- .../Core/Models/Spt/Config/HideoutConfig.cs | 1 - .../Core/Models/Spt/Config/InventoryConfig.cs | 2 +- .../Core/Models/Spt/Config/MatchConfig.cs | 2 +- Libraries/Core/Models/Spt/Config/PmcConfig.cs | 6 +- .../Core/Models/Spt/Config/RagfairConfig.cs | 6 +- .../Core/Models/Spt/Config/RepairConfig.cs | 4 +- .../Models/Spt/Config/SeasonalEventConfig.cs | 34 +- .../Core/Models/Spt/Config/TraderConfig.cs | 2 +- .../Models/Spt/Dialog/SendMessageDetails.cs | 2 +- .../Models/Spt/Logging/LogBackgroundColor.cs | 2 + .../Core/Models/Spt/Logging/LogTextColor.cs | 2 + .../Core/Models/Spt/Mod/NewItemDetails.cs | 12 +- .../Core/Models/Spt/Server/DatabaseTables.cs | 18 +- Libraries/Core/Models/Spt/Server/Locations.cs | 96 +-- .../Core/Routers/Dynamic/BotDynamicRouter.cs | 87 +- .../Routers/Dynamic/BundleDynamicRouter.cs | 3 +- .../Dynamic/CustomizationDynamicRouter.cs | 3 +- .../Core/Routers/Dynamic/DataDynamicRouter.cs | 53 +- .../Core/Routers/Dynamic/HttpDynamicRouter.cs | 6 +- .../Routers/Dynamic/InraidDynamicRouter.cs | 5 +- .../Routers/Dynamic/LocationDynamicRouter.cs | 1 - .../Routers/Dynamic/TraderDynamicRouter.cs | 6 +- Libraries/Core/Routers/EventOutputHolder.cs | 59 +- Libraries/Core/Routers/HttpRouter.cs | 29 +- Libraries/Core/Routers/ImageRouter.cs | 7 +- Libraries/Core/Routers/ItemEventRouter.cs | 115 ++- .../CustomizationItemEventRouter.cs | 11 +- .../ItemEvents/HealthItemEventRouter.cs | 3 +- .../ItemEvents/HideoutItemEventRouter.cs | 6 +- .../ItemEvents/InsuranceItemEventRouter.cs | 7 +- .../ItemEvents/InventoryItemEventRouter.cs | 58 +- .../Routers/ItemEvents/NoteItemEventRouter.cs | 11 +- .../ItemEvents/QuestItemEventRouter.cs | 16 +- .../ItemEvents/RagfairItemEventRouter.cs | 14 +- .../ItemEvents/RepairItemEventRouter.cs | 12 +- .../ItemEvents/TradeItemEventRouter.cs | 14 +- .../ItemEvents/WishlistItemEventRouter.cs | 11 +- .../Routers/SaveLoad/HealthSaveLoadRouter.cs | 20 +- .../Routers/SaveLoad/InraidSaveLoadRouter.cs | 2 +- .../SaveLoad/InsuranceSaveLoadRouter.cs | 2 +- .../Routers/SaveLoad/ProfileSaveLoadRouter.cs | 5 +- .../Routers/Serializers/BundleSerializer.cs | 1 - .../Routers/Serializers/NotifySerializer.cs | 1 - .../Routers/Static/AchievementStaticRouter.cs | 6 +- .../Core/Routers/Static/BotStaticRouter.cs | 13 +- .../Core/Routers/Static/BuildStaticRouter.cs | 94 +-- .../Core/Routers/Static/BundleStaticRouter.cs | 3 +- .../Routers/Static/ClientLogStaticRouter.cs | 9 +- .../Static/CustomizationStaticRouter.cs | 9 +- .../Core/Routers/Static/DataStaticRouter.cs | 102 +-- .../Core/Routers/Static/DialogStaticRouter.cs | 238 +++--- .../Core/Routers/Static/GameStaticRouter.cs | 51 +- .../Core/Routers/Static/HealthStaticRouter.cs | 3 +- .../Core/Routers/Static/InraidStaticRouter.cs | 15 +- .../Routers/Static/InsuranceStaticRouter.cs | 3 +- .../Routers/Static/ItemEventStaticRouter.cs | 3 +- .../Routers/Static/LauncherStaticRouter.cs | 42 +- .../Routers/Static/LocationStaticRouter.cs | 20 +- .../Core/Routers/Static/MatchStaticRouter.cs | 254 +++--- .../Routers/Static/NotifierStaticRouter.cs | 20 +- .../Routers/Static/PrestigeStaticRouter.cs | 8 +- .../Routers/Static/ProfileStaticRouter.cs | 42 +- .../Core/Routers/Static/QuestStaticRouter.cs | 21 +- .../Routers/Static/RagfairStaticRouter.cs | 21 +- .../Core/Routers/Static/TraderStaticRouter.cs | 9 +- .../Routers/Static/WeatherStaticRouter.cs | 6 +- Libraries/Core/Servers/ConfigServer.cs | 13 +- Libraries/Core/Servers/Http/RequestLogger.cs | 1 - .../Core/Servers/Http/SptHttpListener.cs | 43 +- Libraries/Core/Servers/HttpServer.cs | 5 +- Libraries/Core/Servers/RagfairServer.cs | 10 +- Libraries/Core/Servers/SaveServer.cs | 59 +- Libraries/Core/Servers/WebSocketServer.cs | 5 +- .../Ws/SptWebSocketConnectionHandler.cs | 92 +-- Libraries/Core/Services/AirdropService.cs | 41 +- Libraries/Core/Services/BackupService.cs | 76 +- .../Services/BotEquipmentFilterService.cs | 135 +--- .../Services/BotEquipmentModPoolService.cs | 98 ++- .../Services/BotGenerationCacheService.cs | 16 +- .../Core/Services/BotLootCacheService.cs | 181 ++--- Libraries/Core/Services/BotNameService.cs | 13 +- .../Core/Services/BotWeaponModLimitService.cs | 35 +- .../Services/Cache/BundleHashCacheService.cs | 9 +- .../Services/Cache/ModHashCacheService.cs | 10 +- .../Core/Services/CircleOfCultistService.cs | 108 +-- .../Core/Services/CreateProfileService.cs | 110 +-- .../Services/CustomLocationWaveService.cs | 6 - Libraries/Core/Services/DatabaseService.cs | 7 +- Libraries/Core/Services/FenceService.cs | 288 ++----- Libraries/Core/Services/GiftService.cs | 51 +- Libraries/Core/Services/I18nService.cs | 28 +- .../Core/Services/InMemoryCacheService.cs | 5 +- Libraries/Core/Services/InsuranceService.cs | 60 +- .../Core/Services/ItemBaseClassService.cs | 47 +- Libraries/Core/Services/ItemFilterService.cs | 27 +- .../Core/Services/LocalisationService.cs | 10 +- .../Core/Services/LocationLifecycleService.cs | 418 +++++----- Libraries/Core/Services/MailSendService.cs | 58 +- Libraries/Core/Services/MapMarkerService.cs | 4 +- .../Core/Services/Mod/CustomItemService.cs | 33 +- .../Core/Services/NotificationService.cs | 15 +- Libraries/Core/Services/OpenZoneService.cs | 5 +- Libraries/Core/Services/PaymentService.cs | 107 +-- Libraries/Core/Services/PlayerService.cs | 5 +- .../Core/Services/PmcChatResponseService.cs | 88 +-- Libraries/Core/Services/PostDbLoadService.cs | 236 +++--- .../Core/Services/ProfileActivityService.cs | 2 +- .../Core/Services/ProfileFixerService.cs | 195 +---- .../Core/Services/RagfairCategoriesService.cs | 17 +- .../Core/Services/RagfairLinkedItemService.cs | 65 +- .../Core/Services/RagfairOfferService.cs | 41 +- .../Core/Services/RagfairPriceService.cs | 147 ++-- .../Services/RagfairRequiredItemsService.cs | 23 +- Libraries/Core/Services/RagfairTaxService.cs | 38 +- .../Services/RaidTimeAdjustmentService.cs | 51 +- Libraries/Core/Services/RaidWeatherService.cs | 5 +- Libraries/Core/Services/RepairService.cs | 85 +- .../Core/Services/SeasonalEventService.cs | 292 +++---- .../Core/Services/TraderAssortService.cs | 4 +- .../TraderPurchasePersisterService.cs | 43 +- Libraries/Core/Utils/App.cs | 37 +- .../Core/Utils/Callbacks/TimeoutCallback.cs | 1 - Libraries/Core/Utils/Cloners/JsonCloner.cs | 2 + .../Utils/Collections/ExhaustableArray.cs | 25 +- .../Collections/ProbabilityObjectArray.cs | 14 +- Libraries/Core/Utils/CompareUtil.cs | 21 +- Libraries/Core/Utils/DatabaseImporter.cs | 73 +- Libraries/Core/Utils/FileUtil.cs | 12 +- Libraries/Core/Utils/HashUtil.cs | 3 +- Libraries/Core/Utils/HttpFileUtil.cs | 3 +- Libraries/Core/Utils/HttpResponseUtil.cs | 43 +- Libraries/Core/Utils/ImporterUtil.cs | 2 +- .../ArrayToObjectFactoryConverter.cs | 1 + .../BaseInteractionRequestDataConverter.cs | 8 +- .../DictionaryOfListOrTConverter.cs | 15 +- .../Converters/DictionaryOrListConverter.cs | 22 +- .../Utils/Json/Converters/EftEnumConverter.cs | 5 +- .../Utils/Json/Converters/ListOrTConverter.cs | 4 - .../StringToNumberFactoryConverter.cs | 13 +- Libraries/Core/Utils/Json/LazyLoad.cs | 18 +- Libraries/Core/Utils/JsonUtil.cs | 3 +- Libraries/Core/Utils/ProgramStatics.cs | 183 ++--- Libraries/Core/Utils/ProgressWriter.cs | 51 +- Libraries/Core/Utils/RagfairOfferHolder.cs | 41 +- Libraries/Core/Utils/RandomUtil.cs | 53 +- Libraries/Core/Utils/TimeUtil.cs | 33 +- Libraries/Core/Utils/TimerUtil.cs | 41 +- Libraries/Core/Utils/Watermark.cs | 96 ++- Libraries/SptAssets/SptAssets.csproj | 2 +- .../DependencyInjectionRegistrator.cs | 67 +- Server/Logger/AbstractFormatter.cs | 14 +- Server/Logger/ConsoleFormatter.cs | 4 +- Server/Logger/FileFormatter.cs | 9 +- Server/Logger/WebApplicationLogger.cs | 38 +- Server/ModDllLoader.cs | 4 +- Server/Program.cs | 17 +- SptCommon/Extensions/ListExtensions.cs | 6 +- SptCommon/Extensions/MemberInfoExtensions.cs | 1 - SptCommon/Extensions/ObjectExtensions.cs | 131 ++- SptCommon/Extensions/StringExtensions.cs | 3 +- Tools/ItemTplGenerator/ItemOverrides.cs | 2 +- Tools/ItemTplGenerator/ItemTplGenerator.cs | 175 +---- Tools/ItemTplGenerator/SptBasicLogger.cs | 3 +- UnitTests/MSTestSettings.cs | 2 +- UnitTests/Mock/MockLogger.cs | 20 +- UnitTests/Tests/Test.cs | 5 +- UnitTests/Tests/Utils/JsonUtilTests.cs | 1 + UnitTests/Tests/Utils/MathUtilTests.cs | 138 ++-- UnitTests/Tests/Utils/RandomUtilTests.cs | 330 ++++---- 382 files changed, 6348 insertions(+), 10422 deletions(-) diff --git a/ExampleMods/Mods/EditConfigs.cs b/ExampleMods/Mods/EditConfigs.cs index 3900334e..ab19297e 100644 --- a/ExampleMods/Mods/EditConfigs.cs +++ b/ExampleMods/Mods/EditConfigs.cs @@ -3,74 +3,73 @@ using Core.Models.Enums; using Core.Models.Spt.Config; using Core.Servers; -namespace ExampleMods.Mods +namespace ExampleMods.Mods; + +[Injectable] +public class EditConfigs { - [Injectable] - public class EditConfigs + private readonly AirdropConfig _airdropConfig; + private readonly BotConfig _botConfig; + private readonly ConfigServer _configServer; + private readonly HideoutConfig _hideoutConfig; + private readonly PmcChatResponse _pmcChatResponseConfig; + private readonly PmcConfig _pmcConfig; + private readonly QuestConfig _questConfig; + private readonly WeatherConfig _weatherConfig; + + // We access configs via ConfigServer + public EditConfigs( + ConfigServer configServer) { - private readonly ConfigServer _configServer; - private readonly BotConfig _botConfig; - private readonly HideoutConfig _hideoutConfig; - private readonly WeatherConfig _weatherConfig; - private readonly AirdropConfig _airdropConfig; - private readonly PmcChatResponse _pmcChatResponseConfig; - private readonly QuestConfig _questConfig; - private readonly PmcConfig _pmcConfig; + _configServer = configServer; - // We access configs via ConfigServer - public EditConfigs( - ConfigServer configServer) - { - _configServer = configServer; + // We get the bot config by calling GetConfig and passing the configs 'type' within the diamond brackets + _botConfig = _configServer.GetConfig(); + _hideoutConfig = _configServer.GetConfig(); + _weatherConfig = _configServer.GetConfig(); + _airdropConfig = _configServer.GetConfig(); + _pmcChatResponseConfig = _configServer.GetConfig(); + _questConfig = _configServer.GetConfig(); + _pmcConfig = _configServer.GetConfig(); - // We get the bot config by calling GetConfig and passing the configs 'type' within the diamond brackets - _botConfig = _configServer.GetConfig(); - _hideoutConfig = _configServer.GetConfig(); - _weatherConfig = _configServer.GetConfig(); - _airdropConfig = _configServer.GetConfig(); - _pmcChatResponseConfig = _configServer.GetConfig(); - _questConfig = _configServer.GetConfig(); - _pmcConfig = _configServer.GetConfig(); + Run(); + } - Run(); - } + public void Run() + { + // Let's edit the weather config to make the season winter + _weatherConfig.OverrideSeason = Season.WINTER; - public void Run() - { - // Let's edit the weather config to make the season winter - _weatherConfig.OverrideSeason = Season.WINTER; + // Let's edit the hideout config to Make all crafts take 60 seconds + _hideoutConfig.OverrideCraftTimeSeconds = 60; - // Let's edit the hideout config to Make all crafts take 60 seconds - _hideoutConfig.OverrideCraftTimeSeconds = 60; + // Let's edit the hideout config to Make all upgrades take 60 seconds + _hideoutConfig.OverrideBuildTimeSeconds = 60; - // Let's edit the hideout config to Make all upgrades take 60 seconds - _hideoutConfig.OverrideBuildTimeSeconds = 60; + // Let's edit the airdrop config to Make weapon/armor drops really common + _airdropConfig.AirdropTypeWeightings[SptAirdropTypeEnum.weaponArmor] = 999; - // Let's edit the airdrop config to Make weapon/armor drops really common - _airdropConfig.AirdropTypeWeightings[SptAirdropTypeEnum.weaponArmor] = 999; + // Let's edit the airdrop config to Make weapon/armor drops always have 3 sealed weapon crates + var weaponCrateMinMax = _airdropConfig.Loot["weaponArmor"].WeaponCrateCount; + weaponCrateMinMax.Min = 3; + weaponCrateMinMax.Max = 3; - // Let's edit the airdrop config to Make weapon/armor drops always have 3 sealed weapon crates - var weaponCrateMinMax = _airdropConfig.Loot["weaponArmor"].WeaponCrateCount; - weaponCrateMinMax.Min = 3; - weaponCrateMinMax.Max = 3; + // Let's make PMCs always mail you when they kill you + _pmcChatResponseConfig.Killer.ResponseChancePercent = 100; - // Let's make PMCs always mail you when they kill you - _pmcChatResponseConfig.Killer.ResponseChancePercent = 100; + // Let's make quest rewards sent to you via mail last for over a week if you have an unheard profile + _questConfig.MailRedeemTimeHours["unheard_edition"] = 168; - // Let's make quest rewards sent to you via mail last for over a week if you have an unheard profile - _questConfig.MailRedeemTimeHours["unheard_edition"] = 168; + // Let's make the interchange bot cap huge + _botConfig.MaxBotCap["interchange"] = 50; - // Let's make the interchange bot cap huge - _botConfig.MaxBotCap["interchange"] = 50; + // Let's disable loot on scavs + _botConfig.DisableLootOnBotTypes.Add("assault"); - // Let's disable loot on scavs - _botConfig.DisableLootOnBotTypes.Add("assault"); - - // Let's make the conversion rate of scavs to pmcs 100% on factory day - var factory4DayConversionSettings = _pmcConfig.ConvertIntoPmcChance["factory4_day"]; - var assaultConversionSettings = factory4DayConversionSettings["assault"]; - assaultConversionSettings.Min = 100; - assaultConversionSettings.Max = 100; - } + // Let's make the conversion rate of scavs to pmcs 100% on factory day + var factory4DayConversionSettings = _pmcConfig.ConvertIntoPmcChance["factory4_day"]; + var assaultConversionSettings = factory4DayConversionSettings["assault"]; + assaultConversionSettings.Min = 100; + assaultConversionSettings.Max = 100; } } diff --git a/ExampleMods/Mods/EditDatabaseValues.cs b/ExampleMods/Mods/EditDatabaseValues.cs index 0eec9848..7acc8c12 100644 --- a/ExampleMods/Mods/EditDatabaseValues.cs +++ b/ExampleMods/Mods/EditDatabaseValues.cs @@ -4,197 +4,186 @@ using Core.Models.Enums; using Core.Models.Utils; using Core.Services; -namespace ExampleMods.Mods +namespace ExampleMods.Mods; + +[Injectable] +public class EditDatabaseValues { - [Injectable] - public class EditDatabaseValues + private readonly DatabaseService _databaseService; + + public EditDatabaseValues( + DatabaseService databaseService) { - private readonly DatabaseService _databaseService; + _databaseService = databaseService; - public EditDatabaseValues( - DatabaseService databaseService) + Run(); + } + + public void Run() + { + // When SPT starts, it stores all the data found in (SPT_Data\Server\database) in memory + // We can use the '_databaseService' we injected to access this data, this includes files from EFT and SPT + + // Lets edit some globals settings to make the game easier + EditGlobals(); + + // Lets edit the BTR to have the christmas tarcola skin + EditBtr(); + + // Let's edit the hideout so it's easier to upgrade the lavatory + EditHideout(); + + // Lets edit the default scav to + EditScavSettings(); + + // Lets edit Customs + EditCustoms(); + } + + private void EditGlobals() + { + // Let's edit settings in the GLOBALS file (database/globals.json) + var globals = _databaseService.GetGlobals(); + + // Let's edit the scav cooldown to be 1 second + globals.Configuration.SavagePlayCooldown = 1; + + + // Now lets try editing the ragfair unlock level, lets get the ragfair settings first + var ragfairSettings = globals.Configuration.RagFair; + + // Lets set the level you need to be to access flea to be 1 + ragfairSettings.MinUserLevel = 1; + + + // Now lets increase the number of offers you can have listed at one time + // The max is stored in a list, different flea ratings give different offer amounts + + // We loop over all the settings, setting all of them to be 20 + foreach (var offerCountSettings in ragfairSettings.MaxActiveOfferCount) offerCountSettings.Count = 20; + } + + private void EditBtr() + { + // BTR setting can be found in the GLOBALS file too + var globals = _databaseService.GetGlobals(); + + // We get the BTR settings from globals first + var btrSettings = globals.Configuration.BTRSettings; + + // Let's get the settings for woods specifically, we use 'tryGetValue' for this, the settings will be stored in 'woodsBtrSettings' + btrSettings.MapsConfigs.TryGetValue("Woods", out var woodsBtrSettings); + + // Lets set the BTR to use the christmas skin + woodsBtrSettings.BtrSkin = "Tarcola"; + } + + private void EditHideout() + { + // Hideout data can be found in (SPT_Data\Server\database\hideout) + var hideout = _databaseService.GetHideout(); + + // We want the areas, they're stored in a list + var hideoutAreas = hideout.Areas; + + // We find the toilet, we use 'firstOrDefault', if we cant find the lavatory, 'lavatoryArea' will be null + var lavatoryArea = hideoutAreas.FirstOrDefault(area => area.Type == HideoutAreas.LAVATORY); + + + // Now we have the toilet, we can find the requirements to craft, all data is stored by stage + var toiletStages = lavatoryArea.Stages; + + // Stages are stored in a dictionary, a dictionary has a 'key' and a 'value' + // In this case, the 'key' is the upgrade stage, e.g. "1", or "2" + // We reference to each stage as a 'stageKvP' this means 'Key value Pair', every key has a value (key = stage number, value = data for that stage) + foreach (var stageKvP in toiletStages) { - _databaseService = databaseService; + // while we're here, we can make the stages craft really fast (60 seconds) + stageKvP.Value.ConstructionTime = 60; - Run(); - } + // Let's get the stage requirements, they're a list + var stageRequirements = stageKvP.Value.Requirements; - public void Run() - { - // When SPT starts, it stores all the data found in (SPT_Data\Server\database) in memory - // We can use the '_databaseService' we injected to access this data, this includes files from EFT and SPT - - // Lets edit some globals settings to make the game easier - EditGlobals(); - - // Lets edit the BTR to have the christmas tarcola skin - EditBtr(); - - // Let's edit the hideout so it's easier to upgrade the lavatory - EditHideout(); - - // Lets edit the default scav to - EditScavSettings(); - - // Lets edit Customs - EditCustoms(); - } - - private void EditGlobals() - { - // Let's edit settings in the GLOBALS file (database/globals.json) - var globals = _databaseService.GetGlobals(); - - // Let's edit the scav cooldown to be 1 second - globals.Configuration.SavagePlayCooldown = 1; - - - // Now lets try editing the ragfair unlock level, lets get the ragfair settings first - var ragfairSettings = globals.Configuration.RagFair; - - // Lets set the level you need to be to access flea to be 1 - ragfairSettings.MinUserLevel = 1; - - - // Now lets increase the number of offers you can have listed at one time - // The max is stored in a list, different flea ratings give different offer amounts - - // We loop over all the settings, setting all of them to be 20 - foreach (var offerCountSettings in ragfairSettings.MaxActiveOfferCount) - { - offerCountSettings.Count = 20; - } - } - - private void EditBtr() - { - // BTR setting can be found in the GLOBALS file too - var globals = _databaseService.GetGlobals(); - - // We get the BTR settings from globals first - var btrSettings = globals.Configuration.BTRSettings; - - // Let's get the settings for woods specifically, we use 'tryGetValue' for this, the settings will be stored in 'woodsBtrSettings' - btrSettings.MapsConfigs.TryGetValue("Woods", out var woodsBtrSettings); - - // Lets set the BTR to use the christmas skin - woodsBtrSettings.BtrSkin = "Tarcola"; - } - - private void EditHideout() - { - // Hideout data can be found in (SPT_Data\Server\database\hideout) - Core.Models.Spt.Hideout.Hideout hideout = _databaseService.GetHideout(); - - // We want the areas, they're stored in a list - List? hideoutAreas = hideout.Areas; - - // We find the toilet, we use 'firstOrDefault', if we cant find the lavatory, 'lavatoryArea' will be null - HideoutArea? lavatoryArea = hideoutAreas.FirstOrDefault(area => area.Type == HideoutAreas.LAVATORY); - - - - // Now we have the toilet, we can find the requirements to craft, all data is stored by stage - var toiletStages = lavatoryArea.Stages; - - // Stages are stored in a dictionary, a dictionary has a 'key' and a 'value' - // In this case, the 'key' is the upgrade stage, e.g. "1", or "2" - // We reference to each stage as a 'stageKvP' this means 'Key value Pair', every key has a value (key = stage number, value = data for that stage) - foreach (var stageKvP in toiletStages) - { - // while we're here, we can make the stages craft really fast (60 seconds) - stageKvP.Value.ConstructionTime = 60; - - // Let's get the stage requirements, they're a list - var stageRequirements = stageKvP.Value.Requirements; - - // We empty the requirements out, now it can be built straight away - stageRequirements.Clear(); - } - } - - private void EditScavSettings() - { - var bots = _databaseService.GetBots(); - - // Same as the above example, we use 'TryGetValue' to get the 'assault' bot (assault is the internal name for scavs) - bots.Types.TryGetValue("assault", out var assaultBot); - - // Let's make the chance to get a good backpack really high - assaultBot.BotInventory.Equipment.TryGetValue(EquipmentSlots.Backpack, out Dictionary backPacks); - - // We access the backpacks dictionary by key directly using square brackets, we use ItemTpl to get the items ID - // Alternately, we could have typed backPacks["59e763f286f7742ee57895da"] and done the same thing, ItemTpl makes it easier to read - backPacks[ItemTpl.BACKPACK_PILGRIM_TOURIST] = 999999; - - - - - // Now lets make them always have an M4A1 - assaultBot.BotInventory.Equipment.TryGetValue(EquipmentSlots.FirstPrimaryWeapon, out Dictionary primaryWeapons); - - // We edit the weight value (pick chance) that is already there to be massive, making the item more likely to be picked - primaryWeapons[ItemTpl.ASSAULTRIFLE_COLT_M4A1_556X45_ASSAULT_RIFLE] = 999999; - - - - - // Now lets make them always have the first name of Gary - // We start by removing all the existing names - assaultBot.FirstNames.Clear(); - - // We add the new name Gary, very menacing - assaultBot.FirstNames.Add("Gary"); - } - - private void EditCustoms() - { - // Let's get all the maps (called locations) - var locations = _databaseService.GetLocations(); - - // Customs is called 'bigmap' in eft - var customs = locations.Bigmap; - - // Lets get the exits and make them all 100% chance to appear - var exits = customs.Base.Exits; - - // They're stored as a list so we can loop over them - foreach (var exit in exits) - { - // I can't remember which one is used, you'd assume ChancePVE is used in pve, but this is BSG we're dealing with - // So we set both - exit.Chance = 100; - exit.ChancePVE = 100; - } - - - - // Lets try editing the airdrops on customs to be better - var airdropSettings = customs.Base.AirdropParameters; - - // They're stored in an array but there's only one bunch of settings, it means we have to get the first item from the list, - // An alternate way to access the first item is done by using square brackets with the 'index' of the item we want, - // indexes start at 0 so we want to type "[0]" to access the first item in the list, - var actualAirdropSettings = airdropSettings.First(); - - // Make it spawn 100% - actualAirdropSettings.PlaneAirdropChance = 1; // Number between 0 and 1 - - // Make it spawn as early as start of raid - actualAirdropSettings.PlaneAirdropStartMin = 1; - - - - // Let's make bosses spawn 100% of the time - - // We get all the bosses, they're stored in a list - var bosses = customs.Base.BossLocationSpawn; - - // Let's get Reshala, we use "FirstOrDefault" and look for the first boss with the name "bossBully" - var reshala = bosses.FirstOrDefault(boss => boss.BossName == "bossBully"); - - // Set him to 100% - reshala.BossChance = 100; + // We empty the requirements out, now it can be built straight away + stageRequirements.Clear(); } } + + private void EditScavSettings() + { + var bots = _databaseService.GetBots(); + + // Same as the above example, we use 'TryGetValue' to get the 'assault' bot (assault is the internal name for scavs) + bots.Types.TryGetValue("assault", out var assaultBot); + + // Let's make the chance to get a good backpack really high + assaultBot.BotInventory.Equipment.TryGetValue(EquipmentSlots.Backpack, out var backPacks); + + // We access the backpacks dictionary by key directly using square brackets, we use ItemTpl to get the items ID + // Alternately, we could have typed backPacks["59e763f286f7742ee57895da"] and done the same thing, ItemTpl makes it easier to read + backPacks[ItemTpl.BACKPACK_PILGRIM_TOURIST] = 999999; + + + // Now lets make them always have an M4A1 + assaultBot.BotInventory.Equipment.TryGetValue(EquipmentSlots.FirstPrimaryWeapon, out var primaryWeapons); + + // We edit the weight value (pick chance) that is already there to be massive, making the item more likely to be picked + primaryWeapons[ItemTpl.ASSAULTRIFLE_COLT_M4A1_556X45_ASSAULT_RIFLE] = 999999; + + + // Now lets make them always have the first name of Gary + // We start by removing all the existing names + assaultBot.FirstNames.Clear(); + + // We add the new name Gary, very menacing + assaultBot.FirstNames.Add("Gary"); + } + + private void EditCustoms() + { + // Let's get all the maps (called locations) + var locations = _databaseService.GetLocations(); + + // Customs is called 'bigmap' in eft + var customs = locations.Bigmap; + + // Lets get the exits and make them all 100% chance to appear + var exits = customs.Base.Exits; + + // They're stored as a list so we can loop over them + foreach (var exit in exits) + { + // I can't remember which one is used, you'd assume ChancePVE is used in pve, but this is BSG we're dealing with + // So we set both + exit.Chance = 100; + exit.ChancePVE = 100; + } + + + // Lets try editing the airdrops on customs to be better + var airdropSettings = customs.Base.AirdropParameters; + + // They're stored in an array but there's only one bunch of settings, it means we have to get the first item from the list, + // An alternate way to access the first item is done by using square brackets with the 'index' of the item we want, + // indexes start at 0 so we want to type "[0]" to access the first item in the list, + var actualAirdropSettings = airdropSettings.First(); + + // Make it spawn 100% + actualAirdropSettings.PlaneAirdropChance = 1; // Number between 0 and 1 + + // Make it spawn as early as start of raid + actualAirdropSettings.PlaneAirdropStartMin = 1; + + + // Let's make bosses spawn 100% of the time + + // We get all the bosses, they're stored in a list + var bosses = customs.Base.BossLocationSpawn; + + // Let's get Reshala, we use "FirstOrDefault" and look for the first boss with the name "bossBully" + var reshala = bosses.FirstOrDefault(boss => boss.BossName == "bossBully"); + + // Set him to 100% + reshala.BossChance = 100; + } } diff --git a/ExampleMods/Mods/Logging.cs b/ExampleMods/Mods/Logging.cs index f7ce0aa7..8f784473 100644 --- a/ExampleMods/Mods/Logging.cs +++ b/ExampleMods/Mods/Logging.cs @@ -7,36 +7,35 @@ using SptCommon.Annotations; using Core.Models.Logging; using Core.Models.Utils; -namespace ExampleMods.Mods +namespace ExampleMods.Mods; + +[Injectable] +public class Logging { - [Injectable] - public class Logging + private readonly ISptLogger _logger; + + // Constructor - Inject a 'ISptLogger' with your mods Class in the diamond brackets + public Logging( + ISptLogger logger) { - private readonly ISptLogger _logger; + // Save the logger we're injecting into a private variable that is scoped to this class (only this class has access to it) + _logger = logger; - // Constructor - Inject a 'ISptLogger' with your mods Class in the diamond brackets - public Logging( - ISptLogger logger) - { - // Save the logger we're injecting into a private variable that is scoped to this class (only this class has access to it) - _logger = logger; + // Not 100% necessary but let's split our code out into a method to make it easier to read + Run(); + } - // Not 100% necessary but let's split our code out into a method to make it easier to read - Run(); - } + public void Run() + { + // We can access the logger to assigned in the constructor here + _logger.Success("This is a success message"); + _logger.Warning("This is a warning message"); + _logger.Error("This is an error message"); + _logger.Info("This is an info message"); + _logger.Critical("this is a critical message"); - public void Run() - { - // We can access the logger to assigned in the constructor here - _logger.Success("This is a success message"); - _logger.Warning("This is a warning message"); - _logger.Error("This is an error message"); - _logger.Info("This is an info message"); - _logger.Critical("this is a critical message"); - - // Logging with colors requires you to 'pass' the text color and background color - _logger.LogWithColor("This is a message with custom colors", LogTextColor.Red, LogBackgroundColor.Black); - _logger.Debug("This is a debug message that gets written to the log file, not the console"); - } + // Logging with colors requires you to 'pass' the text color and background color + _logger.LogWithColor("This is a message with custom colors", LogTextColor.Red, LogBackgroundColor.Black); + _logger.Debug("This is a debug message that gets written to the log file, not the console"); } } diff --git a/ExampleMods/Mods/Override/WatermarkOverride.cs b/ExampleMods/Mods/Override/WatermarkOverride.cs index fc87e805..05c8a7df 100644 --- a/ExampleMods/Mods/Override/WatermarkOverride.cs +++ b/ExampleMods/Mods/Override/WatermarkOverride.cs @@ -12,7 +12,12 @@ public class WatermarkOverride( ConfigServer _configServer, LocalisationService _localisationService, WatermarkLocale _watermarkLocale -) : Watermark(_logger, _configServer, _localisationService, _watermarkLocale) // was testing overriding with primary constructors, works fine from what i can see +) : Watermark( + _logger, + _configServer, + _localisationService, + _watermarkLocale +) // was testing overriding with primary constructors, works fine from what i can see { public override void Initialize() { diff --git a/Libraries/Core/Callbacks/AchievementCallbacks.cs b/Libraries/Core/Callbacks/AchievementCallbacks.cs index cd434fa0..e03226dd 100644 --- a/Libraries/Core/Callbacks/AchievementCallbacks.cs +++ b/Libraries/Core/Callbacks/AchievementCallbacks.cs @@ -6,8 +6,7 @@ using Core.Utils; namespace Core.Callbacks; [Injectable(InjectableTypeOverride = typeof(AchievementCallbacks))] -public class AchievementCallbacks -( +public class AchievementCallbacks( AchievementController _achievementController, HttpResponseUtil _httpResponseUtil ) diff --git a/Libraries/Core/Callbacks/ClientLogCallbacks.cs b/Libraries/Core/Callbacks/ClientLogCallbacks.cs index 1f2aa17d..32310496 100644 --- a/Libraries/Core/Callbacks/ClientLogCallbacks.cs +++ b/Libraries/Core/Callbacks/ClientLogCallbacks.cs @@ -16,9 +16,8 @@ public class ClientLogCallbacks( ConfigServer _configServer, LocalisationService _localisationService // ModLoadOrder _modLoadOrder // TODO: needs implementing - ) +) { - /// /// Handle /singleplayer/log /// @@ -39,11 +38,11 @@ public class ClientLogCallbacks( public string ReleaseNotes() { var data = _configServer.GetConfig().Release; - + data.BetaDisclaimerText = ProgramStatics.MODS() - ? _localisationService.GetText("release-beta-disclaimer-mods-enabled") + ? _localisationService.GetText("release-beta-disclaimer-mods-enabled") : _localisationService.GetText("release-beta-disclaimer"); - + data.BetaDisclaimerAcceptText = _localisationService.GetText("release-beta-disclaimer-accept"); data.ServerModsLoadedText = _localisationService.GetText("release-server-mods-loaded"); data.ServerModsLoadedDebugText = _localisationService.GetText("release-server-mods-debug-message"); @@ -55,7 +54,7 @@ public class ClientLogCallbacks( data.IsBeta = ProgramStatics.ENTRY_TYPE() == EntryType.BLEEDING_EDGE || ProgramStatics.ENTRY_TYPE() == EntryType.BLEEDING_EDGE_MODS; data.IsModdable = ProgramStatics.MODS(); data.IsModded = false; // TODO - + return _httpResponseUtil.NoBody(data); } diff --git a/Libraries/Core/Callbacks/DataCallbacks.cs b/Libraries/Core/Callbacks/DataCallbacks.cs index 26bf39c9..9426e8f6 100644 --- a/Libraries/Core/Callbacks/DataCallbacks.cs +++ b/Libraries/Core/Callbacks/DataCallbacks.cs @@ -149,13 +149,9 @@ public class DataCallbacks( { var localeId = url.Replace("/client/menu/locale/", ""); var locales = _databaseService.GetLocales(); - var result = locales.Menu?[localeId] - ?? locales.Menu?.FirstOrDefault(m => m.Key == "en").Value; + var result = locales.Menu?[localeId] ?? locales.Menu?.FirstOrDefault(m => m.Key == "en").Value; - if (result == null) - { - throw new Exception($"Unable to determine locale for request with {localeId}"); - } + if (result == null) throw new Exception($"Unable to determine locale for request with {localeId}"); return _httpResponseUtil.GetBody(result); } @@ -171,8 +167,7 @@ public class DataCallbacks( { var localeId = url.Replace("/client/locale/", ""); var locales = _databaseService.GetLocales(); - var result = locales.Global?[localeId].Value - ?? locales.Global?.FirstOrDefault(m => m.Key == "en").Value.Value; + var result = locales.Global?[localeId].Value ?? locales.Global?.FirstOrDefault(m => m.Key == "en").Value.Value; return _httpResponseUtil.GetUnclearedBody(result); } diff --git a/Libraries/Core/Callbacks/DialogueCallbacks.cs b/Libraries/Core/Callbacks/DialogueCallbacks.cs index f0739ec9..25c92d3f 100644 --- a/Libraries/Core/Callbacks/DialogueCallbacks.cs +++ b/Libraries/Core/Callbacks/DialogueCallbacks.cs @@ -18,6 +18,17 @@ public class DialogueCallbacks( ) : OnUpdate { + public bool OnUpdate(long timeSinceLastRun) + { + _dialogueController.Update(); + return true; + } + + public string GetRoute() + { + return "spt-dialogue"; + } + /// /// Handle client/friend/list /// @@ -41,7 +52,7 @@ public class DialogueCallbacks( { var chatServer = new List { - new ChatServer + new() { Id = _hashUtil.Generate(), RegistrationId = 20, @@ -51,7 +62,7 @@ public class DialogueCallbacks( VersionId = "bgkidft87ddd", Ip = "", Port = 0, - Chats = [ new Chat { Id = "0", Members = 0 } ], + Chats = [new Chat { Id = "0", Members = 0 }] } }; @@ -315,15 +326,4 @@ public class DialogueCallbacks( { return "Not Implemented!"; // Not implemented in Node } - - public bool OnUpdate(long timeSinceLastRun) - { - _dialogueController.Update(); - return true; - } - - public string GetRoute() - { - return "spt-dialogue"; - } } diff --git a/Libraries/Core/Callbacks/HealthCallbacks.cs b/Libraries/Core/Callbacks/HealthCallbacks.cs index b809de44..79249f90 100644 --- a/Libraries/Core/Callbacks/HealthCallbacks.cs +++ b/Libraries/Core/Callbacks/HealthCallbacks.cs @@ -13,9 +13,8 @@ public class HealthCallbacks( HttpResponseUtil _httpResponseUtil, ProfileHelper _profileHelper, HealthController _healthController - ) +) { - /// /// Custom spt server request found in modules/QTEPatch.cs /// diff --git a/Libraries/Core/Callbacks/HideoutCallbacks.cs b/Libraries/Core/Callbacks/HideoutCallbacks.cs index 9d3838e1..e95038c5 100644 --- a/Libraries/Core/Callbacks/HideoutCallbacks.cs +++ b/Libraries/Core/Callbacks/HideoutCallbacks.cs @@ -14,153 +14,10 @@ namespace Core.Callbacks; public class HideoutCallbacks( HideoutController _hideoutController, ConfigServer _configServer - ) : OnUpdate +) : OnUpdate { private readonly HideoutConfig _hideoutConfig = _configServer.GetConfig(); - /// - /// Handle HideoutUpgrade event - /// - public ItemEventRouterResponse Upgrade(PmcData pmcData, HideoutUpgradeRequestData request, string sessionID, ItemEventRouterResponse output) - { - _hideoutController.StartUpgrade(pmcData, request, sessionID, output); - - return output; - } - - /// - /// Handle HideoutUpgradeComplete event - /// - public ItemEventRouterResponse UpgradeComplete(PmcData pmcData, HideoutUpgradeCompleteRequestData request, string sessionID, ItemEventRouterResponse output) - { - _hideoutController.UpgradeComplete(pmcData, request, sessionID, output); - - return output; - } - - /// - /// Handle HideoutPutItemsInAreaSlots - /// - public ItemEventRouterResponse PutItemsInAreaSlots(PmcData pmcData, HideoutPutItemInRequestData request, string sessionID) - { - return _hideoutController.PutItemsInAreaSlots(pmcData, request, sessionID); - } - - /// - /// Handle HideoutTakeItemsFromAreaSlots event - /// - public ItemEventRouterResponse TakeItemsFromAreaSlots(PmcData pmcData, HideoutTakeItemOutRequestData request, string sessionID) - { - return _hideoutController.TakeItemsFromAreaSlots(pmcData, request, sessionID); - } - - /// - /// Handle HideoutToggleArea event - /// - public ItemEventRouterResponse ToggleArea(PmcData pmcData, HideoutToggleAreaRequestData request, string sessionID) - { - return _hideoutController.ToggleArea(pmcData, request, sessionID); - } - - /// - /// Handle HideoutSingleProductionStart event - /// - public ItemEventRouterResponse SingleProductionStart(PmcData pmcData, HideoutSingleProductionStartRequestData request, string sessionID) - { - return _hideoutController.SingleProductionStart(pmcData, request, sessionID); - } - - /// - /// Handle HideoutScavCaseProductionStart event - /// - public ItemEventRouterResponse ScavCaseProductionStart(PmcData pmcData, HideoutScavCaseStartRequestData request, string sessionID) - { - return _hideoutController.ScavCaseProductionStart(pmcData, request, sessionID); - } - - /// - /// Handle HideoutContinuousProductionStart - /// - public ItemEventRouterResponse ContinuousProductionStart(PmcData pmcData, HideoutContinuousProductionStartRequestData request, string sessionID) - { - return _hideoutController.ContinuousProductionStart(pmcData, request, sessionID); - } - - /// - /// Handle HideoutTakeProduction event - /// - public ItemEventRouterResponse TakeProduction(PmcData pmcData, HideoutTakeProductionRequestData request, string sessionID) - { - return _hideoutController.TakeProduction(pmcData, request, sessionID); - } - - /// - /// Handle HideoutQuickTimeEvent - /// - public ItemEventRouterResponse HandleQTEEvent(PmcData pmcData, HandleQTEEventRequestData request, string sessionID, ItemEventRouterResponse output) - { - _hideoutController.HandleQTEEventOutcome(sessionID, pmcData, request, output); - - return output; - } - - /// - /// Handle client/game/profile/items/moving - RecordShootingRangePoints - /// - public ItemEventRouterResponse RecordShootingRangePoints(PmcData pmcData, RecordShootingRangePoints request, string sessionID, ItemEventRouterResponse output) - { - _hideoutController.RecordShootingRangePoints(sessionID, pmcData, request); - - return output; - } - - /// - /// Handle client/game/profile/items/moving - RecordShootingRangePoints - /// - public ItemEventRouterResponse ImproveArea(PmcData pmcData, HideoutImproveAreaRequestData request, string sessionID) - { - return _hideoutController.ImproveArea(sessionID, pmcData, request); - } - - /// - /// Handle client/game/profile/items/moving - HideoutCancelProductionCommand - /// - public ItemEventRouterResponse CancelProduction(PmcData pmcData, HideoutCancelProductionRequestData request, string sessionID) - { - return _hideoutController.CancelProduction(sessionID, pmcData, request); - } - - /// - /// Handle client/game/profile/items/moving - HideoutCircleOfCultistProductionStart - /// - public ItemEventRouterResponse CicleOfCultistProductionStart(PmcData pmcData, HideoutCircleOfCultistProductionStartRequestData request, string sessionID) - { - return _hideoutController.CicleOfCultistProductionStart(sessionID, pmcData, request); - } - - /// - /// Handle client/game/profile/items/moving - HideoutDeleteProductionCommand - /// - public ItemEventRouterResponse HideoutDeleteProductionCommand(PmcData pmcData, HideoutDeleteProductionRequestData request, string sessionID) - { - return _hideoutController.HideoutDeleteProductionCommand(sessionID, pmcData, request); - } - - /// - /// Handle client/game/profile/items/moving - HideoutCustomizationApply - /// - public ItemEventRouterResponse HideoutCustomizationApplyCommand(PmcData pmcData, HideoutCustomizationApplyRequestData request, string sessionID) - { - return _hideoutController.HideoutCustomizationApply(sessionID, pmcData, request); - } - - /** - * Handle client/game/profile/items/moving - hideoutCustomizationSetMannequinPose - */ - public ItemEventRouterResponse HideoutCustomizationSetMannequinPose(PmcData pmcData, HideoutCustomizationSetMannequinPoseRequest request, string sessionId) { - return _hideoutController.HideoutCustomizationSetMannequinPose(sessionId, pmcData, request); - } - public bool OnUpdate(long timeSinceLastRun) { if (timeSinceLastRun > _hideoutConfig.RunIntervalSeconds) @@ -176,4 +33,149 @@ public class HideoutCallbacks( { return "spt-hideout"; } + + /// + /// Handle HideoutUpgrade event + /// + public ItemEventRouterResponse Upgrade(PmcData pmcData, HideoutUpgradeRequestData request, string sessionID, ItemEventRouterResponse output) + { + _hideoutController.StartUpgrade(pmcData, request, sessionID, output); + + return output; + } + + /// + /// Handle HideoutUpgradeComplete event + /// + public ItemEventRouterResponse UpgradeComplete(PmcData pmcData, HideoutUpgradeCompleteRequestData request, string sessionID, ItemEventRouterResponse output) + { + _hideoutController.UpgradeComplete(pmcData, request, sessionID, output); + + return output; + } + + /// + /// Handle HideoutPutItemsInAreaSlots + /// + public ItemEventRouterResponse PutItemsInAreaSlots(PmcData pmcData, HideoutPutItemInRequestData request, string sessionID) + { + return _hideoutController.PutItemsInAreaSlots(pmcData, request, sessionID); + } + + /// + /// Handle HideoutTakeItemsFromAreaSlots event + /// + public ItemEventRouterResponse TakeItemsFromAreaSlots(PmcData pmcData, HideoutTakeItemOutRequestData request, string sessionID) + { + return _hideoutController.TakeItemsFromAreaSlots(pmcData, request, sessionID); + } + + /// + /// Handle HideoutToggleArea event + /// + public ItemEventRouterResponse ToggleArea(PmcData pmcData, HideoutToggleAreaRequestData request, string sessionID) + { + return _hideoutController.ToggleArea(pmcData, request, sessionID); + } + + /// + /// Handle HideoutSingleProductionStart event + /// + public ItemEventRouterResponse SingleProductionStart(PmcData pmcData, HideoutSingleProductionStartRequestData request, string sessionID) + { + return _hideoutController.SingleProductionStart(pmcData, request, sessionID); + } + + /// + /// Handle HideoutScavCaseProductionStart event + /// + public ItemEventRouterResponse ScavCaseProductionStart(PmcData pmcData, HideoutScavCaseStartRequestData request, string sessionID) + { + return _hideoutController.ScavCaseProductionStart(pmcData, request, sessionID); + } + + /// + /// Handle HideoutContinuousProductionStart + /// + public ItemEventRouterResponse ContinuousProductionStart(PmcData pmcData, HideoutContinuousProductionStartRequestData request, string sessionID) + { + return _hideoutController.ContinuousProductionStart(pmcData, request, sessionID); + } + + /// + /// Handle HideoutTakeProduction event + /// + public ItemEventRouterResponse TakeProduction(PmcData pmcData, HideoutTakeProductionRequestData request, string sessionID) + { + return _hideoutController.TakeProduction(pmcData, request, sessionID); + } + + /// + /// Handle HideoutQuickTimeEvent + /// + public ItemEventRouterResponse HandleQTEEvent(PmcData pmcData, HandleQTEEventRequestData request, string sessionID, ItemEventRouterResponse output) + { + _hideoutController.HandleQTEEventOutcome(sessionID, pmcData, request, output); + + return output; + } + + /// + /// Handle client/game/profile/items/moving - RecordShootingRangePoints + /// + public ItemEventRouterResponse RecordShootingRangePoints(PmcData pmcData, RecordShootingRangePoints request, string sessionID, + ItemEventRouterResponse output) + { + _hideoutController.RecordShootingRangePoints(sessionID, pmcData, request); + + return output; + } + + /// + /// Handle client/game/profile/items/moving - RecordShootingRangePoints + /// + public ItemEventRouterResponse ImproveArea(PmcData pmcData, HideoutImproveAreaRequestData request, string sessionID) + { + return _hideoutController.ImproveArea(sessionID, pmcData, request); + } + + /// + /// Handle client/game/profile/items/moving - HideoutCancelProductionCommand + /// + public ItemEventRouterResponse CancelProduction(PmcData pmcData, HideoutCancelProductionRequestData request, string sessionID) + { + return _hideoutController.CancelProduction(sessionID, pmcData, request); + } + + /// + /// Handle client/game/profile/items/moving - HideoutCircleOfCultistProductionStart + /// + public ItemEventRouterResponse CicleOfCultistProductionStart(PmcData pmcData, HideoutCircleOfCultistProductionStartRequestData request, string sessionID) + { + return _hideoutController.CicleOfCultistProductionStart(sessionID, pmcData, request); + } + + /// + /// Handle client/game/profile/items/moving - HideoutDeleteProductionCommand + /// + public ItemEventRouterResponse HideoutDeleteProductionCommand(PmcData pmcData, HideoutDeleteProductionRequestData request, string sessionID) + { + return _hideoutController.HideoutDeleteProductionCommand(sessionID, pmcData, request); + } + + /// + /// Handle client/game/profile/items/moving - HideoutCustomizationApply + /// + public ItemEventRouterResponse HideoutCustomizationApplyCommand(PmcData pmcData, HideoutCustomizationApplyRequestData request, string sessionID) + { + return _hideoutController.HideoutCustomizationApply(sessionID, pmcData, request); + } + + /** + * Handle client/game/profile/items/moving - hideoutCustomizationSetMannequinPose + */ + public ItemEventRouterResponse HideoutCustomizationSetMannequinPose(PmcData pmcData, HideoutCustomizationSetMannequinPoseRequest request, string sessionId) + { + return _hideoutController.HideoutCustomizationSetMannequinPose(sessionId, pmcData, request); + } } diff --git a/Libraries/Core/Callbacks/HttpCallbacks.cs b/Libraries/Core/Callbacks/HttpCallbacks.cs index 62a2da92..9e82d047 100644 --- a/Libraries/Core/Callbacks/HttpCallbacks.cs +++ b/Libraries/Core/Callbacks/HttpCallbacks.cs @@ -10,9 +10,9 @@ public class HttpCallbacks(HttpServer _httpServer, ApplicationContext _applicati { public Task OnLoad() { - _httpServer.Load( _applicationContext.GetLatestValue(ContextVariableType.APP_BUILDER)?.GetValue()); + _httpServer.Load(_applicationContext.GetLatestValue(ContextVariableType.APP_BUILDER)?.GetValue()); _applicationContext.ClearValues(ContextVariableType.APP_BUILDER); - + return Task.CompletedTask; } diff --git a/Libraries/Core/Callbacks/InraidCallbacks.cs b/Libraries/Core/Callbacks/InraidCallbacks.cs index 242f1c56..c7e77b38 100644 --- a/Libraries/Core/Callbacks/InraidCallbacks.cs +++ b/Libraries/Core/Callbacks/InraidCallbacks.cs @@ -10,7 +10,7 @@ namespace Core.Callbacks; public class InraidCallbacks( InRaidController _inRaidController, HttpResponseUtil _httpResponseUtil - ) +) { /// /// Handle client/location/getLocalloot diff --git a/Libraries/Core/Callbacks/InsuranceCallbacks.cs b/Libraries/Core/Callbacks/InsuranceCallbacks.cs index 10801aff..43643dca 100644 --- a/Libraries/Core/Callbacks/InsuranceCallbacks.cs +++ b/Libraries/Core/Callbacks/InsuranceCallbacks.cs @@ -18,11 +18,26 @@ public class InsuranceCallbacks( InsuranceService _insuranceService, HttpResponseUtil _httpResponseUtil, ConfigServer _configServer - ) +) : OnUpdate { private InsuranceConfig _insuranceConfig = _configServer.GetConfig(); + public bool OnUpdate(long timeSinceLastRun) + { + if (timeSinceLastRun > Math.Max(_insuranceConfig.RunIntervalSeconds, 1)) + // _insuranceController.ProcessReturn(); + // TODO: InsuranceController is not implemented rn + return true; + + return false; + } + + public string GetRoute() + { + return "spt-insurance"; + } + /// /// Handle client/insurance/items/list/cost /// @@ -32,7 +47,7 @@ public class InsuranceCallbacks( /// public string GetInsuranceCost(string url, GetInsuranceCostRequestData info, string sessionID) { - return _httpResponseUtil.GetBody(_insuranceController.Cost(info, sessionID)); + return _httpResponseUtil.GetBody(_insuranceController.Cost(info, sessionID)); } /// @@ -46,21 +61,4 @@ public class InsuranceCallbacks( { return _insuranceController.Insure(pmcData, info, sessionID); } - - public bool OnUpdate(long timeSinceLastRun) - { - if (timeSinceLastRun > Math.Max(_insuranceConfig.RunIntervalSeconds, 1)) - { - // _insuranceController.ProcessReturn(); - // TODO: InsuranceController is not implemented rn - return true; - } - - return false; - } - - public string GetRoute() - { - return "spt-insurance"; - } } diff --git a/Libraries/Core/Callbacks/ItemEventCallbacks.cs b/Libraries/Core/Callbacks/ItemEventCallbacks.cs index 30aa0c63..1a93bbfc 100644 --- a/Libraries/Core/Callbacks/ItemEventCallbacks.cs +++ b/Libraries/Core/Callbacks/ItemEventCallbacks.cs @@ -11,12 +11,12 @@ public class ItemEventCallbacks(HttpResponseUtil _httpResponseUtil, ItemEventRou { public string HandleEvents(string url, ItemEventRouterRequest info, string sessionID) { - var eventResponse = _itemEventRouter.HandleEvents(info, sessionID); - var result = IsCriticalError(eventResponse.Warnings) - ? _httpResponseUtil.GetBody(eventResponse, GetErrorCode(eventResponse.Warnings), eventResponse.Warnings[0].ErrorMessage) - : _httpResponseUtil.GetBody(eventResponse); + var eventResponse = _itemEventRouter.HandleEvents(info, sessionID); + var result = IsCriticalError(eventResponse.Warnings) + ? _httpResponseUtil.GetBody(eventResponse, GetErrorCode(eventResponse.Warnings), eventResponse.Warnings[0].ErrorMessage) + : _httpResponseUtil.GetBody(eventResponse); - return result; + return result; } /// @@ -26,11 +26,8 @@ public class ItemEventCallbacks(HttpResponseUtil _httpResponseUtil, ItemEventRou /// public bool IsCriticalError(List? warnings) { - if (warnings is null) - { - return false; - } - + if (warnings is null) return false; + // List of non-critical error codes, we return true if any error NOT included is passed in var nonCriticalErrorCodes = new List { BackendErrorCodes.NotEnoughSpace }; @@ -38,19 +35,22 @@ public class ItemEventCallbacks(HttpResponseUtil _httpResponseUtil, ItemEventRou { if (!Enum.TryParse(warning.Code, out BackendErrorCodes code)) throw new Exception($"Unable to parse [{warning.Code}] to BackendErrorCode."); - + if (!nonCriticalErrorCodes.Contains(code)) return true; } - + return false; } public int GetErrorCode(List warnings) { // Cast int to string to get the error code of 220 for Unknown Error. - return int.Parse((warnings[0].Code is null || warnings[0].Code == "None" - ? ((int) BackendErrorCodes.UnknownError).ToString() - : warnings.FirstOrDefault()?.Code) ?? string.Empty); + return int.Parse( + (warnings[0].Code is null || warnings[0].Code == "None" + ? ((int)BackendErrorCodes.UnknownError).ToString() + : warnings.FirstOrDefault()?.Code) ?? + string.Empty + ); } } diff --git a/Libraries/Core/Callbacks/LauncherV2Callbacks.cs b/Libraries/Core/Callbacks/LauncherV2Callbacks.cs index 4a2f3b01..cfb8fff8 100644 --- a/Libraries/Core/Callbacks/LauncherV2Callbacks.cs +++ b/Libraries/Core/Callbacks/LauncherV2Callbacks.cs @@ -15,7 +15,8 @@ public class LauncherV2Callbacks( { public string Ping() { - return _httpResponseUtil.NoBody(new LauncherV2PingResponse + return _httpResponseUtil.NoBody( + new LauncherV2PingResponse { Response = _launcherV2Controller.Ping() } @@ -24,15 +25,18 @@ public class LauncherV2Callbacks( public string Types() { - return _httpResponseUtil.NoBody(new LauncherV2TypesResponse - { - Response = _launcherV2Controller.Types() - }); + return _httpResponseUtil.NoBody( + new LauncherV2TypesResponse + { + Response = _launcherV2Controller.Types() + } + ); } public string Login(LoginRequestData info) { - return _httpResponseUtil.NoBody(new LauncherV2LoginResponse + return _httpResponseUtil.NoBody( + new LauncherV2LoginResponse { Response = _launcherV2Controller.Login(info) } @@ -41,7 +45,8 @@ public class LauncherV2Callbacks( public string Register(RegisterData info) { - return _httpResponseUtil.NoBody(new LauncherV2RegisterResponse + return _httpResponseUtil.NoBody( + new LauncherV2RegisterResponse { Response = _launcherV2Controller.Register(info), Profiles = _profileController.GetMiniProfiles() @@ -51,17 +56,19 @@ public class LauncherV2Callbacks( public string PasswordChange(ChangeRequestData info) { - return _httpResponseUtil.NoBody(new LauncherV2PasswordChangeResponse + return _httpResponseUtil.NoBody( + new LauncherV2PasswordChangeResponse { Response = _launcherV2Controller.PasswordChange(info), Profiles = _profileController.GetMiniProfiles() } ); } - + public string Remove(LoginRequestData info) { - return _httpResponseUtil.NoBody(new LauncherV2RemoveResponse + return _httpResponseUtil.NoBody( + new LauncherV2RemoveResponse { Response = _launcherV2Controller.Remove(info), Profiles = _profileController.GetMiniProfiles() @@ -71,7 +78,8 @@ public class LauncherV2Callbacks( public string CompatibleVersion() { - return _httpResponseUtil.NoBody(new LauncherV2VersionResponse + return _httpResponseUtil.NoBody( + new LauncherV2VersionResponse { Response = new LauncherV2CompatibleVersion { @@ -84,7 +92,8 @@ public class LauncherV2Callbacks( public string Mods() { - return _httpResponseUtil.NoBody(new LauncherV2ModsResponse + return _httpResponseUtil.NoBody( + new LauncherV2ModsResponse { Response = _launcherV2Controller.LoadedMods() } @@ -93,7 +102,8 @@ public class LauncherV2Callbacks( public string Profiles() { - return _httpResponseUtil.NoBody(new LauncherV2ProfilesResponse + return _httpResponseUtil.NoBody( + new LauncherV2ProfilesResponse { Response = _profileController.GetMiniProfiles() } diff --git a/Libraries/Core/Callbacks/MatchCallbacks.cs b/Libraries/Core/Callbacks/MatchCallbacks.cs index f547be19..7494bbb9 100644 --- a/Libraries/Core/Callbacks/MatchCallbacks.cs +++ b/Libraries/Core/Callbacks/MatchCallbacks.cs @@ -108,7 +108,7 @@ public class MatchCallbacks( /// public string AcceptGroupInvite(string url, RequestIdRequest info, string sessionID) { - return _httpResponseUtil.GetBody(new List() { new GroupCharacter() }); + return _httpResponseUtil.GetBody(new List() { new() }); } /// diff --git a/Libraries/Core/Callbacks/NoteCallbacks.cs b/Libraries/Core/Callbacks/NoteCallbacks.cs index 245e1473..c5ebbf6d 100644 --- a/Libraries/Core/Callbacks/NoteCallbacks.cs +++ b/Libraries/Core/Callbacks/NoteCallbacks.cs @@ -9,7 +9,6 @@ namespace Core.Callbacks; [Injectable] public class NoteCallbacks(NoteController _noteController) { - /// /// Handle AddNote event /// diff --git a/Libraries/Core/Callbacks/ProfileCallbacks.cs b/Libraries/Core/Callbacks/ProfileCallbacks.cs index 5688c21f..b2ff42ea 100644 --- a/Libraries/Core/Callbacks/ProfileCallbacks.cs +++ b/Libraries/Core/Callbacks/ProfileCallbacks.cs @@ -94,10 +94,7 @@ public class ProfileCallbacks( public string GetReservedNickname(string url, EmptyRequestData info, string sessionID) { var fullProfile = _profileHelper.GetFullProfile(sessionID); - if (fullProfile?.ProfileInfo?.Username is not null) - { - return _httpResponse.GetBody(fullProfile?.ProfileInfo?.Username); - } + if (fullProfile?.ProfileInfo?.Username is not null) return _httpResponse.GetBody(fullProfile?.ProfileInfo?.Username); return _httpResponse.GetBody("SPTarkov"); } diff --git a/Libraries/Core/Callbacks/RagfairCallbacks.cs b/Libraries/Core/Callbacks/RagfairCallbacks.cs index ce96ebfb..8875b0a4 100644 --- a/Libraries/Core/Callbacks/RagfairCallbacks.cs +++ b/Libraries/Core/Callbacks/RagfairCallbacks.cs @@ -21,7 +21,7 @@ public class RagfairCallbacks( RagfairTaxService _ragfairTaxService, RagfairPriceService _ragfairPriceService, ConfigServer _configServer - ) : OnLoad, OnUpdate +) : OnLoad, OnUpdate { private RagfairConfig _ragfairConfig = _configServer.GetConfig(); @@ -39,19 +39,21 @@ public class RagfairCallbacks( public bool OnUpdate(long timeSinceLastRun) { - if (timeSinceLastRun > _ragfairConfig.RunIntervalSeconds) { + if (timeSinceLastRun > _ragfairConfig.RunIntervalSeconds) + { // There is a flag inside this class that only makes it run once. _ragfairServer.AddPlayerOffers(); - - // Check player offers and mail payment to player if sold - _ragfairController.Update(); - - // Process all offers / expire offers - _ragfairServer.Update(); - - return true; - } - return false; + + // Check player offers and mail payment to player if sold + _ragfairController.Update(); + + // Process all offers / expire offers + _ragfairServer.Update(); + + return true; + } + + return false; } /// diff --git a/Libraries/Core/Callbacks/SaveCallbacks.cs b/Libraries/Core/Callbacks/SaveCallbacks.cs index 36a002f6..a9abd4cb 100644 --- a/Libraries/Core/Callbacks/SaveCallbacks.cs +++ b/Libraries/Core/Callbacks/SaveCallbacks.cs @@ -12,7 +12,7 @@ public class SaveCallbacks( SaveServer _saveServer, ConfigServer _configServer, BackupService _backupService - ) +) : OnLoad, OnUpdate { private readonly CoreConfig _coreConfig = _configServer.GetConfig(); @@ -23,6 +23,11 @@ public class SaveCallbacks( _saveServer.Load(); } + public string GetRoute() + { + return "spt-save"; + } + public bool OnUpdate(long secondsSinceLastRun) { if (secondsSinceLastRun > _coreConfig.ProfileSaveIntervalInSeconds) @@ -33,9 +38,4 @@ public class SaveCallbacks( return false; } - - public string GetRoute() - { - return "spt-save"; - } } diff --git a/Libraries/Core/Callbacks/TraderCallbacks.cs b/Libraries/Core/Callbacks/TraderCallbacks.cs index c9af3b2c..bf13014c 100644 --- a/Libraries/Core/Callbacks/TraderCallbacks.cs +++ b/Libraries/Core/Callbacks/TraderCallbacks.cs @@ -18,23 +18,23 @@ public class TraderCallbacks( ) : OnLoad, OnUpdate { private readonly TraderConfig _traderConfig = _configServer.GetConfig(); - + public Task OnLoad() { _traderController.Load(); return Task.CompletedTask; } - public bool OnUpdate(long _) - { - return _traderController.Update(); - } - public string GetRoute() { return "spt-traders"; } + public bool OnUpdate(long _) + { + return _traderController.Update(); + } + /// /// Handle client/trading/api/traderSettings /// diff --git a/Libraries/Core/Context/ApplicationContext.cs b/Libraries/Core/Context/ApplicationContext.cs index 80d5cae8..9f5785c4 100644 --- a/Libraries/Core/Context/ApplicationContext.cs +++ b/Libraries/Core/Context/ApplicationContext.cs @@ -25,10 +25,7 @@ public class ApplicationContext lock (variablesLock) { var values = new List(); - if (variables.TryGetValue(type, out var savedValues)) - { - values.AddRange(savedValues); - } + if (variables.TryGetValue(type, out var savedValues)) values.AddRange(savedValues); return values; } diff --git a/Libraries/Core/Context/ContextVariable.cs b/Libraries/Core/Context/ContextVariable.cs index 29c4b1ec..46a3ef35 100644 --- a/Libraries/Core/Context/ContextVariable.cs +++ b/Libraries/Core/Context/ContextVariable.cs @@ -4,7 +4,8 @@ public class ContextVariable(object value, ContextVariableType contextVariableIn { private readonly DateTime _timestamp = DateTime.UtcNow; - public T GetValue() { + public T GetValue() + { return (T)value; } diff --git a/Libraries/Core/Controllers/AchievementController.cs b/Libraries/Core/Controllers/AchievementController.cs index 39b58603..bdeb3771 100644 --- a/Libraries/Core/Controllers/AchievementController.cs +++ b/Libraries/Core/Controllers/AchievementController.cs @@ -23,11 +23,10 @@ public class AchievementController( var stats = new Dictionary(); foreach (var achievement in achievements) - { - if (achievement.Id != null) stats.Add(achievement.Id, 0); - } + if (achievement.Id != null) + stats.Add(achievement.Id, 0); - return new() + return new CompletedAchievementsResponse { Elements = stats }; diff --git a/Libraries/Core/Controllers/BotController.cs b/Libraries/Core/Controllers/BotController.cs index 3c8c09af..93d8c027 100644 --- a/Libraries/Core/Controllers/BotController.cs +++ b/Libraries/Core/Controllers/BotController.cs @@ -52,10 +52,7 @@ public class BotController( .First(p => p.Name.ToLower() == (typeInLower == "assaultgroup" ? "assault" : typeInLower)) .GetValue(_botConfig.PresetBatch); - if (value != null) - { - return value; - } + if (value != null) return value; _logger.Warning(_localisationService.GetText("bot-bot_preset_count_value_missing", type)); return 30; @@ -70,18 +67,12 @@ public class BotController( { var difficulty = diffLevel.ToLower(); - if (!(raidConfig != null || ignoreRaidSettings)) - { - _logger.Error(_localisationService.GetText("bot-missing_application_context", "RAID_CONFIGURATION")); - } + if (!(raidConfig != null || ignoreRaidSettings)) _logger.Error(_localisationService.GetText("bot-missing_application_context", "RAID_CONFIGURATION")); // Check value chosen in pre-raid difficulty dropdown // If value is not 'asonline', change requested difficulty to be what was chosen in dropdown var botDifficultyDropDownValue = raidConfig?.WavesSettings?.BotDifficulty?.ToString().ToLower() ?? "asonline"; - if (botDifficultyDropDownValue != "asonline") - { - difficulty = _botDifficultyHelper.ConvertBotDifficultyDropdownToBotDifficulty(botDifficultyDropDownValue); - } + if (botDifficultyDropDownValue != "asonline") difficulty = _botDifficultyHelper.ConvertBotDifficultyDropdownToBotDifficulty(botDifficultyDropDownValue); var botDb = _databaseService.GetBots(); return _botDifficultyHelper.GetBotDifficultySettings(type, difficulty, botDb); @@ -96,10 +87,7 @@ public class BotController( var botTypes = Enum.GetValues().Select(item => item.ToString()).ToList(); foreach (var botType in botTypes) { - if (botTypesDb is null) - { - continue; - } + if (botTypesDb is null) continue; // If bot is usec/bear, swap to different name var botTypeLower = _botHelper.IsBotPmc(botType) @@ -113,10 +101,7 @@ public class BotController( { // No bot of this type found, copy details from assault result[botTypeLower] = result["assault"]; - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Unable to find bot: {botTypeLower} in db, copying 'assault'"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Unable to find bot: {botTypeLower} in db, copying 'assault'"); continue; } @@ -131,10 +116,7 @@ public class BotController( foreach (var (difficultyName, _) in botDetails.BotDifficulty) { // Bot doesn't exist in result, add - if (!result.ContainsKey(botNameKey)) - { - result.TryAdd(botNameKey, new Dictionary()); - } + if (!result.ContainsKey(botNameKey)) result.TryAdd(botNameKey, new Dictionary()); // Store all difficulty values in dict keyed by difficulty type e.g. easy/normal/impossible result[botNameKey].Add(difficultyName, GetBotDifficulty(botNameKey, difficultyName, null, true)); @@ -147,7 +129,7 @@ public class BotController( public List Generate(string sessionId, GenerateBotsRequestData info) { var pmcProfile = _profileHelper.GetPmcProfile(sessionId); - + // Use this opportunity to create and cache bots for later retrieval var multipleBotTypesRequested = info.Conditions?.Count > 1; return multipleBotTypesRequested @@ -166,7 +148,6 @@ public class BotController( var tasks = new List(); // Map conditions to promises for bot generation foreach (var condition in request.Conditions ?? []) - { tasks.Add( Task.Factory.StartNew( () => @@ -185,14 +166,10 @@ public class BotController( } ) ); - } - + Task.WaitAll(tasks.ToArray()); stopwatch.Stop(); - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Took {stopwatch.ElapsedMilliseconds}ms to GenerateMultipleBotsAndCache"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Took {stopwatch.ElapsedMilliseconds}ms to GenerateMultipleBotsAndCache"); return []; } @@ -220,24 +197,17 @@ public class BotController( if (botCacheCount >= botGenerationDetails.BotCountToGenerate) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Cache already has sufficient {cacheKey} bots: {botCacheCount}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Cache already has sufficient {cacheKey} bots: {botCacheCount}"); return; } // We're below desired count, add bots to cache var botsToGenerate = botGenerationDetails.BotCountToGenerate - botCacheCount; var progressWriter = new ProgressWriter(botGenerationDetails.BotCountToGenerate.GetValueOrDefault(30)); - - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Generating {botsToGenerate} bots for cacheKey: {cacheKey}"); - } + + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Generating {botsToGenerate} bots for cacheKey: {cacheKey}"); for (var i = 0; i < botsToGenerate; i++) - { try { var detailsClone = _cloner.Clone(botGenerationDetails); @@ -248,15 +218,12 @@ public class BotController( { _logger.Error($"Failed to generate bot: {botGenerationDetails.Role} #{i + 1}: {e.Message}"); } - } - if(_logger.IsLogEnabled(LogLevel.Debug)) - { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug( $"Generated {botGenerationDetails.BotCountToGenerate} {botGenerationDetails.Role}" + $"({botGenerationDetails.EventRole ?? botGenerationDetails.Role ?? ""}) {botGenerationDetails.BotDifficulty}bots" ); - } } private List ReturnSingleBotFromCache(string sessionId, GenerateBotsRequestData request) @@ -271,7 +238,7 @@ public class BotController( { Role = requestedBot?.Role, Limit = 5, - Difficulty = requestedBot?.Difficulty, + Difficulty = requestedBot?.Difficulty }; var botGenerationDetails = GetBotGenerationDetailsForWave( condition, @@ -321,13 +288,9 @@ public class BotController( { var bossConvertPercent = bossConvertMinMax.GetByJsonProp(requestedBot?.Role?.ToLower() ?? string.Empty); if (bossConvertPercent is not null) - { // Roll a percentage check if we should convert scav to boss if (_randomUtil.GetChance100(_randomUtil.GetDouble(bossConvertPercent.Min!.Value, bossConvertPercent.Max!.Value))) - { UpdateBotGenerationDetailsToRandomBoss(botGenerationDetails, bossesToConvertToWeights); - } - } } // Create a compound key to store bots in cache against @@ -341,14 +304,12 @@ public class BotController( { // No bot in cache, generate new and store in cache GenerateSingleBotAndStoreInCache(botGenerationDetails, sessionId, cacheKey); - - if(_logger.IsLogEnabled(LogLevel.Debug)) - { + + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug( $"Generated {botGenerationDetails.BotCountToGenerate} " + $"{botGenerationDetails.Role} ({botGenerationDetails.EventRole ?? ""}) {botGenerationDetails.BotDifficulty} bots" ); - } } var desiredBot = _botGenerationCacheService.GetBot(cacheKey); @@ -400,10 +361,7 @@ public class BotController( .GetLatestValue(ContextVariableType.RAID_CONFIGURATION) ?.GetValue(); - if (raidSettings is null) - { - _logger.Warning(_localisationService.GetText("bot-unable_to_load_raid_settings_from_appcontext")); - } + if (raidSettings is null) _logger.Warning(_localisationService.GetText("bot-unable_to_load_raid_settings_from_appcontext")); return raidSettings; } @@ -432,9 +390,9 @@ public class BotController( BotRelativeLevelDeltaMin = _pmcConfig.BotRelativeLevelDeltaMin, BotCountToGenerate = botCountToGenerate, BotDifficulty = condition.Difficulty, - LocationSpecificPmcLevelOverride = this.GetPmcLevelRangeForMap(raidSettings?.Location), // Min/max levels for PMCs to generate within + LocationSpecificPmcLevelOverride = GetPmcLevelRangeForMap(raidSettings?.Location), // Min/max levels for PMCs to generate within IsPlayerScav = false, - AllPmcsHaveSameNameAsPlayer = allPmcsHaveSameNameAsPlayer, + AllPmcsHaveSameNameAsPlayer = allPmcsHaveSameNameAsPlayer }; } @@ -442,11 +400,9 @@ public class BotController( { var botCap = _botConfig.MaxBotCap.FirstOrDefault(x => x.Key.ToLower() == location.ToLower()); if (location == "default") - { _logger.Warning( _localisationService.GetText("bot-no_bot_cap_found_for_location", location.ToLower()) ); - } return botCap.Value; } @@ -457,7 +413,7 @@ public class BotController( { PmcType = _pmcConfig.PmcType, Assault = _botConfig.AssaultBrainType, - PlayerScav = _botConfig.PlayerScavBrainType, + PlayerScav = _botConfig.PlayerScavBrainType }; } } @@ -465,11 +421,11 @@ public class BotController( public record AiBotBrainTypes { [JsonPropertyName("pmc")] - public Dictionary>> PmcType { get; set; } - + public Dictionary>> PmcType { get; set; } + [JsonPropertyName("assault")] - public Dictionary> Assault { get; set; } - + public Dictionary> Assault { get; set; } + [JsonPropertyName("playerScav")] - public Dictionary> PlayerScav { get; set; } + public Dictionary> PlayerScav { get; set; } } diff --git a/Libraries/Core/Controllers/BuildController.cs b/Libraries/Core/Controllers/BuildController.cs index b516efb4..84489a10 100644 --- a/Libraries/Core/Controllers/BuildController.cs +++ b/Libraries/Core/Controllers/BuildController.cs @@ -36,9 +36,7 @@ public class BuildController( const string secureContainerSlotId = "SecuredContainer"; var profile = _profileHelper.GetFullProfile(sessionID); if (profile is not null && profile.UserBuildData is null) - { profile.UserBuildData = new UserBuilds { EquipmentBuilds = [], WeaponBuilds = [], MagazineBuilds = [] }; - } // Ensure the secure container in the default presets match what the player has equipped var defaultEquipmentPresetsClone = _cloner.Clone( @@ -52,18 +50,13 @@ public class BuildController( x => x.SlotId == secureContainerSlotId ); if (playerSecureContainer is not null && playerSecureContainer.Template != firstDefaultItemsSecureContainer?.Template) - { // Default equipment presets' secure container tpl doesn't match players secure container tpl foreach (var defaultPreset in defaultEquipmentPresetsClone ?? []) { // Find presets secure container var secureContainer = defaultPreset.Items?.FirstOrDefault(item => item.SlotId == secureContainerSlotId); - if (secureContainer is not null) - { - secureContainer.Template = playerSecureContainer.Template; - } + if (secureContainer is not null) secureContainer.Template = playerSecureContainer.Template; } - } // Clone player build data from profile and append the above defaults onto end var userBuildsClone = _cloner.Clone(profile?.UserBuildData); @@ -87,7 +80,7 @@ public class BuildController( body.Root = body.Items.FirstOrDefault().Id; // Create new object ready to save into profile userbuilds.weaponBuilds - WeaponBuild newBuild = new WeaponBuild { Id = body.Id, Name = body.Name, Root = body.Root, Items = body.Items }; + var newBuild = new WeaponBuild { Id = body.Id, Name = body.Name, Root = body.Root, Items = body.Items }; var profile = _profileHelper.GetFullProfile(sessionId); @@ -124,13 +117,13 @@ public class BuildController( // Root ID and the base item ID need to match. request.Items = _itemHelper.ReplaceIDs(request.Items, pmcData); - EquipmentBuild newBuild = new EquipmentBuild + var newBuild = new EquipmentBuild { Id = request.Id, Name = request.Name, BuildType = EquipmentBuildType.Custom, Root = request.Items[0].Id, - Items = request.Items, + Items = request.Items }; var existingBuild = existingSavedEquipmentBuilds.FirstOrDefault( @@ -167,14 +160,14 @@ public class BuildController( /// public void CreateMagazineTemplate(string sessionId, SetMagazineRequest request) { - MagazineBuild result = new MagazineBuild + var result = new MagazineBuild { Id = request.Id, Name = request.Name, Caliber = request.Caliber, TopCount = request.TopCount, BottomCount = request.BottomCount, - Items = request.Items, + Items = request.Items }; var profile = _profileHelper.GetFullProfile(sessionId); diff --git a/Libraries/Core/Controllers/ClientLogController.cs b/Libraries/Core/Controllers/ClientLogController.cs index 6ed8b437..1073d749 100644 --- a/Libraries/Core/Controllers/ClientLogController.cs +++ b/Libraries/Core/Controllers/ClientLogController.cs @@ -8,9 +8,8 @@ namespace Core.Controllers; [Injectable] public class ClientLogController( ISptLogger _logger - ) +) { - /// /// Handle /singleplayer/log /// diff --git a/Libraries/Core/Controllers/CustomizationController.cs b/Libraries/Core/Controllers/CustomizationController.cs index e6825c6a..0843525d 100644 --- a/Libraries/Core/Controllers/CustomizationController.cs +++ b/Libraries/Core/Controllers/CustomizationController.cs @@ -55,10 +55,7 @@ public class CustomizationController( ) .ToList(); - if (matchingSuits == null) - { - throw new Exception(_localisationService.GetText("customisation-unable_to_get_trader_suits", traderId)); - } + if (matchingSuits == null) throw new Exception(_localisationService.GetText("customisation-unable_to_get_trader_suits", traderId)); return matchingSuits; } @@ -104,7 +101,7 @@ public class CustomizationController( return output; } - + // Charge player for buying item PayForClothingItems(sessionId, pmcData, buyClothingRequest.Items, output); @@ -127,20 +124,14 @@ public class CustomizationController( { var suits = _saveServer.GetProfile(sessionId).Suits; - if (suits is null || suits.Count == 0) - { - return false; - } + if (suits is null || suits.Count == 0) return false; return suits.Contains(suitId); } private Suit? GetTraderClothingOffer(string sessionId, string? offerId) { var foundSuit = GetAllTraderSuits(sessionId).FirstOrDefault(s => s.Id == offerId); - if (foundSuit is null) - { - _logger.Error(_localisationService.GetText("customisation-unable_to_find_suit_with_id", offerId)); - } + if (foundSuit is null) _logger.Error(_localisationService.GetText("customisation-unable_to_find_suit_with_id", offerId)); return foundSuit; } @@ -156,11 +147,8 @@ public class CustomizationController( List? itemsToPayForClothingWith, ItemEventRouterResponse output) { - if (itemsToPayForClothingWith is null || itemsToPayForClothingWith.Count == 0) - { - return; - } - + if (itemsToPayForClothingWith is null || itemsToPayForClothingWith.Count == 0) return; + foreach (var inventoryItemToProcess in itemsToPayForClothingWith) { var options = new ProcessBuyTradeRequestData @@ -189,9 +177,7 @@ public class CustomizationController( foreach (var trader in traders) if (trader.Value.Base?.CustomizationSeller is not null && trader.Value.Base.CustomizationSeller.Value) - { result.AddRange(GetTraderSuits(trader.Key, sessionId)); - } return result; } @@ -220,10 +206,7 @@ public class CustomizationController( var customisationResultsClone = _cloner.Clone(_databaseService.GetTemplates().CustomisationStorage); var profile = _profileHelper.GetFullProfile(sessionId); - if (profile is null) - { - return customisationResultsClone!; - } + if (profile is null) return customisationResultsClone!; customisationResultsClone!.AddRange(profile.CustomisationUnlocks ?? []); @@ -240,7 +223,6 @@ public class CustomizationController( public ItemEventRouterResponse SetCustomisation(string sessionId, CustomizationSetRequest request, PmcData pmcData) { foreach (var customisation in request.Customizations) - { switch (customisation.Type) { case "dogTag": @@ -253,7 +235,6 @@ public class CustomizationController( _logger.Error($"Unhandled customisation type: {customisation.Type}"); break; } - } return _eventOutputHolder.GetOutput(sessionId); } @@ -285,9 +266,6 @@ public class CustomizationController( } // Feet - if (dbSuit.Parent == _lowerParentClothingId) - { - pmcData.Customization.Feet = dbSuit.Properties.Feet; - } + if (dbSuit.Parent == _lowerParentClothingId) pmcData.Customization.Feet = dbSuit.Properties.Feet; } } diff --git a/Libraries/Core/Controllers/DialogueController.cs b/Libraries/Core/Controllers/DialogueController.cs index f6b28790..5b5dcb74 100644 --- a/Libraries/Core/Controllers/DialogueController.cs +++ b/Libraries/Core/Controllers/DialogueController.cs @@ -37,9 +37,7 @@ public class DialogueController( public void RegisterChatBot(IDialogueChatBot chatBot) // TODO: this is in with the helper types { if (_dialogueChatBots.Any(cb => cb.GetChatBot().Id == chatBot.GetChatBot().Id)) - { _logger.Error(_localisationService.GetText("dialog-chatbot_id_already_exists", chatBot.GetChatBot().Id)); - } _dialogueChatBots.Add(chatBot); } @@ -51,10 +49,7 @@ public class DialogueController( public void Update() { var profiles = _saveServer.GetProfiles(); - foreach (var kvp in profiles) - { - RemoveExpiredItemsFromMessages(kvp.Key); - } + foreach (var kvp in profiles) RemoveExpiredItemsFromMessages(kvp.Key); } /// @@ -70,23 +65,19 @@ public class DialogueController( // Add any friends the user has after the chatbots var profile = _profileHelper.GetFullProfile(sessionId); if (profile?.FriendProfileIds is not null) - { foreach (var friendId in profile.FriendProfileIds) { var friendProfile = _profileHelper.GetChatRoomMemberFromSessionId(friendId); if (friendProfile is not null) - { friends.Add( new UserDialogInfo { Id = friendProfile.Id, Aid = friendProfile.Aid, - Info = friendProfile.Info, + Info = friendProfile.Info } ); - } } - } return new GetFriendListDataResponse { @@ -105,10 +96,7 @@ public class DialogueController( foreach (var bot in _dialogueChatBots) { var botData = bot.GetChatBot(); - if (chatBotConfig.EnabledBots.ContainsKey(botData.Id!)) - { - activeBots.Add(botData); - } + if (chatBotConfig.EnabledBots.ContainsKey(botData.Id!)) activeBots.Add(botData); } return activeBots; @@ -124,10 +112,7 @@ public class DialogueController( public List GenerateDialogueList(string sessionId) { var data = new List(); - foreach (var dialogueId in _dialogueHelper.GetDialogsForProfile(sessionId)) - { - data.Add(GetDialogueInfo(dialogueId.Key, sessionId)); - } + foreach (var dialogueId in _dialogueHelper.GetDialogsForProfile(sessionId)) data.Add(GetDialogueInfo(dialogueId.Key, sessionId)); return data; } @@ -153,7 +138,7 @@ public class DialogueController( New = dialogue?.New, AttachmentsNew = dialogue?.AttachmentsNew, Pinned = dialogue?.Pinned, - Users = GetDialogueUsers(dialogue, dialogue?.Type, sessionId), + Users = GetDialogueUsers(dialogue, dialogue?.Type, sessionId) }; return result; @@ -177,7 +162,6 @@ public class DialogueController( if (messageType == MessageType.USER_MESSAGE && dialog?.Users is not null && dialog.Users.All(userDialog => userDialog.Id != profile.CharacterData?.PmcData?.SessionId)) - { dialog.Users.Add( new UserDialogInfo { @@ -189,11 +173,10 @@ public class DialogueController( Nickname = profile.CharacterData?.PmcData?.Info?.Nickname, Side = profile.CharacterData?.PmcData?.Info?.Side, MemberCategory = profile.CharacterData?.PmcData?.Info?.MemberCategory, - SelectedMemberCategory = profile.CharacterData?.PmcData?.Info?.SelectedMemberCategory, - }, + SelectedMemberCategory = profile.CharacterData?.PmcData?.Info?.SelectedMemberCategory + } } ); - } return dialog?.Users!; } @@ -225,7 +208,7 @@ public class DialogueController( { Messages = dialogue.Messages, Profiles = GetProfilesForMail(fullProfile, dialogue.Users), - HasMessagesWithRewards = MessagesHaveUncollectedRewards(dialogue.Messages!), + HasMessagesWithRewards = MessagesHaveUncollectedRewards(dialogue.Messages!) }; } @@ -249,22 +232,16 @@ public class DialogueController( Pinned = false, Messages = [], New = 0, - Type = request.Type, + Type = request.Type }; - if (request.Type != MessageType.USER_MESSAGE) - { - return profile.DialogueRecords[request.DialogId!]; - } + if (request.Type != MessageType.USER_MESSAGE) return profile.DialogueRecords[request.DialogId!]; var dialogue = profile.DialogueRecords[request.DialogId!]; dialogue.Users = []; var chatBot = _dialogueChatBots.FirstOrDefault(cb => cb.GetChatBot().Id == request.DialogId); - if (chatBot is null) - { - return profile.DialogueRecords[request.DialogId!]; - } + if (chatBot is null) return profile.DialogueRecords[request.DialogId!]; dialogue.Users ??= []; dialogue.Users.Add(chatBot.GetChatBot()); @@ -282,17 +259,12 @@ public class DialogueController( { List result = []; if (userDialogs is null) - { // Nothing to add return result; - } result.AddRange(userDialogs); - if (result.Any(userDialog => userDialog.Id == fullProfile.ProfileInfo?.ProfileId)) - { - return result; - } + if (result.Any(userDialog => userDialog.Id == fullProfile.ProfileInfo?.ProfileId)) return result; // Player doesn't exist, add them in before returning var pmcProfile = fullProfile.CharacterData?.PmcData; @@ -307,7 +279,7 @@ public class DialogueController( Side = pmcProfile?.Info?.Side, Level = pmcProfile?.Info?.Level, MemberCategory = pmcProfile?.Info?.MemberCategory, - SelectedMemberCategory = pmcProfile?.Info?.SelectedMemberCategory, + SelectedMemberCategory = pmcProfile?.Info?.SelectedMemberCategory } } ); @@ -328,12 +300,8 @@ public class DialogueController( var newAttachmentCount = 0; var activeMessages = GetActiveMessagesFromDialog(sessionId, dialogueId); foreach (var message in activeMessages) - { if (message.HasRewards.GetValueOrDefault(false) && !message.RewardCollected.GetValueOrDefault(false)) - { newAttachmentCount++; - } - } return newAttachmentCount; } @@ -382,7 +350,7 @@ public class DialogueController( new { sessionId, - dialogueId, + dialogueId } ) ); @@ -410,7 +378,7 @@ public class DialogueController( new { sessionId, - dialogueId, + dialogueId } ) ); @@ -437,7 +405,7 @@ public class DialogueController( "dialogue-unable_to_find_dialogs_in_profile", new { - sessionId, + sessionId } ) ); @@ -498,11 +466,13 @@ public class DialogueController( { _mailSendService.SendPlayerMessageToNpc(sessionId, request.DialogId!, request.Text!); - return (_dialogueChatBots.FirstOrDefault(cb => - cb.GetChatBot().Id == request.DialogId) - ?.HandleMessage(sessionId, request) - ?? request.DialogId) - ?? string.Empty; + return (_dialogueChatBots.FirstOrDefault( + cb => + cb.GetChatBot().Id == request.DialogId + ) + ?.HandleMessage(sessionId, request) ?? + request.DialogId) ?? + string.Empty; } /// @@ -521,10 +491,7 @@ public class DialogueController( /// Session id private void RemoveExpiredItemsFromMessages(string sessionId) { - foreach (var dialogueId in _dialogueHelper.GetDialogsForProfile(sessionId)) - { - RemoveExpiredItemsFromMessage(sessionId, dialogueId.Key); - } + foreach (var dialogueId in _dialogueHelper.GetDialogsForProfile(sessionId)) RemoveExpiredItemsFromMessage(sessionId, dialogueId.Key); } /// @@ -535,18 +502,11 @@ public class DialogueController( private void RemoveExpiredItemsFromMessage(string sessionId, string dialogueId) { var dialogs = _dialogueHelper.GetDialogsForProfile(sessionId); - if (!dialogs.TryGetValue(dialogueId, out var dialog)) - { - return; - } + if (!dialogs.TryGetValue(dialogueId, out var dialog)) return; foreach (var message in dialog.Messages ?? []) - { if (MessageHasExpired(message)) - { message.Items = new MessageItems(); - } - } } /** @@ -564,30 +524,25 @@ public class DialogueController( // To avoid needing to jump between profiles, auto-accept all friend requests var friendProfile = _profileHelper.GetFullProfile(request.To); if (friendProfile?.CharacterData?.PmcData is null) - { return new FriendRequestSendResponse { Status = BackendErrorCodes.PlayerProfileNotFound, RequestId = "", // Unused in an error state - RetryAfter = 600, + RetryAfter = 600 }; - } // Only add the profile to the friends list if it doesn't already exist var profile = _saveServer.GetProfile(sessionID); - if (!profile.FriendProfileIds.Contains(request.To)) - { - profile.FriendProfileIds.Add(request.To); - } + if (!profile.FriendProfileIds.Contains(request.To)) profile.FriendProfileIds.Add(request.To); // We need to delay this so that the friend request gets properly added to the clientside list before we accept it _ = new Timer( _ => { - WsFriendsListAccept notification = new WsFriendsListAccept + var notification = new WsFriendsListAccept { EventType = NotificationEventType.friendListRequestAccept, - Profile = _profileHelper.GetChatRoomMemberFromPmcProfile(friendProfile.CharacterData.PmcData), + Profile = _profileHelper.GetChatRoomMemberFromPmcProfile(friendProfile.CharacterData.PmcData) }; _notificationSendHelper.SendMessage(sessionID, notification); }, @@ -608,9 +563,6 @@ public class DialogueController( { var profile = _saveServer.GetProfile(sessionID); var friendIndex = profile.FriendProfileIds.IndexOf(request.FriendId); - if (friendIndex != -1) - { - profile.FriendProfileIds.RemoveAt(friendIndex); - } + if (friendIndex != -1) profile.FriendProfileIds.RemoveAt(friendIndex); } } diff --git a/Libraries/Core/Controllers/GameController.cs b/Libraries/Core/Controllers/GameController.cs index 3c28ce4c..60eece65 100644 --- a/Libraries/Core/Controllers/GameController.cs +++ b/Libraries/Core/Controllers/GameController.cs @@ -44,12 +44,12 @@ public class GameController( ICloner _cloner ) { + protected BotConfig _botConfig = _configServer.GetConfig(); protected CoreConfig _coreConfig = _configServer.GetConfig(); + protected double _deviation = 0.0001; + protected HideoutConfig _hideoutConfig = _configServer.GetConfig(); protected HttpConfig _httpConfig = _configServer.GetConfig(); protected RagfairConfig _ragfairConfig = _configServer.GetConfig(); - protected HideoutConfig _hideoutConfig = _configServer.GetConfig(); - protected BotConfig _botConfig = _configServer.GetConfig(); - protected double _deviation = 0.0001; /// /// Handle client/game/start @@ -82,40 +82,25 @@ public class GameController( _logger.Error($"{nameof(fullProfile)} is null on GameController.GameStart"); return; } - + fullProfile.SptData ??= new Spt { Version = "Replace_me" }; fullProfile.SptData.Migrations ??= new Dictionary(); fullProfile.FriendProfileIds ??= []; - - if (fullProfile.ProfileInfo?.IsWiped is not null && fullProfile.ProfileInfo.IsWiped.Value) - { - return; - } - + + if (fullProfile.ProfileInfo?.IsWiped is not null && fullProfile.ProfileInfo.IsWiped.Value) return; + fullProfile.CharacterData!.PmcData!.WishList ??= new DictionaryOrList(new Dictionary(), []); fullProfile.CharacterData.ScavData!.WishList ??= new DictionaryOrList(new Dictionary(), []); - if (fullProfile.DialogueRecords is not null) - { - _profileFixerService.CheckForAndFixDialogueAttachments(fullProfile); - } + if (fullProfile.DialogueRecords is not null) _profileFixerService.CheckForAndFixDialogueAttachments(fullProfile); - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Started game with session {sessionId} {fullProfile.ProfileInfo?.Username}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Started game with session {sessionId} {fullProfile.ProfileInfo?.Username}"); var pmcProfile = fullProfile.CharacterData.PmcData; - if (_coreConfig.Fixes.FixProfileBreakingInventoryItemIssues) - { - _profileFixerService.FixProfileBreakingInventoryItemIssues(pmcProfile); - } + if (_coreConfig.Fixes.FixProfileBreakingInventoryItemIssues) _profileFixerService.FixProfileBreakingInventoryItemIssues(pmcProfile); - if (pmcProfile.Health is not null) - { - UpdateProfileHealthValues(pmcProfile); - } + if (pmcProfile.Health is not null) UpdateProfileHealthValues(pmcProfile); if (pmcProfile.Inventory is not null) { @@ -143,10 +128,7 @@ public class GameController( CheckForAndRemoveUndefinedDialogues(fullProfile); } - if (pmcProfile.Skills?.Common is not null) - { - WarnOnActiveBotReloadSkill(pmcProfile); - } + if (pmcProfile.Skills?.Common is not null) WarnOnActiveBotReloadSkill(pmcProfile); _seasonalEventService.GivePlayerSeasonalGifts(sessionId); } @@ -160,8 +142,9 @@ public class GameController( { var profile = _profileHelper.GetPmcProfile(sessionId); var gameTime = profile?.Stats?.Eft?.OverallCounters?.Items? - .FirstOrDefault(c => c.Key!.Contains("LifeTime") - && c.Key.Contains("Pmc"))?.Value ?? 0D; + .FirstOrDefault(c => c.Key!.Contains("LifeTime") && c.Key.Contains("Pmc")) + ?.Value ?? + 0D; var config = new GameConfigResponse { @@ -173,7 +156,7 @@ public class GameController( Aid = profile?.Aid, Taxonomy = 6, ActiveProfileId = sessionId, - Backend = new() + Backend = new Backend { Lobby = _httpServerHelper.GetBackendUrl(), Trading = _httpServerHelper.GetBackendUrl(), @@ -185,7 +168,7 @@ public class GameController( UtcTime = _timeUtil.GetTimeStamp(), TotalInGame = gameTime, SessionMode = "pve", - PurchasedGames = new() + PurchasedGames = new PurchasedGames { IsEftPurchased = true, IsArenaPurchased = false @@ -205,7 +188,7 @@ public class GameController( string sessionId, GameModeRequestData requestData) { - return new() + return new GameModeResponse { GameMode = "pve", BackendUrl = _httpServerHelper.GetBackendUrl() @@ -291,7 +274,7 @@ public class GameController( /// public SurveyResponseData GetSurvey(string sessionId) { - return this._coreConfig.Survey; + return _coreConfig.Survey; } /// @@ -301,10 +284,7 @@ public class GameController( private void WarnOnActiveBotReloadSkill(PmcData pmcProfile) { var botReloadSkill = _profileHelper.GetSkillFromProfile(pmcProfile, SkillTypes.BotReload); - if (botReloadSkill?.Progress > 0) - { - _logger.Warning(_localisationService.GetText("server_start_player_active_botreload_skill")); - } + if (botReloadSkill?.Progress > 0) _logger.Warning(_localisationService.GetText("server_start_player_active_botreload_skill")); } /// @@ -323,40 +303,35 @@ public class GameController( // Base values double energyRegenPerHour = 60; double hydrationRegenPerHour = 60; - double hpRegenPerHour = 456.6; + var hpRegenPerHour = 456.6; // Set new values, whatever is smallest energyRegenPerHour += pmcProfile.Bonuses! .Where(bonus => bonus.Type == BonusType.EnergyRegeneration) - .Aggregate(0d, (sum, bonus) => sum + (bonus.Value!.Value)); - + .Aggregate(0d, (sum, bonus) => sum + bonus.Value!.Value); + hydrationRegenPerHour += pmcProfile.Bonuses! .Where(bonus => bonus.Type == BonusType.HydrationRegeneration) - .Aggregate(0d, (sum, bonus) => sum + (bonus.Value!.Value)); - + .Aggregate(0d, (sum, bonus) => sum + bonus.Value!.Value); + hpRegenPerHour += pmcProfile.Bonuses! .Where(bonus => bonus.Type == BonusType.HealthRegeneration) - .Aggregate(0d, (sum, bonus) => sum + (bonus.Value!.Value)); + .Aggregate(0d, (sum, bonus) => sum + bonus.Value!.Value); // Player has energy deficit - if (Math.Abs((pmcProfile.Health?.Energy?.Current - pmcProfile.Health?.Energy?.Maximum) ?? 1) <= _deviation) + if (Math.Abs(pmcProfile.Health?.Energy?.Current - pmcProfile.Health?.Energy?.Maximum ?? 1) <= _deviation) { // Set new value, whatever is smallest pmcProfile.Health!.Energy!.Current += Math.Round(energyRegenPerHour * (diffSeconds!.Value / 3600)); - if (pmcProfile.Health.Energy.Current > pmcProfile.Health.Energy.Maximum) - { - pmcProfile.Health.Energy.Current = pmcProfile.Health.Energy.Maximum; - } + if (pmcProfile.Health.Energy.Current > pmcProfile.Health.Energy.Maximum) pmcProfile.Health.Energy.Current = pmcProfile.Health.Energy.Maximum; } // Player has hydration deficit - if (Math.Abs((pmcProfile.Health?.Hydration?.Current - pmcProfile.Health?.Hydration?.Maximum) ?? 1) <= _deviation) + if (Math.Abs(pmcProfile.Health?.Hydration?.Current - pmcProfile.Health?.Hydration?.Maximum ?? 1) <= _deviation) { pmcProfile.Health!.Hydration!.Current += Math.Round(hydrationRegenPerHour * (diffSeconds!.Value / 3600)); if (pmcProfile.Health.Hydration.Current > pmcProfile.Health.Hydration.Maximum) - { pmcProfile.Health.Hydration.Current = pmcProfile.Health.Hydration.Maximum; - } } // Check all body parts @@ -364,21 +339,12 @@ public class GameController( .Select(bodyPartKvP => bodyPartKvP.Value)) { // Check part hp - if (bodyPart.Health!.Current < bodyPart.Health.Maximum) - { - bodyPart.Health.Current += Math.Round(hpRegenPerHour * (diffSeconds!.Value / 3600)); - } + if (bodyPart.Health!.Current < bodyPart.Health.Maximum) bodyPart.Health.Current += Math.Round(hpRegenPerHour * (diffSeconds!.Value / 3600)); - if (bodyPart.Health.Current > bodyPart.Health.Maximum) - { - bodyPart.Health.Current = bodyPart.Health.Maximum; - } + if (bodyPart.Health.Current > bodyPart.Health.Maximum) bodyPart.Health.Current = bodyPart.Health.Maximum; - if (bodyPart.Effects is null || bodyPart.Effects.Count == 0) - { - continue; - } + if (bodyPart.Effects is null || bodyPart.Effects.Count == 0) continue; // Look for effects foreach (var effectKvP in bodyPart.Effects) @@ -387,10 +353,7 @@ public class GameController( if (effectKvP.Value.Time < 1) { // More than 30 mins has passed - if (diffSeconds > 1800) - { - bodyPart.Effects.Remove(effectKvP.Key); - } + if (diffSeconds > 1800) bodyPart.Effects.Remove(effectKvP.Key); continue; } @@ -398,10 +361,8 @@ public class GameController( // Decrement effect time value by difference between current time and time health was last updated effectKvP.Value.Time -= diffSeconds; if (effectKvP.Value.Time < 1) - { // Effect time was sub 1, set floor it can be effectKvP.Value.Time = 1; - } } } @@ -421,16 +382,10 @@ public class GameController( var currentTimeStamp = _timeUtil.GetTimeStamp(); // One day post-profile creation - if (currentTimeStamp > timeStampProfileCreated + oneDaySeconds) - { - _giftService.SendPraporStartingGift(pmcProfile.SessionId!, 1); - } + if (currentTimeStamp > timeStampProfileCreated + oneDaySeconds) _giftService.SendPraporStartingGift(pmcProfile.SessionId!, 1); // Two day post-profile creation - if (currentTimeStamp > timeStampProfileCreated + oneDaySeconds * 2) - { - _giftService.SendPraporStartingGift(pmcProfile.SessionId!, 2); - } + if (currentTimeStamp > timeStampProfileCreated + oneDaySeconds * 2) _giftService.SendPraporStartingGift(pmcProfile.SessionId!, 2); } /** @@ -438,7 +393,7 @@ public class GameController( * @param pmcProfile Player profile */ protected void SendMechanicGiftsToNewProfile(PmcData pmcProfile) - { + { _giftService.SendGiftWithSilentReceivedCheck("MechanicGiftDay1", pmcProfile.SessionId, 1); } @@ -495,27 +450,16 @@ public class GameController( var bots = _databaseService.GetBots().Types; // Official names can only be 15 chars in length - if (playerName.Length > _botConfig.BotNameLengthLimit) - { - return; - } + if (playerName.Length > _botConfig.BotNameLengthLimit) return; // Skip if player name exists already if (bots!.TryGetValue("bear", out var bearBot)) - { if (bearBot is not null && bearBot.FirstNames!.Any(x => x == playerName)) - { bearBot.FirstNames!.Add(playerName); - } - } if (bots.TryGetValue("bear", out var usecBot)) - { if (usecBot is not null && usecBot.FirstNames!.Any(x => x == playerName)) - { usecBot.FirstNames!.Add(playerName); - } - } } } @@ -525,10 +469,7 @@ public class GameController( /// Profile to check for dialog in private void CheckForAndRemoveUndefinedDialogues(SptProfile fullProfile) { - if (fullProfile.DialogueRecords!.TryGetValue("undefined", out var _)) - { - fullProfile.DialogueRecords.Remove("undefined"); - } + if (fullProfile.DialogueRecords!.TryGetValue("undefined", out _)) fullProfile.DialogueRecords.Remove("undefined"); } /// @@ -540,7 +481,7 @@ public class GameController( if (_logger.IsLogEnabled(LogLevel.Debug)) { _logger.Debug($"Profile made with: {fullProfile.SptData?.Version}"); - _logger.Debug($"Server version: {(ProgramStatics.SPT_VERSION()) ?? _coreConfig.SptVersion} {ProgramStatics.COMMIT()}"); + _logger.Debug($"Server version: {ProgramStatics.SPT_VERSION() ?? _coreConfig.SptVersion} {ProgramStatics.COMMIT()}"); _logger.Debug($"Debug enabled: {ProgramStatics.DEBUG()}"); _logger.Debug($"Mods enabled: {ProgramStatics.MODS()}"); } diff --git a/Libraries/Core/Controllers/HealthController.cs b/Libraries/Core/Controllers/HealthController.cs index a3e059a9..e8a2bb0c 100644 --- a/Libraries/Core/Controllers/HealthController.cs +++ b/Libraries/Core/Controllers/HealthController.cs @@ -69,15 +69,12 @@ public class HealthController( } // Resource in medkit is spent, delete it - if (healingItemToUse.Upd.MedKit.HpResource <= 0) - { - _inventoryHelper.RemoveItem(pmcData, request.Item, sessionID, output); - } + if (healingItemToUse.Upd.MedKit.HpResource <= 0) _inventoryHelper.RemoveItem(pmcData, request.Item, sessionID, output); var healingItemDbDetails = _itemHelper.GetItem(healingItemToUse.Template); var healItemEffectDetails = healingItemDbDetails.Value.Properties.EffectsDamage; - BodyPartHealth bodyPartToHeal = pmcData.Health.BodyParts.GetValueOrDefault(request.Part.ToString()); + var bodyPartToHeal = pmcData.Health.BodyParts.GetValueOrDefault(request.Part.ToString()); if (bodyPartToHeal is null) { _logger.Warning($"Player: {sessionID} Tried to heal a non-existent body part: {request.Part}"); @@ -98,10 +95,8 @@ public class HealthController( { // Check if healing item removes the effect on limb if (!healItemEffectDetails.TryGetValue(Enum.Parse(effectKey), out var matchingEffectFromHealingItem)) - { // Healing item doesn't have matching effect, it doesn't remove the effect continue; - } // Adjust limb heal amount based on if its fixing an effect (request.count is TOTAL cost of hp resource on heal item, NOT amount to heal limb) amountToHealLimb -= (int)(matchingEffectFromHealingItem.Cost ?? 0); @@ -113,10 +108,7 @@ public class HealthController( bodyPartToHeal.Health.Current += amountToHealLimb; // Ensure we've not healed beyond the limbs max hp - if (bodyPartToHeal.Health.Current > bodyPartToHeal.Health.Maximum) - { - bodyPartToHeal.Health.Current = bodyPartToHeal.Health.Maximum; - } + if (bodyPartToHeal.Health.Current > bodyPartToHeal.Health.Maximum) bodyPartToHeal.Health.Current = bodyPartToHeal.Health.Maximum; return output; } @@ -139,13 +131,11 @@ public class HealthController( var itemToConsume = pmcData.Inventory.Items.FirstOrDefault(item => item.Id == request.Item); if (itemToConsume is null) - { // Item not found, very bad return _httpResponseUtil.AppendErrorToOutput( output, _localisationService.GetText("health-unable_to_find_item_to_consume", request.Item) ); - } var consumedItemMaxResource = _itemHelper.GetItem(itemToConsume.Template).Value.Properties.MaxResource; if (consumedItemMaxResource > 1) @@ -154,22 +144,15 @@ public class HealthController( _itemHelper.AddUpdObjectToItem(itemToConsume); if (itemToConsume.Upd.FoodDrink is null) - { itemToConsume.Upd.FoodDrink = new UpdFoodDrink { HpPercent = consumedItemMaxResource - request.Count }; - } else - { itemToConsume.Upd.FoodDrink.HpPercent -= request.Count; - } resourceLeft = itemToConsume.Upd.FoodDrink.HpPercent.Value; } // Remove item from inventory if resource has dropped below threshold - if (consumedItemMaxResource == 1 || resourceLeft < 1) - { - _inventoryHelper.RemoveItem(pmcData, request.Item, sessionID, output); - } + if (consumedItemMaxResource == 1 || resourceLeft < 1) _inventoryHelper.RemoveItem(pmcData, request.Item, sessionID, output); // Check what effect eating item has and handle var foodItemDbDetails = _itemHelper.GetItem(itemToConsume.Template).Value; @@ -198,14 +181,10 @@ public class HealthController( OffraidEatRequestData request) { if (foodIsSingleUse) - { // Apply whole value from passed in parameter bodyValue.Current += consumptionDetails.Value; - } else - { bodyValue.Current += request.Count; - } // Ensure current never goes over max if (bodyValue.Current > bodyValue.Maximum) @@ -216,10 +195,7 @@ public class HealthController( } // Same as above but for the lower bound - if (bodyValue.Current < 0) - { - bodyValue.Current = 0; - } + if (bodyValue.Current < 0) bodyValue.Current = 0; } /// @@ -248,10 +224,7 @@ public class HealthController( }; _paymentService.PayMoney(pmcData, payMoneyRequest, sessionID, output); - if (output.Warnings.Count > 0) - { - return output; - } + if (output.Warnings.Count > 0) return output; foreach (var bodyPartKvP in healthTreatmentRequest.Difference.BodyParts.GetAllPropsAsDict()) { @@ -261,25 +234,17 @@ public class HealthController( // Bodypart healing is chosen when part request hp is above 0 if (partRequest.Health > 0) - { // Heal bodypart profilePart.Health.Current = profilePart.Health.Maximum; - } // Check for effects to remove if (partRequest.Effects?.Count > 0) { // Found some, loop over them and remove from pmc profile - foreach (var effect in partRequest.Effects) - { - pmcData.Health.BodyParts[bodyPartKvP.Key].Effects.Remove(effect); - } + foreach (var effect in partRequest.Effects) pmcData.Health.BodyParts[bodyPartKvP.Key].Effects.Remove(effect); // Remove empty effect object - if (pmcData.Health.BodyParts[bodyPartKvP.Key].Effects.Count == 0) - { - pmcData.Health.BodyParts[bodyPartKvP.Key].Effects = null; - } + if (pmcData.Health.BodyParts[bodyPartKvP.Key].Effects.Count == 0) pmcData.Health.BodyParts[bodyPartKvP.Key].Effects = null; } } diff --git a/Libraries/Core/Controllers/HideoutController.cs b/Libraries/Core/Controllers/HideoutController.cs index a85ea64b..a9b08277 100644 --- a/Libraries/Core/Controllers/HideoutController.cs +++ b/Libraries/Core/Controllers/HideoutController.cs @@ -46,7 +46,6 @@ public class HideoutController( ConfigServer _configServer ) { - protected HideoutConfig _hideoutConfig = _configServer.GetConfig(); public const string NameTaskConditionCountersCraftingId = "673f5d6fdd6ed700c703afdc"; protected List _hideoutAreas = @@ -54,9 +53,11 @@ public class HideoutController( HideoutAreas.AIR_FILTERING, HideoutAreas.WATER_COLLECTOR, HideoutAreas.GENERATOR, - HideoutAreas.BITCOIN_FARM, + HideoutAreas.BITCOIN_FARM ]; + protected HideoutConfig _hideoutConfig = _configServer.GetConfig(); + public void StartUpgrade(PmcData pmcData, HideoutUpgradeRequestData request, string sessionID, ItemEventRouterResponse output) { var items = request.Items.Select( @@ -87,13 +88,9 @@ public class HideoutController( item.inventoryItem.Upd.StackObjectsCount is not null && item.inventoryItem.Upd.StackObjectsCount > item.requestedItem.Count ) - { item.inventoryItem.Upd.StackObjectsCount -= item.requestedItem.Count; - } else - { _inventoryHelper.RemoveItem(pmcData, item.inventoryItem.Id, sessionID, output); - } } // Construction time management @@ -122,10 +119,7 @@ public class HideoutController( var ctime = hideoutDataDb.Stages[(profileHideoutArea.Level + 1).ToString()].ConstructionTime; if (ctime > 0) { - if (_profileHelper.IsDeveloperAccount(sessionID)) - { - ctime = 40; - } + if (_profileHelper.IsDeveloperAccount(sessionID)) ctime = 40; var timestamp = _timeUtil.GetTimeStamp(); @@ -168,16 +162,11 @@ public class HideoutController( var hideoutStage = hideoutData.Stages[profileHideoutArea.Level.ToString()]; var bonuses = hideoutStage.Bonuses; if (bonuses?.Count > 0) - { foreach (var bonus in bonuses) - { _hideoutHelper.ApplyPlayerUpgradesBonuses(pmcData, bonus); - } - } // Upgrade includes a container improvement/addition if (!string.IsNullOrEmpty(hideoutStage?.Container)) - { AddContainerImprovementToProfile( output, sessionID, @@ -186,22 +175,17 @@ public class HideoutController( hideoutData, hideoutStage ); - } // Upgrading water collector / med station if ( profileHideoutArea.Type == HideoutAreas.WATER_COLLECTOR || profileHideoutArea.Type == HideoutAreas.MEDSTATION ) - { SetWallVisibleIfPrereqsMet(pmcData); - } // Cleanup temporary buffs/debuffs from wall if complete if (profileHideoutArea.Type == HideoutAreas.EMERGENCY_WALL && profileHideoutArea.Level == 6) - { _hideoutHelper.RemoveHideoutWallBuffsAndDebuffs(hideoutData, pmcData); - } // Add Skill Points Per Area Upgrade _profileHelper.AddSkillPointsToPlayer( @@ -218,10 +202,7 @@ public class HideoutController( if (medStation?.Level >= 1 && waterCollector?.Level >= 1) { var wall = pmcData.Hideout.Areas.FirstOrDefault((area) => area.Type == HideoutAreas.EMERGENCY_WALL); - if (wall?.Level == 0) - { - wall.Level = 3; - } + if (wall?.Level == 0) wall.Level = 3; } } @@ -230,27 +211,21 @@ public class HideoutController( { // Add key/value to `hideoutAreaStashes` dictionary - used to link hideout area to inventory stash by its id if (!pmcData.Inventory.HideoutAreaStashes.ContainsKey(dbHideoutArea.Type.ToString())) - { pmcData.Inventory.HideoutAreaStashes[dbHideoutArea.Type.ToString()] = dbHideoutArea.Id; - } // Add/upgrade stash item in player inventory AddUpdateInventoryItemToProfile(sessionID, pmcData, dbHideoutArea, hideoutStage); // Edge case, add/update `stand1/stand2/stand3` children if (dbHideoutArea.Type == HideoutAreas.EQUIPMENT_PRESETS_STAND) - { // Can have multiple 'standx' children depending on upgrade level AddMissingPresetStandItemsToProfile(sessionID, hideoutStage, pmcData, dbHideoutArea, output); - } // Dont inform client when upgraded area is hall of fame or equipment stand, BSG doesn't inform client this specifc upgrade has occurred // will break client if sent List check = [HideoutAreas.PLACE_OF_FAME]; if (!check.Contains(dbHideoutArea.Type ?? HideoutAreas.NOTSET)) - { AddContainerUpgradeToClientOutput(sessionID, dbHideoutArea.Type, dbHideoutArea, hideoutStage, output); - } // Some hideout areas (Gun stand) have child areas linked to it var childDbArea = _databaseService @@ -260,9 +235,7 @@ public class HideoutController( { // Add key/value to `hideoutAreaStashes` dictionary - used to link hideout area to inventory stash by its id if (pmcData.Inventory.HideoutAreaStashes.GetValueOrDefault(childDbArea.Type.ToString()) is null) - { pmcData.Inventory.HideoutAreaStashes[childDbArea.Type.ToString()] = childDbArea.Id; - } // Set child area level to same as parent area pmcData.Hideout.Areas.FirstOrDefault((hideoutArea) => hideoutArea.Type == childDbArea.Type).Level = @@ -297,15 +270,13 @@ public class HideoutController( ItemEventRouterResponse output) { if (output.ProfileChanges[sessionID].ChangedHideoutStashes is null) - { output.ProfileChanges[sessionID].ChangedHideoutStashes = new Dictionary(); - } // Inform client of changes output.ProfileChanges[sessionID].ChangedHideoutStashes[areaType.ToString()] = new HideoutStashItem { Id = hideoutDbData.Id, - Template = hideoutStage.Container, + Template = hideoutStage.Container }; } @@ -370,7 +341,7 @@ public class HideoutController( Id = item.inventoryItem.Id, Template = item.inventoryItem.Template, Upd = item.inventoryItem.Upd - }, + } ]; _inventoryHelper.RemoveItem(pmcData, item.inventoryItem.Id, sessionID, output); @@ -445,15 +416,13 @@ public class HideoutController( ItemWithModsToAdd = [itemToReturn.ConvertToItem()], FoundInRaid = itemToReturn.Upd?.SpawnedInSession, Callback = null, - UseSortingTable = false, + UseSortingTable = false }; _inventoryHelper.AddItemToStash(sessionID, request, pmcData, output); if (output.Warnings?.Count > 0) - { // Adding to stash failed, drop out - don't remove item from hideout area slot return output; - } // Remove items from slot, locationIndex remains var hideoutSlotIndex = hideoutArea.Slots.FindIndex((slot) => slot.LocationIndex == slotIndexToRemove); @@ -510,18 +479,12 @@ public class HideoutController( // Handle tools not having a `count`, but always only requiring 1 var requiredCount = requirement.Count ?? 1; - if (requiredCount <= 0) - { - continue; - } + if (requiredCount <= 0) continue; _inventoryHelper.RemoveItemByCount(pmcData, itemToDelete.Id, requiredCount, sessionID, output); // Tools don't have a count - if (requirement.Type != "Tool") - { - requirement.Count -= (int)itemToDelete.Count; - } + if (requirement.Type != "Tool") requirement.Count -= (int)itemToDelete.Count; } return output; @@ -546,13 +509,9 @@ public class HideoutController( } if (inventoryItem.Upd?.StackObjectsCount is not null && inventoryItem.Upd.StackObjectsCount > requestedItem.Count) - { inventoryItem.Upd.StackObjectsCount -= requestedItem.Count; - } else - { _inventoryHelper.RemoveItem(pmcData, requestedItem.Id, sessionID, output); - } } var recipe = _databaseService.GetHideout().Production?.ScavRecipes?.FirstOrDefault(r => r.Id == body.RecipeId); @@ -592,10 +551,7 @@ public class HideoutController( private double? GetScavCaseTime(PmcData pmcData, double? productionTime) { var fenceLevel = _fenceService.GetFenceInfo(pmcData); - if (fenceLevel is null) - { - return productionTime; - } + if (fenceLevel is null) return productionTime; return productionTime * fenceLevel.ScavCaseTimeModifier; } @@ -661,10 +617,7 @@ public class HideoutController( foreach (var production in productionDict) { // Skip undefined production objects - if (production.Value is null) - { - continue; - } + if (production.Value is null) continue; // Production or ScavCase if (production.Value.RecipeId == request.RecipeId) @@ -723,11 +676,11 @@ public class HideoutController( if (rewardIsStackable ?? false) { // Create root item - Item rewardToAdd = new Item + var rewardToAdd = new Item { Id = _hashUtil.Generate(), Template = recipe.EndProduct, - Upd = new Upd { StackObjectsCount = recipe.Count }, + Upd = new Upd { StackObjectsCount = recipe.Count } }; // Split item into separate items with acceptable stack sizes @@ -739,50 +692,39 @@ public class HideoutController( // Not stackable, may have to send send multiple of reward // Add the first reward item to array when not a preset (first preset added above earlier) - if (!rewardIsPreset) - { - itemAndChildrenToSendToPlayer.Add([new Item { Id = _hashUtil.Generate(), Template = recipe.EndProduct }]); - } + if (!rewardIsPreset) itemAndChildrenToSendToPlayer.Add([new Item { Id = _hashUtil.Generate(), Template = recipe.EndProduct }]); // Add multiple of item if recipe requests it // Start index at one so we ignore first item in array var countOfItemsToReward = recipe.Count; for (var index = 1; index < countOfItemsToReward; index++) { - List itemAndMods = _itemHelper.ReplaceIDs(_cloner.Clone(itemAndChildrenToSendToPlayer.FirstOrDefault())); + var itemAndMods = _itemHelper.ReplaceIDs(_cloner.Clone(itemAndChildrenToSendToPlayer.FirstOrDefault())); itemAndChildrenToSendToPlayer.AddRange([itemAndMods]); } } // Recipe has an `isEncoded` requirement for reward(s), Add `RecodableComponent` property if (recipe.IsEncoded ?? false) - { foreach (var reward in itemAndChildrenToSendToPlayer) { _itemHelper.AddUpdObjectToItem(reward.FirstOrDefault()); reward.FirstOrDefault().Upd.RecodableComponent = new UpdRecodableComponent { IsEncoded = true }; } - } // Build an array of the tools that need to be returned to the player List> toolsToSendToPlayer = []; var hideoutProduction = pmcData.Hideout.Production[prodId]; if (hideoutProduction.SptRequiredTools?.Count > 0) - { foreach (var tool in hideoutProduction.SptRequiredTools) - { toolsToSendToPlayer.Add([tool]); - } - } // Check if the recipe is the same as the last one - get bonus when crafting same thing multiple times var area = pmcData.Hideout.Areas.FirstOrDefault(area => area.Type == recipe.AreaType); if (area is not null && request.RecipeId != area.LastRecipe) - { // 1 point per craft upon the end of production for alternating between 2 different crafting recipes in the same module craftingExpAmount += _hideoutConfig.ExpCraftAmount; // Default is 10 - } // Update variable with time spent crafting item(s) // 1 point per 8 hours of crafting @@ -814,34 +756,28 @@ public class HideoutController( foreach (var toolItem in toolsToSendToPlayer) { // Note: FIR state will be based on the first item's SpawnedInSession property per item group - AddItemsDirectRequest addToolsRequest = new AddItemsDirectRequest + var addToolsRequest = new AddItemsDirectRequest { ItemsWithModsToAdd = [toolItem], FoundInRaid = toolItem[0].Upd?.SpawnedInSession ?? false, UseSortingTable = false, - Callback = null, + Callback = null }; _inventoryHelper.AddItemsToStash(sessionID, addToolsRequest, pmcData, output); - if (output.Warnings?.Count > 0) - { - return; - } + if (output.Warnings?.Count > 0) return; } // Add the crafting result to the stash, marked as FiR - AddItemsDirectRequest addItemsRequest = new AddItemsDirectRequest + var addItemsRequest = new AddItemsDirectRequest { ItemsWithModsToAdd = itemAndChildrenToSendToPlayer, FoundInRaid = true, UseSortingTable = false, - Callback = null, + Callback = null }; _inventoryHelper.AddItemsToStash(sessionID, addItemsRequest, pmcData, output); - if (output.Warnings?.Count > 0) - { - return; - } + if (output.Warnings?.Count > 0) return; // - increment skill point for crafting // - delete the production in profile Hideout.Production @@ -861,10 +797,7 @@ public class HideoutController( _profileHelper.AddSkillPointsToPlayer(pmcData, SkillTypes.Crafting, craftingExpAmount); var intellectAmountToGive = 0.5 * Math.Round((double)(craftingExpAmount / 15)); - if (intellectAmountToGive > 0) - { - _profileHelper.AddSkillPointsToPlayer(pmcData, SkillTypes.Intellect, intellectAmountToGive); - } + if (intellectAmountToGive > 0) _profileHelper.AddSkillPointsToPlayer(pmcData, SkillTypes.Intellect, intellectAmountToGive); } area.LastRecipe = request.RecipeId; @@ -879,36 +812,29 @@ public class HideoutController( // Continious recipies need the craft time refreshed as it gets created once on initial craft and stays the same regardless of what // production.json is set to if (recipe.Continuous ?? false) - { pmcData.Hideout.Production[prodId].ProductionTime = _hideoutHelper.GetAdjustedCraftTimeWithSkills( pmcData, recipe.Id, true ); - } // Flag normal (non continious) crafts as complete - if (!recipe.Continuous ?? false) - { - pmcData.Hideout.Production[prodId].InProgress = false; - } + if (!recipe.Continuous ?? false) pmcData.Hideout.Production[prodId].InProgress = false; } private TaskConditionCounter GetHoursCraftingTaskConditionCounter(PmcData pmcData, HideoutProduction recipe) { - if (!pmcData.TaskConditionCounters.TryGetValue(HideoutController.NameTaskConditionCountersCraftingId, out var _)) - { + if (!pmcData.TaskConditionCounters.TryGetValue(NameTaskConditionCountersCraftingId, out _)) // Doesn't exist, create - pmcData.TaskConditionCounters[HideoutController.NameTaskConditionCountersCraftingId] = new TaskConditionCounter + pmcData.TaskConditionCounters[NameTaskConditionCountersCraftingId] = new TaskConditionCounter { Id = recipe.Id, - Type = HideoutController.NameTaskConditionCountersCraftingId, + Type = NameTaskConditionCountersCraftingId, SourceId = "CounterCrafting", - Value = 0, + Value = 0 }; - } - return pmcData.TaskConditionCounters[HideoutController.NameTaskConditionCountersCraftingId]; + return pmcData.TaskConditionCounters[NameTaskConditionCountersCraftingId]; } private void HandleScavCase(string sessionID, PmcData pmcData, HideoutTakeProductionRequestData request, ItemEventRouterResponse output) @@ -916,14 +842,12 @@ public class HideoutController( var ongoingProductions = pmcData.Hideout.Production; string? prodId = null; foreach (var production in ongoingProductions) - { // Production or ScavCase - if ((production.Value).RecipeId == request.RecipeId) + if (production.Value.RecipeId == request.RecipeId) { prodId = production.Key; // Set to objects key break; } - } if (prodId == null) { @@ -942,19 +866,16 @@ public class HideoutController( // Create rewards for scav case var scavCaseRewards = _scavCaseRewardGenerator.Generate(request.RecipeId); - AddItemsDirectRequest addItemsRequest = new AddItemsDirectRequest + var addItemsRequest = new AddItemsDirectRequest { ItemsWithModsToAdd = scavCaseRewards, FoundInRaid = true, Callback = null, - UseSortingTable = false, + UseSortingTable = false }; _inventoryHelper.AddItemsToStash(sessionID, addItemsRequest, pmcData, output); - if (output.Warnings?.Count > 0) - { - return; - } + if (output.Warnings?.Count > 0) return; // Remove the old production from output object before its sent to client output.ProfileChanges[sessionID].Production.Remove(request.RecipeId); @@ -981,7 +902,6 @@ public class HideoutController( var qteDb = _databaseService.GetHideout().Qte; var relevantQte = qteDb.FirstOrDefault(qte => qte.Id == request.Id); foreach (var outcome in request.Results) - { if (outcome) { // Success @@ -994,17 +914,10 @@ public class HideoutController( pmcData.Health.Energy.Current += relevantQte.Results[QteEffectType.singleFailEffect].Energy; pmcData.Health.Hydration.Current += relevantQte.Results[QteEffectType.singleFailEffect].Hydration; } - } - if (pmcData.Health.Energy.Current < 1) - { - pmcData.Health.Energy.Current = 1; - } + if (pmcData.Health.Energy.Current < 1) pmcData.Health.Energy.Current = 1; - if (pmcData.Health.Hydration.Current < 1) - { - pmcData.Health.Hydration.Current = 1; - } + if (pmcData.Health.Hydration.Current < 1) pmcData.Health.Hydration.Current = 1; HandleMusclePain(pmcData, relevantQte.Results[QteEffectType.finishEffect]); } @@ -1021,7 +934,7 @@ public class HideoutController( pmcData.Health.BodyParts["Chest"].Effects ??= new Dictionary(); pmcData.Health.BodyParts["Chest"].Effects["MildMusclePain"] = new BodyPartEffectProperties { - Time = finishEffect.RewardEffects.FirstOrDefault().Time, // TODO - remove hard coded access, get value properly + Time = finishEffect.RewardEffects.FirstOrDefault().Time // TODO - remove hard coded access, get value properly }; return; @@ -1034,7 +947,7 @@ public class HideoutController( pmcData.Health.BodyParts["Chest"].Effects["SevereMusclePain"] = new BodyPartEffectProperties { - Time = finishEffect.RewardEffects.FirstOrDefault().Time, + Time = finishEffect.RewardEffects.FirstOrDefault().Time }; } } @@ -1086,13 +999,9 @@ public class HideoutController( item.inventoryItem.Upd.StackObjectsCount is not null && item.inventoryItem.Upd.StackObjectsCount > item.requestedItem.Count ) - { item.inventoryItem.Upd.StackObjectsCount -= item.requestedItem.Count; - } else - { _inventoryHelper.RemoveItem(pmcData, item.inventoryItem.Id, sessionId, output); - } } var profileHideoutArea = pmcData.Hideout.Areas.FirstOrDefault(x => x.Type == request.AreaType); @@ -1115,17 +1024,14 @@ public class HideoutController( var improvements = hideoutDbData.Stages[profileHideoutArea.Level.ToString()].Improvements; var timestamp = _timeUtil.GetTimeStamp(); - if (output.ProfileChanges[sessionId].Improvements is null) - { - output.ProfileChanges[sessionId].Improvements = new Dictionary(); - } + if (output.ProfileChanges[sessionId].Improvements is null) output.ProfileChanges[sessionId].Improvements = new Dictionary(); foreach (var improvement in improvements) { var improvementDetails = new HideoutImprovement { Completed = false, - ImproveCompleteTimestamp = (long)(timestamp + improvement.ImprovementTime), + ImproveCompleteTimestamp = (long)(timestamp + improvement.ImprovementTime) }; output.ProfileChanges[sessionId].Improvements[improvement.Id] = improvementDetails; @@ -1232,7 +1138,7 @@ public class HideoutController( Id = standId, Template = ItemTpl.INVENTORY_DEFAULT, ParentId = equipmentPresetHideoutArea.Id, - SlotId = mannequinSlot.Name, + SlotId = mannequinSlot.Name }; pmcData.Inventory.Items.Add(mannequinToAdd); @@ -1245,7 +1151,7 @@ public class HideoutController( ) .Template, // Same pocket tpl as players profile (unheard get bigger, matching pockets etc) ParentId = standId, - SlotId = "Pockets", + SlotId = "Pockets" }; pmcData.Inventory.Items.Add(mannequinPocketItemToAdd); output.ProfileChanges[sessionId].Items.NewItems.Add(mannequinToAdd); @@ -1290,16 +1196,12 @@ public class HideoutController( public void Update() { foreach (var sessionID in _saveServer.GetProfiles()) - { if (sessionID.Value.CharacterData.PmcData.Hideout is not null && _profileActivityService.ActiveWithinLastMinutes( sessionID.Key, _hideoutConfig.UpdateProfileHideoutWhenActiveWithinMinutes ) ) - { _hideoutHelper.UpdatePlayerHideout(sessionID.Key); - } - } } } diff --git a/Libraries/Core/Controllers/InRaidController.cs b/Libraries/Core/Controllers/InRaidController.cs index 26e77c28..4260352d 100644 --- a/Libraries/Core/Controllers/InRaidController.cs +++ b/Libraries/Core/Controllers/InRaidController.cs @@ -16,8 +16,8 @@ public class InRaidController( ConfigServer _configServer ) { - protected InRaidConfig _inRaidConfig = _configServer.GetConfig(); protected BotConfig _botConfig = _configServer.GetConfig(); + protected InRaidConfig _inRaidConfig = _configServer.GetConfig(); /// /// Save locationId to active profiles in-raid object AND app context @@ -43,9 +43,7 @@ public class InRaidController( // If equipment match overwrite existing data from update to date raid data for scavenger screen to work correctly. // otherwise Scav inventory will be overwritten and break scav regeneration, breaking profile. if (serverScavProfile.Inventory.Equipment == offRaidProfileData.Inventory.Equipment) - { serverScavProfile.Inventory.Items = offRaidProfileData.Inventory.Items; - } } /// diff --git a/Libraries/Core/Controllers/InsuranceController.cs b/Libraries/Core/Controllers/InsuranceController.cs index 439c6c25..d877f04e 100644 --- a/Libraries/Core/Controllers/InsuranceController.cs +++ b/Libraries/Core/Controllers/InsuranceController.cs @@ -86,12 +86,8 @@ public class InsuranceController( var profileInsuranceDetails = _saveServer.GetProfile(sessionId).InsuranceList; if (profileInsuranceDetails.Count > 0) - { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Found {profileInsuranceDetails.Count} insurance packages in profile {sessionId}"); - } - } return profileInsuranceDetails.Where(insured => insuranceTime >= insured.ScheduledTime).ToList(); } @@ -105,12 +101,10 @@ public class InsuranceController( */ protected void ProcessInsuredItems(List insuranceDetails, string sessionId) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug( $"Processing {insuranceDetails.Count} insurance packages, which includes a total of: {CountAllInsuranceItems(insuranceDetails)} items, in profile: {sessionId}" ); - } // Iterate over each of the insurance packages. foreach (var insured in insuranceDetails) @@ -170,10 +164,7 @@ public class InsuranceController( ) .ToList(); - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Removed processed insurance package. Remaining packages: {profile.InsuranceList.Count}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Removed processed insurance package. Remaining packages: {profile.InsuranceList.Count}"); } /** @@ -198,10 +189,7 @@ public class InsuranceController( ); // Process all items that are not attached, attachments; those are handled separately, by value. - if (hasRegularItems) - { - ProcessRegularItems(insured, toDelete, parentAttachmentsMap); - } + if (hasRegularItems) ProcessRegularItems(insured, toDelete, parentAttachmentsMap); // Process attached, attachments, by value, only if there are any. if (parentAttachmentsMap.Count > 0) @@ -215,12 +203,8 @@ public class InsuranceController( // Log the number of items marked for deletion, if any if (!toDelete.Any()) - { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Marked {toDelete.Count} items for deletion from insurance."); - } - } return toDelete; } @@ -253,7 +237,7 @@ public class InsuranceController( { insuredItemId = insuredItem.Id, insuredItemTpl = insuredItem.Template, - parentId = insuredItem.ParentId, + parentId = insuredItem.ParentId } ) ); @@ -273,7 +257,7 @@ public class InsuranceController( new { insuredItemId = insuredItem.Id, - insuredItemTpl = insuredItem.Template, + insuredItemTpl = insuredItem.Template } ) ); @@ -293,7 +277,7 @@ public class InsuranceController( { insuredItemId = insuredItem.Id, insuredItemTpl = insuredItem.Template, - parentId = insuredItem.ParentId, + parentId = insuredItem.ParentId } ) ); @@ -304,10 +288,7 @@ public class InsuranceController( // Update (or add to) the main-parent to attachments map. if (mainParentToAttachmentsMap.ContainsKey(mainParent.Id)) { - if (mainParentToAttachmentsMap.TryGetValue(mainParent.Id, out var parent)) - { - parent.Add(insuredItem); - } + if (mainParentToAttachmentsMap.TryGetValue(mainParent.Id, out var parent)) parent.Add(insuredItem); } else { @@ -344,24 +325,14 @@ public class InsuranceController( // attachment on the main-parent. For example, if the attachment is a stock, we need to check to see if // it's moddable in the upper receiver (attachment/parent), which is attached to the gun (main-parent). if (attachment.ParentId is not null) - { if (itemsMap.TryGetValue(attachment.ParentId, out var directParentItem)) - { attachmentParentItem = directParentItem; - } - } - if (_itemHelper.IsRaidModdable(attachment, attachmentParentItem) ?? false) - { - moddableAttachments.Add(attachment); - } + if (_itemHelper.IsRaidModdable(attachment, attachmentParentItem) ?? false) moddableAttachments.Add(attachment); } // If any moddable attachments remain, add them to the updated map. - if (moddableAttachments.Count > 0) - { - updatedMap.TryAdd(map.Key, moddableAttachments); - } + if (moddableAttachments.Count > 0) updatedMap.TryAdd(map.Key, moddableAttachments); } return updatedMap; @@ -382,10 +353,7 @@ public class InsuranceController( foreach (var insuredItem in insured.Items) { // Skip if the item is an attachment. These are handled separately. - if (_itemHelper.IsAttachmentAttached(insuredItem)) - { - continue; - } + if (_itemHelper.IsAttachmentAttached(insuredItem)) continue; // Roll for item deletion var itemRoll = RollForDelete(insured.TraderId, insuredItem); @@ -401,10 +369,7 @@ public class InsuranceController( insured.Items, insuredItem.Id ); - foreach (var item in itemAndChildren) - { - toDelete.Add(item.Id); - } + foreach (var item in itemAndChildren) toDelete.Add(item.Id); // Remove the parent (and its children) from the parentAttachmentsMap. parentAttachmentsMap.Remove(insuredItem.Id); @@ -433,18 +398,12 @@ public class InsuranceController( { // Skip processing if parentId is already marked for deletion, as all attachments for that parent will // already be marked for deletion as well. - if (toDelete.Contains(parentObj.Key)) - { - continue; - } + if (toDelete.Contains(parentObj.Key)) continue; // Log the parent item's name. itemsMap.TryGetValue(parentObj.Key, out var parentItem); var parentName = _itemHelper.GetItemName(parentItem.Template); - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Processing attachments of parent {parentName}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Processing attachments of parent {parentName}"); // Process the attachments for this individual parent item. ProcessAttachmentByParent(parentObj.Value, insuredTraderId, toDelete); @@ -473,25 +432,17 @@ public class InsuranceController( // Create prob array and add all attachments with rouble price as the weight var attachmentsProbabilityArray = new ProbabilityObjectArray(_mathUtil, _cloner); foreach (var attachmentTpl in weightedAttachmentByPrice) - { attachmentsProbabilityArray.Add( new ProbabilityObject(attachmentTpl.Key, attachmentTpl.Value, null) ); - } // Draw x attachments from weighted array to remove from parent, remove from pool after being picked var attachmentIdsToRemove = attachmentsProbabilityArray.Draw((int)countOfAttachmentsToRemove, false); - foreach (var attachmentId in attachmentIdsToRemove) - { - toDelete.Add(attachmentId); - } + foreach (var attachmentId in attachmentIdsToRemove) toDelete.Add(attachmentId); LogAttachmentsBeingRemoved(attachmentIdsToRemove, attachments, weightedAttachmentByPrice); - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Number of attachments to be deleted: {attachmentIdsToRemove.Count}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Number of attachments to be deleted: {attachmentIdsToRemove.Count}"); } private void LogAttachmentsBeingRemoved(List attachmentIdsToRemove, List attachments, Dictionary attachmentPrices) @@ -500,12 +451,10 @@ public class InsuranceController( foreach (var attachmentId in attachmentIdsToRemove) { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug( $"Attachment {index} Id: {attachmentId} Tpl: {attachments.FirstOrDefault((x) => x.Id == attachmentId)?.Template} - " + $"Price: {attachmentPrices[attachmentId]}" ); - } index++; } } @@ -518,10 +467,7 @@ public class InsuranceController( foreach (var attachment in attachments) { var price = _ragfairPriceService.GetDynamicItemPrice(attachment.Template, Money.ROUBLES); - if (price is not null) - { - result[attachment.Id] = Math.Round(price ?? 0); - } + if (price is not null) result[attachment.Id] = Math.Round(price ?? 0); } _weightedRandomHelper.ReduceWeightValues(result); @@ -533,10 +479,7 @@ public class InsuranceController( { var removeCount = 0; - if (_randomUtil.GetChance100(_insuranceConfig.ChanceNoAttachmentsTakenPercent)) - { - return removeCount; - } + if (_randomUtil.GetChance100(_insuranceConfig.ChanceNoAttachmentsTakenPercent)) return removeCount; // Get attachments count above or equal to price set in config return weightedAttachmentByPrice @@ -564,19 +507,13 @@ public class InsuranceController( // Map is labs + insurance is disabled in base.json if (IsMapLabsAndInsuranceDisabled(insurance)) - { // Trader has labs-specific messages // Wipe out returnable items HandleLabsInsurance(traderDialogMessages, insurance); - } else if (insurance.Items?.Count == 0) - { // Not labs and no items to return if (traderDialogMessages.TryGetValue("insuranceFailed", out var insuranceFailedTemplates)) - { insurance.MessageTemplateId = _randomUtil.GetArrayValue(insuranceFailedTemplates); - } - } // Send the insurance message _mailSendService.SendLocalisedNpcMessageToPlayer( @@ -592,9 +529,8 @@ public class InsuranceController( private bool IsMapLabsAndInsuranceDisabled(Insurance insurance, string labsId = "laboratory") { - return (insurance.SystemData?.Location?.ToLower() == labsId - && !(_databaseService.GetLocation(labsId)?.Base?.Insurance.GetValueOrDefault(false) ?? false) - ); + return insurance.SystemData?.Location?.ToLower() == labsId && + !(_databaseService.GetLocation(labsId)?.Base?.Insurance.GetValueOrDefault(false) ?? false); } /** @@ -618,10 +554,7 @@ public class InsuranceController( private bool? RollForDelete(string traderId, Item? insuredItem = null) { var trader = _traderHelper.GetTraderById(traderId); - if (trader is null) - { - return null; - } + if (trader is null) return null; const int maxRoll = 9999; const int conversionFactor = 100; @@ -633,10 +566,8 @@ public class InsuranceController( // Log the roll with as much detail as possible. var itemName = insuredItem is not null ? $"{_itemHelper.GetItemName(insuredItem.Template)}" : ""; var status = roll ? "Delete" : "Keep"; - if(_logger.IsLogEnabled(LogLevel.Debug)) - { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Rolling {itemName} with {trader} - Return {traderReturnChance}% - Roll: {returnChance} - Status: {status}"); - } return roll; } @@ -661,7 +592,6 @@ public class InsuranceController( // Get price of all items being insured, add to 'itemsToPay' foreach (var key in body.Items) - { itemsToPay.Add( new IdWithCount { @@ -673,7 +603,6 @@ public class InsuranceController( ) } ); - } var options = new ProcessBuyTradeRequestData { @@ -688,10 +617,7 @@ public class InsuranceController( // pay for the item insurance _paymentService.PayMoney(pmcData, options, sessionId, output); - if (output.Warnings?.Count > 0) - { - return output; - } + if (output.Warnings?.Count > 0) return output; // add items to InsuredItems list once money has been paid pmcData.InsuredItems ??= []; @@ -699,10 +625,7 @@ public class InsuranceController( { pmcData.InsuredItems.Add(new InsuredItem { TId = body.TransactionId, ItemId = inventoryItemsHash[key].Id }); // If Item is Helmet or Body Armour -> Handle insurance of soft inserts - if (_itemHelper.ArmorItemHasRemovableOrSoftInsertSlots(inventoryItemsHash[key].Template)) - { - InsureSoftInserts(inventoryItemsHash[key], pmcData, body); - } + if (_itemHelper.ArmorItemHasRemovableOrSoftInsertSlots(inventoryItemsHash[key].Template)) InsureSoftInserts(inventoryItemsHash[key], pmcData, body); } _profileHelper.AddSkillPointsToPlayer(pmcData, SkillTypes.Charisma, itemsToInsureCount * 0.01); @@ -726,11 +649,8 @@ public class InsuranceController( foreach (var softInsertSlot in softInsertSlots) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"SoftInsertSlots: {softInsertSlot.SlotId}"); - } - + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"SoftInsertSlots: {softInsertSlot.SlotId}"); + pmcData.InsuredItems.Add(new InsuredItem { TId = body.TransactionId, ItemId = softInsertSlot.Id }); } } @@ -761,10 +681,7 @@ public class InsuranceController( // Ensure hash has item in it if (!inventoryItemsHash.ContainsKey(itemId)) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Item with id: {itemId} missing from player inventory, skipping"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Item with id: {itemId} missing from player inventory, skipping"); continue; } diff --git a/Libraries/Core/Controllers/InventoryController.cs b/Libraries/Core/Controllers/InventoryController.cs index 132f4861..69664b58 100644 --- a/Libraries/Core/Controllers/InventoryController.cs +++ b/Libraries/Core/Controllers/InventoryController.cs @@ -83,9 +83,7 @@ public class InventoryController( // Item is moving into or out of place of fame dog tag slot if (moveRequest.To?.Container != null && (moveRequest.To.Container.StartsWith("dogtag") || originalLocationSlotId.StartsWith("dogtag"))) - { _hideoutHelper.ApplyPlaceOfFameDogtagBonus(pmcData); - } } else { @@ -155,7 +153,7 @@ public class InventoryController( _logger.Success($"Set trader {mailEvent.Entity}: Standing to: {mailEvent.Value}"); break; case ProfileChangeEventType.ProfileLevel: - pmcData.Info.Experience = (int) mailEvent.Value.Value; + pmcData.Info.Experience = (int)mailEvent.Value.Value; // Will calculate level below _traderHelper.ValidateTraderStandingsAndPlayerLevelForProfile(sessionId); _logger.Success($"Set profile xp to: {mailEvent.Value}"); @@ -347,23 +345,16 @@ public class InventoryController( inventoryItem.ParentId = change.ParentId; inventoryItem.SlotId = change.SlotId; if (change.Location is not null) - { inventoryItem.Location = change.Location; - } else - { inventoryItem.Location = null; - } } } public ItemEventRouterResponse ReadEncyclopedia(PmcData pmcData, InventoryReadEncyclopediaRequestData body, string sessionId) { - foreach (var id in body.Ids) - { - pmcData.Encyclopedia[id] = true; - } + foreach (var id in body.Ids) pmcData.Encyclopedia[id] = true; return _eventOutputHolder.GetOutput(sessionId); } @@ -373,7 +364,6 @@ public class InventoryController( { string? itemId = null; if (request.FromOwner is not null) - { try { itemId = GetExaminedItemTpl(request, sessionId); @@ -382,25 +372,17 @@ public class InventoryController( { _logger.Error(_localisationService.GetText("inventory-examine_item_does_not_exist", request.Item)); } - } if (itemId is null) - { // item template if (_databaseService.GetItems().ContainsKey(request.Item)) - { itemId = request.Item; - } - } if (itemId is null) { // Player inventory var target = pmcData.Inventory.Items.FirstOrDefault(item => item.Id == request.Item); - if (target is not null) - { - itemId = target.Template; - } + if (target is not null) itemId = target.Template; } if (itemId is not null) @@ -415,29 +397,22 @@ public class InventoryController( if (_presetHelper.IsPreset(request.Item)) return _presetHelper.GetBaseItemTpl(request.Item); if (request.FromOwner.Id == Traders.FENCE) - { // Get tpl from fence assorts return _fenceService.GetRawFenceAssorts().Items.FirstOrDefault(x => x.Id == request.Item)?.Template; - } if (request.FromOwner.Type == "Trader") - { // Not fence // get tpl from trader assort return _databaseService .GetTrader(request.FromOwner.Id) .Assort.Items.FirstOrDefault(item => item.Id == request.Item) ?.Template; - } if (request.FromOwner.Type == "RagFair") { // Try to get tplId from items.json first var item = _itemHelper.GetItem(request.Item); - if (item.Key) - { - return item.Value.Id; - } + if (item.Key) return item.Value.Id; // Try alternate way of getting offer if first approach fails var offer = _ragfairOfferService.GetOfferByOfferId(request.Item) ?? @@ -445,20 +420,14 @@ public class InventoryController( // Try find examine item inside offer items array var matchingItem = offer.Items.FirstOrDefault(offerItem => offerItem.Id == request.Item); - if (matchingItem is not null) - { - return matchingItem.Template; - } + if (matchingItem is not null) return matchingItem.Template; // Unable to find item in database or ragfair _logger.Warning(_localisationService.GetText("inventory-unable_to_find_item", request.Item)); } - + // get hideout item - if (request.FromOwner.Type == "HideoutProduction") - { - return request.Item; - } + if (request.FromOwner.Type == "HideoutProduction") return request.Item; if (request.FromOwner.Type == "Mail") { @@ -472,10 +441,7 @@ public class InventoryController( // get the Id given and get the Template ID from that var item = message.Items.Data.FirstOrDefault(item => item.Id == request.Item); - if (item is not null) - { - return item.Template; - } + if (item is not null) return item.Template; } _logger.Error($"Unable to get item with id: {request.Item}"); @@ -559,10 +525,7 @@ public class InventoryController( var playerData = pmcData; // We may be folding data on scav profile, get that profile instead - if (request.FromOwner?.Type == "Profile" && request.FromOwner.Id != playerData.Id) - { - playerData = _profileHelper.GetScavProfile(sessionId); - } + if (request.FromOwner?.Type == "Profile" && request.FromOwner.Id != playerData.Id) playerData = _profileHelper.GetScavProfile(sessionId); var itemToFold = playerData.Inventory.Items.FirstOrDefault(item => item?.Id == request.Item); if (itemToFold is null) @@ -592,10 +555,7 @@ public class InventoryController( { // During post-raid scav transfer, the swap may be in the scav inventory var playerData = pmcData; - if (request.FromOwner?.Type == "Profile" && request.FromOwner.Id != playerData.Id) - { - playerData = _profileHelper.GetScavProfile(sessionId); - } + if (request.FromOwner?.Type == "Profile" && request.FromOwner.Id != playerData.Id) playerData = _profileHelper.GetScavProfile(sessionId); var itemOne = playerData.Inventory.Items.FirstOrDefault(x => x.Id == request.Item); if (itemOne is null) @@ -631,24 +591,16 @@ public class InventoryController( // Request object has location data, add it in, otherwise remove existing location from object if (request.To.Location is not null) - { itemOne.Location = request.To.Location; - } else - { itemOne.Location = null; - } itemTwo.ParentId = request.To2.Id; itemTwo.SlotId = request.To2.Container; if (request.To2.Location is not null) - { itemTwo.Location = request.To2.Location; - } else - { itemTwo.Location = null; - } // Client already informed of inventory locations, nothing for us to do return _eventOutputHolder.GetOutput(sessionId); @@ -696,15 +648,11 @@ public class InventoryController( var sourceStackCount = sourceItem.Upd.StackObjectsCount; if (sourceStackCount > request.Count) - { // Source items stack count greater than new desired count sourceItem.Upd.StackObjectsCount = sourceStackCount - request.Count; - } else - { // Moving a full stack onto a smaller stack sourceItem.Upd.StackObjectsCount = sourceStackCount - 1; - } destinationItem.Upd ??= new Upd { StackObjectsCount = 1 }; @@ -743,27 +691,19 @@ public class InventoryController( } if (destinationItem.Upd?.StackObjectsCount is null) - { // No stackcount on destination, add one destinationItem.Upd = new Upd { StackObjectsCount = 1 }; - } if (sourceItem.Upd is null) - { sourceItem.Upd = new Upd { StackObjectsCount = 1 }; - } else if (sourceItem.Upd.StackObjectsCount is null) - { // Items pulled out of raid can have no stack count if the stack should be 1 sourceItem.Upd.StackObjectsCount = 1; - } // Remove FiR status from destination stack when source stack has no FiR but destination does if (!sourceItem.Upd.SpawnedInSession.GetValueOrDefault(false) && destinationItem.Upd.SpawnedInSession.GetValueOrDefault(false)) - { destinationItem.Upd.SpawnedInSession = false; - } destinationItem.Upd.StackObjectsCount += sourceItem.Upd.StackObjectsCount; // Add source stackcount to destination diff --git a/Libraries/Core/Controllers/LauncherController.cs b/Libraries/Core/Controllers/LauncherController.cs index 6f741e1c..d29b6296 100644 --- a/Libraries/Core/Controllers/LauncherController.cs +++ b/Libraries/Core/Controllers/LauncherController.cs @@ -45,7 +45,7 @@ public class LauncherController( BackendUrl = _httpServerHelper.GetBackendUrl(), Name = _coreConfig.ServerName, Editions = profiles, - ProfileDescriptions = GetProfileDescriptions(), + ProfileDescriptions = GetProfileDescriptions() }; } @@ -83,10 +83,7 @@ public class LauncherController( foreach (var kvp in _saveServer.GetProfiles()) { var account = _saveServer.GetProfile(kvp.Key).ProfileInfo; - if (info?.Username == account?.Username) - { - return kvp.Key; - } + if (info?.Username == account?.Username) return kvp.Key; } return null; @@ -95,12 +92,8 @@ public class LauncherController( public string Register(RegisterData info) { foreach (var kvp in _saveServer.GetProfiles()) - { if (info.Username == _saveServer.GetProfile(kvp.Key).ProfileInfo?.Username) - { return ""; - } - } return CreateAccount(info); } @@ -117,7 +110,7 @@ public class LauncherController( Username = info.Username, Password = info.Password, IsWiped = true, - Edition = info.Edition, + Edition = info.Edition }; _saveServer.CreateProfile(newProfileDetails); @@ -146,10 +139,7 @@ public class LauncherController( { var sessionID = Login(info); - if (!string.IsNullOrEmpty(sessionID)) - { - _saveServer.GetProfile(sessionID).ProfileInfo!.Username = info.Change; - } + if (!string.IsNullOrEmpty(sessionID)) _saveServer.GetProfile(sessionID).ProfileInfo!.Username = info.Change; return sessionID; } @@ -158,10 +148,7 @@ public class LauncherController( { var sessionID = Login(info); - if (!string.IsNullOrEmpty(sessionID)) - { - _saveServer.GetProfile(sessionID).ProfileInfo!.Password = info.Change; - } + if (!string.IsNullOrEmpty(sessionID)) _saveServer.GetProfile(sessionID).ProfileInfo!.Password = info.Change; return sessionID; } @@ -173,10 +160,7 @@ public class LauncherController( */ public string? Wipe(RegisterData info) { - if (!_coreConfig.AllowProfileWipe) - { - return null; - } + if (!_coreConfig.AllowProfileWipe) return null; var sessionID = Login(info); diff --git a/Libraries/Core/Controllers/LauncherV2Controller.cs b/Libraries/Core/Controllers/LauncherV2Controller.cs index e30c70dd..e4afb813 100644 --- a/Libraries/Core/Controllers/LauncherV2Controller.cs +++ b/Libraries/Core/Controllers/LauncherV2Controller.cs @@ -58,7 +58,7 @@ public class LauncherV2Controller( var casterPropertyValue = propertyValue as ProfileSides; result[templatesProperty.GetJsonName()] = _localisationService.GetText(casterPropertyValue?.DescriptionLocaleKey!); } - + return result; } @@ -82,12 +82,8 @@ public class LauncherV2Controller( public bool Register(RegisterData info) { foreach (var session in _saveServer.GetProfiles()) - { if (info.Username == _saveServer.GetProfile(session.Key).ProfileInfo!.Username) - { return false; - } - } CreateAccount(info); return true; @@ -104,7 +100,7 @@ public class LauncherV2Controller( if (sessionId is null) return false; - + _saveServer.GetProfile(sessionId).ProfileInfo!.Password = info.Password; return true; } @@ -117,7 +113,7 @@ public class LauncherV2Controller( public bool Remove(LoginRequestData info) { var sessionId = GetSessionId(info); - + return sessionId is not null && _saveServer.RemoveProfile(sessionId); } @@ -169,22 +165,22 @@ public class LauncherV2Controller( IsWiped = true, Edition = info.Edition }; - + _saveServer.CreateProfile(newProfileDetails); - + _saveServer.LoadProfile(profileId); _saveServer.SaveProfile(profileId); - + return profileId; } - + protected string GenerateProfileId() { var timestamp = _timeUtil.GetTimeStamp(); return FormatID(timestamp, timestamp * _randomUtil.GetInt(1, 1000000)); } - + protected string FormatID(long timeStamp, long counter) { var timeStampStr = Convert.ToString(timeStamp, 16).PadLeft(8, '0'); @@ -196,13 +192,8 @@ public class LauncherV2Controller( protected string? GetSessionId(LoginRequestData info) { foreach (var profile in _saveServer.GetProfiles()) - { - if (info.Username == profile.Value.ProfileInfo!.Username - && info.Password == profile.Value.ProfileInfo.Password) - { + if (info.Username == profile.Value.ProfileInfo!.Username && info.Password == profile.Value.ProfileInfo.Password) return profile.Key; - } - } return null; } diff --git a/Libraries/Core/Controllers/LocationController.cs b/Libraries/Core/Controllers/LocationController.cs index f1d52da8..f2ba8e53 100644 --- a/Libraries/Core/Controllers/LocationController.cs +++ b/Libraries/Core/Controllers/LocationController.cs @@ -18,7 +18,6 @@ public class LocationController( ICloner _cloner ) { - /// /// Handle client/locations /// Get all maps base location properties without loot data @@ -38,10 +37,7 @@ public class LocationController( var mapBase = kvp.Value.Base; if (mapBase == null) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Map: {kvp} has no base json file, skipping generation"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Map: {kvp} has no base json file, skipping generation"); continue; } @@ -65,10 +61,7 @@ public class LocationController( /// public GetAirdropLootResponse? GetAirDropLoot(GetAirdropLootRequest? request) { - if (request?.ContainerId is not null) - { - return _airdropService.GenerateCustomAirdropLoot(request); - } + if (request?.ContainerId is not null) return _airdropService.GenerateCustomAirdropLoot(request); return _airdropService.GenerateAirdropLoot(); } diff --git a/Libraries/Core/Controllers/MatchController.cs b/Libraries/Core/Controllers/MatchController.cs index 1c551065..a7fe9111 100644 --- a/Libraries/Core/Controllers/MatchController.cs +++ b/Libraries/Core/Controllers/MatchController.cs @@ -50,7 +50,7 @@ public class MatchController( /// public ProfileStatusResponse JoinMatch(MatchGroupStartGameRequest info, string sessionId) { - ProfileStatusResponse output = new ProfileStatusResponse + var output = new ProfileStatusResponse { MaxPveCountExceeded = false, // get list of players joining into the match @@ -105,11 +105,9 @@ public class MatchController( // Set pmcs to difficulty set in pre-raid screen if override in bot config isnt enabled if (!_pmcConfig.UseDifficultyOverride) - { _pmcConfig.Difficulty = ConvertDifficultyDropdownIntoBotDifficulty( request.WavesSettings.BotDifficulty.ToString() ); - } } /// @@ -120,10 +118,7 @@ public class MatchController( private string ConvertDifficultyDropdownIntoBotDifficulty(string botDifficulty) { // Edge case medium - must be altered - if (botDifficulty.ToLower() == "medium") - { - return "normal"; - } + if (botDifficulty.ToLower() == "medium") return "normal"; return botDifficulty; } diff --git a/Libraries/Core/Controllers/NoteController.cs b/Libraries/Core/Controllers/NoteController.cs index bcabb0f0..8a923d03 100644 --- a/Libraries/Core/Controllers/NoteController.cs +++ b/Libraries/Core/Controllers/NoteController.cs @@ -23,9 +23,9 @@ public class NoteController( NoteActionData body, string sessionId) { - Note newNote = new Note { Time = body.Note.Time, Text = body.Note.Text }; + var newNote = new Note { Time = body.Note.Time, Text = body.Note.Text }; pmcData.Notes.DataNotes.Add(newNote); - + return _eventOutputHolder.GetOutput(sessionId); } @@ -41,10 +41,10 @@ public class NoteController( NoteActionData body, string sessionId) { - Note noteToEdit = pmcData.Notes.DataNotes[body.Index!.Value]; + var noteToEdit = pmcData.Notes.DataNotes[body.Index!.Value]; noteToEdit.Time = body.Note.Time; noteToEdit.Text = body.Note.Text; - + return _eventOutputHolder.GetOutput(sessionId); } diff --git a/Libraries/Core/Controllers/NotifierController.cs b/Libraries/Core/Controllers/NotifierController.cs index 52c55f7f..fb913630 100644 --- a/Libraries/Core/Controllers/NotifierController.cs +++ b/Libraries/Core/Controllers/NotifierController.cs @@ -11,7 +11,7 @@ namespace Core.Controllers; public class NotifierController( HttpServerHelper _httpServerHelper, NotifierHelper _notifierHelper - ) +) { /// /// Resolve an array of session notifications. @@ -59,9 +59,9 @@ public class NotifierController( // _notificationService.UpdateMessageOnQueue(sessionID, []); // resolve(messages); - //}; + //}; - // immediately check + // immediately check // checkNotifications(); //}); } diff --git a/Libraries/Core/Controllers/PrestigeController.cs b/Libraries/Core/Controllers/PrestigeController.cs index 52b73db6..0ade8e3a 100644 --- a/Libraries/Core/Controllers/PrestigeController.cs +++ b/Libraries/Core/Controllers/PrestigeController.cs @@ -55,25 +55,25 @@ public class PrestigeController( ObtainPrestigeRequestList request) { // Going to prestige 1 - + // transfer // 5% of skills should be transfered over // 5% of mastering should be transfered over // earned achievements should be transfered over // profile stats should be transfered over // prestige progress should be transfered over - + // reset // trader standing // task progress // character level // stash // hideout progress - + // going to prestige 2 // most likely the same, but wait for dump of new beginnings quest - - + + // Clone existing profile, create a new one var prePrestigeProfileClone = _cloner.Clone(_profileHelper.GetFullProfile(sessionId)); var prePrestigePmc = prePrestigeProfileClone.CharacterData.PmcData; @@ -87,7 +87,7 @@ public class PrestigeController( (customisation) => customisation.Value.Name == prePrestigePmc.Info.Voice ) .Value.Id, - SptForcePrestigeLevel = prePrestigeProfileClone.CharacterData.PmcData.Info.PrestigeLevel.GetValueOrDefault(0) + 1, // Current + 1 + SptForcePrestigeLevel = prePrestigeProfileClone.CharacterData.PmcData.Info.PrestigeLevel.GetValueOrDefault(0) + 1 // Current + 1 }; // Reset profile @@ -104,15 +104,11 @@ public class PrestigeController( skillToCopy.Progress = skillToCopy.Progress.Value * 0.05; var existingSkill = newProfile.CharacterData.PmcData.Skills.Common.FirstOrDefault((skill) => skill.Id == skillToCopy.Id); if (existingSkill is not null) - { existingSkill.Progress = skillToCopy.Progress; - } else - { newProfile.CharacterData.PmcData.Skills.Common.Add(skillToCopy); - } } - + // Copy mastering to new profile var masteringSkillsToCopy = prePrestigePmc.Skills.Mastering; foreach (var skillToCopy in masteringSkillsToCopy) @@ -123,35 +119,29 @@ public class PrestigeController( (skill) => skill.Id == skillToCopy.Id ); if (existingSkill is not null) - { existingSkill.Progress = skillToCopy.Progress; - } else - { newProfile.CharacterData.PmcData.Skills.Mastering.Add(skillToCopy); - } } - + // Add existing completed achievements and new one for prestige newProfile.CharacterData.PmcData.Achievements = prePrestigeProfileClone.CharacterData.PmcData.Achievements; // this *should* only contain completed ones // Add "Prestigious" achievement if (!newProfile.CharacterData.PmcData.Achievements.ContainsKey("676091c0f457869a94017a23")) - { newProfile.CharacterData.PmcData.Achievements.Add("676091c0f457869a94017a23", _timeUtil.GetTimeStamp()); - } // TODO: is there one for second prestige // Add existing Stats to profile newProfile.CharacterData.PmcData.Stats = prePrestigePmc.Stats; - + // Assumes Prestige data is in descending order var indexOfPrestigeObtained = (int)Math.Min(createRequest.SptForcePrestigeLevel.Value - 1, 1); // Index starts at 0 var currentPrestigeData = _databaseService.GetTemplates().Prestige.Elements[indexOfPrestigeObtained]; var prestigeRewards = _databaseService.GetTemplates() .Prestige.Elements.Slice(0, indexOfPrestigeObtained + 1) .SelectMany((prestige) => prestige.Rewards); - + AddPrestigeRewardsToProfile(sessionId, newProfile, prestigeRewards); // Flag profile as having achieved this prestige level @@ -159,7 +149,6 @@ public class PrestigeController( newProfile.CharacterData.PmcData.Info.PrestigeLevel++; if (request is not null) - { // Copy transferred items foreach (var transferRequest in request) { @@ -169,7 +158,7 @@ public class PrestigeController( ItemWithModsToAdd = [item], FoundInRaid = item.Upd?.SpawnedInSession, UseSortingTable = false, - Callback = null, + Callback = null }; _inventoryHelper.AddItemToStash( sessionId, @@ -178,40 +167,39 @@ public class PrestigeController( _eventOutputHolder.GetOutput(sessionId) ); } - } - + // Force save of above changes to disk _saveServer.SaveProfile(sessionId); } private void AddPrestigeRewardsToProfile(string sessionId, SptProfile newProfile, IEnumerable rewards) { - foreach (var reward in rewards) { - switch (reward.Type) { - case RewardType.CustomizationDirect: { + foreach (var reward in rewards) + switch (reward.Type) + { + case RewardType.CustomizationDirect: + { _profileHelper.AddHideoutCustomisationUnlock(newProfile, reward, CustomisationSource.PRESTIGE); break; } case RewardType.Skill: if (Enum.TryParse(reward.Target, out SkillTypes result)) - { _profileHelper.AddSkillPointsToPlayer( newProfile.CharacterData.PmcData, result, ((JsonElement)reward.Value).ToObject() ); - } else - { _logger.Error($"Unable to parse reward Target to Enum: {reward.Target}"); - } break; - case RewardType.Item: { - AddItemDirectRequest addItemRequest = new AddItemDirectRequest { + case RewardType.Item: + { + var addItemRequest = new AddItemDirectRequest + { ItemWithModsToAdd = reward.Items, FoundInRaid = reward.Items.FirstOrDefault()?.Upd?.SpawnedInSession, UseSortingTable = false, - Callback = null, + Callback = null }; _inventoryHelper.AddItemToStash( sessionId, @@ -229,6 +217,5 @@ public class PrestigeController( _logger.Error($"Unhandled prestige reward type: {reward.Type}"); break; } - } } } diff --git a/Libraries/Core/Controllers/ProfileController.cs b/Libraries/Core/Controllers/ProfileController.cs index e16cd686..32d7dd42 100644 --- a/Libraries/Core/Controllers/ProfileController.cs +++ b/Libraries/Core/Controllers/ProfileController.cs @@ -51,19 +51,15 @@ public class ProfileController( public MiniProfile GetMiniProfile(string sessionID) { var profile = _saveServer.GetProfile(sessionID); - if (profile?.CharacterData == null) - { - throw new Exception($"Unable to find character data for id: {sessionID}. Profile may be corrupt"); - } + if (profile?.CharacterData == null) throw new Exception($"Unable to find character data for id: {sessionID}. Profile may be corrupt"); var pmc = profile.CharacterData.PmcData; var maxLvl = _profileHelper.GetMaxLevel(); // Player hasn't completed profile creation process, send defaults var currlvl = pmc?.Info?.Level.GetValueOrDefault(1); - var xpToNextLevel = _profileHelper.GetExperience(((currlvl ?? 1) + 1)); + var xpToNextLevel = _profileHelper.GetExperience((currlvl ?? 1) + 1); if (pmc?.Info?.Level == null) - { return new MiniProfile { Username = profile.ProfileInfo?.Username ?? "", @@ -77,9 +73,8 @@ public class ProfileController( MaxLevel = maxLvl, Edition = profile.ProfileInfo?.Edition ?? "", ProfileId = profile.ProfileInfo?.ProfileId ?? "", - SptData = _profileHelper.GetDefaultSptDataObject(), + SptData = _profileHelper.GetDefaultSptDataObject() }; - } return new MiniProfile { @@ -87,14 +82,14 @@ public class ProfileController( Nickname = pmc.Info.Nickname, HasPassword = profile.ProfileInfo.Password != "", Side = pmc.Info.Side, - CurrentLevel = (int)(pmc.Info.Level), - CurrentExperience = (pmc.Info.Experience ?? 0), + CurrentLevel = (int)pmc.Info.Level, + CurrentExperience = pmc.Info.Experience ?? 0, PreviousExperience = currlvl == 0 ? 0 : _profileHelper.GetExperience((int)currlvl), NextLevel = xpToNextLevel, MaxLevel = maxLvl, Edition = profile.ProfileInfo?.Edition ?? "", ProfileId = profile.ProfileInfo?.ProfileId ?? "", - SptData = profile.SptData, + SptData = profile.SptData }; } @@ -133,15 +128,9 @@ public class ProfileController( */ public string ValidateNickname(ValidateNicknameRequestData info, string sessionID) { - if (info.Nickname.Length < 3) - { - return "tooshort"; - } + if (info.Nickname.Length < 3) return "tooshort"; - if (_profileHelper.IsNicknameTaken(info, sessionID)) - { - return "taken"; - } + if (_profileHelper.IsNicknameTaken(info, sessionID)) return "taken"; return "OK"; } @@ -188,10 +177,7 @@ public class ProfileController( { var pmcProfile = profile?.CharacterData?.PmcData; - if (!pmcProfile?.Info?.LowerNickname?.Contains(info.Nickname.ToLower()) ?? false) - { - continue; - } + if (!pmcProfile?.Info?.LowerNickname?.Contains(info.Nickname.ToLower()) ?? false) continue; result.Add(_profileHelper.GetChatRoomMemberFromPmcProfile(pmcProfile)); } @@ -210,8 +196,8 @@ public class ProfileController( MaxPveCountExceeded = false, Profiles = [ - new() { ProfileId = account.ScavengerId, ProfileToken = null, Status = "Free", Sid = "", Ip = "", Port = 0 }, - new() { ProfileId = account.ProfileId, ProfileToken = null, Status = "Free", Sid = "", Ip = "", Port = 0 }, + new ProfileStatusData { ProfileId = account.ScavengerId, ProfileToken = null, Status = "Free", Sid = "", Ip = "", Port = 0 }, + new ProfileStatusData { ProfileId = account.ProfileId, ProfileToken = null, Status = "Free", Sid = "", Ip = "", Port = 0 } ] }; @@ -261,7 +247,7 @@ public class ProfileController( MemberCategory = profileToViewPmc.Info.MemberCategory as int?, BannedState = profileToViewPmc.Info.BannedState, BannedUntil = profileToViewPmc.Info.BannedUntil, - RegistrationDate = profileToViewPmc.Info.RegistrationDate, + RegistrationDate = profileToViewPmc.Info.RegistrationDate }, Customization = { @@ -269,13 +255,13 @@ public class ProfileController( Body = profileToViewPmc.Customization.Body, Feet = profileToViewPmc.Customization.Feet, Hands = profileToViewPmc.Customization.Hands, - Dogtag = profileToViewPmc.Customization.DogTag, + Dogtag = profileToViewPmc.Customization.DogTag }, Skills = profileToViewPmc.Skills, Equipment = { Id = profileToViewPmc.Inventory.Equipment, - Items = profileToViewPmc.Inventory.Items, + Items = profileToViewPmc.Inventory.Items }, Achievements = profileToViewPmc.Achievements, FavoriteItems = _profileHelper.GetOtherProfileFavorites(profileToViewPmc), @@ -284,15 +270,15 @@ public class ProfileController( Eft = { TotalInGameTime = profileToViewPmc.Stats.Eft.TotalInGameTime, - OverAllCounters = profileToViewPmc.Stats.Eft.OverallCounters, - }, + OverAllCounters = profileToViewPmc.Stats.Eft.OverallCounters + } }, ScavStats = { Eft = { TotalInGameTime = profileToViewScav.Stats.Eft.TotalInGameTime, - OverAllCounters = profileToViewScav.Stats.Eft.OverallCounters, + OverAllCounters = profileToViewScav.Stats.Eft.OverallCounters } }, Hideout = profileToViewPmc.Hideout, @@ -308,20 +294,11 @@ public class ProfileController( public bool SetChosenProfileIcon(string sessionId, GetProfileSettingsRequest request) { var profileToUpdate = _profileHelper.GetPmcProfile(sessionId); - if (profileToUpdate == null) - { - return false; - } + if (profileToUpdate == null) return false; - if (request.MemberCategory != null) - { - profileToUpdate.Info.SelectedMemberCategory = request.MemberCategory as MemberCategory?; - } + if (request.MemberCategory != null) profileToUpdate.Info.SelectedMemberCategory = request.MemberCategory as MemberCategory?; - if (request.SquadInviteRestriction != null) - { - profileToUpdate.Info.SquadInviteRestriction = request.SquadInviteRestriction; - } + if (request.SquadInviteRestriction != null) profileToUpdate.Info.SquadInviteRestriction = request.SquadInviteRestriction; return true; } diff --git a/Libraries/Core/Controllers/QuestController.cs b/Libraries/Core/Controllers/QuestController.cs index 4d29b6f6..9276fbc6 100644 --- a/Libraries/Core/Controllers/QuestController.cs +++ b/Libraries/Core/Controllers/QuestController.cs @@ -107,10 +107,7 @@ public class QuestController( acceptedQuest.QuestId, sessionID ); - if (newlyAccessibleQuests.Count > 0) - { - acceptQuestResponse.ProfileChanges[sessionID].Quests.AddRange(newlyAccessibleQuests); - } + if (newlyAccessibleQuests.Count > 0) acceptQuestResponse.ProfileChanges[sessionID].Quests.AddRange(newlyAccessibleQuests); return acceptQuestResponse; } @@ -120,11 +117,9 @@ public class QuestController( foreach (var condition in questConditions) { if (pmcData.TaskConditionCounters.TryGetValue(condition.Id, out var counter)) - { _logger.Error( $"Unable to add new task condition counter: {condition.ConditionType} for qeust: {questId} to profile: {pmcData.SessionId} as it already exists:" ); - } switch (condition.ConditionType) { @@ -134,7 +129,7 @@ public class QuestController( Id = condition.Id, SourceId = questId, Type = condition.ConditionType, - Value = 0, + Value = 0 }; break; } @@ -186,10 +181,7 @@ public class QuestController( var matchingQuest = repeatableQuest.ActiveQuests.FirstOrDefault(x => x.Id == acceptedQuest.QuestId); if (matchingQuest is not null) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Accepted repeatable quest {acceptedQuest.QuestId} from {repeatableQuest.Name}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Accepted repeatable quest {acceptedQuest.QuestId} from {repeatableQuest.Name}"); matchingQuest.SptRepatableGroupName = repeatableQuest.Name; return matchingQuest; @@ -217,7 +209,6 @@ public class QuestController( // Decrement number of items handed in QuestCondition? handoverRequirements = null; foreach (var condition in quest.Conditions.AvailableForFinish) - { if (condition.Id == handoverQuestRequest.ConditionId && handoverQuestTypes.Contains(condition.ConditionType)) { handedInCount = int.Parse(condition.Value.ToString()); @@ -249,19 +240,14 @@ public class QuestController( break; } } - } - if (isItemHandoverQuest && handedInCount == 0) - { - return ShowRepeatableQuestInvalidConditionError(handoverQuestRequest, output); - } + if (isItemHandoverQuest && handedInCount == 0) return ShowRepeatableQuestInvalidConditionError(handoverQuestRequest, output); var totalItemCountToRemove = 0d; foreach (var itemHandover in handoverQuestRequest.Items) { var matchingItemInProfile = pmcData.Inventory.Items.FirstOrDefault(item => item.Id == itemHandover.Id); if (!(matchingItemInProfile is not null && handoverRequirements.Target.List.Contains(matchingItemInProfile.Template))) - { // Item handed in by player doesnt match what was requested return ShowQuestItemHandoverMatchError( handoverQuestRequest, @@ -269,7 +255,6 @@ public class QuestController( handoverRequirements, output ); - } // Remove the right quantity of given items var itemCountToRemove = Math.Min(itemHandover.Count ?? 0, handedInCount - totalItemCountToRemove); @@ -284,10 +269,7 @@ public class QuestController( sessionID, output ); - if (totalItemCountToRemove == handedInCount) - { - break; - } + if (totalItemCountToRemove == handedInCount) break; } else { @@ -306,13 +288,12 @@ public class QuestController( // Important: loop backward when removing items from the array we're looping on while (index-- > 0) - { if (toRemove.Contains(pmcData.Inventory.Items[index].Id)) { var removedItem = _cloner.Clone(pmcData.Inventory.Items[index]); pmcData.Inventory.Items.RemoveAt(index); - // Remove the item + // Remove the item // If the removed item has a numeric `location` property, re-calculate all the child // element `location` properties of the parent so they are sequential, while retaining order if (removedItem.Location.GetType() == typeof(int)) @@ -324,15 +305,11 @@ public class QuestController( childItems.RemoveAt(0); // Remove the parent // Sort by the current `location` and update - childItems.Sort((a, b) => (((int)a.Location) > ((int)b.Location) ? 1 : -1)); + childItems.Sort((a, b) => (int)a.Location > (int)b.Location ? 1 : -1); - for (int i = 0; i < childItems.Count; i++) - { - childItems[i].Location = i; - } + for (var i = 0; i < childItems.Count; i++) childItems[i].Location = i; } } - } } } @@ -370,7 +347,7 @@ public class QuestController( { questId = handoverQuestRequest.QuestId, handedInTpl = itemHandedOver?.Template ?? "UNKNOWN", - requiredTpl = handoverRequirements.Target.List.FirstOrDefault(), + requiredTpl = handoverRequirements.Target.List.FirstOrDefault() } ); _logger.Error(errorMessage); @@ -392,7 +369,7 @@ public class QuestController( Id = conditionId, SourceId = questId, Type = "HandoverItem", - Value = counterValue, + Value = counterValue }; } diff --git a/Libraries/Core/Controllers/RagfairController.cs b/Libraries/Core/Controllers/RagfairController.cs index 3e3cdec7..66e323e4 100644 --- a/Libraries/Core/Controllers/RagfairController.cs +++ b/Libraries/Core/Controllers/RagfairController.cs @@ -25,32 +25,32 @@ namespace Core.Controllers; [Injectable] public class RagfairController { - private readonly ISptLogger _logger; - private readonly TimeUtil _timeUtil; - private readonly JsonUtil _jsonUtil; - private readonly HttpResponseUtil _httpResponseUtil; - private readonly EventOutputHolder _eventOutputHolder; - private readonly RagfairServer _ragfairServer; - private readonly ItemHelper _itemHelper; - private readonly InventoryHelper _inventoryHelper; - private readonly RagfairSellHelper _ragfairSellHelper; - private readonly HandbookHelper _handbookHelper; - private readonly ProfileHelper _profileHelper; - private readonly PaymentHelper _paymentHelper; - private readonly RagfairHelper _ragfairHelper; - private readonly RagfairSortHelper _ragfairSortHelper; - private readonly RagfairOfferHelper _ragfairOfferHelper; - private readonly TraderHelper _traderHelper; - private readonly DatabaseService _databaseService; - private readonly LocalisationService _localisationService; - private readonly RagfairTaxService _ragfairTaxService; - private readonly RagfairOfferService _ragfairOfferService; - private readonly PaymentService _paymentService; - private readonly RagfairPriceService _ragfairPriceService; - private readonly RagfairOfferGenerator _ragfairOfferGenerator; private readonly ConfigServer _configServer; + private readonly DatabaseService _databaseService; + private readonly EventOutputHolder _eventOutputHolder; + private readonly HandbookHelper _handbookHelper; + private readonly HttpResponseUtil _httpResponseUtil; + private readonly InventoryHelper _inventoryHelper; + private readonly ItemHelper _itemHelper; + private readonly JsonUtil _jsonUtil; + private readonly LocalisationService _localisationService; + private readonly ISptLogger _logger; + private readonly PaymentHelper _paymentHelper; + private readonly PaymentService _paymentService; + private readonly ProfileHelper _profileHelper; private readonly RagfairConfig _ragfairConfig; + private readonly RagfairHelper _ragfairHelper; + private readonly RagfairOfferGenerator _ragfairOfferGenerator; + private readonly RagfairOfferHelper _ragfairOfferHelper; + private readonly RagfairOfferService _ragfairOfferService; + private readonly RagfairPriceService _ragfairPriceService; + private readonly RagfairSellHelper _ragfairSellHelper; + private readonly RagfairServer _ragfairServer; + private readonly RagfairSortHelper _ragfairSortHelper; + private readonly RagfairTaxService _ragfairTaxService; + private readonly TimeUtil _timeUtil; + private readonly TraderHelper _traderHelper; public RagfairController( ISptLogger logger, @@ -119,9 +119,7 @@ public class RagfairController if ( pmcProfile.RagfairInfo is not null && pmcProfile.Info.Level >= _databaseService.GetGlobals().Configuration.RagFair.MinUserLevel ) - { _ragfairOfferHelper.ProcessOffersOnProfile(sessionId); - } } } @@ -142,16 +140,14 @@ public class RagfairController { Offers = [], OffersCount = searchRequest.Limit, - SelectedCategory = searchRequest.HandbookId, + SelectedCategory = searchRequest.HandbookId }; result.Offers = GetOffersForSearchType(searchRequest, itemsToAdd, traderAssorts, profile.CharacterData.PmcData); // Client requested a category refresh if (searchRequest.UpdateOfferCount.GetValueOrDefault(false)) - { result.Categories = GetSpecificCategories(profile.CharacterData.PmcData, searchRequest, result.Offers); - } AddIndexValueToOffers(result.Offers); @@ -167,10 +163,7 @@ public class RagfairController { // For the items, check the barter schemes. The method getDisplayableAssorts sets a flag sptQuestLocked // to true if the quest is not completed yet - if (_ragfairOfferHelper.TraderOfferItemQuestLocked(traderOffer, traderAssorts)) - { - traderOffer.Locked = true; - } + if (_ragfairOfferHelper.TraderOfferItemQuestLocked(traderOffer, traderAssorts)) traderOffer.Locked = true; // Update offers BuyRestrictionCurrent/BuyRestrictionMax values SetTraderOfferPurchaseLimits(traderOffer, profile); @@ -208,7 +201,7 @@ public class RagfairController new { offerId = offer.Items.First().Id, - traderId = offer.User.Id, + traderId = offer.User.Id } ) ); @@ -263,10 +256,7 @@ public class RagfairController { var counter = 0; - foreach (var offer in offers) - { - offer.InternalId = ++counter; - } + foreach (var offer in offers) offer.InternalId = ++counter; } /** @@ -293,10 +283,7 @@ public class RagfairController else { _logger.Error(_localisationService.GetText("ragfair-unable_to_get_categories")); - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug(_jsonUtil.Serialize(searchRequest)); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug(_jsonUtil.Serialize(searchRequest)); return new Dictionary(); } @@ -335,15 +322,9 @@ public class RagfairController PmcData pmcProfile) { // Searching for items in preset menu - if (searchRequest.BuildCount > 0) - { - return _ragfairOfferHelper.GetOffersForBuild(searchRequest, itemsToAdd, traderAssorts, pmcProfile); - } + if (searchRequest.BuildCount > 0) return _ragfairOfferHelper.GetOffersForBuild(searchRequest, itemsToAdd, traderAssorts, pmcProfile); - if (searchRequest.NeededSearchId?.Length > 0) - { - return _ragfairOfferHelper.GetOffersThatRequireItem(searchRequest, pmcProfile); - } + if (searchRequest.NeededSearchId?.Length > 0) return _ragfairOfferHelper.GetOffersThatRequireItem(searchRequest, pmcProfile); // Searching for general items return _ragfairOfferHelper.GetValidOffers(searchRequest, itemsToAdd, traderAssorts, pmcProfile); @@ -375,10 +356,7 @@ public class RagfairController // No offers listed, get price from live ragfair price list prices.json // No flea price, get handbook price var fleaPrices = _databaseService.GetPrices(); - if (!fleaPrices.TryGetValue(getPriceRequest.TemplateId, out var tplPrice)) - { - tplPrice = _handbookHelper.GetTemplatePrice(getPriceRequest.TemplateId); - } + if (!fleaPrices.TryGetValue(getPriceRequest.TemplateId, out var tplPrice)) tplPrice = _handbookHelper.GetTemplatePrice(getPriceRequest.TemplateId); return new GetItemPriceResult { Avg = tplPrice, Min = tplPrice, Max = tplPrice }; } @@ -391,40 +369,26 @@ public class RagfairController foreach (var offer in offers) { // Exclude barter items, they tend to have outrageous equivalent prices - if (offer.Requirements.Any(req => !_paymentHelper.IsMoneyTpl(req.Template))) - { - continue; - } + if (offer.Requirements.Any(req => !_paymentHelper.IsMoneyTpl(req.Template))) continue; - if (ignoreTraderOffers && _ragfairOfferHelper.OfferIsFromTrader(offer)) - { - continue; - } + if (ignoreTraderOffers && _ragfairOfferHelper.OfferIsFromTrader(offer)) continue; // Figure out how many items the requirementsCost is applying to, and what the per-item price is var offerItemCount = offer.SellInOnePiece.GetValueOrDefault(false) - ? (offer.Items.First().Upd?.StackObjectsCount ?? 1) + ? offer.Items.First().Upd?.StackObjectsCount ?? 1 : 1; var perItemPrice = offer.RequirementsCost / offerItemCount; // Handle min/max calculations based on the per-item price if (perItemPrice < minMax.Min) - { minMax.Min = perItemPrice; - } - else if (perItemPrice > minMax.Max) - { - minMax.Max = perItemPrice; - } + else if (perItemPrice > minMax.Max) minMax.Max = perItemPrice; sum += perItemPrice.Value; totalOfferCount++; } - if (totalOfferCount == 0) - { - return -1d; - } + if (totalOfferCount == 0) return -1d; return sum / totalOfferCount; } @@ -442,16 +406,11 @@ public class RagfairController var fullProfile = _profileHelper.GetFullProfile(sessionID); var validationMessage = ""; - if (!IsValidPlayerOfferRequest(offerRequest, validationMessage)) - { - return _httpResponseUtil.AppendErrorToOutput(output, validationMessage); - } + if (!IsValidPlayerOfferRequest(offerRequest, validationMessage)) return _httpResponseUtil.AppendErrorToOutput(output, validationMessage); var typeOfOffer = GetOfferType(offerRequest); if (typeOfOffer == FleaOfferType.UNKNOWN) - { return _httpResponseUtil.AppendErrorToOutput(output, $"Unknown offer type: {typeOfOffer}, cannot list item on flea"); - } switch (typeOfOffer) { @@ -504,21 +463,12 @@ public class RagfairController if (!sellInOncePiece) { - if (offerRequest.Items.Count == 1) - { - return FleaOfferType.SINGLE; - } + if (offerRequest.Items.Count == 1) return FleaOfferType.SINGLE; - if (offerRequest.Items.Count > 1) - { - return FleaOfferType.MULTI; - } + if (offerRequest.Items.Count > 1) return FleaOfferType.MULTI; } - if (sellInOncePiece) - { - return FleaOfferType.PACK; - } + if (sellInOncePiece) return FleaOfferType.PACK; return FleaOfferType.UNKNOWN; } @@ -542,14 +492,12 @@ public class RagfairController // Get first item and its children and use as template var firstListingAndChidren = _itemHelper.FindAndReturnChildrenAsItems( pmcData.Inventory.Items, - offerRequest.Items[0]); + offerRequest.Items[0] + ); // Find items to be listed on flea (+ children) from player inventory var result = GetItemsToListOnFleaFromInventory(pmcData, offerRequest.Items); - if (result.Items is null || !string.IsNullOrEmpty(result.ErrorMessage)) - { - _httpResponseUtil.AppendErrorToOutput(output, result.ErrorMessage); - } + if (result.Items is null || !string.IsNullOrEmpty(result.ErrorMessage)) _httpResponseUtil.AppendErrorToOutput(output, result.ErrorMessage); // Total count of items summed using their stack counts var stackCountTotal = _ragfairOfferHelper.GetTotalStackCountSize(result.Items); @@ -557,7 +505,7 @@ public class RagfairController // When listing identical items on flea, condense separate items into one stack with a merged stack count // e.g. 2 ammo items, stackObjectCount = 3 for each, will result in 1 stack of 6 - firstListingAndChidren[0].Upd ??= new Upd{ }; + firstListingAndChidren[0].Upd ??= new Upd { }; firstListingAndChidren[0].Upd.StackObjectsCount = stackCountTotal; @@ -568,14 +516,11 @@ public class RagfairController var newRootOfferItem = offer.Items[0]; // Average offer price for single item (or whole weapon) - var averages = GetItemMinAvgMaxFleaPriceValues(new GetMarketPriceRequestData{ TemplateId = offer.Items[0].Template }); + var averages = GetItemMinAvgMaxFleaPriceValues(new GetMarketPriceRequestData { TemplateId = offer.Items[0].Template }); var averageOfferPrice = averages.Avg; // Check for and apply item price modifer if it exists in config - if (_ragfairConfig.Dynamic.ItemPriceMultiplier.TryGetValue(newRootOfferItem.Template, out var itemPriceModifer)) - { - averageOfferPrice *= itemPriceModifer; - } + if (_ragfairConfig.Dynamic.ItemPriceMultiplier.TryGetValue(newRootOfferItem.Template, out var itemPriceModifer)) averageOfferPrice *= itemPriceModifer; // Get average of item+children quality var qualityMultiplier = _itemHelper.GetItemQualityModifierForItems(offer.Items, true); @@ -590,7 +535,8 @@ public class RagfairController var sellChancePercent = _ragfairSellHelper.CalculateSellChance( averageOfferPrice.Value, playerListedPriceInRub, - qualityMultiplier); + qualityMultiplier + ); // Create array of sell times for items listed offer.SellResults = _ragfairSellHelper.RollForSale(sellChancePercent, (int)stackCountTotal); @@ -605,11 +551,9 @@ public class RagfairController playerListedPriceInRub, (int)stackCountTotal, offerRequest, - output); - if (taxFeeChargeFailed) - { - return output; - } + output + ); + if (taxFeeChargeFailed) return output; } // Add offer to players profile + add to client response @@ -617,9 +561,7 @@ public class RagfairController output.ProfileChanges[sessionID].RagFairOffers.Add(offer); // Remove items from inventory after creating offer - foreach (var itemToRemove in offerRequest.Items) { - _inventoryHelper.RemoveItem(pmcData, itemToRemove, sessionID, output); - } + foreach (var itemToRemove in offerRequest.Items) _inventoryHelper.RemoveItem(pmcData, itemToRemove, sessionID, output); return output; } @@ -643,14 +585,12 @@ public class RagfairController // Get first item and its children and use as template var firstListingAndChidren = _itemHelper.FindAndReturnChildrenAsItems( pmcData.Inventory.Items, - offerRequest.Items[0]); + offerRequest.Items[0] + ); // Find items to be listed on flea (+ children) from player inventory var result = GetItemsToListOnFleaFromInventory(pmcData, offerRequest.Items); - if (result.Items is null || !string.IsNullOrEmpty(result.ErrorMessage)) - { - _httpResponseUtil.AppendErrorToOutput(output, result.ErrorMessage); - } + if (result.Items is null || !string.IsNullOrEmpty(result.ErrorMessage)) _httpResponseUtil.AppendErrorToOutput(output, result.ErrorMessage); // Total count of items summed using their stack counts var stackCountTotal = _ragfairOfferHelper.GetTotalStackCountSize(result.Items); @@ -668,14 +608,11 @@ public class RagfairController var newRootOfferItem = offer.Items[0]; // Single price for an item - var averages = GetItemMinAvgMaxFleaPriceValues( new GetMarketPriceRequestData{ TemplateId = firstListingAndChidren[0].Template }); + var averages = GetItemMinAvgMaxFleaPriceValues(new GetMarketPriceRequestData { TemplateId = firstListingAndChidren[0].Template }); var singleItemPrice = averages.Avg; // Check for and apply item price modifer if it exists in config - if (_ragfairConfig.Dynamic.ItemPriceMultiplier.TryGetValue(newRootOfferItem.Template, out double itemPriceModifer)) - { - singleItemPrice *= itemPriceModifer; - } + if (_ragfairConfig.Dynamic.ItemPriceMultiplier.TryGetValue(newRootOfferItem.Template, out var itemPriceModifer)) singleItemPrice *= itemPriceModifer; // Get average of item+children quality var qualityMultiplier = _itemHelper.GetItemQualityModifierForItems(offer.Items, true); @@ -690,7 +627,8 @@ public class RagfairController var sellChancePercent = _ragfairSellHelper.CalculateSellChance( singleItemPrice.Value * stackCountTotal, playerListedPriceInRub, - qualityMultiplier); + qualityMultiplier + ); // Create array of sell times for items listed + sell all at once as its a pack offer.SellResults = _ragfairSellHelper.RollForSale(sellChancePercent, (int)stackCountTotal, true); @@ -705,11 +643,9 @@ public class RagfairController playerListedPriceInRub, (int)stackCountTotal, offerRequest, - output); - if (taxFeeChargeFailed) - { - return output; - } + output + ); + if (taxFeeChargeFailed) return output; } // Add offer to players profile + add to client response @@ -717,9 +653,7 @@ public class RagfairController output.ProfileChanges[sessionID].RagFairOffers.Add(offer); // Remove items from inventory after creating offer - foreach (var itemToRemove in offerRequest.Items) { - _inventoryHelper.RemoveItem(pmcData, itemToRemove, sessionID, output); - } + foreach (var itemToRemove in offerRequest.Items) _inventoryHelper.RemoveItem(pmcData, itemToRemove, sessionID, output); return output; } @@ -741,10 +675,7 @@ public class RagfairController // Find items to be listed on flea from player inventory var result = GetItemsToListOnFleaFromInventory(pmcData, offerRequest.Items); - if (result.Items is null || !string.IsNullOrEmpty(result.ErrorMessage)) - { - _httpResponseUtil.AppendErrorToOutput(output, result.ErrorMessage); - } + if (result.Items is null || !string.IsNullOrEmpty(result.ErrorMessage)) _httpResponseUtil.AppendErrorToOutput(output, result.ErrorMessage); // Total count of items summed using their stack counts var stackCountTotal = _ragfairOfferHelper.GetTotalStackCountSize(result.Items); @@ -767,10 +698,8 @@ public class RagfairController var averageOfferPriceSingleItem = averages.Avg; // Check for and apply item price modifer if it exists in config - if (_ragfairConfig.Dynamic.ItemPriceMultiplier.TryGetValue(rootItem.Template, out double itemPriceModifer)) - { + if (_ragfairConfig.Dynamic.ItemPriceMultiplier.TryGetValue(rootItem.Template, out var itemPriceModifer)) averageOfferPriceSingleItem *= itemPriceModifer; - } // Multiply single item price by quality averageOfferPriceSingleItem *= qualityMultiplier; @@ -795,10 +724,7 @@ public class RagfairController offerRequest, output ); - if (taxFeeChargeFailed) - { - return output; - } + if (taxFeeChargeFailed) return output; } // Add offer to players profile + add to client response @@ -806,10 +732,7 @@ public class RagfairController output.ProfileChanges[sessionID].RagFairOffers.Add(offer); // Remove items from inventory after creating offer - foreach (var itemToRemove in offerRequest.Items) - { - _inventoryHelper.RemoveItem(pmcData, itemToRemove, sessionID, output); - } + foreach (var itemToRemove in offerRequest.Items) _inventoryHelper.RemoveItem(pmcData, itemToRemove, sessionID, output); return output; } @@ -846,10 +769,7 @@ public class RagfairController offerRequest.SellInOnePiece.GetValueOrDefault(false) ); - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Offer tax to charge: {tax}, pulled from client: {storedClientTaxValue.Count is not null}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Offer tax to charge: {tax}, pulled from client: {storedClientTaxValue.Count is not null}"); // cleanup of cache now we've used the tax value from it _ragfairTaxService.ClearStoredOfferTaxById(offerRequest.Items.First()); @@ -892,7 +812,7 @@ public class RagfairController { Template = item.Template, Count = item.Count, - OnlyFunctional = item.OnlyFunctional, + OnlyFunctional = item.OnlyFunctional } ); @@ -919,13 +839,9 @@ public class RagfairController var requestedItemTpl = item.Template; if (_paymentHelper.IsMoneyTpl(requestedItemTpl)) - { requirementsPriceInRub += _handbookHelper.InRUB(item.Count.Value, requestedItemTpl); - } else - { requirementsPriceInRub += _itemHelper.GetDynamicItemPrice(requestedItemTpl).Value * item.Count.Value; - } } return requirementsPriceInRub; @@ -963,12 +879,6 @@ public class RagfairController return new GetItemsToListOnFleaFromInventoryResult { Items = itemsToReturn, ErrorMessage = errorMessage }; } - public record GetItemsToListOnFleaFromInventoryResult - { - public List>? Items { get; set; } - public string? ErrorMessage { get; set; } - } - public ItemEventRouterResponse RemoveOffer(RemoveOfferRequestData removeRequest, string sessionId) { var output = _eventOutputHolder.GetOutput(sessionId); @@ -1050,10 +960,7 @@ public class RagfairController { var count = 1; var sellInOncePiece = playerOffer.SellInOnePiece.GetValueOrDefault(false); - if (!sellInOncePiece) - { - count = (int)playerOffer.Items.Sum(offerItem => offerItem.Upd?.StackObjectsCount ?? 0); - } + if (!sellInOncePiece) count = (int)playerOffer.Items.Sum(offerItem => offerItem.Upd?.StackObjectsCount ?? 0); var tax = _ragfairTaxService.CalculateTax( playerOffer.Items.First(), @@ -1066,12 +973,10 @@ public class RagfairController var request = CreateBuyTradeRequestObject(CurrencyType.RUB, tax); _paymentService.PayMoney(pmcData, request, sessionId, output); if (output.Warnings.Count > 0) - { return _httpResponseUtil.AppendErrorToOutput( output, _localisationService.GetText("ragfair-unable_to_pay_commission_fee") ); - } } // Add extra time to offer @@ -1096,7 +1001,7 @@ public class RagfairController Type = "", ItemId = "", Count = 0, - SchemeId = 0, + SchemeId = 0 }; } @@ -1117,4 +1022,10 @@ public class RagfairController return offerToReturn; } + + public record GetItemsToListOnFleaFromInventoryResult + { + public List>? Items { get; set; } + public string? ErrorMessage { get; set; } + } } diff --git a/Libraries/Core/Controllers/RepairController.cs b/Libraries/Core/Controllers/RepairController.cs index 5e238b32..eabb8e2d 100644 --- a/Libraries/Core/Controllers/RepairController.cs +++ b/Libraries/Core/Controllers/RepairController.cs @@ -11,7 +11,7 @@ namespace Core.Controllers; public class RepairController( EventOutputHolder _eventOutputHolder, RepairService _repairService - ) +) { /// /// Handle TraderRepair event @@ -29,7 +29,8 @@ public class RepairController( var output = _eventOutputHolder.GetOutput(sessionID); // find the item to repair - foreach (var repairItem in body.RepairItems) { + foreach (var repairItem in body.RepairItems) + { var repairDetails = _repairService.RepairItemByTrader(sessionID, pmcData, repairItem, body.TId); _repairService.PayForRepair( @@ -38,12 +39,10 @@ public class RepairController( repairItem.Id, repairDetails.RepairCost.Value, body.TId, - output); + output + ); - if (output.Warnings?.Count > 0) - { - return output; - } + if (output.Warnings?.Count > 0) return output; // Add repaired item to output object output.ProfileChanges[sessionID].Items.ChangedItems.Add(repairDetails.RepairedItem); diff --git a/Libraries/Core/Controllers/RepeatableQuestController.cs b/Libraries/Core/Controllers/RepeatableQuestController.cs index 6d3d04b8..8ce171df 100644 --- a/Libraries/Core/Controllers/RepeatableQuestController.cs +++ b/Libraries/Core/Controllers/RepeatableQuestController.cs @@ -89,10 +89,7 @@ public class RepeatableQuestController( ); // If the configuration dictates to replace with the same quest type, adjust the available quest types - if (repeatableConfig?.KeepDailyQuestTypeOnReplacement is not null) - { - repeatableConfig.Types = [questToReplace.Type.ToString()]; - } + if (repeatableConfig?.KeepDailyQuestTypeOnReplacement is not null) repeatableConfig.Types = [questToReplace.Type.ToString()]; // Generate meta-data for what type/levelrange of quests can be generated for player var allowedQuestTypes = GenerateQuestPool(repeatableConfig, pmcData.Info.Level); @@ -117,11 +114,9 @@ public class RepeatableQuestController( repeatablesOfTypeInProfile.ActiveQuests.Add(newRepeatableQuest); if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug( $"Removing: {repeatableConfig.Name} quest: {questToReplace.Id} from trader: {questToReplace.TraderId} as its been replaced" ); - } RemoveQuestFromProfile(fullProfile, questToReplace.Id); @@ -153,10 +148,7 @@ public class RepeatableQuestController( // Not free, Charge player + appy charisma bonus to cost of replacement cost.Count = (int)Math.Truncate(cost.Count.Value * (1 - Math.Truncate(charismaBonus / 100) * 0.001)); _paymentService.AddPaymentToOutput(pmcData, cost.TemplateId, cost.Count.Value, sessionID, output); - if (output.Warnings.Count > 0) - { - return output; - } + if (output.Warnings.Count > 0) return output; } } @@ -227,16 +219,12 @@ public class RepeatableQuestController( string replacedQuestId) { if (repeatablesOfTypeInProfile.ActiveQuests.Count == 1) - { // Only one repeatable quest being replaced (e.g. scav_daily), remove everything ready for new quest requirement to be added // Will assist in cleanup of existing profiles data repeatablesOfTypeInProfile.ChangeRequirement.Clear(); - } else - { // Multiple active quests of this type (e.g. daily or weekly) are active, just remove the single replaced quest repeatablesOfTypeInProfile.ChangeRequirement.Remove(replacedQuestId); - } } private RepeatableQuest? AttemptToGenerateRepeatableQuest(string sessionId, PmcData pmcData, @@ -256,18 +244,13 @@ public class RepeatableQuestController( ); if (newRepeatableQuest is not null) - { // Successfully generated a quest, exit loop break; - } attempts++; } - if (attempts > maxAttempts) - { - _logger.Error("We were stuck in repeatable quest generation. This should never happen. Please report"); - } + if (attempts > maxAttempts) _logger.Error("We were stuck in repeatable quest generation. This should never happen. Please report"); return newRepeatableQuest; } @@ -279,12 +262,10 @@ public class RepeatableQuestController( // Find quest we're replacing in scav profile quests array and remove it if (fullProfile.CharacterData.ScavData is not null) - { _questHelper.FindAndRemoveQuestFromArrayIfExists( questToReplaceId, fullProfile.CharacterData.ScavData.Quests ); - } } /** @@ -301,10 +282,8 @@ public class RepeatableQuestController( var questToReplace = repeatablesInProfile.ActiveQuests.FirstOrDefault(repeatable => repeatable.Id == questId); if (questToReplace is null) - { // Not found, skip to next repeatable sub-type continue; - } return new GetRepeatableByIdResult { Quest = questToReplace, RepeatableType = repeatablesInProfile }; } @@ -328,20 +307,15 @@ public class RepeatableQuestController( var canAccessRepeatables = CanProfileAccessRepeatableQuests(repeatableConfig, pmcData); if (!canAccessRepeatables) - { // Don't send any repeatables, even existing ones continue; - } // Existing repeatables are still valid, add to return data and move to next sub-type if (currentTime < generatedRepeatables.EndTime - 1) { returnData.Add(generatedRepeatables); - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"[Quest Check] {repeatableTypeLower} quests are still valid."); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"[Quest Check] {repeatableTypeLower} quests are still valid."); continue; } @@ -351,10 +325,7 @@ public class RepeatableQuestController( // Set endtime to be now + new duration generatedRepeatables.EndTime = currentTime + repeatableConfig.ResetTime; generatedRepeatables.InactiveQuests = []; - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Generating new {repeatableTypeLower}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Generating new {repeatableTypeLower}"); // Put old quests to inactive (this is required since only then the client makes them fail due to non-completion) // Also need to push them to the "inactiveQuests" list since we need to remove them from offraidData.profile.Quests @@ -391,10 +362,7 @@ public class RepeatableQuestController( } // check if there are no more quest types available - if (questTypePool.Types.Count == 0) - { - break; - } + if (questTypePool.Types.Count == 0) break; quest.Side = repeatableConfig.Side; generatedRepeatables.ActiveQuests.Add(quest); @@ -473,18 +441,12 @@ public class RepeatableQuestController( private bool CanProfileAccessRepeatableQuests(RepeatableQuestConfig repeatableConfig, PmcData pmcData) { // PMC and daily quests not unlocked yet - if (repeatableConfig.Side == "Pmc" && !PlayerHasDailyPmcQuestsUnlocked(pmcData, repeatableConfig)) - { - return false; - } + if (repeatableConfig.Side == "Pmc" && !PlayerHasDailyPmcQuestsUnlocked(pmcData, repeatableConfig)) return false; // Scav and daily quests not unlocked yet if (repeatableConfig.Side == "Scav" && !PlayerHasDailyScavQuestsUnlocked(pmcData)) { - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug("Daily scav quests still locked, Intel center not built"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug("Daily scav quests still locked, Intel center not built"); return false; } @@ -521,21 +483,16 @@ public class RepeatableQuestController( foreach (var activeQuest in generatedRepeatables.ActiveQuests) { var questStatusInProfile = pmcData.Quests.FirstOrDefault(quest => quest.QId == activeQuest.Id); - if (questStatusInProfile is null) - { - continue; - } + if (questStatusInProfile is null) continue; // Keep finished quests in list so player can hand in if (questStatusInProfile.Status == QuestStatusEnum.AvailableForFinish) { questsToKeep.Add(activeQuest); if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug( // TODO: this shouldnt happen, doesnt on live $"Keeping repeatable quest: {activeQuest.Id} in activeQuests since it is available to hand in" ); - } continue; } @@ -632,17 +589,10 @@ public class RepeatableQuestController( { var locationNames = new List(); foreach (var locationName in value) - { if (IsPmcLevelAllowedOnLocation(locationName, pmcLevel)) - { locationNames.Add(locationName); - } - } - if (locationNames.Count > 0) - { - allowedLocation[location] = locationNames; - } + if (locationNames.Count > 0) allowedLocation[location] = locationNames; } return allowedLocation; @@ -657,16 +607,10 @@ public class RepeatableQuestController( protected bool IsPmcLevelAllowedOnLocation(string location, int pmcLevel) { // All PMC levels are allowed for 'any' location requirement - if (location == ELocationName.any.ToString()) - { - return true; - } + if (location == ELocationName.any.ToString()) return true; var locationBase = _databaseService.GetLocation(location.ToLower())?.Base; - if (locationBase is null) - { - return true; - } + if (locationBase is null) return true; return pmcLevel <= locationBase.RequiredPlayerLevelMax && pmcLevel >= locationBase.RequiredPlayerLevelMin; } @@ -680,14 +624,10 @@ public class RepeatableQuestController( private int GetQuestCount(RepeatableQuestConfig repeatableConfig, PmcData pmcData) { var questCount = repeatableConfig.NumQuests.GetValueOrDefault(0); - if (questCount == 0) - { - _logger.Warning($"Repeatable {repeatableConfig.Name} quests have a count of 0"); - } + if (questCount == 0) _logger.Warning($"Repeatable {repeatableConfig.Name} quests have a count of 0"); // Add elite bonus to daily quests if (repeatableConfig.Name.ToLower() == "daily" && _profileHelper.HasEliteSkillLevel(SkillTypes.Charisma, pmcData)) - { // Elite charisma skill gives extra daily quest(s) questCount += _databaseService .GetGlobals() @@ -698,7 +638,6 @@ public class RepeatableQuestController( .EliteBonusSettings .RepeatableQuestExtraCount .GetValueOrDefault(0); - } return questCount; } diff --git a/Libraries/Core/Controllers/TradeController.cs b/Libraries/Core/Controllers/TradeController.cs index 7f9a19ca..3932bcd1 100644 --- a/Libraries/Core/Controllers/TradeController.cs +++ b/Libraries/Core/Controllers/TradeController.cs @@ -58,7 +58,7 @@ public class TradeController( if (request.Type == "buy_from_trader") { var foundInRaid = _traderConfig.PurchasesAreFoundInRaid; - ProcessBuyTradeRequestData buyData = (ProcessBuyTradeRequestData)request; + var buyData = (ProcessBuyTradeRequestData)request; _tradeHelper.buyItem(pmcData, buyData, sessionID, foundInRaid, output); return output; @@ -67,7 +67,7 @@ public class TradeController( // Selling if (request.Type == "sell_to_trader") { - ProcessSellTradeRequestData sellData = (ProcessSellTradeRequestData)request; + var sellData = (ProcessSellTradeRequestData)request; _tradeHelper.sellItem(pmcData, pmcData, sellData, sessionID, output); return output; @@ -97,13 +97,11 @@ public class TradeController( { var fleaOffer = _ragfairServer.GetOffer(offer.Id); if (fleaOffer is null) - { return _httpResponseUtil.AppendErrorToOutput( output, $"Offer with ID {offer.Id} not found", BackendErrorCodes.OfferNotFound ); - } if (offer.Count == 0) { @@ -115,19 +113,12 @@ public class TradeController( } if (_ragfairOfferHelper.OfferIsFromTrader(fleaOffer)) - { BuyTraderItemFromRagfair(sessionID, pmcData, fleaOffer, offer, output); - } else - { BuyPmcItemFromRagfair(sessionID, pmcData, fleaOffer, offer, output); - } // Exit loop early if problem found - if (output.Warnings?.Count > 0) - { - return output; - } + if (output.Warnings?.Count > 0) return output; } return output; @@ -152,17 +143,14 @@ public class TradeController( if (PlayerLacksTraderLoyaltyLevelToBuyOffer(fleaOffer, pmcData)) { var errorMessage = $"Unable to buy item: {fleaOffer.Items[0].Template} from trader: {fleaOffer.User.Id} as loyalty level too low, skipping"; - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug(errorMessage); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug(errorMessage); _httpResponseUtil.AppendErrorToOutput(output, errorMessage, BackendErrorCodes.RagfairUnavailable); return; } - ProcessBuyTradeRequestData buyData = new ProcessBuyTradeRequestData + var buyData = new ProcessBuyTradeRequestData { Action = "TradingConfirm", Type = "buy_from_ragfair", @@ -170,7 +158,7 @@ public class TradeController( ItemId = fleaOffer.Root, Count = requestOffer.Count, SchemeId = 0, - SchemeItems = requestOffer.Items, + SchemeItems = requestOffer.Items }; _tradeHelper.buyItem(pmcData, buyData, sessionId, _traderConfig.PurchasesAreFoundInRaid, output); @@ -191,7 +179,7 @@ public class TradeController( OfferRequest requestOffer, ItemEventRouterResponse output) { - ProcessBuyTradeRequestData buyData = new ProcessBuyTradeRequestData + var buyData = new ProcessBuyTradeRequestData { Action = "TradingConfirm", Type = "buy_from_ragfair", @@ -199,15 +187,12 @@ public class TradeController( ItemId = fleaOffer.Id, // Store ragfair offerId in buyRequestData.item_id Count = requestOffer.Count, SchemeId = 0, - SchemeItems = requestOffer.Items, + SchemeItems = requestOffer.Items }; // buyItem() must occur prior to removing the offer stack, otherwise item inside offer doesn't exist for confirmTrading() to use _tradeHelper.buyItem(pmcData, buyData, sessionId, _ragfairConfig.Dynamic.PurchasesAreFoundInRaid, output); - if (output.Warnings?.Count > 0) - { - return; - } + if (output.Warnings?.Count > 0) return; // resolve when a profile buy another profile's offer var offerOwnerId = fleaOffer.User?.Id; @@ -237,17 +222,12 @@ public class TradeController( string? offerOwnerId) { // No ownerid, not player offer - if (offerOwnerId is null) - { - return false; - } + if (offerOwnerId is null) return false; var offerCreatorProfile = _profileHelper.GetPmcProfile(offerOwnerId); if (offerCreatorProfile is null || offerCreatorProfile.RagfairInfo.Offers?.Count == 0) - { // No profile or no offers return false; - } // Does offer id exist in profile return offerCreatorProfile.RagfairInfo.Offers.Any(offer => offer.Id == offerId); @@ -296,17 +276,14 @@ public class TradeController( int roublesToSend, string trader) { - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Selling scav items to fence for {roublesToSend} roubles"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Selling scav items to fence for {roublesToSend} roubles"); // Create single currency item with all currency on it - Item rootCurrencyReward = new Item + var rootCurrencyReward = new Item { Id = _hashUtil.Generate(), Template = Money.ROUBLES, - Upd = new Upd { StackObjectsCount = roublesToSend }, + Upd = new Upd { StackObjectsCount = roublesToSend } }; // Ensure money is properly split to follow its max stack size limit @@ -317,7 +294,7 @@ public class TradeController( sessionId, _traderHelper.GetTraderById(trader).ToString(), MessageType.MESSAGE_WITH_ITEMS, - _randomUtil.GetArrayValue((_databaseService.GetTrader(trader).Dialogue.TryGetValue("SoldItems", out var items)) ? items : new List()), + _randomUtil.GetArrayValue(_databaseService.GetTrader(trader).Dialogue.TryGetValue("SoldItems", out var items) ? items : new List()), curencyReward.SelectMany(x => x).ToList(), _timeUtil.GetHoursAsSeconds(72) ); @@ -344,10 +321,8 @@ public class TradeController( { var itemDetails = _itemHelper.GetItem(itemToSell.Template); if (!(itemDetails.Key && _itemHelper.IsOfBaseclasses(itemDetails.Value.Id, traderDetails.ItemsBuy.Category))) - { // Skip if tpl isn't item OR item doesn't fulfil match traders buy categories continue; - } // Get price of item multiplied by how many are in stack totalPrice += (int)((handbookPrices[itemToSell.Template] ?? 0) * (itemToSell.Upd?.StackObjectsCount ?? 1)); diff --git a/Libraries/Core/Controllers/TraderController.cs b/Libraries/Core/Controllers/TraderController.cs index f2fb7dbd..d1071df0 100644 --- a/Libraries/Core/Controllers/TraderController.cs +++ b/Libraries/Core/Controllers/TraderController.cs @@ -59,17 +59,13 @@ public class TraderController( // Adjust price by traderPriceMultipler config property if (_traderConfig.TraderPriceMultipler != 1) - { foreach (var kvp in trader.Value?.Assort?.BarterScheme) { var barterSchemeItem = kvp.Value[0][0]; if (barterSchemeItem != null && _paymentHelper.IsMoneyTpl(barterSchemeItem?.Template)) - { - barterSchemeItem.Count += Math.Round((barterSchemeItem?.Count * _traderConfig?.TraderPriceMultipler) ?? 0D, 2); - } + barterSchemeItem.Count += Math.Round(barterSchemeItem?.Count * _traderConfig?.TraderPriceMultipler ?? 0D, 2); } - } // Create dict of pristine trader assorts on server start if (_traderAssortService.GetPristineTraderAssort(trader.Key) == null) @@ -81,7 +77,8 @@ public class TraderController( _traderPurchasePersisterService.RemoveStalePurchasesFromProfiles(trader.Key); // Set to next hour on clock or current time + 60 mins - trader.Value.Base.NextResupply = traderResetStartsWithServer ? (int)_traderHelper.GetNextUpdateTimestamp(trader.Value.Base.Id) : (int)nextHourTimestamp; + trader.Value.Base.NextResupply = + traderResetStartsWithServer ? (int)_traderHelper.GetNextUpdateTimestamp(trader.Value.Base.Id) : (int)nextHourTimestamp; } } @@ -101,10 +98,7 @@ public class TraderController( continue; case Traders.FENCE: { - if (_fenceService.NeedsPartialRefresh()) - { - _fenceService.GenerateFenceAssorts(); - } + if (_fenceService.NeedsPartialRefresh()) _fenceService.GenerateFenceAssorts(); continue; } } @@ -135,10 +129,7 @@ public class TraderController( { traders.Add(_traderHelper.GetTrader(traderId, sessionId)); - if (pmcData?.Info != null) - { - _traderHelper.LevelUp(traderId, pmcData); - } + if (pmcData?.Info != null) _traderHelper.LevelUp(traderId, pmcData); } traders.Sort(SortByTraderId); @@ -186,7 +177,7 @@ public class TraderController( { var handbookPrices = _ragfairPriceService.GetAllStaticPrices(); - return new() + return new GetItemPricesResponse { SupplyNextTime = _traderHelper.GetNextUpdateTimestamp(traderId), Prices = handbookPrices, diff --git a/Libraries/Core/Controllers/WishlistController.cs b/Libraries/Core/Controllers/WishlistController.cs index 3b13fc5b..935093e5 100644 --- a/Libraries/Core/Controllers/WishlistController.cs +++ b/Libraries/Core/Controllers/WishlistController.cs @@ -23,10 +23,7 @@ public class WishlistController( AddToWishlistRequest request, string sessionId) { - foreach (var item in request.Items) - { - pmcData.WishList.Dictionary.Add(item.Key, item.Value); - } + foreach (var item in request.Items) pmcData.WishList.Dictionary.Add(item.Key, item.Value); return _eventOutputHolder.GetOutput(sessionId); } @@ -43,10 +40,7 @@ public class WishlistController( RemoveFromWishlistRequest request, string sessionId) { - foreach (var itemId in request.Items) - { - pmcData.WishList.Dictionary.Remove(itemId); - } + foreach (var itemId in request.Items) pmcData.WishList.Dictionary.Remove(itemId); return _eventOutputHolder.GetOutput(sessionId); } diff --git a/Libraries/Core/DI/OnLoad.cs b/Libraries/Core/DI/OnLoad.cs index c697c111..60ada15a 100644 --- a/Libraries/Core/DI/OnLoad.cs +++ b/Libraries/Core/DI/OnLoad.cs @@ -4,4 +4,4 @@ public interface OnLoad { Task OnLoad(); string GetRoute(); -} \ No newline at end of file +} diff --git a/Libraries/Core/DI/Router.cs b/Libraries/Core/DI/Router.cs index 087c72b7..83598e9b 100644 --- a/Libraries/Core/DI/Router.cs +++ b/Libraries/Core/DI/Router.cs @@ -20,10 +20,7 @@ public abstract class Router protected List GetInternalHandledRoutes() { - if (handledRoutes.Count == 0) - { - handledRoutes = GetHandledRoutes(); - } + if (handledRoutes.Count == 0) handledRoutes = GetHandledRoutes(); return handledRoutes; } @@ -31,11 +28,9 @@ public abstract class Router public bool CanHandle(string url, bool partialMatch = false) { if (partialMatch) - { return GetInternalHandledRoutes() .Where((r) => r.dynamic) .Any((r) => url.Contains(r.route)); - } return GetInternalHandledRoutes() .Where((r) => !r.dynamic) @@ -59,10 +54,7 @@ public abstract class StaticRouter : Router var action = _actions.Single(route => route.url == url); var type = action.bodyType; IRequestData? info = null; - if (type != null && !string.IsNullOrEmpty(body)) - { - info = (IRequestData?)_jsonUtil.Deserialize(body, type); - } + if (type != null && !string.IsNullOrEmpty(body)) info = (IRequestData?)_jsonUtil.Deserialize(body, type); return action.action(url, info, sessionID, output); } @@ -74,8 +66,8 @@ public abstract class StaticRouter : Router public abstract class DynamicRouter : Router { - private readonly List actions; private readonly JsonUtil _jsonUtil; + private readonly List actions; public DynamicRouter(JsonUtil jsonUtil, List routes) : base() { @@ -88,10 +80,7 @@ public abstract class DynamicRouter : Router var action = actions.First(r => url.Contains(r.url)); var type = action.bodyType; IRequestData? info = null; - if (type != null && !string.IsNullOrEmpty(body)) - { - info = (IRequestData?)_jsonUtil.Deserialize(body, type); - } + if (type != null && !string.IsNullOrEmpty(body)) info = (IRequestData?)_jsonUtil.Deserialize(body, type); return action.action(url, info, sessionID, output); } diff --git a/Libraries/Core/Generators/BotEquipmentModGenerator.cs b/Libraries/Core/Generators/BotEquipmentModGenerator.cs index 23ce9a21..55c7c3ca 100644 --- a/Libraries/Core/Generators/BotEquipmentModGenerator.cs +++ b/Libraries/Core/Generators/BotEquipmentModGenerator.cs @@ -58,9 +58,7 @@ public class BotEquipmentModGenerator( // Get mod pool for the desired item if (!settings.ModPool.TryGetValue(parentTemplate.Id, out var compatibleModsPool)) - { _logger.Warning($"bot: {settings.BotData.Role} lacks a mod slot pool for item: {parentTemplate.Id} {parentTemplate.Name}"); - } // Iterate over mod pool and choose mods to add to item foreach (var (modSlotName, modPool) in compatibleModsPool ?? []) @@ -93,16 +91,10 @@ public class BotEquipmentModGenerator( ); // Rolled to skip mod and it shouldn't be force-spawned - if (modSpawnResult == ModSpawn.SKIP && !forceSpawn) - { - continue; - } + if (modSpawnResult == ModSpawn.SKIP && !forceSpawn) continue; // Ensure submods for nvgs all spawn together - if (modSlotName == "mod_nvg") - { - forceSpawn = true; - } + if (modSlotName == "mod_nvg") forceSpawn = true; // Get pool of items we can add for this slot var modPoolToChooseFrom = modPool; @@ -110,10 +102,8 @@ public class BotEquipmentModGenerator( // Filter the pool of items in blacklist var filteredModPool = FilterModsByBlacklist(modPoolToChooseFrom, specificBlacklist, modSlotName); if (filteredModPool.Count > 0) - { // use filtered pool as it has items in it modPoolToChooseFrom = filteredModPool; - } // Slot can hold armor plates + we are filtering possible items by bot level, handle if ( @@ -131,11 +121,9 @@ public class BotEquipmentModGenerator( { case Result.UNKNOWN_FAILURE or Result.NO_DEFAULT_FILTER: if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug( $"Plate slot: {modSlotName} selection for armor: {parentTemplate.Id} failed: {plateSlotFilteringOutcome.Result}, skipping" ); - } continue; case Result.LACKS_PLATE_WEIGHTS: @@ -172,10 +160,7 @@ public class BotEquipmentModGenerator( } // Compatible item not found + not required - skip - if (!(found || itemSlotTemplate.Required.GetValueOrDefault(false))) - { - continue; - } + if (!(found || itemSlotTemplate.Required.GetValueOrDefault(false))) continue; // Get chosen mods db template and check it fits into slot var modTemplate = _itemHelper.GetItem(modTpl); @@ -188,9 +173,7 @@ public class BotEquipmentModGenerator( settings.BotData.Role ) ) - { continue; - } // Generate new id to ensure all items are unique on bot var modId = _hashUtil.Generate(); @@ -200,7 +183,6 @@ public class BotEquipmentModGenerator( // Does item being added exist in mod pool - has its own mod pool if (settings.ModPool.ContainsKey(modTpl)) - { // Call self again with mod being added as item to add child mods to GenerateModsForEquipment( equipment, @@ -210,7 +192,6 @@ public class BotEquipmentModGenerator( specificBlacklist, forceSpawn ); - } } return equipment; @@ -230,7 +211,7 @@ public class BotEquipmentModGenerator( var result = new FilterPlateModsForSlotByLevelResult { Result = Result.UNKNOWN_FAILURE, - PlateModTemplates = null, + PlateModTemplates = null }; // Not pmc or not a plate slot, return original mod pool array @@ -299,29 +280,21 @@ public class BotEquipmentModGenerator( chosenArmorPlateLevelString = chosenArmorPlateLevelDouble.ToString(); // New chosen plate class is higher than max, then set to min and check if valid - if (chosenArmorPlateLevelDouble > minMaxArmorPlateClass.Max) - { - chosenArmorPlateLevelString = minMaxArmorPlateClass.Min.ToString(); - } + if (chosenArmorPlateLevelDouble > minMaxArmorPlateClass.Max) chosenArmorPlateLevelString = minMaxArmorPlateClass.Min.ToString(); findCompatiblePlateAttempts++; platesOfDesiredLevel = platesFromDb.Where((item) => item.Properties.ArmorClass == chosenArmorPlateLevelDouble); // Valid plates found, exit - if (platesOfDesiredLevel.Any()) - { - break; - } + if (platesOfDesiredLevel.Any()) break; // No valid plate class found in 3 tries, attempt default plates if (findCompatiblePlateAttempts >= maxAttempts) { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug( $"Plate filter too restrictive for armor: {armorItem.Name} {armorItem.Id}, unable to find plates of level: {chosenArmorPlateLevelString}, using items default plate" ); - } var defaultPlate = GetDefaultPlateTpl(armorItem, modSlot); if (defaultPlate is not null) @@ -365,15 +338,9 @@ public class BotEquipmentModGenerator( platePool.Sort( (x, y) => { - if (x.Properties.ArmorClass < y.Properties.ArmorClass) - { - return -1; - } + if (x.Properties.ArmorClass < y.Properties.ArmorClass) return -1; - if (x.Properties.ArmorClass > y.Properties.ArmorClass) - { - return 1; - } + if (x.Properties.ArmorClass > y.Properties.ArmorClass) return 1; return 0; } @@ -381,8 +348,8 @@ public class BotEquipmentModGenerator( return new MinMax { - Min = (platePool[0].Properties.ArmorClass), - Max = (platePool[platePool.Count - 1].Properties.ArmorClass), + Min = platePool[0].Properties.ArmorClass, + Max = platePool[platePool.Count - 1].Properties.ArmorClass }; } @@ -430,7 +397,7 @@ public class BotEquipmentModGenerator( { weaponName = request.ParentTemplate.Name, weaponId = request.ParentTemplate.Id, - botRole = request.BotData.Role, + botRole = request.BotData.Role } ) ); @@ -469,7 +436,7 @@ public class BotEquipmentModGenerator( modSlot = modSlot, weaponId = request.ParentTemplate.Id, weaponName = request.ParentTemplate.Name, - botRole = request.BotData.Role, + botRole = request.BotData.Role } ) ); @@ -484,10 +451,7 @@ public class BotEquipmentModGenerator( request.ModSpawnChances, botEquipConfig ); - if (modSpawnResult == ModSpawn.SKIP) - { - continue; - } + if (modSpawnResult == ModSpawn.SKIP) continue; var isRandomisableSlot = randomisationSettings?.RandomisedWeaponModSlots?.Contains(modSlot) ?? false; ModToSpawnRequest modToSpawnRequest = new() @@ -509,15 +473,9 @@ public class BotEquipmentModGenerator( var modToAdd = ChooseModToPutIntoSlot(modToSpawnRequest); // Compatible mod not found - if (modToAdd is null) - { - continue; - } + if (modToAdd is null) continue; - if (!IsModValidForSlot(modToAdd, modsParentSlot, modSlot, request.ParentTemplate, request.BotData.Role)) - { - continue; - } + if (!IsModValidForSlot(modToAdd, modsParentSlot, modSlot, request.ParentTemplate, request.BotData.Role)) continue; var modToAddTemplate = modToAdd.Value; // Skip adding mod to weapon if type limit reached @@ -530,9 +488,7 @@ public class BotEquipmentModGenerator( request.Weapon ) ) - { continue; - } // If item is a mount for scopes, set scope chance to 100%, this helps fix empty mounts appearing on weapons if (ModSlotCanHoldScope(modSlot, modToAddTemplate.Value.Parent)) @@ -543,7 +499,6 @@ public class BotEquipmentModGenerator( // Hydrate pool of mods that fit into mount as its a randomisable slot if (isRandomisableSlot) - { // Add scope mods to modPool dictionary to ensure the mount has a scope in the pool to pick AddCompatibleModsForProvidedMod( "mod_scope", @@ -551,7 +506,6 @@ public class BotEquipmentModGenerator( request.ModPool, botEquipBlacklist ); - } } // If picked item is muzzle adapter that can hold a child, adjust spawn chance @@ -572,14 +526,12 @@ public class BotEquipmentModGenerator( // Handguard mod can take a sub handguard mod + weapon has no UBGL (takes same slot) // Force spawn chance to be 100% to ensure it gets added if ( - modSlot == "mod_handguard" && - modToAddTemplate.Value.Properties.Slots.Any((slot) => slot.Name == "mod_handguard") && - !request.Weapon.Any((item) => item.SlotId == "mod_launcher") - ) - { + modSlot == "mod_handguard" && + modToAddTemplate.Value.Properties.Slots.Any((slot) => slot.Name == "mod_handguard") && + !request.Weapon.Any((item) => item.SlotId == "mod_launcher") + ) // Needed for handguards with lower request.ModSpawnChances["mod_handguard"] = 100; - } // If stock mod can take a sub stock mod, force spawn chance to be 100% to ensure sub-stock gets added // Or if bot has stock force enabled @@ -594,13 +546,8 @@ public class BotEquipmentModGenerator( if (_itemHelper.IsOfBaseclass(modToAddTemplate.Value.Id, BaseClasses.IRON_SIGHT)) { if (modSlot == "mod_sight_front") - { request.WeaponStats.HasFrontIronSight = true; - } - else if (modSlot == "mod_sight_rear") - { - request.WeaponStats.HasRearIronSight = true; - } + else if (modSlot == "mod_sight_rear") request.WeaponStats.HasRearIronSight = true; } else if (!(request.WeaponStats.HasOptic ?? false) && _itemHelper.IsOfBaseclass(modToAddTemplate.Value.Id, BaseClasses.SIGHTS)) { @@ -620,10 +567,7 @@ public class BotEquipmentModGenerator( ); // Update conflicting item list now item has been chosen - foreach (var conflictingItem in modToAddTemplate.Value.Properties.ConflictingItems) - { - request.ConflictingItemTpls.Add(conflictingItem); - } + foreach (var conflictingItem in modToAddTemplate.Value.Properties.ConflictingItems) request.ConflictingItemTpls.Add(conflictingItem); // I first thought we could use the recursive generateModsForItems as previously for cylinder magazines. // However, the recursion doesn't go over the slots of the parent mod but over the modPool which is given by the bot config @@ -673,7 +617,7 @@ public class BotEquipmentModGenerator( ParentTemplate = modToAddTemplate.Value, ModSpawnChances = request.ModSpawnChances, AmmoTpl = request.AmmoTpl, - BotData = new() + BotData = new BotData { Role = request.BotData.Role, Level = request.BotData.Level, @@ -725,10 +669,8 @@ public class BotEquipmentModGenerator( { // Gas block /w front sight is special case, deem it a 'front sight' too if (modSlot == "mod_gas_block" && tpl == "5ae30e795acfc408fb139a0b") - { // M4A1 front sight with gas block return true; - } return ((string[]) ["mod_sight_front", "mod_sight_rear"]).Contains(modSlot); } @@ -741,19 +683,17 @@ public class BotEquipmentModGenerator( /// true if it can hold a scope public bool ModSlotCanHoldScope(string modSlot, string modsParentId) { - return ( - ((string[]) - [ - "mod_scope", - "mod_mount", - "mod_mount_000", - "mod_scope_000", - "mod_scope_001", - "mod_scope_002", - "mod_scope_003", - ]).Contains(modSlot.ToLower()) && - modsParentId == BaseClasses.MOUNT - ); + return ((string[]) + [ + "mod_scope", + "mod_mount", + "mod_mount_000", + "mod_scope_000", + "mod_scope_001", + "mod_scope_002", + "mod_scope_003" + ]).Contains(modSlot.ToLower()) && + modsParentId == BaseClasses.MOUNT; } /// @@ -778,10 +718,7 @@ public class BotEquipmentModGenerator( return; } - foreach (var modName in modSlotsToAdjust) - { - modSpawnChances[modName] = newChancePercent; - } + foreach (var modName in modSlotsToAdjust) modSpawnChances[modName] = newChancePercent; } /// @@ -804,10 +741,7 @@ public class BotEquipmentModGenerator( public List SortModKeys(List unsortedSlotKeys, string itemTplWithKeysToSort) { // No need to sort with only 1 item in array - if (unsortedSlotKeys.Count <= 1) - { - return unsortedSlotKeys; - } + if (unsortedSlotKeys.Count <= 1) return unsortedSlotKeys; var isMount = _itemHelper.IsOfBaseclass(itemTplWithKeysToSort, BaseClasses.MOUNT); @@ -940,17 +874,13 @@ public class BotEquipmentModGenerator( { var slotRequired = itemSlot.Required; if (GetAmmoContainers().Contains(modSlotName)) - { // Always force mags/cartridges in weapon to spawn return ModSpawn.SPAWN; - } var spawnMod = _probabilityHelper.RollChance(modSpawnChances.GetValueOrDefault(modSlotName.ToLower())); if (!spawnMod && (slotRequired.GetValueOrDefault(false) || (botEquipConfig.WeaponSlotIdsToMakeRequired?.Contains(modSlotName) ?? false))) - { // Edge case: Mod is required but spawn chance roll failed, choose default mod spawn for slot return ModSpawn.DEFAULT_MOD; - } return spawnMod ? ModSpawn.SPAWN : ModSpawn.SKIP; } @@ -967,10 +897,7 @@ public class BotEquipmentModGenerator( var weaponTemplate = _itemHelper.GetItem(request.Weapon[0].Template).Value; // It's ammo, use predefined ammo parameter - if (GetAmmoContainers().Contains(request.ModSlot) && request.ModSlot != "mod_magazine") - { - return _itemHelper.GetItem(request.AmmoTpl); - } + if (GetAmmoContainers().Contains(request.ModSlot) && request.ModSlot != "mod_magazine") return _itemHelper.GetItem(request.AmmoTpl); // Ensure there's a pool of mods to pick from var modPool = GetModPoolForSlot(request, weaponTemplate); @@ -978,47 +905,35 @@ public class BotEquipmentModGenerator( { // Nothing in mod pool + item not required if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug($"Mod pool for optional slot: {request.ModSlot} on item: {request.ParentTemplate.Name} was empty, skipping mod"); - } return null; } // Filter out non-whitelisted scopes, use full modpool if filtered pool would have no elements if (request.ModSlot.Contains("mod_scope") && request.BotWeaponSightWhitelist is not null) - { // scope pool has more than one scope if (modPool.Count > 1) - { modPool = FilterSightsByWeaponType(request.Weapon[0], modPool, request.BotWeaponSightWhitelist); - } - } if (request.ModSlot == "mod_gas_block") { - if (request.WeaponStats.HasOptic ?? false && modPool.Count > 1) + if (request.WeaponStats.HasOptic ?? (false && modPool.Count > 1)) { // Attempt to limit modpool to low profile gas blocks when weapon has an optic var onlyLowProfileGasBlocks = modPool.Where( (tpl) => _botConfig.LowProfileGasBlockTpls.Contains(tpl) ); - if (onlyLowProfileGasBlocks.Count() > 0) - { - modPool = onlyLowProfileGasBlocks.ToHashSet(); - } + if (onlyLowProfileGasBlocks.Count() > 0) modPool = onlyLowProfileGasBlocks.ToHashSet(); } - else if (request.WeaponStats.HasRearIronSight ?? false && modPool.Count() > 1) + else if (request.WeaponStats.HasRearIronSight ?? (false && modPool.Count() > 1)) { // Attempt to limit modpool to high profile gas blocks when weapon has rear iron sight + no front iron sight var onlyHighProfileGasBlocks = modPool.Where( (tpl) => !_botConfig.LowProfileGasBlockTpls.Contains(tpl) ); - if (onlyHighProfileGasBlocks.Count() > 0) - { - modPool = onlyHighProfileGasBlocks.ToHashSet(); - } + if (onlyHighProfileGasBlocks.Count() > 0) modPool = onlyHighProfileGasBlocks.ToHashSet(); } } @@ -1028,9 +943,7 @@ public class BotEquipmentModGenerator( (request?.IsRandomisableSlot ?? false) && request.RandomisationSettings.MinimumMagazineSize is not null ) - { modPool = GetFilterdMagazinePoolByCapacity(request, modPool).ToHashSet(); - } // Pick random mod that's compatible var chosenModResult = GetCompatibleWeaponModTplForSlotFromPool( @@ -1042,19 +955,13 @@ public class BotEquipmentModGenerator( request.ModSlot ); if (chosenModResult.SlotBlocked.GetValueOrDefault(false) && !parentSlot.Required.GetValueOrDefault(false)) - { // Don't bother trying to fit mod, slot is completely blocked return null; - } // Log if mod chosen was incompatible - if (chosenModResult.Incompatible.GetValueOrDefault(false) && !(parentSlot.Required.GetValueOrDefault(false))) - { + if (chosenModResult.Incompatible.GetValueOrDefault(false) && !parentSlot.Required.GetValueOrDefault(false)) if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug($"Unable to find compatible mod of type: {parentSlot.Name}, in slot: {request.ModSlot} reason: {chosenModResult.Reason}"); - } - } // Get random mod to attach from items db for required slots if none found above if (!(chosenModResult.Found ?? false) && parentSlot != null && (parentSlot.Required ?? false)) @@ -1064,19 +971,14 @@ public class BotEquipmentModGenerator( } // Compatible item not found + not required - if (!(chosenModResult.Found.GetValueOrDefault(false)) && parentSlot is not null && (!parentSlot.Required.GetValueOrDefault(false))) - { - return null; - } + if (!chosenModResult.Found.GetValueOrDefault(false) && parentSlot is not null && !parentSlot.Required.GetValueOrDefault(false)) return null; if (!(chosenModResult.Found ?? false) && parentSlot is not null) { if (parentSlot.Required.GetValueOrDefault(false)) - { _logger.Warning( $"Required slot unable to be filled, {request.ModSlot} on {request.ParentTemplate.Name} {request.ParentTemplate.Id} for weapon: {request.Weapon[0].Template}" ); - } return null; } @@ -1105,7 +1007,7 @@ public class BotEquipmentModGenerator( if (!desiredMagazineTpls.Any()) { - _logger.Warning($"Magazine size filter for { weaponTpl} was too strict, ignoring filter"); + _logger.Warning($"Magazine size filter for {weaponTpl} was too strict, ignoring filter"); return modPool; } @@ -1130,21 +1032,17 @@ public class BotEquipmentModGenerator( // Filter out incompatible mods from pool var preFilteredModPool = GetFilteredModPool(modPool, request.ConflictingItemTpls); if (preFilteredModPool.Count == 0) - { - return new() + return new ChooseRandomCompatibleModResult { Incompatible = true, Found = false, Reason = $"Unable to add mod to {choiceTypeEnum.ToString()} slot: {modSlotName}. All: {modPool.Count()} had conflicts" }; - } // Filter mod pool to only items that appear in parents allowed list preFilteredModPool = preFilteredModPool.Where((tpl) => parentSlot.Props.Filters[0].Filter.Contains(tpl)).ToList(); if (preFilteredModPool.Count == 0) - { - return new() { Incompatible = true, Found = false, Reason = "No mods found in parents allowed list" }; - } + return new ChooseRandomCompatibleModResult { Incompatible = true, Found = false, Reason = "No mods found in parents allowed list" }; return GetCompatibleModFromPool(preFilteredModPool, choiceTypeEnum, weapon); } @@ -1166,7 +1064,7 @@ public class BotEquipmentModGenerator( { Incompatible = true, Found = false, - Reason = "unknown", + Reason = "unknown" }; // Limit how many attempts to find a compatible mod can occur before giving up @@ -1178,16 +1076,12 @@ public class BotEquipmentModGenerator( chosenTpl = exhaustableModPool.GetRandomValue(); var pickedItemDetails = _itemHelper.GetItem(chosenTpl); if (!pickedItemDetails.Key) - { // Not valid item, try again continue; - } if (pickedItemDetails.Value.Properties is null) - { // no props data, try again continue; - } // Success - Default wanted + only 1 item in pool if (modSpawnType == ModSpawn.DEFAULT_MOD && modPool.Count == 1) @@ -1270,15 +1164,10 @@ public class BotEquipmentModGenerator( public HashSet GetModPoolForSlot(ModToSpawnRequest request, TemplateItem weaponTemplate) { // Mod is flagged as being default only, try and find it in globals - if (request.ModSpawnResult == ModSpawn.DEFAULT_MOD) - { - return GetModPoolForDefaultSlot(request, weaponTemplate); - } + if (request.ModSpawnResult == ModSpawn.DEFAULT_MOD) return GetModPoolForDefaultSlot(request, weaponTemplate); if (request.IsRandomisableSlot.GetValueOrDefault(false)) - { return GetDynamicModPool(request.ParentTemplate.Id, request.ModSlot, request.BotEquipBlacklist); - } // Required mod is not default or randomisable, use existing pool return request.ItemModPool[request.ModSlot]; @@ -1290,12 +1179,8 @@ public class BotEquipmentModGenerator( if (matchingModFromPreset is null) { if (request.ItemModPool[request.ModSlot]?.Count > 1) - { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug($"{request.BotData.Role} No default: {request.ModSlot} mod found for: {weaponTemplate.Name}, using existing pool"); - } - } // Couldn't find default in globals, use existing mod pool data return request.ItemModPool[request.ModSlot]; @@ -1306,10 +1191,8 @@ public class BotEquipmentModGenerator( // You'd have a mod being picked without any sub-mods in its chain, possibly resulting in missing required mods not being added // Mod is in existing mod pool if (request.ItemModPool[request.ModSlot].Contains(matchingModFromPreset.Template)) - { // Found mod on preset + it already exists in mod pool return [matchingModFromPreset.Template]; - } // Get an array of items that are allowed in slot from parent item // Check the filter of the slot to ensure a chosen mod fits @@ -1325,36 +1208,26 @@ public class BotEquipmentModGenerator( ) { // Chosen mod has no conflicts + no children + is in parent compat list - if (!request.ConflictingItemTpls.Contains(matchingModFromPreset.Template)) - { - return [matchingModFromPreset.Template]; - } + if (!request.ConflictingItemTpls.Contains(matchingModFromPreset.Template)) return [matchingModFromPreset.Template]; // Above chosen mod had conflicts with existing weapon mods if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug( $"{request.BotData.Role} Chosen default: {request.ModSlot} mod found for: {weaponTemplate.Name} weapon conflicts with item on weapon, cannot use default" ); - } var existingModPool = request.ItemModPool[request.ModSlot]; if (existingModPool.Count == 1) { // The only item in pool isn't compatible if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug( $"{request.BotData.Role} {request.ModSlot} Mod pool for: {weaponTemplate.Name} weapon has only incompatible items, using parent list instead" ); - } // Last ditch, use full pool of items minus conflicts var newListOfModsForSlot = parentSlotCompatibleItems.Where((tpl) => !request.ConflictingItemTpls.Contains(tpl)); - if (newListOfModsForSlot.Count() > 0) - { - return newListOfModsForSlot.ToHashSet(); - } + if (newListOfModsForSlot.Count() > 0) return newListOfModsForSlot.ToHashSet(); } // Return full mod pool @@ -1381,17 +1254,11 @@ public class BotEquipmentModGenerator( { // Edge case - using mp5sd reciever means default mp5 handguard doesn't fit var isMp5sd = parentItemTpl == "5926f2e086f7745aae644231"; - if (isMp5sd) - { - return _presetHelper.GetPreset("59411abb86f77478f702b5d2"); - } + if (isMp5sd) return _presetHelper.GetPreset("59411abb86f77478f702b5d2"); // Edge case - dvl 500mm is the silenced barrel and has specific muzzle mods var isDvl500mmSilencedBarrel = parentItemTpl == "5888945a2459774bf43ba385"; - if (isDvl500mmSilencedBarrel) - { - return _presetHelper.GetPreset("59e8d2b386f77445830dd299"); - } + if (isDvl500mmSilencedBarrel) return _presetHelper.GetPreset("59e8d2b386f77445830dd299"); return _presetHelper.GetDefaultPreset(weaponTemplate.Id); } @@ -1405,10 +1272,7 @@ public class BotEquipmentModGenerator( public bool WeaponModComboIsIncompatible(List weapon, string modTpl) { // STM-9 + AR-15 Lone Star Ion Lite handguard - if (weapon[0].Template == "60339954d62c9b14ed777c06" && modTpl == "5d4405f0a4b9361e6a4e6bd9") - { - return true; - } + if (weapon[0].Template == "60339954d62c9b14ed777c06" && modTpl == "5d4405f0a4b9361e6a4e6bd9") return true; return false; } @@ -1464,10 +1328,7 @@ public class BotEquipmentModGenerator( while (exhaustableModPool.HasValues()) { tmpModTpl = exhaustableModPool.GetRandomValue(); - if (!_botGeneratorHelper.IsItemIncompatibleWithCurrentItems(items, tmpModTpl, modSlot).Incompatible.GetValueOrDefault(false)) - { - return tmpModTpl; - } + if (!_botGeneratorHelper.IsItemIncompatibleWithCurrentItems(items, tmpModTpl, modSlot).Incompatible.GetValueOrDefault(false)) return tmpModTpl; } // No mod found @@ -1497,14 +1358,11 @@ public class BotEquipmentModGenerator( new { modId = modBeingAddedDbTemplate.Value?.Id ?? "UNKNOWN", - modSlot = modSlot, + modSlot = modSlot } ) ); - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Item -> {parentTemplate?.Id}; Slot -> {modSlot}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Item -> {parentTemplate?.Id}; Slot -> {modSlot}"); return false; } @@ -1514,7 +1372,6 @@ public class BotEquipmentModGenerator( { // Parent slot must be filled but db object is invalid, show warning and return false if (slotAddedToTemplate.Required ?? false) - { _logger.Warning( _localisationService.GetText( "bot-unable_to_add_mod_item_invalid", @@ -1523,11 +1380,10 @@ public class BotEquipmentModGenerator( itemName = modBeingAddedDbTemplate.Value?.Name ?? "UNKNOWN", iodSlot = modSlot, parentItemName = parentTemplate.Name, - botRole = botRole, + botRole = botRole } ) ); - } return false; } @@ -1548,21 +1404,14 @@ public class BotEquipmentModGenerator( EquipmentFilterDetails botEquipBlacklist) { var desiredSlotObject = modTemplate.Properties.Slots?.FirstOrDefault((slot) => slot.Name.Contains(desiredSlotName)); - if (desiredSlotObject is null) - { - return; - } + if (desiredSlotObject is null) return; var supportedSubMods = desiredSlotObject.Props.Filters[0].Filter; - if (supportedSubMods is null) - { - return; - } + if (supportedSubMods is null) return; // Filter mods var filteredMods = FilterModsByBlacklist(supportedSubMods.ToHashSet(), botEquipBlacklist, desiredSlotName); if (!filteredMods.Any()) - { _logger.Warning( _localisationService .GetText( @@ -1570,11 +1419,10 @@ public class BotEquipmentModGenerator( new { slotName = desiredSlotObject.Name, - itemName = modTemplate.Name, + itemName = modTemplate.Name } ) ); - } modPool.TryAdd(modTemplate.Id, new Dictionary>()); @@ -1615,10 +1463,7 @@ public class BotEquipmentModGenerator( public HashSet FilterModsByBlacklist(HashSet allowedMods, EquipmentFilterDetails? botEquipBlacklist, string modSlot) { // No blacklist, nothing to filter out - if (botEquipBlacklist is null) - { - return allowedMods; - } + if (botEquipBlacklist is null) return allowedMods; var result = new HashSet(); @@ -1651,24 +1496,21 @@ public class BotEquipmentModGenerator( new { weaponId = cylinderMagTemplate.Id, - weaponName = cylinderMagTemplate.Name, + weaponName = cylinderMagTemplate.Name } ) ); var camoraSlots = cylinderMagTemplate.Properties.Slots.Where((slot) => slot.Name.StartsWith("camora")); // Attempt to generate camora slots for item - modPool[cylinderMagTemplate.Id] = new(); - foreach (var camora in camoraSlots) - { - modPool[cylinderMagTemplate.Id][camora.Name] = camora.Props.Filters?[0].Filter.ToHashSet(); - } + modPool[cylinderMagTemplate.Id] = new Dictionary>(); + foreach (var camora in camoraSlots) modPool[cylinderMagTemplate.Id][camora.Name] = camora.Props.Filters?[0].Filter.ToHashSet(); itemModPool = modPool[cylinderMagTemplate.Id]; } ExhaustableArray exhaustableModPool = null; - string modSlot = "cartridges"; + var modSlot = "cartridges"; const string camoraFirstSlot = "camora_000"; if (itemModPool.TryGetValue(modSlot, out var value)) { @@ -1709,13 +1551,15 @@ public class BotEquipmentModGenerator( { var modSlotId = slot.Name; var modId = _hashUtil.Generate(); - items.Add(new() - { - Id = modId, - Template = modTpl, - ParentId = cylinderMagParentId, - SlotId = modSlotId - }); + items.Add( + new Item + { + Id = modId, + Template = modTpl, + ParentId = cylinderMagParentId, + SlotId = modSlotId + } + ); } } @@ -1749,11 +1593,9 @@ public class BotEquipmentModGenerator( if (!botWeaponSightWhitelist.TryGetValue(weaponDetails.Value.Parent, out var whitelistedSightTypes)) { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug( $"Unable to find whitelist for weapon type: {weaponDetails.Value.Parent} {weaponDetails.Value.Name}, skipping sight filtering" ); - } return scopes; } @@ -1794,10 +1636,8 @@ public class BotEquipmentModGenerator( ) ) ?? false) - { // Add mod to allowed list filteredScopesAndMods.Add(item); - } } } @@ -1805,9 +1645,7 @@ public class BotEquipmentModGenerator( if (filteredScopesAndMods is null || filteredScopesAndMods.Count() == 0) { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug($"Scope whitelist too restrictive for: {weapon.Template} {weaponDetails.Value.Name}, skipping filter"); - } return scopes; } diff --git a/Libraries/Core/Generators/BotGenerator.cs b/Libraries/Core/Generators/BotGenerator.cs index 8a23e957..acb12fc9 100644 --- a/Libraries/Core/Generators/BotGenerator.cs +++ b/Libraries/Core/Generators/BotGenerator.cs @@ -66,7 +66,7 @@ public class BotGenerator( BotRelativeLevelDeltaMin = 0, BotCountToGenerate = 1, BotDifficulty = difficulty, - IsPlayerScav = true, + IsPlayerScav = true }; bot = GenerateBot(sessionId, bot, botTemplate, botGenDetails); @@ -128,10 +128,7 @@ public class BotGenerator( ? preparedBotBase.Info.Side // Use side to get usec.json or bear.json when bot will be PMC : botGenerationDetails.Role; var botJsonTemplateClone = _cloner.Clone(_botHelper.GetBotTemplate(botRole)); - if (botJsonTemplateClone is null) - { - _logger.Error($"Unable to retrieve: {botRole} bot template, cannot generate bot of this type"); - } + if (botJsonTemplateClone is null) _logger.Error($"Unable to retrieve: {botRole} bot template, cannot generate bot of this type"); return GenerateBot(sessionId, preparedBotBase, botJsonTemplateClone, botGenerationDetails); } @@ -185,14 +182,12 @@ public class BotGenerator( // Only filter bot equipment, never players if (!botGenerationDetails.IsPlayerScav.GetValueOrDefault(false)) - { _botEquipmentFilterService.FilterBotEquipment( sessionId, botJsonTemplate, botLevel.Level.Value, botGenerationDetails ); - } bot.Info.Nickname = _botNameService.GenerateUniqueBotNickname( botJsonTemplate, @@ -214,24 +209,17 @@ public class BotGenerator( } if (!_seasonalEventService.ChristmasEventEnabled()) - { // Process all bots EXCEPT gifter, he needs christmas items if (botGenerationDetails.Role != "gifter") - { _seasonalEventService.RemoveChristmasItemsFromBotInventory( botJsonTemplate.BotInventory, botGenerationDetails.Role ); - } - } RemoveBlacklistedLootFromBotTemplate(botJsonTemplate.BotInventory); // Remove hideout data if bot is not a PMC or pscav - match what live sends - if (!(botGenerationDetails.IsPmc.GetValueOrDefault(false) || botGenerationDetails.IsPlayerScav.GetValueOrDefault(false))) - { - bot.Hideout = null; - } + if (!(botGenerationDetails.IsPmc.GetValueOrDefault(false) || botGenerationDetails.IsPlayerScav.GetValueOrDefault(false))) bot.Hideout = null; bot.Info.Experience = botLevel.Exp; bot.Info.Level = botLevel.Level; @@ -260,10 +248,7 @@ public class BotGenerator( { bot.Info.IsStreamerModeAvailable = true; // Set to true so client patches can pick it up later - client sometimes alters botrole to assaultGroup SetRandomisedGameVersionAndCategory(bot.Info); - if (bot.Info.GameVersion == GameEditions.UNHEARD) - { - AddAdditionalPocketLootWeightsForUnheardBot(botJsonTemplate); - } + if (bot.Info.GameVersion == GameEditions.UNHEARD) AddAdditionalPocketLootWeightsForUnheardBot(botJsonTemplate); } // Add drip @@ -281,10 +266,7 @@ public class BotGenerator( bot.Info.GameVersion ); - if (_botConfig.BotRolesWithDogTags.Contains(botRoleLowercase)) - { - AddDogtagToBot(bot); - } + if (_botConfig.BotRolesWithDogTags.Contains(botRoleLowercase)) AddDogtagToBot(bot); // Generate new bot ID AddIdsToBot(bot, botGenerationDetails); @@ -293,10 +275,7 @@ public class BotGenerator( GenerateInventoryId(bot); // Set role back to originally requested now its been generated - if (botGenerationDetails.EventRole is not null) - { - bot.Info.Settings.Role = botGenerationDetails.EventRole; - } + if (botGenerationDetails.EventRole is not null) bot.Info.Settings.Role = botGenerationDetails.EventRole; return bot; } @@ -320,13 +299,9 @@ public class BotGenerator( /// Experience for kill public double GetExperienceRewardForKillByDifficulty(Dictionary experiences, string botDifficulty, string role) { - if (!experiences.TryGetValue(botDifficulty.ToLower(), out var result)) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Unable to find experience: {botDifficulty} for {role} bot, falling back to `normal`"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Unable to find experience: {botDifficulty} for {role} bot, falling back to `normal`"); return _randomUtil.GetDouble(experiences["normal"].Min.Value, experiences["normal"].Max.Value); } @@ -385,20 +360,16 @@ public class BotGenerator( ); if (blacklist?.Gear is null) - { // Nothing to filter by return; - } foreach (var (equipmentSlot, blacklistedTpls) in blacklist.Gear) { var equipmentDict = botJsonTemplate.BotInventory.Equipment[equipmentSlot]; foreach (var blacklistedTpl in blacklistedTpls) - { // Set weighting to 0, will never be picked equipmentDict[blacklistedTpl] = 0; - } } } @@ -430,24 +401,14 @@ public class BotGenerator( var propValue = (Dictionary)prop.GetValue(botInventory.Items); // No container, skip - if (propValue?.Count == 0) - { - continue; - } + if (propValue?.Count == 0) continue; List tplsToRemove = []; foreach (var (key, _) in propValue) - { if (_itemFilterService.IsLootableItemBlacklisted(key)) - { tplsToRemove.Add(key); - } - } - foreach (var blacklistedTplToRemove in tplsToRemove) - { - propValue.Remove(blacklistedTplToRemove); - } + foreach (var blacklistedTplToRemove in tplsToRemove) propValue.Remove(blacklistedTplToRemove); prop.SetValue(botInventory.Items, propValue); } @@ -483,10 +444,7 @@ public class BotGenerator( public void LogPmcGeneratedCount(List output) { var pmcCount = output.Aggregate(0, (acc, cur) => { return cur.Info.Side is "Bear" or "Usec" ? acc + 1 : acc; }); - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Generated {output.Count} total bots. Replaced {pmcCount} with PMCs"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Generated {output.Count} total bots. Replaced {pmcCount} with PMCs"); } /// @@ -503,17 +461,17 @@ public class BotGenerator( BotBaseHealth health = new() { - Hydration = new() + Hydration = new CurrentMinMax { Current = _randomUtil.GetInt((int)healthObj.Hydration.Min, (int)healthObj.Hydration.Max), Maximum = healthObj.Hydration.Max }, - Energy = new() + Energy = new CurrentMinMax { Current = _randomUtil.GetInt((int)healthObj.Energy.Min, (int)healthObj.Energy.Max), Maximum = healthObj.Energy.Max }, - Temperature = new() + Temperature = new CurrentMinMax { Current = _randomUtil.GetInt((int)healthObj.Temperature.Min, (int)healthObj.Temperature.Max), Maximum = healthObj.Temperature.Max @@ -523,7 +481,7 @@ public class BotGenerator( { "Head", new BodyPartHealth { - Health = new() + Health = new CurrentMinMax { Current = _randomUtil.GetInt((int)bodyParts.Head.Min, (int)bodyParts.Head.Max), Maximum = Math.Round(bodyParts.Head.Max ?? 0) @@ -533,7 +491,7 @@ public class BotGenerator( { "Chest", new BodyPartHealth { - Health = new() + Health = new CurrentMinMax { Current = _randomUtil.GetInt((int)bodyParts.Chest.Min, (int)bodyParts.Chest.Max), Maximum = Math.Round(bodyParts.Chest.Max ?? 0) @@ -543,7 +501,7 @@ public class BotGenerator( { "Stomach", new BodyPartHealth { - Health = new() + Health = new CurrentMinMax { Current = _randomUtil.GetInt((int)bodyParts.Stomach.Min, (int)bodyParts.Stomach.Max), Maximum = Math.Round(bodyParts.Stomach.Max ?? 0) @@ -553,7 +511,7 @@ public class BotGenerator( { "LeftArm", new BodyPartHealth { - Health = new() + Health = new CurrentMinMax { Current = _randomUtil.GetInt((int)bodyParts.LeftArm.Min, (int)bodyParts.LeftArm.Max), Maximum = Math.Round(bodyParts.LeftArm.Max ?? 0) @@ -563,7 +521,7 @@ public class BotGenerator( { "RightArm", new BodyPartHealth { - Health = new() + Health = new CurrentMinMax { Current = _randomUtil.GetInt((int)bodyParts.RightArm.Min, (int)bodyParts.RightArm.Max), Maximum = Math.Round(bodyParts.RightArm.Max ?? 0) @@ -573,7 +531,7 @@ public class BotGenerator( { "LeftLeg", new BodyPartHealth { - Health = new() + Health = new CurrentMinMax { Current = _randomUtil.GetInt((int)bodyParts.LeftLeg.Min, (int)bodyParts.LeftLeg.Max), Maximum = Math.Round(bodyParts.LeftLeg.Max ?? 0) @@ -583,7 +541,7 @@ public class BotGenerator( { "RightLeg", new BodyPartHealth { - Health = new() + Health = new CurrentMinMax { Current = _randomUtil.GetInt((int)bodyParts.RightLeg.Min, (int)bodyParts.RightLeg.Max), Maximum = Math.Round(bodyParts.RightLeg.Max ?? 0) @@ -665,10 +623,7 @@ public class BotGenerator( { // Get skill from dict, skip if not found var skill = kvp.Value; - if (skill == null) - { - return null; - } + if (skill == null) return null; // All skills have id and progress props var skillToAdd = new BaseSkill @@ -726,16 +681,10 @@ public class BotGenerator( // Optimisation - skip items without a parentId // They are never linked to root inventory item + we already handled root item above - if (item.ParentId is null) - { - continue; - } + if (item.ParentId is null) continue; // Item is a child of root inventory item, update its parentId value to newly generated id - if (item.ParentId == profile.Inventory.Equipment) - { - item.ParentId = newInventoryItemId; - } + if (item.ParentId == profile.Inventory.Equipment) item.ParentId = newInventoryItemId; } // Update inventory equipment id to new one we generated @@ -797,10 +746,10 @@ public class BotGenerator( Template = GetDogtagTplByGameVersionAndSide(bot.Info.Side, bot.Info.GameVersion), ParentId = bot.Inventory.Equipment, SlotId = "Dogtag", - Upd = new() + Upd = new Upd { - SpawnedInSession = true, - }, + SpawnedInSession = true + } }; bot.Inventory.Items.Add(inventoryItem); @@ -815,7 +764,6 @@ public class BotGenerator( public string GetDogtagTplByGameVersionAndSide(string side, string gameVersion) { if (side.ToLower() == "usec") - { switch (gameVersion) { case GameEditions.EDGE_OF_DARKNESS: @@ -825,7 +773,6 @@ public class BotGenerator( default: return ItemTpl.BARTER_DOGTAG_USEC; } - } switch (gameVersion) { diff --git a/Libraries/Core/Generators/BotInventoryGenerator.cs b/Libraries/Core/Generators/BotInventoryGenerator.cs index 98206814..14c77e97 100644 --- a/Libraries/Core/Generators/BotInventoryGenerator.cs +++ b/Libraries/Core/Generators/BotInventoryGenerator.cs @@ -40,7 +40,7 @@ public class BotInventoryGenerator( private BotConfig _botConfig = _configServer.GetConfig(); // Slots handled individually inside `GenerateAndAddEquipmentToBot` - List _excludedEquipmentSlots = + private List _excludedEquipmentSlots = [ EquipmentSlots.Pockets, EquipmentSlots.FirstPrimaryWeapon, @@ -123,12 +123,12 @@ public class BotInventoryGenerator( { Items = [ - new() { Id = equipmentId, Template = ItemTpl.INVENTORY_DEFAULT }, - new() { Id = stashId, Template = ItemTpl.STASH_STANDARD_STASH_10X30 }, - new() { Id = questRaidItemsId, Template = ItemTpl.STASH_QUESTRAID }, - new() { Id = questStashItemsId, Template = ItemTpl.STASH_QUESTOFFLINE }, - new() { Id = sortingTableId, Template = ItemTpl.SORTINGTABLE_SORTING_TABLE }, - new() { Id = hideoutCustomizationStashId, Template = ItemTpl.HIDEOUTAREACONTAINER_CUSTOMIZATION } + new Item { Id = equipmentId, Template = ItemTpl.INVENTORY_DEFAULT }, + new Item { Id = stashId, Template = ItemTpl.STASH_STANDARD_STASH_10X30 }, + new Item { Id = questRaidItemsId, Template = ItemTpl.STASH_QUESTRAID }, + new Item { Id = questStashItemsId, Template = ItemTpl.STASH_QUESTOFFLINE }, + new Item { Id = sortingTableId, Template = ItemTpl.SORTINGTABLE_SORTING_TABLE }, + new Item { Id = hideoutCustomizationStashId, Template = ItemTpl.HIDEOUTAREACONTAINER_CUSTOMIZATION } ], Equipment = equipmentId, Stash = stashId, @@ -138,7 +138,7 @@ public class BotInventoryGenerator( HideoutAreaStashes = new Dictionary(), FastPanel = new Dictionary(), FavoriteItems = [], - HideoutCustomizationStashId = hideoutCustomizationStashId, + HideoutCustomizationStashId = hideoutCustomizationStashId }; } @@ -165,16 +165,12 @@ public class BotInventoryGenerator( raidConfig is not null && _weatherHelper.IsNightTime(raidConfig.TimeVariant) ) - { - foreach (var equipmentSlotKvP in (randomistionDetails.NighttimeChanges.EquipmentModsModifiers)) - { + foreach (var equipmentSlotKvP in randomistionDetails.NighttimeChanges.EquipmentModsModifiers) // Never let mod chance go outside of 0 - 100 randomistionDetails.EquipmentMods[equipmentSlotKvP.Key] = Math.Min( Math.Max(randomistionDetails.EquipmentMods[equipmentSlotKvP.Key] + equipmentSlotKvP.Value, 0), 100 ); - } - } // Get profile of player generating bots, we use their level later on var pmcProfile = _profileHelper.GetPmcProfile(sessionId); @@ -188,10 +184,7 @@ public class BotInventoryGenerator( { // Skip some slots as they need to be done in a specific order + with specific parameter values // e.g. Weapons - if (_excludedEquipmentSlots.Contains(equipmentSlot)) - { - continue; - } + if (_excludedEquipmentSlots.Contains(equipmentSlot)) continue; GenerateEquipment( new GenerateEquipmentProperties @@ -223,7 +216,7 @@ public class BotInventoryGenerator( BotEquipmentConfig = botEquipConfig, RandomisationDetails = randomistionDetails, GenerateModsBlacklist = [ItemTpl.POCKETS_1X4_TUE, ItemTpl.POCKETS_LARGE], - GeneratingPlayerLevel = pmcProfile?.Info?.Level ?? 1, + GeneratingPlayerLevel = pmcProfile?.Info?.Level ?? 1 } ); @@ -238,7 +231,7 @@ public class BotInventoryGenerator( Inventory = botInventory, BotEquipmentConfig = botEquipConfig, RandomisationDetails = randomistionDetails, - GeneratingPlayerLevel = pmcProfile?.Info?.Level ?? 1, + GeneratingPlayerLevel = pmcProfile?.Info?.Level ?? 1 } ); @@ -253,7 +246,7 @@ public class BotInventoryGenerator( Inventory = botInventory, BotEquipmentConfig = botEquipConfig, RandomisationDetails = randomistionDetails, - GeneratingPlayerLevel = pmcProfile?.Info?.Level ?? 1, + GeneratingPlayerLevel = pmcProfile?.Info?.Level ?? 1 } ); @@ -268,7 +261,7 @@ public class BotInventoryGenerator( Inventory = botInventory, BotEquipmentConfig = botEquipConfig, RandomisationDetails = randomistionDetails, - GeneratingPlayerLevel = pmcProfile?.Info?.Level ?? 1, + GeneratingPlayerLevel = pmcProfile?.Info?.Level ?? 1 } ); @@ -283,29 +276,22 @@ public class BotInventoryGenerator( Inventory = botInventory, BotEquipmentConfig = botEquipConfig, RandomisationDetails = randomistionDetails, - GeneratingPlayerLevel = pmcProfile?.Info?.Level ?? 1, + GeneratingPlayerLevel = pmcProfile?.Info?.Level ?? 1 } ); // Bot has no armor vest and flagged to be forced to wear armored rig in this event if (botEquipConfig.ForceOnlyArmoredRigWhenNoArmor.GetValueOrDefault(false) && !hasArmorVest) - { // Filter rigs down to only those with armor FilterRigsToThoseWithProtection(templateInventory.Equipment, botRole); - } // Optimisation - Remove armored rigs from pool if (hasArmorVest) - { // Filter rigs down to only those with armor FilterRigsToThoseWithoutProtection(templateInventory.Equipment, botRole); - } // Bot is flagged as always needing a vest - if (botEquipConfig.ForceRigWhenNoVest.GetValueOrDefault(false) && !hasArmorVest) - { - wornItemChances.EquipmentChances["TacticalVest"] = 100; - } + if (botEquipConfig.ForceRigWhenNoVest.GetValueOrDefault(false) && !hasArmorVest) wornItemChances.EquipmentChances["TacticalVest"] = 100; GenerateEquipment( new GenerateEquipmentProperties @@ -318,7 +304,7 @@ public class BotInventoryGenerator( Inventory = botInventory, BotEquipmentConfig = botEquipConfig, RandomisationDetails = randomistionDetails, - GeneratingPlayerLevel = pmcProfile?.Info?.Level ?? 1, + GeneratingPlayerLevel = pmcProfile?.Info?.Level ?? 1 } ); } @@ -343,10 +329,7 @@ public class BotInventoryGenerator( if (!tacVestsWithArmor.Any()) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Unable to filter to only armored rigs as bot: {botRole} has none in pool"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Unable to filter to only armored rigs as bot: {botRole} has none in pool"); return; } @@ -369,10 +352,7 @@ public class BotInventoryGenerator( if (!allowEmptyResult && !tacVestsWithoutArmor.Any()) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Unable to filter to only unarmored rigs as bot: {botRole} has none in pool"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Unable to filter to only unarmored rigs as bot: {botRole} has none in pool"); return; } @@ -416,10 +396,7 @@ public class BotInventoryGenerator( var attempts = 0; while (!found) { - if (!settings.RootEquipmentPool.Any()) - { - return false; - } + if (!settings.RootEquipmentPool.Any()) return false; var chosenItemTpl = _weightedRandomHelper.GetWeightedValue(settings.RootEquipmentPool); var dbResult = _itemHelper.GetItem(chosenItemTpl); @@ -427,10 +404,7 @@ public class BotInventoryGenerator( if (!dbResult.Key) { _logger.Error(_localisationService.GetText("bot-missing_item_template", chosenItemTpl)); - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"EquipmentSlot-> {settings.RootEquipmentSlot}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"EquipmentSlot-> {settings.RootEquipmentSlot}"); // Remove picked item settings.RootEquipmentPool.Remove(chosenItemTpl); @@ -449,10 +423,7 @@ public class BotInventoryGenerator( if (compatibilityResult.Incompatible ?? false) { // Tried x different items that failed, stop - if (attempts > maxAttempts) - { - return false; - } + if (attempts > maxAttempts) return false; // Remove picked item from pool settings.RootEquipmentPool.Remove(chosenItemTpl); @@ -488,17 +459,14 @@ public class BotInventoryGenerator( if (_botConfig.Equipment.ContainsKey(settings.BotData.EquipmentRole) && settings.RandomisationDetails?.RandomisedArmorSlots != null && settings.RandomisationDetails.RandomisedArmorSlots.Contains(settings.RootEquipmentSlot.ToString())) - { // Filter out mods from relevant blacklist settings.ModPool[pickedItemDb.Id] = GetFilteredDynamicModsForItem( pickedItemDb.Id, botEquipBlacklist.Equipment ); - } var itemIsOnGenerateModBlacklist = settings.GenerateModsBlacklist != null && settings.GenerateModsBlacklist.Contains(pickedItemDb.Id); // Does item have slots for sub-mods to be inserted into - if (pickedItemDb.Properties?.Slots?.Count > 0 - && !itemIsOnGenerateModBlacklist) + if (pickedItemDb.Properties?.Slots?.Count > 0 && !itemIsOnGenerateModBlacklist) { var childItemsToAdd = _botEquipmentModGenerator.GenerateModsForEquipment( [item], @@ -533,13 +501,11 @@ public class BotInventoryGenerator( foreach (var modSlot in modPool) { // Get blacklist - if (!equipmentBlacklist.TryGetValue(modSlot.Key, out var blacklistedMods)) - { - blacklistedMods = []; - }; + if (!equipmentBlacklist.TryGetValue(modSlot.Key, out var blacklistedMods)) blacklistedMods = []; + ; // Get mods not on blacklist - var filteredMods = modPool[modSlot.Key].Where((slotName) => !(blacklistedMods).Contains(slotName)); + var filteredMods = modPool[modSlot.Key].Where((slotName) => !blacklistedMods.Contains(slotName)); if (!filteredMods.Any()) { _logger.Warning($"Filtering {modSlot.Key} pool resulting in 0 items, skipping filter"); @@ -568,10 +534,8 @@ public class BotInventoryGenerator( { var weaponSlotsToFill = GetDesiredWeaponsForBot(equipmentChances); foreach (var desiredWeapons in weaponSlotsToFill) - { // Add weapon to bot if true and bot json has something to put into the slot if (desiredWeapons.ShouldSpawn && templateInventory.Equipment[desiredWeapons.Slot].Any()) - { AddWeaponAndMagazinesToInventory( sessionId, desiredWeapons, @@ -583,8 +547,6 @@ public class BotInventoryGenerator( itemGenerationLimitsMinMax, botLevel ); - } - } } /// @@ -597,16 +559,16 @@ public class BotInventoryGenerator( var shouldSpawnPrimary = _randomUtil.GetChance100(equipmentChances.EquipmentChances["FirstPrimaryWeapon"]); return [ - new() + new DesiredWeapons { Slot = EquipmentSlots.FirstPrimaryWeapon, ShouldSpawn = shouldSpawnPrimary }, - new() + new DesiredWeapons { Slot = EquipmentSlots.SecondPrimaryWeapon, ShouldSpawn = shouldSpawnPrimary && _randomUtil.GetChance100(equipmentChances.EquipmentChances["SecondPrimaryWeapon"]) }, - new() + new DesiredWeapons { Slot = EquipmentSlots.Holster, ShouldSpawn = !shouldSpawnPrimary || _randomUtil.GetChance100(equipmentChances.EquipmentChances["Holster"]) // No primary = force pistol diff --git a/Libraries/Core/Generators/BotLevelGenerator.cs b/Libraries/Core/Generators/BotLevelGenerator.cs index ccd10a03..fab74e45 100644 --- a/Libraries/Core/Generators/BotLevelGenerator.cs +++ b/Libraries/Core/Generators/BotLevelGenerator.cs @@ -27,30 +27,21 @@ public class BotLevelGenerator( /// IRandomisedBotLevelResult object public RandomisedBotLevelResult GenerateBotLevel(MinMax levelDetails, BotGenerationDetails botGenerationDetails, BotBase bot) { - if (!botGenerationDetails.IsPmc.GetValueOrDefault(false)) - { - return new RandomisedBotLevelResult { Exp = 0, Level = 1 }; - } + if (!botGenerationDetails.IsPmc.GetValueOrDefault(false)) return new RandomisedBotLevelResult { Exp = 0, Level = 1 }; var expTable = _databaseService.GetGlobals().Configuration.Exp.Level.ExperienceTable; var botLevelRange = GetRelativePmcBotLevelRange(botGenerationDetails, levelDetails, expTable.Length); // Get random level based on the exp table. - int exp = 0; + var exp = 0; var level = int.Parse( ChooseBotLevel(botLevelRange.Min.Value, botLevelRange.Max.Value, 1, 1.15) .ToString() ); // TODO - nasty double to string to int conversion - for (var i = 0; i < level; i++) - { - exp += expTable[i].Experience.Value; - } + for (var i = 0; i < level; i++) exp += expTable[i].Experience.Value; // Sprinkle in some random exp within the level, unless we are at max level. - if (level < expTable.Length - 1) - { - exp += _randomUtil.GetInt(0, expTable[level].Experience.Value - 1); - } + if (level < expTable.Length - 1) exp += _randomUtil.GetInt(0, expTable[level].Experience.Value - 1); return new RandomisedBotLevelResult { Level = level, Exp = exp }; } diff --git a/Libraries/Core/Generators/BotLootGenerator.cs b/Libraries/Core/Generators/BotLootGenerator.cs index b91a4280..49b09a23 100644 --- a/Libraries/Core/Generators/BotLootGenerator.cs +++ b/Libraries/Core/Generators/BotLootGenerator.cs @@ -47,10 +47,7 @@ public class BotLootGenerator( // Clone limits and set all values to 0 to use as a running total var limitsForBotDict = _cloner.Clone(limits); // Init current count of items we want to limit - foreach (var limit in limitsForBotDict) - { - limitsForBotDict[limit.Key] = 0; - } + foreach (var limit in limitsForBotDict) limitsForBotDict[limit.Key] = 0; return new ItemSpawnLimitSettings { @@ -113,10 +110,7 @@ public class BotLootGenerator( } // Forced pmc healing loot into secure container - if (isPmc && _pmcConfig.ForceHealingItemsIntoSecure) - { - AddForcedMedicalItemsToPmcSecure(botInventory, botRole); - } + if (isPmc && _pmcConfig.ForceHealingItemsIntoSecure) AddForcedMedicalItemsToPmcSecure(botInventory, botRole); var botItemLimits = GetItemSpawnLimitsForBot(botRole); @@ -235,7 +229,6 @@ public class BotLootGenerator( { // Add randomly generated weapon to PMC backpacks if (isPmc && _randomUtil.GetChance100(_pmcConfig.LooseWeaponInBackpackChancePercent)) - { AddLooseWeaponsToInventorySlot( sessionId, botInventory, @@ -247,7 +240,6 @@ public class BotLootGenerator( botLevel, filledContainerIds ); - } var backpackLootRoubleTotal = GetBackpackRoubleTotalByLevel(botLevel, isPmc); AddLootFromPool( @@ -271,7 +263,6 @@ public class BotLootGenerator( // TacticalVest - generate loot if they have one if (containersBotHasAvailable.Contains(EquipmentSlots.TacticalVest)) - { // Vest AddLootFromPool( _botLootCacheService.GetLootFromCache( @@ -290,7 +281,6 @@ public class BotLootGenerator( isPmc, filledContainerIds ); - } // Pockets AddLootFromPool( @@ -315,7 +305,6 @@ public class BotLootGenerator( // only add if not a pmc or is pmc and flag is true if (!isPmc || (isPmc && _pmcConfig.AddSecureContainerLootFromBotConfig)) - { AddLootFromPool( _botLootCacheService.GetLootFromCache(botRole, isPmc, LootCacheType.Secure, botJsonTemplate), [EquipmentSlots.SecuredContainer], @@ -327,7 +316,6 @@ public class BotLootGenerator( isPmc, filledContainerIds ); - } } private MinMaxLootItemValue? GetSingleItemLootPriceLimits(int botLevel, bool isPmc) @@ -368,15 +356,9 @@ public class BotLootGenerator( { List result = [EquipmentSlots.Pockets]; - if ((botInventory.Items ?? []).Any((item) => item.SlotId == EquipmentSlots.TacticalVest.ToString())) - { - result.Add(EquipmentSlots.TacticalVest); - } + if ((botInventory.Items ?? []).Any((item) => item.SlotId == EquipmentSlots.TacticalVest.ToString())) result.Add(EquipmentSlots.TacticalVest); - if ((botInventory.Items ?? []).Any((item) => item.SlotId == EquipmentSlots.Backpack.ToString())) - { - result.Add(EquipmentSlots.Backpack); - } + if ((botInventory.Items ?? []).Any((item) => item.SlotId == EquipmentSlots.Backpack.ToString())) result.Add(EquipmentSlots.Backpack); return result; } @@ -449,10 +431,7 @@ public class BotLootGenerator( for (var i = 0; i < totalItemCount; i++) { // Pool can become empty if item spawn limits keep removing items - if (pool.Count == 0) - { - return; - } + if (pool.Count == 0) return; var weightedItemTpl = _weightedRandomHelper.GetWeightedValue(pool); var (key, itemToAddTemplate) = _itemHelper.GetItem(weightedItemTpl); @@ -481,7 +460,7 @@ public class BotLootGenerator( Id = newRootItemId, Template = itemToAddTemplate?.Id ?? string.Empty, Upd = _botGeneratorHelper.GenerateExtraPropertiesForItem(itemToAddTemplate, botRole) - }, + } ]; // Is Simple-Wallet / WZ wallet @@ -505,14 +484,12 @@ public class BotLootGenerator( { // Add each currency to wallet foreach (var itemToAdd in itemsToAdd) - { _inventoryHelper.PlaceItemInContainer( containerGrid, itemToAdd, itemWithChildrenToAdd[0].Id, "main" ); - } itemWithChildrenToAdd.AddRange(itemsToAdd.SelectMany(x => x)); } @@ -538,24 +515,20 @@ public class BotLootGenerator( if (itemAddedResult == ItemAddedResult.NO_CONTAINERS) { // Bot has no container to put item in, exit - if(_logger.IsLogEnabled(LogLevel.Debug)) - { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Unable to add: {totalItemCount} items to bot as it lacks a container to include them"); - } break; } fitItemIntoContainerAttempts++; if (fitItemIntoContainerAttempts >= 4) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug( $"Failed placing item: {itemToAddTemplate.Id} - {itemToAddTemplate.Name}: {i} of: {totalItemCount} items into: {botRole} " + $"containers: {string.Join(",", equipmentSlots)}. Tried: {fitItemIntoContainerAttempts} " + $"times, reason: {itemAddedResult}, skipping" ); - } break; } @@ -571,10 +544,7 @@ public class BotLootGenerator( if (totalValueLimitRub > 0) { currentTotalRub += _handbookHelper.GetTemplatePrice(itemToAddTemplate.Id); - if (currentTotalRub > totalValueLimitRub) - { - break; - } + if (currentTotalRub > totalValueLimitRub) break; } } } @@ -599,12 +569,12 @@ public class BotLootGenerator( var chosenStackCount = _weightedRandomHelper.GetWeightedValue(_botConfig.WalletLoot.StackSizeWeight); List items = [ - new Item + new() { Id = _hashUtil.Generate(), Template = _weightedRandomHelper.GetWeightedValue(_botConfig.WalletLoot.CurrencyWeight), ParentId = walletId, - Upd = new() + Upd = new Upd { StackObjectsCount = int.Parse(chosenStackCount) } @@ -627,24 +597,15 @@ public class BotLootGenerator( { // Fill ammo box if (_itemHelper.IsOfBaseclass(itemToAddTemplate.Id, BaseClasses.AMMO_BOX)) - { _itemHelper.AddCartridgesToAmmoBox(itemToAddChildrenTo, itemToAddTemplate); - } // Make money a stack else if (_itemHelper.IsOfBaseclass(itemToAddTemplate.Id, BaseClasses.MONEY)) - { RandomiseMoneyStackSize(botRole, itemToAddTemplate, itemToAddChildrenTo[0]); - } // Make ammo a stack else if (_itemHelper.IsOfBaseclass(itemToAddTemplate.Id, BaseClasses.AMMO)) - { RandomiseAmmoStackSize(isPmc, itemToAddTemplate, itemToAddChildrenTo[0]); - } // Must add soft inserts/plates - else if (_itemHelper.ItemRequiresSoftInserts(itemToAddTemplate.Id)) - { - _itemHelper.AddChildSlotItems(itemToAddChildrenTo, itemToAddTemplate, null, false); - } + else if (_itemHelper.ItemRequiresSoftInserts(itemToAddTemplate.Id)) _itemHelper.AddChildSlotItems(itemToAddChildrenTo, itemToAddTemplate, null, false); } /// @@ -682,10 +643,7 @@ public class BotLootGenerator( (int)_pmcConfig.LooseWeaponInBackpackLootMinMax.Max ); - if (randomisedWeaponCount <= 0) - { - return; - } + if (randomisedWeaponCount <= 0) return; for (var i = 0; i < randomisedWeaponCount; i++) { @@ -709,12 +667,8 @@ public class BotLootGenerator( ); if (result != ItemAddedResult.SUCCESS) - { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Failed to add additional weapon {generatedWeapon.Weapon[0].Id} to bot backpack, reason: {result.ToString()}"); - } - } } } @@ -729,33 +683,24 @@ public class BotLootGenerator( { // PMCs and scavs have different sections of bot config for spawn limits if (itemSpawnLimits is not null && itemSpawnLimits.GlobalLimits?.Count == 0) - { // No items found in spawn limit, drop out return false; - } // No spawn limits, skipping - if (itemSpawnLimits is null) - { - return false; - } + if (itemSpawnLimits is null) return false; var idToCheckFor = GetMatchingIdFromSpawnLimits(itemTemplate, itemSpawnLimits.GlobalLimits); if (idToCheckFor is null) - { // ParentId or tplid not found in spawnLimits, not a spawn limited item, skip return false; - } // Use tryAdd to see if it exists, and automatically add 1 if (!itemSpawnLimits.CurrentLimits.TryAdd(idToCheckFor, 1)) - { // if it does exist, come in here and increment // Increment item count with this bot type itemSpawnLimits.CurrentLimits[idToCheckFor]++; - } - + // Check if over limit var currentLimitCount = itemSpawnLimits.CurrentLimits[idToCheckFor]; @@ -764,8 +709,7 @@ public class BotLootGenerator( // Prevent edge-case of small loot pools + code trying to add limited item over and over infinitely if (currentLimitCount > currentLimitCount * 10) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug( _localisationService.GetText( "bot-item_spawn_limit_reached_skipping_item", @@ -777,7 +721,6 @@ public class BotLootGenerator( } ) ); - } return false; } @@ -797,10 +740,7 @@ public class BotLootGenerator( public void RandomiseMoneyStackSize(string botRole, TemplateItem itemTemplate, Item moneyItem) { // Get all currency weights for this bot type - if (!_botConfig.CurrencyStackSize.TryGetValue(botRole, out var currencyWeights)) - { - currencyWeights = _botConfig.CurrencyStackSize["default"]; - } + if (!_botConfig.CurrencyStackSize.TryGetValue(botRole, out var currencyWeights)) currencyWeights = _botConfig.CurrencyStackSize["default"]; var currencyWeight = currencyWeights[moneyItem.Template]; @@ -831,19 +771,13 @@ public class BotLootGenerator( /// Dictionary of tplIds and limit public Dictionary GetItemSpawnLimitsForBotType(string botRole) { - if (_botHelper.IsBotPmc(botRole)) - { - return _botConfig.ItemSpawnLimits["pmc"]; - } + if (_botHelper.IsBotPmc(botRole)) return _botConfig.ItemSpawnLimits["pmc"]; - if (_botConfig.ItemSpawnLimits.ContainsKey(botRole.ToLower())) - { - return _botConfig.ItemSpawnLimits[botRole.ToLower()]; - } + if (_botConfig.ItemSpawnLimits.ContainsKey(botRole.ToLower())) return _botConfig.ItemSpawnLimits[botRole.ToLower()]; _logger.Warning(_localisationService.GetText("bot-unable_to_find_spawn_limits_fallback_to_defaults", botRole)); - return new(); + return new Dictionary(); } /// @@ -854,16 +788,10 @@ public class BotLootGenerator( /// id as string, otherwise undefined public string? GetMatchingIdFromSpawnLimits(TemplateItem itemTemplate, Dictionary spawnLimits) { - if (spawnLimits.ContainsKey(itemTemplate.Id)) - { - return itemTemplate.Id; - } + if (spawnLimits.ContainsKey(itemTemplate.Id)) return itemTemplate.Id; // tplId not found in spawnLimits, check if parentId is - if (spawnLimits.ContainsKey(itemTemplate.Parent)) - { - return itemTemplate.Parent; - } + if (spawnLimits.ContainsKey(itemTemplate.Parent)) return itemTemplate.Parent; // parentId and tplId not found return null; diff --git a/Libraries/Core/Generators/BotWeaponGenerator.cs b/Libraries/Core/Generators/BotWeaponGenerator.cs index 04d803bc..6e3a5fbf 100644 --- a/Libraries/Core/Generators/BotWeaponGenerator.cs +++ b/Libraries/Core/Generators/BotWeaponGenerator.cs @@ -34,11 +34,11 @@ public class BotWeaponGenerator( IEnumerable inventoryMagGenComponents ) { - protected IEnumerable _inventoryMagGenComponents = MagGenSetUp(inventoryMagGenComponents); + protected const string _modMagazineSlotId = "mod_magazine"; protected BotConfig _botConfig = _configServer.GetConfig(); + protected IEnumerable _inventoryMagGenComponents = MagGenSetUp(inventoryMagGenComponents); protected PmcConfig _pmcConfig = _configServer.GetConfig(); protected RepairConfig _repairConfig = _configServer.GetConfig(); - protected const string _modMagazineSlotId = "mod_magazine"; private static List MagGenSetUp(IEnumerable components) { @@ -139,10 +139,8 @@ public class BotWeaponGenerator( // Chance to add randomised weapon enhancement if (isPmc && _randomUtil.GetChance100(_pmcConfig.WeaponHasEnhancementChancePercent)) - { // Add buff to weapon root _repairService.AddBuff(_repairConfig.RepairKit.Weapon, weaponWithModsArray[0]); - } // Add mods to weapon base if (modPool.Keys.Contains(weaponTpl)) @@ -161,10 +159,10 @@ public class BotWeaponGenerator( ParentTemplate = weaponItemTemplate, ModSpawnChances = modChances, AmmoTpl = ammoTpl, - BotData = new() { Role = botRole, Level = botLevel, EquipmentRole = botEquipmentRole }, + BotData = new BotData { Role = botRole, Level = botLevel, EquipmentRole = botEquipmentRole }, ModLimits = modLimits, - WeaponStats = new(), - ConflictingItemTpls = new(), + WeaponStats = new WeaponStats(), + ConflictingItemTpls = new HashSet() }; weaponWithModsArray = _botEquipmentModGenerator.GenerateModsForWeapon( sessionId, @@ -174,7 +172,6 @@ public class BotWeaponGenerator( // Use weapon preset from globals.json if weapon isn't valid if (!IsWeaponValid(weaponWithModsArray, botRole)) - { // Weapon is bad, fall back to weapons preset weaponWithModsArray = GetPresetWeaponMods( weaponTpl, @@ -183,19 +180,15 @@ public class BotWeaponGenerator( weaponItemTemplate, botRole ); - } var tempList = _cloner.Clone(weaponWithModsArray.Where((item) => item.SlotId == _modMagazineSlotId)); // Fill existing magazines to full and sync ammo type - foreach (var magazine in tempList) - { - FillExistingMagazines(weaponWithModsArray, magazine, ammoTpl); - } + foreach (var magazine in tempList) FillExistingMagazines(weaponWithModsArray, magazine, ammoTpl); // Add cartridge(s) to gun chamber(s) if (weaponItemTemplate.Properties.Chambers?.Any() ?? - false && - weaponItemTemplate.Properties.Chambers[0].Props.Filters[0].Filter.Contains(ammoTpl)) + (false && + weaponItemTemplate.Properties.Chambers[0].Props.Filters[0].Filter.Contains(ammoTpl))) { // Guns have variety of possible Chamber ids, patron_in_weapon/patron_in_weapon_000/patron_in_weapon_001 var chamberSlotNames = weaponItemTemplate.Properties.Chambers.Select((chamberSlot) => chamberSlot.Name); @@ -212,13 +205,13 @@ public class BotWeaponGenerator( FillUbgl(weaponWithModsArray, ubglMod, ubglAmmoTpl); } - return new() + return new GenerateWeaponResult { Weapon = weaponWithModsArray, ChosenAmmoTemplate = ammoTpl, ChosenUbglAmmoTemplate = ubglAmmoTpl, WeaponMods = modPool, - WeaponTemplate = weaponItemTemplate, + WeaponTemplate = weaponItemTemplate }; } @@ -238,13 +231,13 @@ public class BotWeaponGenerator( { // Not found, add new slot to weapon weaponWithModsList.Add( - new() + new Item { Id = _hashUtil.Generate(), Template = ammoTemplate, ParentId = weaponWithModsList[0].Id, SlotId = slotId, - Upd = new() { StackObjectsCount = 1 }, + Upd = new Upd { StackObjectsCount = 1 } } ); } @@ -252,7 +245,7 @@ public class BotWeaponGenerator( { // Already exists, update values existingItemWithSlot.Template = ammoTemplate; - existingItemWithSlot.Upd = new() { StackObjectsCount = 1 }; + existingItemWithSlot.Upd = new Upd { StackObjectsCount = 1 }; } } } @@ -272,7 +265,7 @@ public class BotWeaponGenerator( { return [ - new() + new Item { Id = _hashUtil.Generate(), Template = weaponTemplate, @@ -301,14 +294,12 @@ public class BotWeaponGenerator( // TODO: Preset weapons trigger a lot of warnings regarding missing ammo in magazines & such Preset preset = null; foreach (var (_, itemPreset) in _databaseService.GetGlobals().ItemPresets) - { if (itemPreset.Items[0].Template == weaponTemplate) { preset = _cloner.Clone(itemPreset); break; } - } if (preset is not null) { @@ -338,10 +329,7 @@ public class BotWeaponGenerator( foreach (var mod in weaponItemList) { var modTemplate = _itemHelper.GetItem(mod.Template).Value; - if (!modTemplate.Properties.Slots?.Any() ?? false) - { - continue; - } + if (!modTemplate.Properties.Slots?.Any() ?? false) continue; // Iterate over required slots in db item, check mod exists for that slot foreach (var modSlotTemplate in modTemplate.Properties.Slots?.Where((slot) => slot.Required.GetValueOrDefault(false)) ?? []) @@ -360,7 +348,7 @@ public class BotWeaponGenerator( modSlot = modSlotTemplate.Name, modName = modTemplate.Name, slotId = mod.SlotId, - botRole = botRole, + botRole = botRole } ) ); @@ -394,6 +382,7 @@ public class BotWeaponGenerator( return; } + //var isInternalMag = magTemplate.Properties.ReloadMagType == ReloadMode.InternalMagazine; var ammoTemplate = _itemHelper.GetItem(generatedWeaponResult.ChosenAmmoTemplate); if (!ammoTemplate.Key) @@ -406,10 +395,7 @@ public class BotWeaponGenerator( } // Has an UBGL - if (generatedWeaponResult.ChosenUbglAmmoTemplate is not null) - { - AddUbglGrenadesToBotInventory(weaponAndMods, generatedWeaponResult, inventory); - } + if (generatedWeaponResult.ChosenUbglAmmoTemplate is not null) AddUbglGrenadesToBotInventory(weaponAndMods, generatedWeaponResult, inventory); var inventoryMagGenModel = new InventoryMagGen( magWeights, @@ -446,8 +432,8 @@ public class BotWeaponGenerator( // Define min/max of how many grenades bot will have GenerationData ubglMinMax = new() { - Weights = new() { { 1, 1 }, { 2, 1 } }, - Whitelist = new(), + Weights = new Dictionary { { 1, 1 }, { 2, 1 } }, + Whitelist = new Dictionary() }; // get ammo template from db @@ -482,12 +468,12 @@ public class BotWeaponGenerator( { var id = _hashUtil.Generate(); _botGeneratorHelper.AddItemWithChildrenToEquipmentSlot( - new() { EquipmentSlots.SecuredContainer }, + new List { EquipmentSlots.SecuredContainer }, id, ammoTemplate, - new() + new List { - new() { Id = id, Template = ammoTemplate, Upd = new() { StackObjectsCount = stackSize } } + new() { Id = id, Template = ammoTemplate, Upd = new Upd { StackObjectsCount = stackSize } } }, inventory ); @@ -508,14 +494,10 @@ public class BotWeaponGenerator( { // Edge case - magazineless chamber loaded weapons dont have magazines, e.g. mp18 // return default mag tpl - if (weaponTemplate.Properties.ReloadMode == ReloadMode.OnlyBarrel) - { - return _botWeaponGeneratorHelper.GetWeaponsDefaultMagazineTpl(weaponTemplate); - } + if (weaponTemplate.Properties.ReloadMode == ReloadMode.OnlyBarrel) return _botWeaponGeneratorHelper.GetWeaponsDefaultMagazineTpl(weaponTemplate); // log error if no magazine AND not a chamber loaded weapon (e.g. shotgun revolver) if (!weaponTemplate.Properties.IsChamberLoad ?? false) - { // Shouldn't happen _logger.Warning( _localisationService.GetText( @@ -523,19 +505,16 @@ public class BotWeaponGenerator( new { weaponId = weaponTemplate.Id, - botRole = botRole, + botRole = botRole } ) ); - } var defaultMagTplId = _botWeaponGeneratorHelper.GetWeaponsDefaultMagazineTpl(weaponTemplate); - if(_logger.IsLogEnabled(LogLevel.Debug)) - { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug( $"[{botRole}] Unable to find magazine for weapon: {weaponTemplate.Id} {weaponTemplate.Name}, using mag template default: {defaultMagTplId}." ); - } return defaultMagTplId; } @@ -554,8 +533,7 @@ public class BotWeaponGenerator( var desiredCaliber = GetWeaponCaliber(weaponTemplate); if (!cartridgePool.TryGetValue(desiredCaliber, out var cartridgePoolForWeapon) || cartridgePoolForWeapon?.Keys.Count == 0) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug( _localisationService.GetText( "bot-no_caliber_data_for_weapon_falling_back_to_default", @@ -563,11 +541,10 @@ public class BotWeaponGenerator( { weaponId = weaponTemplate.Id, weaponName = weaponTemplate.Name, - defaultAmmo = weaponTemplate.Properties.DefAmmo, + defaultAmmo = weaponTemplate.Properties.DefAmmo } ) ); - } // Immediately returns, default ammo is guaranteed to be compatible return weaponTemplate.Properties.DefAmmo; @@ -576,26 +553,18 @@ public class BotWeaponGenerator( // Get cartridges the weapons first chamber allow var compatibleCartridgesInTemplate = GetCompatibleCartridgesFromWeaponTemplate(weaponTemplate); if (compatibleCartridgesInTemplate is null) - { // No chamber data found in weapon, send default return weaponTemplate.Properties.DefAmmo; - } // Inner join the weapons allowed + passed in cartridge pool to get compatible cartridges Dictionary compatibleCartridges = new(); foreach (var cartridge in cartridgePoolForWeapon) - { if (compatibleCartridgesInTemplate.Contains(cartridge.Key)) - { compatibleCartridges[cartridge.Key] = cartridgePoolForWeapon[cartridge.Key]; - } - } if (!compatibleCartridges.Any()) - { // No compatible cartridges, use default return weaponTemplate.Properties.DefAmmo; - } return _weightedRandomHelper.GetWeightedValue(compatibleCartridges); } @@ -608,10 +577,7 @@ public class BotWeaponGenerator( protected List? GetCompatibleCartridgesFromWeaponTemplate(TemplateItem weaponTemplate) { var cartridges = weaponTemplate.Properties?.Chambers.FirstOrDefault()?.Props?.Filters?[0].Filter; - if (cartridges is not null) - { - return cartridges; - } + if (cartridges is not null) return cartridges; // Fallback to the magazine if possible, e.g. for revolvers // Grab the magazines template var firstMagazine = weaponTemplate.Properties.Slots.FirstOrDefault(slot => slot.Name == "mod_magazine"); @@ -621,11 +587,9 @@ public class BotWeaponGenerator( // Get the first slots array of cartridges cartridges = magProperties.Slots.FirstOrDefault()?.Props.Filters?[0].Filter; if (cartridges is null) - { // Normal magazines // None found, try the cartridges array cartridges = magProperties.Cartridges.FirstOrDefault()?.Props.Filters[0].Filter; - } return cartridges; } @@ -637,28 +601,20 @@ public class BotWeaponGenerator( /// Caliber as string protected string? GetWeaponCaliber(TemplateItem weaponTemplate) { - if (weaponTemplate.Properties.Caliber is not null) - { - return weaponTemplate.Properties.Caliber; - } + if (weaponTemplate.Properties.Caliber is not null) return weaponTemplate.Properties.Caliber; if (weaponTemplate.Properties.AmmoCaliber is not null) - { // 9x18pmm has a typo, should be Caliber9x18PM return weaponTemplate.Properties.AmmoCaliber == "Caliber9x18PMM" ? "Caliber9x18PM" : weaponTemplate.Properties.AmmoCaliber; - } if (weaponTemplate.Properties.LinkedWeapon is not null) { var ammoInChamber = _itemHelper.GetItem( weaponTemplate.Properties.Chambers[0].Props.Filters[0].Filter[0] ); - if (!ammoInChamber.Key) - { - return null; - } + if (!ammoInChamber.Key) return null; return ammoInChamber.Value.Properties.Caliber; } @@ -689,13 +645,9 @@ public class BotWeaponGenerator( // Exchange of the camora ammo is not necessary we could also just check for stackSize > 0 here // and remove the else if (_botWeaponGeneratorHelper.MagazineIsCylinderRelated(parentItem.Name)) - { FillCamorasWithAmmo(weaponMods, magazine.Id, cartridgeTemplate); - } else - { AddOrUpdateMagazinesChildWithAmmo(weaponMods, magazine, cartridgeTemplate, magazineTemplate); - } } /// @@ -707,13 +659,13 @@ public class BotWeaponGenerator( protected void FillUbgl(List weaponMods, Item ubglMod, string ubglAmmoTpl) { weaponMods.Add( - new() + new Item { Id = _hashUtil.Generate(), Template = ubglAmmoTpl, ParentId = ubglMod.Id, SlotId = "patron_in_weapon", - Upd = new() { StackObjectsCount = 1 }, + Upd = new Upd { StackObjectsCount = 1 } } ); } @@ -731,10 +683,8 @@ public class BotWeaponGenerator( (m) => m.ParentId == magazine.Id && m.SlotId == "cartridges" ); if (magazineCartridgeChildItem is not null) - { // Delete the existing cartridge object and create fresh below weaponWithMods.Remove(magazineCartridgeChildItem); - } // Create array with just magazine List magazineWithCartridges = [magazine]; @@ -764,13 +714,9 @@ public class BotWeaponGenerator( { camora.Template = ammoTpl; if (camora.Upd is not null) - { camora.Upd.StackObjectsCount = 1; - } else - { - camora.Upd = new() { StackObjectsCount = 1 }; - } + camora.Upd = new Upd { StackObjectsCount = 1 }; } } } diff --git a/Libraries/Core/Generators/FenceBaseAssortGenerator.cs b/Libraries/Core/Generators/FenceBaseAssortGenerator.cs index 7abe1934..e1136aff 100644 --- a/Libraries/Core/Generators/FenceBaseAssortGenerator.cs +++ b/Libraries/Core/Generators/FenceBaseAssortGenerator.cs @@ -40,47 +40,29 @@ public class FenceBaseAssortGenerator( foreach (var rootItemDb in itemHelper.GetItems().Where(IsValidFenceItem)) { // Skip blacklisted items - if (itemFilterService.IsItemBlacklisted(rootItemDb.Id)) - { - continue; - } + if (itemFilterService.IsItemBlacklisted(rootItemDb.Id)) continue; // Skip reward item blacklist - if (itemFilterService.IsItemRewardBlacklisted(rootItemDb.Id)) - { - continue; - } + if (itemFilterService.IsItemRewardBlacklisted(rootItemDb.Id)) continue; // Invalid - if (!itemHelper.IsValidItem(rootItemDb.Id)) - { - continue; - } + if (!itemHelper.IsValidItem(rootItemDb.Id)) continue; // Item base type blacklisted if (traderConfig.Fence.Blacklist.Count > 0) - { if (traderConfig.Fence.Blacklist.Contains(rootItemDb.Id) || itemHelper.IsOfBaseclasses(rootItemDb.Id, traderConfig.Fence.Blacklist) ) - { continue; - } - } // Only allow rigs with no slots (carrier rigs) if (itemHelper.IsOfBaseclass(rootItemDb.Id, BaseClasses.VEST) && (rootItemDb.Properties?.Slots?.Count ?? 0) > 0 ) - { continue; - } // Skip seasonal event items when not in seasonal event - if (traderConfig.Fence.BlacklistSeasonalItems && blockedSeasonalItems.Contains(rootItemDb.Id)) - { - continue; - } + if (traderConfig.Fence.BlacklistSeasonalItems && blockedSeasonalItems.Contains(rootItemDb.Id)) continue; // Create item object in array var itemWithChildrenToAdd = new List @@ -91,27 +73,19 @@ public class FenceBaseAssortGenerator( Template = rootItemDb.Id, ParentId = "hideout", SlotId = "hideout", - Upd = new Upd { StackObjectsCount = 9999999 }, + Upd = new Upd { StackObjectsCount = 9999999 } } }; // Ensure ammo is not above penetration limit value if (itemHelper.IsOfBaseclasses(rootItemDb.Id, [BaseClasses.AMMO_BOX, BaseClasses.AMMO])) - { if (IsAmmoAbovePenetrationLimit(rootItemDb)) - { continue; - } - } if (itemHelper.IsOfBaseclass(rootItemDb.Id, BaseClasses.AMMO_BOX)) - { // Only add cartridges to box if box has no children if (itemWithChildrenToAdd.Count == 1) - { itemHelper.AddCartridgesToAmmoBox(itemWithChildrenToAdd, rootItemDb); - } - } // Ensure IDs are unique itemHelper.RemapRootItemId(itemWithChildrenToAdd); @@ -143,10 +117,7 @@ public class FenceBaseAssortGenerator( foreach (var defaultPreset in defaultPresets) { // Skip presets we've already added - if (baseFenceAssort.Items.Any((item) => item.Upd != null && item.Upd.SptPresetId == defaultPreset.Id)) - { - continue; - } + if (baseFenceAssort.Items.Any((item) => item.Upd != null && item.Upd.SptPresetId == defaultPreset.Id)) continue; // Construct preset + mods var itemAndChildren = itemHelper.ReplaceIDs(_cloner.Clone(defaultPreset.Items)); @@ -165,7 +136,7 @@ public class FenceBaseAssortGenerator( { StackObjectsCount = 1, SptPresetId = - defaultPreset.Id, // Store preset id here so we can check it later to prevent preset dupes + defaultPreset.Id // Store preset id here so we can check it later to prevent preset dupes }; // Updated root item, exit loop @@ -181,14 +152,14 @@ public class FenceBaseAssortGenerator( var itemQualityModifier = itemHelper.GetItemQualityModifierForItems(itemAndChildren); // Multiply weapon+mods rouble price by quality modifier - baseFenceAssort.BarterScheme[itemAndChildren[0].Id] = new() + baseFenceAssort.BarterScheme[itemAndChildren[0].Id] = new List> { new() { new BarterScheme { Template = Money.ROUBLES, - Count = Math.Round(price * itemQualityModifier), + Count = Math.Round(price * itemQualityModifier) } } }; @@ -238,10 +209,7 @@ public class FenceBaseAssortGenerator( } // Plain old ammo, get its pen property - if (itemHelper.IsOfBaseclass(rootItemDb.Id, BaseClasses.AMMO)) - { - return rootItemDb.Properties.PenetrationPower; - } + if (itemHelper.IsOfBaseclass(rootItemDb.Id, BaseClasses.AMMO)) return rootItemDb.Properties.PenetrationPower; // Not an ammobox or ammo return null; @@ -256,26 +224,20 @@ public class FenceBaseAssortGenerator( { // Armor has no mods, make no additions var hasMods = itemDbDetails.Properties.Slots.Count > 0; - if (!hasMods) - { - return; - } + if (!hasMods) return; // Check for and add required soft inserts to armors var requiredSlots = itemDbDetails.Properties.Slots.Where((slot) => slot.Required ?? false).ToList(); var hasRequiredSlots = requiredSlots.Count > 0; if (hasRequiredSlots) - { foreach (var requiredSlot in requiredSlots) { var modItemDbDetails = itemHelper.GetItem(requiredSlot.Props.Filters[0].Plate).Value; var plateTpl = requiredSlot.Props.Filters[0].Plate; // `Plate` property appears to be the 'default' item for slot if (string.IsNullOrEmpty(plateTpl)) - { // Some bsg plate properties are empty, skip mod continue; - } var mod = new Item { @@ -283,33 +245,29 @@ public class FenceBaseAssortGenerator( Template = plateTpl, ParentId = armor[0].Id, SlotId = requiredSlot.Name, - Upd = new() + Upd = new Upd { - Repairable = new() + Repairable = new UpdRepairable { Durability = modItemDbDetails.Properties.MaxDurability, - MaxDurability = modItemDbDetails.Properties.MaxDurability, - }, - }, + MaxDurability = modItemDbDetails.Properties.MaxDurability + } + } }; armor.Add(mod); } - } // Check for and add plate items var plateSlots = itemDbDetails.Properties.Slots.Where((slot) => itemHelper.IsRemovablePlateSlot(slot.Name)) .ToList(); if (plateSlots.Count > 0) - { foreach (var plateSlot in plateSlots) { var plateTpl = plateSlot.Props.Filters[0].Plate; if (string.IsNullOrEmpty(plateTpl)) - { // Bsg data lacks a default plate, skip adding mod continue; - } var modItemDbDetails = itemHelper.GetItem(plateTpl).Value; armor.Add( @@ -319,18 +277,17 @@ public class FenceBaseAssortGenerator( Template = plateSlot.Props.Filters[0].Plate, // `Plate` property appears to be the 'default' item for slot ParentId = armor[0].Id, SlotId = plateSlot.Name, - Upd = new() + Upd = new Upd { - Repairable = new() + Repairable = new UpdRepairable { Durability = modItemDbDetails.Properties.MaxDurability, - MaxDurability = modItemDbDetails.Properties.MaxDurability, - }, - }, + MaxDurability = modItemDbDetails.Properties.MaxDurability + } + } } ); } - } } /** diff --git a/Libraries/Core/Generators/LocationLootGenerator.cs b/Libraries/Core/Generators/LocationLootGenerator.cs index a2f41d69..749cf011 100644 --- a/Libraries/Core/Generators/LocationLootGenerator.cs +++ b/Libraries/Core/Generators/LocationLootGenerator.cs @@ -51,43 +51,35 @@ public class LocationLootGenerator( var staticWeaponsOnMapClone = _cloner.Clone(mapData.StaticContainers.Value.StaticWeapons); if (staticWeaponsOnMapClone is null) - { _logger.Error( _localisationService.GetText("location-unable_to_find_static_weapon_for_map", locationBase.Name) ); - } // Add mounted weapons to output loot result.AddRange(staticWeaponsOnMapClone); var allStaticContainersOnMapClone = _cloner.Clone(mapData.StaticContainers.Value.StaticContainers); if (allStaticContainersOnMapClone is null) - { _logger.Error( _localisationService.GetText("location-unable_to_find_static_container_for_map", locationBase.Name) ); - } // Containers that MUST be added to map (e.g. quest containers) var staticForcedOnMapClone = _cloner.Clone(mapData.StaticContainers.Value.StaticForced); if (staticForcedOnMapClone is null) - { _logger.Error( _localisationService.GetText( "location-unable_to_find_forced_static_data_for_map", locationBase.Name ) ); - } // Remove christmas items from loot data if (!_seasonalEventService.ChristmasEventEnabled()) - { allStaticContainersOnMapClone = allStaticContainersOnMapClone.Where( item => !_seasonalEventConfig.ChristmasContainerIds.Contains(item.Template.Id) ) .ToList(); - } var staticRandomisableContainersOnMap = GetRandomisableContainersOnMap(allStaticContainersOnMapClone); @@ -114,10 +106,7 @@ public class LocationLootGenerator( staticLootItemCount += containerWithLoot.Template.Items.Count; } - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Added {guaranteedContainers.Count} guaranteed containers"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Added {guaranteedContainers.Count} guaranteed containers"); // Randomisation is turned off globally or just turned off for this map if ( @@ -127,12 +116,10 @@ public class LocationLootGenerator( ) ) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug( $"Container randomisation disabled, Adding {staticRandomisableContainersOnMap.Count} containers to {locationBase.Name}" ); - } foreach (var container in staticRandomisableContainersOnMap) { var containerWithLoot = AddLootToContainer( @@ -166,17 +153,11 @@ public class LocationLootGenerator( foreach (var (key, data) in mapping) { // Count chosen was 0, skip - if (data.ChosenCount == 0) - { - continue; - } + if (data.ChosenCount == 0) continue; if (data.ContainerIdsWithProbability.Count == 0) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Group: {key} has no containers with < 100 % spawn chance to choose from, skipping"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Group: {key} has no containers with < 100 % spawn chance to choose from, skipping"); continue; } @@ -189,18 +170,13 @@ public class LocationLootGenerator( data.ContainerIdsWithProbability = new Dictionary(); foreach (var containerId in containerIdsCopy) if (_randomUtil.GetChance100(containerIdsCopy[containerId.Key] * 100)) - { data.ContainerIdsWithProbability[containerId.Key] = containerIdsCopy[containerId.Key]; - } // Set desired count to size of array (we want all containers chosen) data.ChosenCount = data.ContainerIdsWithProbability.Count; // EDGE CASE: chosen container count could be 0 - if (data.ChosenCount == 0) - { - continue; - } + if (data.ChosenCount == 0) continue; } // Pass possible containers into function to choose some @@ -213,12 +189,10 @@ public class LocationLootGenerator( ); if (containerObject is null) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug( $"Container: {chosenContainerId} not found in staticRandomisableContainersOnMap, this is bad" ); - } continue; } @@ -296,12 +270,10 @@ public class LocationLootGenerator( var containerIds = containerData.ContainerIdsWithProbability.Keys.ToList(); if (containerData.ChosenCount > containerIds.Count) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug( $"Group: {groupId} wants {containerData.ChosenCount} containers but pool only has {containerIds.Count}, add what's available" ); - } return containerIds; } @@ -331,9 +303,7 @@ public class LocationLootGenerator( // Create dictionary of all group ids and choose a count of containers the map will spawn of that group var mapping = new Dictionary(); foreach (var groupKvP in staticContainerGroupData.ContainersGroups) - { if (staticContainerGroupData.ContainersGroups.TryGetValue(groupKvP.Key, out var groupData)) - { mapping[groupKvP.Key] = new ContainerGroupCount { ContainerIdsWithProbability = new Dictionary(), @@ -348,8 +318,6 @@ public class LocationLootGenerator( ) ) }; - } - } // Add an empty group for containers without a group id but still have a < 100% chance to spawn // Likely bad BSG data, will be fixed...eventually, example of the groupids: `NEED_TO_BE_FIXED1`,`NEED_TO_BE_FIXED_SE02`, `NEED_TO_BE_FIXED_NW_01` @@ -373,21 +341,22 @@ public class LocationLootGenerator( if (container.Probability >= 1) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug( $"Container {container.Template.Id} with group: {groupData.GroupId} had 100 % chance to spawn was picked as random container, skipping" ); - } continue; } - mapping.TryAdd(groupData.GroupId, new ContainerGroupCount - { - ChosenCount = 0d, - ContainerIdsWithProbability = new Dictionary() - }); + mapping.TryAdd( + groupData.GroupId, + new ContainerGroupCount + { + ChosenCount = 0d, + ContainerIdsWithProbability = new Dictionary() + } + ); mapping[groupData.GroupId].ContainerIdsWithProbability.TryAdd(container.Template.Id, container.Probability.Value); } @@ -447,10 +416,7 @@ public class LocationLootGenerator( foreach (var tplToAdd in tplsToAddToContainer) { var chosenItemWithChildren = CreateStaticLootItem(tplToAdd, staticAmmoDist, parentId); - if (chosenItemWithChildren is null) - { - continue; - } + if (chosenItemWithChildren is null) continue; var items = _locationConfig.TplsToStripChildItemsFrom.Contains(tplToAdd) ? [chosenItemWithChildren.Items[0]] // Strip children from parent @@ -464,17 +430,15 @@ public class LocationLootGenerator( if (!result.Success.GetValueOrDefault(false)) { if (failedToFitCount > _locationConfig.FitLootIntoContainerAttempts) - { // x attempts to fit an item, container is probably full, stop trying to add more break; - } // Can't fit item, skip failedToFitCount++; continue; } - + _containerHelper.FillContainerMapWithItem( containerMap, result.X.Value, @@ -485,9 +449,9 @@ public class LocationLootGenerator( ); var rotation = result.Rotation.GetValueOrDefault(false) ? 1 : 0; - + items[0].SlotId = "main"; - items[0].Location = new ItemLocation{ X = result.X, Y = result.Y, R = rotation }; + items[0].Location = new ItemLocation { X = result.X, Y = result.Y, R = rotation }; // Add loot to container before returning containerClone.Template.Items.AddRange(items); @@ -517,7 +481,7 @@ public class LocationLootGenerator( }; } - + // Multi-mod-item, use helper to get size of item + attached mods var result = _inventoryHelper.GetItemSize(rootItem.Template, rootItem.Id, items); return new ItemSize @@ -525,7 +489,6 @@ public class LocationLootGenerator( Width = result[0], Height = result[1] }; - } /// @@ -614,16 +577,11 @@ public class LocationLootGenerator( foreach (var icd in itemContainerDistribution) { if (!seasonalEventActive && seasonalItemTplBlacklist.Contains(icd.Tpl)) - { // Skip seasonal event items if they're not enabled continue; - } // Ensure no blacklisted lootable items are in pool - if (_itemFilterService.IsLootableItemBlacklisted(icd.Tpl)) - { - continue; - } + if (_itemFilterService.IsLootableItemBlacklisted(icd.Tpl)) continue; itemDistribution.Add(new ProbabilityObject(icd.Tpl, icd.RelativeProbability.Value, null)); } @@ -697,18 +655,12 @@ public class LocationLootGenerator( // Point is blacklisted, skip if (blacklistedSpawnpoints?.Contains(spawnpoint.Template.Id) ?? false) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Ignoring loose loot location: {spawnpoint.Template.Id}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Ignoring loose loot location: {spawnpoint.Template.Id}"); continue; } // We've handled IsAlwaysSpawn above, so skip them - if (spawnpoint.Template.IsAlwaysSpawn ?? false) - { - continue; - } + if (spawnpoint.Template.IsAlwaysSpawn ?? false) continue; // 100%, add it to guaranteed if (spawnpoint.Probability == 1) @@ -728,13 +680,9 @@ public class LocationLootGenerator( var randomSpawnpointCount = desiredSpawnpointCount - chosenSpawnpoints.Count; // Only draw random spawn points if needed if (randomSpawnpointCount > 0 && spawnpointArray.Count > 0) - { // Add randomly chosen spawn points foreach (var si in spawnpointArray.Draw((int)randomSpawnpointCount, false)) - { chosenSpawnpoints.Add(spawnpointArray.Data(si)); - } - } // Filter out duplicate locationIds // prob can be done better chosenSpawnpoints = chosenSpawnpoints.GroupBy(spawnpoint => spawnpoint.LocationId).Select(group => group.First()).ToList(); @@ -742,9 +690,7 @@ public class LocationLootGenerator( // Do we have enough items in pool to fulfill requirement var tooManySpawnPointsRequested = desiredSpawnpointCount - chosenSpawnpoints.Count > 0; if (tooManySpawnPointsRequested) - { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug( _localisationService.GetText( "location-spawn_point_count_requested_vs_found", @@ -752,12 +698,10 @@ public class LocationLootGenerator( { requested = desiredSpawnpointCount + guaranteedLoosePoints.Count, found = chosenSpawnpoints.Count, - mapName = locationName, + mapName = locationName } ) ); - } - } // Iterate over spawnpoints var seasonalEventActive = _seasonalEventService.SeasonalEventEnabled(); @@ -782,22 +726,18 @@ public class LocationLootGenerator( // Ensure no seasonal items are in pool if not in-season if (!seasonalEventActive) - { spawnPoint.Template.Items = spawnPoint.Template.Items.Where( (item) => !seasonalItemTplBlacklist.Contains(item.Template) ) .ToList(); - } // Spawn point has no items after filtering, skip if (spawnPoint.Template.Items is null || spawnPoint.Template.Items.Count == 0) { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug( _localisationService.GetText("location-spawnpoint_missing_items", spawnPoint.Template.Id) ); - } continue; } @@ -809,10 +749,7 @@ public class LocationLootGenerator( var itemArray = new ProbabilityObjectArray(_mathUtil, _cloner); foreach (var itemDist in spawnPoint.ItemDistribution) { - if (!validItemIds.Contains(itemDist.ComposedKey.Key)) - { - continue; - } + if (!validItemIds.Contains(itemDist.ComposedKey.Key)) continue; itemArray.Add(new ProbabilityObject(itemDist.ComposedKey.Key, itemDist.RelativeProbability ?? 0, null)); } @@ -858,7 +795,6 @@ public class LocationLootGenerator( { var lootToForceSingleAmountOnMap = _locationConfig.ForcedLootSingleSpawnById.GetValueOrDefault(locationName); if (lootToForceSingleAmountOnMap is not null) - { // Process loot items defined as requiring only 1 spawn position as they appear in multiple positions on the map foreach (var itemTpl in lootToForceSingleAmountOnMap) { @@ -868,20 +804,16 @@ public class LocationLootGenerator( ); if (items is null || !items.Any()) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Unable to adjust loot item {itemTpl} as it does not exist inside {locationName} forced loot."); - } continue; } // Create probability array of all spawn positions for this spawn id var spawnpointArray = new ProbabilityObjectArray(_mathUtil, _cloner); foreach (var si in items) - { // use locationId as template.Id is the same across all items spawnpointArray.Add(new ProbabilityObject(si.LocationId, si.Probability ?? 0, si)); - } // Choose 1 out of all found spawn positions for spawn id and add to loot array foreach (var spawnPointLocationId in spawnpointArray.Draw(1, false)) @@ -906,7 +838,6 @@ public class LocationLootGenerator( lootLocationTemplates.Add(lootItem); } } - } var seasonalEventActive = _seasonalEventService.SeasonalEventEnabled(); var seasonalItemTplBlacklist = _seasonalEventService.GetInactiveSeasonalEventItems(); @@ -917,16 +848,10 @@ public class LocationLootGenerator( var firstLootItemTpl = forcedLootLocation.Template.Items.FirstOrDefault().Template; // Skip spawn positions processed already - if (lootToForceSingleAmountOnMap?.Contains(firstLootItemTpl) ?? false) - { - continue; - } + if (lootToForceSingleAmountOnMap?.Contains(firstLootItemTpl) ?? false) continue; // Skip adding seasonal items when seasonal event is not active - if (!seasonalEventActive && seasonalItemTplBlacklist.Contains(firstLootItemTpl)) - { - continue; - } + if (!seasonalEventActive && seasonalItemTplBlacklist.Contains(firstLootItemTpl)) continue; var locationTemplateToAdd = forcedLootLocation.Template; var createItemResult = CreateDynamicLootItem( @@ -949,12 +874,10 @@ public class LocationLootGenerator( } else { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug( $"Attempted to add a forced loot location with Id: {locationTemplateToAdd.Id} to map {locationName} that already has that id in use, skipping" ); - } } } } @@ -963,39 +886,43 @@ public class LocationLootGenerator( { var chosenItem = items.FirstOrDefault((item) => item.Id == chosenComposedKey); var chosenTpl = chosenItem?.Template; - if (chosenTpl is null) { - throw new Exception($"Item for tpl {chosenComposedKey} was not found in the spawn point"); - } + if (chosenTpl is null) throw new Exception($"Item for tpl {chosenComposedKey} was not found in the spawn point"); var itemTemplate = _itemHelper.GetItem(chosenTpl).Value; - if (itemTemplate is null) { - _logger.Error($"Item tpl: {chosenTpl} cannot be found in database"); - } + if (itemTemplate is null) _logger.Error($"Item tpl: {chosenTpl} cannot be found in database"); // Item array to return List itemWithMods = []; // Money/Ammo - don't rely on items in spawnPoint.template.Items so we can randomise it ourselves - if (_itemHelper.IsOfBaseclasses(chosenTpl, [BaseClasses.MONEY, BaseClasses.AMMO])) { + if (_itemHelper.IsOfBaseclasses(chosenTpl, [BaseClasses.MONEY, BaseClasses.AMMO])) + { var stackCount = itemTemplate.Properties.StackMaxSize == 1 ? 1 : _randomUtil.GetInt((int)itemTemplate.Properties.StackMinRandom, (int)itemTemplate.Properties.StackMaxRandom); - itemWithMods.Add(new Item { - Id = _hashUtil.Generate(), - Template = chosenTpl, - Upd = new Upd { StackObjectsCount = stackCount } - }); - } else if (_itemHelper.IsOfBaseclass(chosenTpl, BaseClasses.AMMO_BOX)) { + itemWithMods.Add( + new Item + { + Id = _hashUtil.Generate(), + Template = chosenTpl, + Upd = new Upd { StackObjectsCount = stackCount } + } + ); + } + else if (_itemHelper.IsOfBaseclass(chosenTpl, BaseClasses.AMMO_BOX)) + { // Fill with cartridges - List ammoBoxItem = [ new Item { Id = _hashUtil.Generate(), Template = chosenTpl }]; + List ammoBoxItem = [new() { Id = _hashUtil.Generate(), Template = chosenTpl }]; _itemHelper.AddCartridgesToAmmoBox(ammoBoxItem, itemTemplate); itemWithMods.AddRange(ammoBoxItem); - } else if (_itemHelper.IsOfBaseclass(chosenTpl, BaseClasses.MAGAZINE)) { + } + else if (_itemHelper.IsOfBaseclass(chosenTpl, BaseClasses.MAGAZINE)) + { // Create array with just magazine - List magazineItem = [new Item { Id = _hashUtil.Generate(), Template = chosenTpl }]; + List magazineItem = [new() { Id = _hashUtil.Generate(), Template = chosenTpl }]; - if (_randomUtil.GetChance100(_locationConfig.StaticMagazineLootHasAmmoChancePercent)) { + if (_randomUtil.GetChance100(_locationConfig.StaticMagazineLootHasAmmoChancePercent)) // Add randomised amount of cartridges _itemHelper.FillMagazineWithRandomCartridge( magazineItem, @@ -1004,10 +931,11 @@ public class LocationLootGenerator( null, _locationConfig.MinFillLooseMagazinePercent / 100 ); - } itemWithMods.AddRange(magazineItem); - } else { + } + else + { // Also used by armors to get child mods // Get item + children and add into array we return var itemWithChildren = _itemHelper.FindAndReturnChildrenAsItems(items, chosenItem.Id); @@ -1015,10 +943,9 @@ public class LocationLootGenerator( // Ensure all IDs are unique itemWithChildren = _itemHelper.ReplaceIDs(_cloner.Clone(itemWithChildren)); - if (_locationConfig.TplsToStripChildItemsFrom.Contains(chosenItem.Template)) { + if (_locationConfig.TplsToStripChildItemsFrom.Contains(chosenItem.Template)) // Strip children from parent before adding itemWithChildren = [itemWithChildren[0]]; - } itemWithMods.AddRange(itemWithChildren); } @@ -1033,8 +960,9 @@ public class LocationLootGenerator( { return _locationConfig.LooseLootMultiplier[location]; } - - protected double getStaticLootMultiplerForLocation(string location) { + + protected double getStaticLootMultiplerForLocation(string location) + { return _locationConfig.StaticLootMultiplier[location]; } @@ -1055,14 +983,11 @@ public class LocationLootGenerator( var width = itemTemplate.Properties.Width; var height = itemTemplate.Properties.Height; - List items = [new Item { Id = _hashUtil.Generate(), Template = chosenTpl }]; + List items = [new() { Id = _hashUtil.Generate(), Template = chosenTpl }]; var rootItem = items.FirstOrDefault(); // Use passed in parentId as override for new item - if (!string.IsNullOrEmpty(parentId)) - { - rootItem.ParentId = parentId; - } + if (!string.IsNullOrEmpty(parentId)) rootItem.ParentId = parentId; if ( _itemHelper.IsOfBaseclass(chosenTpl, BaseClasses.MONEY) || @@ -1072,7 +997,7 @@ public class LocationLootGenerator( // Edge case - some ammos e.g. flares or M406 grenades shouldn't be stacked var stackCount = itemTemplate.Properties.StackMaxSize == 1 ? 1 - : _randomUtil.GetInt((int)(itemTemplate.Properties.StackMinRandom), (int)(itemTemplate.Properties.StackMaxRandom)); + : _randomUtil.GetInt((int)itemTemplate.Properties.StackMinRandom, (int)itemTemplate.Properties.StackMaxRandom); rootItem.Upd = new Upd { StackObjectsCount = stackCount }; } @@ -1100,7 +1025,7 @@ public class LocationLootGenerator( tpl = chosenTpl, defaultId = defaultPreset.Id, defaultName = defaultPreset.Name, - parentId, + parentId } ) ); @@ -1111,10 +1036,7 @@ public class LocationLootGenerator( else { // RSP30 (62178be9d0050232da3485d9/624c0b3340357b5f566e8766/6217726288ed9f0845317459) doesn't have any default presets and kills this code below as it has no chidren to reparent - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"createStaticLootItem() No preset found for weapon: {chosenTpl}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"createStaticLootItem() No preset found for weapon: {chosenTpl}"); } rootItem = items[0]; @@ -1126,7 +1048,7 @@ public class LocationLootGenerator( new { tpl = chosenTpl, - parentId, + parentId } ) ); @@ -1136,10 +1058,7 @@ public class LocationLootGenerator( try { - if (children?.Count > 0) - { - items = _itemHelper.ReparentItemAndChildren(rootItem, children); - } + if (children?.Count > 0) items = _itemHelper.ReparentItemAndChildren(rootItem, children); } catch (Exception e) { @@ -1149,7 +1068,7 @@ public class LocationLootGenerator( new { tpl = chosenTpl, - parentId = parentId, + parentId = parentId } ) ); @@ -1230,13 +1149,11 @@ public class LocationLootGenerator( { // We make base item above, at start of function, no need to do it here if ((itemTemplate.Properties.Slots?.Count ?? 0) > 0) - { items = _itemHelper.AddChildSlotItems( items, itemTemplate, _locationConfig.EquipmentLootSettings.ModSpawnChancePercent ); - } } } diff --git a/Libraries/Core/Generators/LootGenerator.cs b/Libraries/Core/Generators/LootGenerator.cs index 9d8f8aaa..c41771a4 100644 --- a/Libraries/Core/Generators/LootGenerator.cs +++ b/Libraries/Core/Generators/LootGenerator.cs @@ -28,9 +28,8 @@ public class LootGenerator( WeightedRandomHelper _weightedRandomHelper, RagfairLinkedItemService _ragfairLinkedItemService, ICloner _cloner - ) +) { - /// /// Generate a list of items based on configuration options parameter /// @@ -44,24 +43,33 @@ public class LootGenerator( // Handle sealed weapon containers var sealedWeaponCrateCount = _randomUtil.GetDouble( options.WeaponCrateCount.Min.Value, - options.WeaponCrateCount.Max.Value); - if (sealedWeaponCrateCount > 0) { + options.WeaponCrateCount.Max.Value + ); + if (sealedWeaponCrateCount > 0) + { // Get list of all sealed containers from db - they're all the same, just for flavor var itemsDb = _itemHelper.GetItems(); - var sealedWeaponContainerPool = (itemsDb).Where((item) => - item.Name.Contains("event_container_airdrop")); + var sealedWeaponContainerPool = itemsDb.Where( + (item) => + item.Name.Contains("event_container_airdrop") + ); - for (var index = 0; index < sealedWeaponCrateCount; index++) { + for (var index = 0; index < sealedWeaponCrateCount; index++) + { // Choose one at random + add to results array var chosenSealedContainer = _randomUtil.GetArrayValue(sealedWeaponContainerPool); - result.Add( new Item{ - Id = _hashUtil.Generate(), - Template = chosenSealedContainer.Id, - Upd = new Upd{ - StackObjectsCount = 1, - SpawnedInSession = true - }, - }); + result.Add( + new Item + { + Id = _hashUtil.Generate(), + Template = chosenSealedContainer.Id, + Upd = new Upd + { + StackObjectsCount = 1, + SpawnedInSession = true + } + } + ); } } @@ -70,17 +78,17 @@ public class LootGenerator( options.ItemBlacklist, options.ItemTypeWhitelist, options.UseRewardItemBlacklist.GetValueOrDefault(false), - options.AllowBossItems.GetValueOrDefault(false)); + options.AllowBossItems.GetValueOrDefault(false) + ); // Pool has items we could add as loot, proceed - if (rewardPoolResults.ItemPool.Count > 0) { + if (rewardPoolResults.ItemPool.Count > 0) + { var randomisedItemCount = _randomUtil.GetDouble(options.ItemCount.Min.Value, options.ItemCount.Max.Value); - for (var index = 0; index < randomisedItemCount; index++) { - if (!FindAndAddRandomItemToLoot(rewardPoolResults.ItemPool, itemTypeCounts, options, result)) { + for (var index = 0; index < randomisedItemCount; index++) + if (!FindAndAddRandomItemToLoot(rewardPoolResults.ItemPool, itemTypeCounts, options, result)) // Failed to add, reduce index so we get another attempt index--; - } - } } var globalDefaultPresets = _presetHelper.GetDefaultPresets().Values; @@ -88,52 +96,60 @@ public class LootGenerator( // Filter default presets to just weapons var randomisedWeaponPresetCount = _randomUtil.GetDouble( options.WeaponPresetCount.Min.Value, - options.WeaponPresetCount.Max.Value); - if (randomisedWeaponPresetCount > 0) { - var weaponDefaultPresets = globalDefaultPresets.Where((preset) => - _itemHelper.IsOfBaseclass(preset.Encyclopedia, BaseClasses.WEAPON)).ToList(); + options.WeaponPresetCount.Max.Value + ); + if (randomisedWeaponPresetCount > 0) + { + var weaponDefaultPresets = globalDefaultPresets.Where( + (preset) => + _itemHelper.IsOfBaseclass(preset.Encyclopedia, BaseClasses.WEAPON) + ) + .ToList(); - if (weaponDefaultPresets.Any()) { - for (var index = 0; index < randomisedWeaponPresetCount; index++) { + if (weaponDefaultPresets.Any()) + for (var index = 0; index < randomisedWeaponPresetCount; index++) if ( - !FindAndAddRandomPresetToLoot( - weaponDefaultPresets, - itemTypeCounts, - rewardPoolResults.Blacklist, - result) - ) { + !FindAndAddRandomPresetToLoot( + weaponDefaultPresets, + itemTypeCounts, + rewardPoolResults.Blacklist, + result + ) + ) // Failed to add, reduce index so we get another attempt index--; - } - } - } } // Filter default presets to just armors and then filter again by protection level var randomisedArmorPresetCount = _randomUtil.GetDouble( options.ArmorPresetCount.Min.Value, - options.ArmorPresetCount.Max.Value); - if (randomisedArmorPresetCount > 0) { - var armorDefaultPresets = globalDefaultPresets.Where((preset) => - _itemHelper.ArmorItemCanHoldMods(preset.Encyclopedia)); - var levelFilteredArmorPresets = armorDefaultPresets.Where((armor) => - IsArmorOfDesiredProtectionLevel(armor, options)).ToList(); + options.ArmorPresetCount.Max.Value + ); + if (randomisedArmorPresetCount > 0) + { + var armorDefaultPresets = globalDefaultPresets.Where( + (preset) => + _itemHelper.ArmorItemCanHoldMods(preset.Encyclopedia) + ); + var levelFilteredArmorPresets = armorDefaultPresets.Where( + (armor) => + IsArmorOfDesiredProtectionLevel(armor, options) + ) + .ToList(); // Add some armors to rewards - if (levelFilteredArmorPresets.Any()) { - for (var index = 0; index < randomisedArmorPresetCount; index++) { + if (levelFilteredArmorPresets.Any()) + for (var index = 0; index < randomisedArmorPresetCount; index++) if ( - !FindAndAddRandomPresetToLoot( - levelFilteredArmorPresets, - itemTypeCounts, - rewardPoolResults.Blacklist, - result) - ) { + !FindAndAddRandomPresetToLoot( + levelFilteredArmorPresets, + itemTypeCounts, + rewardPoolResults.Blacklist, + result + ) + ) // Failed to add, reduce index so we get another attempt index--; - } - } - } } return result; @@ -151,18 +167,21 @@ public class LootGenerator( var forcedItems = forcedLootDict; - foreach (var forcedItemKvP in forcedItems) { + foreach (var forcedItemKvP in forcedItems) + { var details = forcedLootDict[forcedItemKvP.Key]; var randomisedItemCount = _randomUtil.GetDouble(details.Min.Value, details.Max.Value); // Add forced loot item to result - var newLootItem = new Item{ + var newLootItem = new Item + { Id = _hashUtil.Generate(), Template = forcedItemKvP.Key, - Upd = new Upd{ + Upd = new Upd + { StackObjectsCount = randomisedItemCount, - SpawnedInSession = true, - }, + SpawnedInSession = true + } }; var splitResults = _itemHelper.SplitStack(newLootItem); @@ -195,7 +214,7 @@ public class LootGenerator( // Get all items that match the blacklisted types and fold into item blacklist var itemTypeBlacklist = _itemFilterService.GetItemRewardBaseTypeBlacklist(); - var itemsMatchingTypeBlacklist = (itemsDb) + var itemsMatchingTypeBlacklist = itemsDb .Where((templateItem) => _itemHelper.IsOfBaseclasses(templateItem.Parent, itemTypeBlacklist)) .Select((templateItem) => templateItem.Id); @@ -207,26 +226,19 @@ public class LootGenerator( } if (!allowBossItems) - { - foreach (var bossItem in _itemFilterService.GetBossItems()) { + foreach (var bossItem in _itemFilterService.GetBossItems()) itemBlacklist.Add(bossItem); - } - } var items = itemsDb.Where( - (item) => - !itemBlacklist.Contains(item.Id) && + (item) => + !itemBlacklist.Contains(item.Id) && item.Type.ToLower() == "item" && - !item.Properties.QuestItem.GetValueOrDefault(false) && - itemTypeWhitelist.Contains(item.Parent)).ToList(); + !item.Properties.QuestItem.GetValueOrDefault(false) && + itemTypeWhitelist.Contains(item.Parent) + ) + .ToList(); - return new ItemRewardPoolResults{ ItemPool = items, Blacklist = itemBlacklist }; - } - - public record ItemRewardPoolResults - { - public List ItemPool { get; set; } - public HashSet Blacklist { get; set; } + return new ItemRewardPoolResults { ItemPool = items, Blacklist = itemBlacklist }; } /// @@ -238,12 +250,10 @@ public class LootGenerator( protected bool IsArmorOfDesiredProtectionLevel(Preset armor, LootRequest options) { string[] relevantSlots = ["front_plate", "helmet_top", "soft_armor_front"]; - foreach (var slotId in relevantSlots) { + foreach (var slotId in relevantSlots) + { var armorItem = armor.Items.FirstOrDefault((item) => item?.SlotId?.ToLower() == slotId); - if (armorItem is null) - { - continue; - } + if (armorItem is null) continue; var armorDetails = _itemHelper.GetItem(armorItem.Template).Value; var armorClass = armorDetails.Properties.ArmorClass; @@ -262,9 +272,7 @@ public class LootGenerator( private Dictionary InitItemLimitCounter(Dictionary limits) { var itemTypeCounts = new Dictionary(); - foreach (var itemTypeId in limits) { - itemTypeCounts[itemTypeId.Key] = new ItemLimit() { Current = 0, Max = limits[itemTypeId.Key] }; - } + foreach (var itemTypeId in limits) itemTypeCounts[itemTypeId.Key] = new ItemLimit() { Current = 0, Max = limits[itemTypeId.Key] }; return itemTypeCounts; } @@ -284,36 +292,31 @@ public class LootGenerator( var randomItem = _randomUtil.GetArrayValue(items); var itemLimitCount = itemTypeCounts.TryGetValue(randomItem.Parent, out var randomItemLimitCount); - if (!itemLimitCount && randomItemLimitCount?.Current > randomItemLimitCount?.Max) { - return false; - } + if (!itemLimitCount && randomItemLimitCount?.Current > randomItemLimitCount?.Max) return false; // Skip armors as they need to come from presets - if (_itemHelper.ArmorItemCanHoldMods(randomItem.Id)) { - return false; - } + if (_itemHelper.ArmorItemCanHoldMods(randomItem.Id)) return false; - var newLootItem = new Item { + var newLootItem = new Item + { Id = _hashUtil.Generate(), Template = randomItem.Id, - Upd = new Upd { + Upd = new Upd + { StackObjectsCount = 1, - SpawnedInSession = true, - }, + SpawnedInSession = true + } }; // Special case - handle items that need a stackcount > 1 - if (randomItem.Properties.StackMaxSize > 1) { - newLootItem.Upd.StackObjectsCount = GetRandomisedStackCount(randomItem, options); - } + if (randomItem.Properties.StackMaxSize > 1) newLootItem.Upd.StackObjectsCount = GetRandomisedStackCount(randomItem, options); newLootItem.Template = randomItem.Id; result.Add(newLootItem); - if (randomItemLimitCount is not null) { + if (randomItemLimitCount is not null) // Increment item count as it's in limit array randomItemLimitCount.Current++; - } // Item added okay return true; @@ -330,7 +333,8 @@ public class LootGenerator( var min = item.Properties.StackMinRandom; var max = item.Properties.StackMaxSize; - if (options.ItemStackLimits.TryGetValue(item.Id, out var itemLimits)) { + if (options.ItemStackLimits.TryGetValue(item.Id, out var itemLimits)) + { min = itemLimits.Min; max = (int?)itemLimits.Max; } @@ -353,40 +357,36 @@ public class LootGenerator( { // Choose random preset and get details from item db using encyclopedia value (encyclopedia === tplId) var chosenPreset = _randomUtil.GetArrayValue(presetPool); - if (chosenPreset is null ) { + if (chosenPreset is null) + { _logger.Warning("Unable to find random preset in given presets, skipping"); return false; } // No `_encyclopedia` property, not possible to reliably get root item tpl - if (chosenPreset.Encyclopedia is null) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Preset with id: {chosenPreset?.Id} lacks encyclopedia property, skipping"); - } + if (chosenPreset.Encyclopedia is null) + { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Preset with id: {chosenPreset?.Id} lacks encyclopedia property, skipping"); return false; } // Get preset root item db details via its `_encyclopedia` property var itemDbDetails = _itemHelper.GetItem(chosenPreset.Encyclopedia); - if (!itemDbDetails.Key) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"$Unable to find preset with tpl: {chosenPreset.Encyclopedia}, skipping"); - } + if (!itemDbDetails.Key) + { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"$Unable to find preset with tpl: {chosenPreset.Encyclopedia}, skipping"); return false; } // Skip preset if root item is blacklisted - if (itemBlacklist.Contains(chosenPreset.Items[0].Template)) { - return false; - } + if (itemBlacklist.Contains(chosenPreset.Items[0].Template)) return false; // Some custom mod items lack a parent property - if (itemDbDetails.Value.Parent is null) { + if (itemDbDetails.Value.Parent is null) + { _logger.Error(_localisationService.GetText("loot-item_missing_parentid", itemDbDetails.Value?.Name)); return false; @@ -394,21 +394,16 @@ public class LootGenerator( // Check chosen preset hasn't exceeded spawn limit var hasItemLimitCount = itemTypeCounts.TryGetValue(itemDbDetails.Value.Parent, out var itemLimitCount); - if (!hasItemLimitCount && itemLimitCount?.Current > itemLimitCount?.Max) { - return false; - } + if (!hasItemLimitCount && itemLimitCount?.Current > itemLimitCount?.Max) return false; var presetAndMods = _itemHelper.ReplaceIDs(_cloner.Clone(chosenPreset.Items)); _itemHelper.RemapRootItemId(presetAndMods); // Add chosen preset tpl to result array - foreach (var item in presetAndMods) { - result.Add(item); - } + foreach (var item in presetAndMods) result.Add(item); - if (itemLimitCount is not null) { + if (itemLimitCount is not null) // Increment item count as item has been chosen and its inside itemLimitCount dictionary itemLimitCount.Current++; - } // Item added okay return true; @@ -430,7 +425,8 @@ public class LootGenerator( // Get itemDb details of weapon var weaponDetailsDb = _itemHelper.GetItem(chosenWeaponTpl); - if (!weaponDetailsDb.Key) { + if (!weaponDetailsDb.Key) + { _logger.Error( _localisationService.GetText("loot-non_item_picked_as_sealed_weapon_crate_reward", chosenWeaponTpl) ); @@ -444,7 +440,8 @@ public class LootGenerator( : _randomUtil.GetArrayValue(_presetHelper.GetPresets(chosenWeaponTpl)); // No default preset found for weapon, choose a random one - if (chosenWeaponPreset is null) { + if (chosenWeaponPreset is null) + { _logger.Warning( _localisationService.GetText("loot-default_preset_not_found_using_random", chosenWeaponTpl) ); @@ -460,11 +457,12 @@ public class LootGenerator( // Get a random collection of weapon mods related to chosen weawpon and add them to result array var linkedItemsToWeapon = _ragfairLinkedItemService.GetLinkedDbItems(chosenWeaponTpl); - itemsToReturn.AddRange(GetSealedContainerWeaponModRewards(containerSettings, linkedItemsToWeapon, chosenWeaponPreset) + itemsToReturn.AddRange( + GetSealedContainerWeaponModRewards(containerSettings, linkedItemsToWeapon, chosenWeaponPreset) ); // Handle non-weapon mod reward types - itemsToReturn.AddRange((GetSealedContainerNonWeaponModRewards(containerSettings, weaponDetailsDb.Value))); + itemsToReturn.AddRange(GetSealedContainerNonWeaponModRewards(containerSettings, weaponDetailsDb.Value)); return itemsToReturn; } @@ -480,35 +478,39 @@ public class LootGenerator( { List> rewards = []; - foreach (var (rewardKey,settings) in containerSettings.RewardTypeLimits) { + foreach (var (rewardKey, settings) in containerSettings.RewardTypeLimits) + { var rewardCount = _randomUtil.GetDouble(settings.Min.Value, settings.Max.Value); - if (rewardCount == 0) { - continue; - } + if (rewardCount == 0) continue; // Edge case - ammo boxes - if (rewardKey == BaseClasses.AMMO_BOX) { + if (rewardKey == BaseClasses.AMMO_BOX) + { // Get ammoboxes from db - var ammoBoxesDetails = containerSettings.AmmoBoxWhitelist.Select((tpl) => { - var itemDetails = _itemHelper.GetItem(tpl); - return itemDetails.Value; - }); + var ammoBoxesDetails = containerSettings.AmmoBoxWhitelist.Select( + (tpl) => + { + var itemDetails = _itemHelper.GetItem(tpl); + return itemDetails.Value; + } + ); // Need to find boxes that matches weapons caliber var weaponCaliber = weaponDetailsDb.Properties.AmmoCaliber; - var ammoBoxesMatchingCaliber = ammoBoxesDetails.Where((x) => - x.Properties.AmmoCaliber == weaponCaliber); - if (!ammoBoxesMatchingCaliber.Any()) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"No ammo box with caliber {weaponCaliber} found, skipping"); - } + var ammoBoxesMatchingCaliber = ammoBoxesDetails.Where( + (x) => + x.Properties.AmmoCaliber == weaponCaliber + ); + if (!ammoBoxesMatchingCaliber.Any()) + { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"No ammo box with caliber {weaponCaliber} found, skipping"); continue; } - for (var index = 0; index < rewardCount; index++) { + for (var index = 0; index < rewardCount; index++) + { var chosenAmmoBox = _randomUtil.GetArrayValue(ammoBoxesMatchingCaliber); var ammoBoxReward = new List { new() { Id = _hashUtil.Generate(), Template = chosenAmmoBox.Id } }; _itemHelper.AddCartridgesToAmmoBox(ammoBoxReward, chosenAmmoBox); @@ -519,25 +521,25 @@ public class LootGenerator( } // Get all items of the desired type + not quest items + not globally blacklisted - var rewardItemPool = _databaseService.GetItems().Values.Where( - (item) => - item.Parent == rewardKey && - item.Type.ToLower() == "item" && - _itemFilterService.IsItemBlacklisted(item.Id) && - !(containerSettings.AllowBossItems || _itemFilterService.IsBossItem(item.Id)) && - item.Properties.QuestItem is null - ); + var rewardItemPool = _databaseService.GetItems() + .Values.Where( + (item) => + item.Parent == rewardKey && + item.Type.ToLower() == "item" && + _itemFilterService.IsItemBlacklisted(item.Id) && + !(containerSettings.AllowBossItems || _itemFilterService.IsBossItem(item.Id)) && + item.Properties.QuestItem is null + ); - if (rewardItemPool.Count() == 0) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"No items with base type of {rewardKey} found, skipping"); - } + if (rewardItemPool.Count() == 0) + { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"No items with base type of {rewardKey} found, skipping"); continue; } - for (var index = 0; index < rewardCount; index++) { + for (var index = 0; index < rewardCount; index++) + { // Choose a random item from pool var chosenRewardItem = _randomUtil.GetArrayValue(rewardItemPool); var rewardItem = new List { new() { Id = _hashUtil.Generate(), Template = chosenRewardItem.Id } }; @@ -560,31 +562,30 @@ public class LootGenerator( Preset chosenWeaponPreset) { List> modRewards = []; - - foreach (var (rewardKey,settings) in containerSettings.WeaponModRewardLimits) { + + foreach (var (rewardKey, settings) in containerSettings.WeaponModRewardLimits) + { var rewardCount = _randomUtil.GetDouble(settings.Min.Value, settings.Max.Value); - + // Nothing to add, skip reward type - if (rewardCount == 0) { - continue; - } + if (rewardCount == 0) continue; // Get items that fulfil reward type criteria from items that fit on gun var relatedItems = linkedItemsToWeapon?.Where( (item) => item?.Parent == rewardKey && !_itemFilterService.IsItemBlacklisted(item.Id) ); - if (relatedItems is null || relatedItems.Count() == 0) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { + if (relatedItems is null || relatedItems.Count() == 0) + { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug( $"No items found to fulfil reward type: {rewardKey} for weapon: {chosenWeaponPreset.Name}, skipping type" ); - } continue; } // Find a random item of the desired type and add as reward - for (var index = 0; index < rewardCount; index++) { + for (var index = 0; index < rewardCount; index++) + { var chosenItem = _randomUtil.DrawRandomFromList(relatedItems.ToList()); var reward = new List { new() { Id = _hashUtil.Generate(), Template = chosenItem[0].Id } }; @@ -605,11 +606,13 @@ public class LootGenerator( List> itemsToReturn = []; // Get random items and add to newItemRequest - for (var index = 0; index < rewardContainerDetails.RewardCount; index++) { + for (var index = 0; index < rewardContainerDetails.RewardCount; index++) + { // Pick random reward from pool, add to request object var chosenRewardItemTpl = PickRewardItem(rewardContainerDetails); - if (_presetHelper.HasPreset(chosenRewardItemTpl)) { + if (_presetHelper.HasPreset(chosenRewardItemTpl)) + { var preset = _presetHelper.GetDefaultPreset(chosenRewardItemTpl); // Ensure preset has unique ids and is cloned so we don't alter the preset data stored in memory @@ -621,7 +624,7 @@ public class LootGenerator( continue; } - List rewardItem = [new Item { Id = _hashUtil.Generate(), Template = chosenRewardItemTpl }]; + List rewardItem = [new() { Id = _hashUtil.Generate(), Template = chosenRewardItemTpl }]; itemsToReturn.Add(rewardItem); } @@ -635,16 +638,22 @@ public class LootGenerator( /// Single tpl protected string PickRewardItem(RewardDetails rewardContainerDetails) { - if (rewardContainerDetails.RewardTplPool is not null && rewardContainerDetails.RewardTplPool.Count > 0) { + if (rewardContainerDetails.RewardTplPool is not null && rewardContainerDetails.RewardTplPool.Count > 0) return _weightedRandomHelper.GetWeightedValue(rewardContainerDetails.RewardTplPool); - } return _randomUtil.GetArrayValue( - GetItemRewardPool([], rewardContainerDetails.RewardTypePool, true, true).ItemPool.Select( - (item) => item.Id - ) + GetItemRewardPool([], rewardContainerDetails.RewardTypePool, true, true) + .ItemPool.Select( + (item) => item.Id + ) ); } + + public record ItemRewardPoolResults + { + public List ItemPool { get; set; } + public HashSet Blacklist { get; set; } + } } public class ItemLimit diff --git a/Libraries/Core/Generators/PMCLootGenerator.cs b/Libraries/Core/Generators/PMCLootGenerator.cs index 04af656b..f3cd3457 100644 --- a/Libraries/Core/Generators/PMCLootGenerator.cs +++ b/Libraries/Core/Generators/PMCLootGenerator.cs @@ -12,19 +12,19 @@ namespace Core.Generators; [Injectable] public class PMCLootGenerator { - private readonly ISptLogger _logger; + private readonly ConfigServer _configServer; private readonly DatabaseService _databaseService; - private readonly ItemHelper _itemHelper; private readonly ItemFilterService _itemFilterService; + private readonly ItemHelper _itemHelper; + private readonly ISptLogger _logger; + private readonly PmcConfig _pmcConfig; private readonly RagfairPriceService _ragfairPriceService; private readonly SeasonalEventService _seasonalEventService; private readonly WeightedRandomHelper _weightedRandomHelper; - private readonly ConfigServer _configServer; private Dictionary? _backpackLootPool; private Dictionary? _pocketLootPool; private Dictionary? _vestLootPool; - private readonly PmcConfig _pmcConfig; public PMCLootGenerator( ISptLogger logger, @@ -35,7 +35,7 @@ public class PMCLootGenerator SeasonalEventService seasonalEventService, WeightedRandomHelper weightedRandomHelper, ConfigServer configServer - ) + ) { _logger = logger; _databaseService = databaseService; @@ -78,7 +78,6 @@ public class PMCLootGenerator ); foreach (var (tpl, template) in itemsToAdd) - { // If pmc has price override, use that. Otherwise, use flea price if (pmcPriceOverrides.ContainsKey(tpl)) { @@ -90,15 +89,12 @@ public class PMCLootGenerator var price = _ragfairPriceService.GetDynamicItemPrice(tpl, Money.ROUBLES); _pocketLootPool[tpl] = price ?? 0; } - } var highestPrice = _pocketLootPool.Max(price => price.Value); foreach (var (key, _) in _pocketLootPool) - { // Invert price so cheapest has a larger weight // Times by highest price so most expensive item has weight of 1 - _pocketLootPool[key] = Math.Round((1 / _pocketLootPool[key]) * highestPrice); - } + _pocketLootPool[key] = Math.Round(1 / _pocketLootPool[key] * highestPrice); _weightedRandomHelper.ReduceWeightValues(_pocketLootPool); } @@ -109,22 +105,10 @@ public class PMCLootGenerator private HashSet GetLootBlacklist() { var blacklist = new HashSet(); - foreach (var blacklistedItem in _pmcConfig.PocketLoot.Blacklist) - { - blacklist.Add(blacklistedItem); - } - foreach (var blacklistedItem in _pmcConfig.GlobalLootBlacklist) - { - blacklist.Add(blacklistedItem); - } - foreach (var blacklistedItem in _itemFilterService.GetBlacklistedItems()) - { - blacklist.Add(blacklistedItem); - } - foreach (var blacklistedItem in _seasonalEventService.GetInactiveSeasonalEventItems()) - { - blacklist.Add(blacklistedItem); - } + foreach (var blacklistedItem in _pmcConfig.PocketLoot.Blacklist) blacklist.Add(blacklistedItem); + foreach (var blacklistedItem in _pmcConfig.GlobalLootBlacklist) blacklist.Add(blacklistedItem); + foreach (var blacklistedItem in _itemFilterService.GetBlacklistedItems()) blacklist.Add(blacklistedItem); + foreach (var blacklistedItem in _seasonalEventService.GetInactiveSeasonalEventItems()) blacklist.Add(blacklistedItem); return blacklist; } @@ -154,10 +138,10 @@ public class PMCLootGenerator _itemHelper.IsValidItem(item.Value.Id) && !blacklist.Contains(item.Value.Id) && !blacklist.Contains(item.Value.Parent) && - ItemFitsInto2By2Slot(item.Value)); + ItemFitsInto2By2Slot(item.Value) + ); foreach (var (tpl, template) in itemsToAdd) - { // If pmc has price override, use that. Otherwise, use flea price if (pmcPriceOverrides.ContainsKey(tpl)) { @@ -169,15 +153,12 @@ public class PMCLootGenerator var price = _ragfairPriceService.GetDynamicItemPrice(tpl, Money.ROUBLES); _vestLootPool[tpl] = price ?? 0; } - } var highestPrice = _vestLootPool.Max(price => price.Value); foreach (var (key, _) in _vestLootPool) - { // Invert price so cheapest has a larger weight // Times by highest price so most expensive item has weight of 1 - _vestLootPool[key] = Math.Round((1 / _vestLootPool[key]) * highestPrice); - } + _vestLootPool[key] = Math.Round(1 / _vestLootPool[key] * highestPrice); _weightedRandomHelper.ReduceWeightValues(_vestLootPool); } @@ -234,10 +215,11 @@ public class PMCLootGenerator (item) => allowedItemTypeWhitelist.Contains(item.Value.Parent) && _itemHelper.IsValidItem(item.Value.Id) && - !blacklist.Contains(item.Value.Id) && - !blacklist.Contains(item.Value.Parent)); + !blacklist.Contains(item.Value.Id) && + !blacklist.Contains(item.Value.Parent) + ); - foreach (var (tpl, template) in itemsToAdd) { + foreach (var (tpl, template) in itemsToAdd) // If pmc has price override, use that. Otherwise, use flea price if (pmcPriceOverrides.ContainsKey(tpl)) { @@ -249,14 +231,12 @@ public class PMCLootGenerator var price = _ragfairPriceService.GetDynamicItemPrice(tpl, Money.ROUBLES); _backpackLootPool[tpl] = price ?? 0; } - } var highestPrice = _backpackLootPool.Max(price => price.Value); - foreach (var (key, _) in _backpackLootPool) { + foreach (var (key, _) in _backpackLootPool) // Invert price so cheapest has a larger weight // Times by highest price so most expensive item has weight of 1 - _backpackLootPool[key] = Math.Round((1 / _backpackLootPool[key]) * highestPrice); - } + _backpackLootPool[key] = Math.Round(1 / _backpackLootPool[key] * highestPrice); _weightedRandomHelper.ReduceWeightValues(_backpackLootPool); } diff --git a/Libraries/Core/Generators/PlayerScavGenerator.cs b/Libraries/Core/Generators/PlayerScavGenerator.cs index 2a1dddd1..c4fb2028 100644 --- a/Libraries/Core/Generators/PlayerScavGenerator.cs +++ b/Libraries/Core/Generators/PlayerScavGenerator.cs @@ -2,6 +2,7 @@ using SptCommon.Annotations; using Core.Helpers; using Core.Models.Eft.Common; using Core.Models.Eft.Common.Tables; +using Core.Models.Eft.Notes; using Core.Models.Enums; using Core.Models.Spt.Config; using Core.Models.Utils; @@ -9,6 +10,7 @@ using Core.Servers; using Core.Services; using Core.Utils; using Core.Utils.Cloners; +using Core.Utils.Json; using LogLevel = Core.Models.Spt.Logging.LogLevel; @@ -53,14 +55,9 @@ public class PlayerScavGenerator( // use karma level to get correct karmaSettings if (!_playerScavConfig.KarmaLevel.TryGetValue(scavKarmaLevel.ToString(), out var playerScavKarmaSettings)) - { _logger.Error(_localisationService.GetText("scav-missing_karma_settings", scavKarmaLevel)); - } - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Generated player scav loadout with karma level {scavKarmaLevel}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Generated player scav loadout with karma level {scavKarmaLevel}"); // Edit baseBotNode values var baseBotNode = ConstructBotBaseTemplate(playerScavKarmaSettings.BotTypeForLoot); @@ -81,7 +78,7 @@ public class PlayerScavGenerator( scavData.Savage = null; scavData.Aid = pmcDataClone.Aid; scavData.TradersInfo = pmcDataClone.TradersInfo; - scavData.Info.Settings = new(); + scavData.Info.Settings = new BotInfoSettings(); scavData.Info.Bans = []; scavData.Info.RegistrationDate = pmcDataClone.Info.RegistrationDate; scavData.Info.GameVersion = pmcDataClone.Info.GameVersion; @@ -98,10 +95,10 @@ public class PlayerScavGenerator( scavData.Info.Level = GetScavLevel(existingScavDataClone); scavData.Info.Experience = GetScavExperience(existingScavDataClone); scavData.Quests = existingScavDataClone.Quests ?? []; - scavData.TaskConditionCounters = existingScavDataClone.TaskConditionCounters ?? new(); - scavData.Notes = existingScavDataClone.Notes ?? new() { DataNotes = new() }; - scavData.WishList = existingScavDataClone.WishList ?? new(new(), new()); - scavData.Encyclopedia = pmcDataClone.Encyclopedia ?? new(); + scavData.TaskConditionCounters = existingScavDataClone.TaskConditionCounters ?? new Dictionary(); + scavData.Notes = existingScavDataClone.Notes ?? new Notes { DataNotes = new List() }; + scavData.WishList = existingScavDataClone.WishList ?? new DictionaryOrList(new Dictionary(), new List()); + scavData.Encyclopedia = pmcDataClone.Encyclopedia ?? new Dictionary(); // Add additional items to player scav as loot AddAdditionalLootToPlayerScavContainers( @@ -168,12 +165,8 @@ public class PlayerScavGenerator( ); if (result != ItemAddedResult.SUCCESS) - { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug($"Unable to add keycard to bot. Reason: {result.ToString()}"); - } - } } } @@ -232,17 +225,12 @@ public class PlayerScavGenerator( foreach (var equipmentKvP in karmaSettings.Modifiers.Equipment) { // Adjustment value zero, nothing to do - if (equipmentKvP.Value == 0) - { - continue; - } + if (equipmentKvP.Value == 0) continue; // Try add new key with value if (!baseBotNode.BotChances.EquipmentChances.TryAdd(equipmentKvP.Key, equipmentKvP.Value)) - { // Unable to add new, update existing baseBotNode.BotChances.EquipmentChances[equipmentKvP.Key] += equipmentKvP.Value; - } } // Adjust mod chance values @@ -255,8 +243,9 @@ public class PlayerScavGenerator( { baseBotNode.BotChances.WeaponModsChances.TryAdd(modKvP.Key, 0); baseBotNode.BotChances.WeaponModsChances[modKvP.Key] += value; - }; - + } + + ; } // Adjust item spawn quantity values @@ -271,10 +260,7 @@ public class PlayerScavGenerator( foreach (var equipmentBlacklistKvP in karmaSettings.EquipmentBlacklist) { baseBotNode.BotInventory.Equipment.TryGetValue(equipmentBlacklistKvP.Key, out var equipmentDict); - foreach (var itemToRemove in equipmentBlacklistKvP.Value) - { - equipmentDict.Remove(itemToRemove); - } + foreach (var itemToRemove in equipmentBlacklistKvP.Value) equipmentDict.Remove(itemToRemove); } } @@ -288,10 +274,10 @@ public class PlayerScavGenerator( protected Skills GetDefaultScavSkills() { - return new() + return new Skills { - Common = new(), - Mastering = new(), + Common = new List(), + Mastering = new List(), Points = 0 }; } @@ -337,14 +323,10 @@ public class PlayerScavGenerator( var modifier = 1; foreach (var bonus in pmcData.Bonuses) - { if (bonus.Type == BonusType.ScavCooldownTimer) - { // Value is negative, so add. // Also note that for scav cooldown, multiple bonuses stack additively. modifier += (int)(bonus?.Value ?? 1) / 100; - } - } var fenceInfo = _fenceService.GetFenceInfo(pmcData); modifier *= (int)(fenceInfo.SavageCooldownModifier ?? 1); diff --git a/Libraries/Core/Generators/RagfairAssortGenerator.cs b/Libraries/Core/Generators/RagfairAssortGenerator.cs index ceb019e8..ba4bfed6 100644 --- a/Libraries/Core/Generators/RagfairAssortGenerator.cs +++ b/Libraries/Core/Generators/RagfairAssortGenerator.cs @@ -32,7 +32,7 @@ public class RagfairAssortGenerator( BaseClasses.INVENTORY, BaseClasses.STATIONARY_CONTAINER, BaseClasses.POCKETS, - BaseClasses.BUILT_IN_INSERTS, + BaseClasses.BUILT_IN_INSERTS ]; /** @@ -42,10 +42,7 @@ public class RagfairAssortGenerator( */ public List> GetAssortItems() { - if (!AssortsAreGenerated()) - { - generatedAssortItems = GenerateRagfairAssortItems(); - } + if (!AssortsAreGenerated()) generatedAssortItems = GenerateRagfairAssortItems(); return generatedAssortItems; } @@ -95,10 +92,7 @@ public class RagfairAssortGenerator( foreach (var item in dbItemsClone) { - if (!itemHelper.IsValidItem(item.Id, ragfairItemInvalidBaseTypes)) - { - continue; - } + if (!itemHelper.IsValidItem(item.Id, ragfairItemInvalidBaseTypes)) continue; // Skip seasonal items when not in-season if ( @@ -106,15 +100,11 @@ public class RagfairAssortGenerator( !seasonalEventActive && seasonalItemTplBlacklist.Contains(item.Id) ) - { continue; - } if (processedArmorItems.Contains(item.Id)) - { // Already processed continue; - } var ragfairAssort = CreateRagfairAssortRootItem( item.Id, diff --git a/Libraries/Core/Generators/RagfairOfferGenerator.cs b/Libraries/Core/Generators/RagfairOfferGenerator.cs index 985472d7..a40b37c5 100644 --- a/Libraries/Core/Generators/RagfairOfferGenerator.cs +++ b/Libraries/Core/Generators/RagfairOfferGenerator.cs @@ -43,14 +43,15 @@ public class RagfairOfferGenerator( ICloner cloner ) { - protected RagfairConfig ragfairConfig = configServer.GetConfig(); - protected TraderConfig traderConfig = configServer.GetConfig(); - protected BotConfig botConfig = configServer.GetConfig(); protected List? allowedFleaPriceItemsForBarter; + protected BotConfig botConfig = configServer.GetConfig(); /** Internal counter to ensure each offer created has a unique value for its intId property */ protected int offerCounter = 0; - + + protected RagfairConfig ragfairConfig = configServer.GetConfig(); + protected TraderConfig traderConfig = configServer.GetConfig(); + /** * Create a flea offer and store it in the Ragfair server offers array * @param userID Owner of the offer @@ -97,21 +98,27 @@ public class RagfairOfferGenerator( { var isTrader = ragfairServerHelper.IsTrader(userID); - var offerRequirements = barterScheme.Select((barter) => { - var offerRequirement = new OfferRequirement{ - Template = barter.Template, - Count = Math.Round((double) barter.Count, 2), - OnlyFunctional = barter.OnlyFunctional ?? false, - }; + var offerRequirements = barterScheme.Select( + (barter) => + { + var offerRequirement = new OfferRequirement + { + Template = barter.Template, + Count = Math.Round((double)barter.Count, 2), + OnlyFunctional = barter.OnlyFunctional ?? false + }; - // Dogtags define level and side - if (barter.Level != null) { - offerRequirement.Level = barter.Level; - offerRequirement.Side = barter.Side; - } + // Dogtags define level and side + if (barter.Level != null) + { + offerRequirement.Level = barter.Level; + offerRequirement.Side = barter.Side; + } - return offerRequirement; - }).ToList(); + return offerRequirement; + } + ) + .ToList(); // Clone to avoid modifying original array var itemsClone = cloner.Clone(items); @@ -119,28 +126,28 @@ public class RagfairOfferGenerator( // Hydrate ammo boxes with cartridges + ensure only 1 item is present (ammo box) // On offer refresh don't re-add cartridges to ammo box that already has cartridges - if (itemHelper.IsOfBaseclass(itemsClone[0].Template, BaseClasses.AMMO_BOX) && itemsClone.Count == 1) { + if (itemHelper.IsOfBaseclass(itemsClone[0].Template, BaseClasses.AMMO_BOX) && itemsClone.Count == 1) itemHelper.AddCartridgesToAmmoBox(itemsClone, itemHelper.GetItem(items[0].Template).Value); - } - var roubleListingPrice = Math.Round((double) ConvertOfferRequirementsIntoRoubles(offerRequirements)); + var roubleListingPrice = Math.Round((double)ConvertOfferRequirementsIntoRoubles(offerRequirements)); var singleItemListingPrice = isPackOffer ? roubleListingPrice / itemStackCount : roubleListingPrice; - var offer = new RagfairOffer { - Id= hashUtil.Generate(), - InternalId= offerCounter, - User= CreateUserDataForFleaOffer(userID, isTrader), - Root= items[0].Id, - Items= itemsClone, - ItemsCost= Math.Round((double) handbookHelper.GetTemplatePrice(items[0].Template)), // Handbook price - Requirements= offerRequirements, - RequirementsCost= Math.Round(singleItemListingPrice), - SummaryCost= roubleListingPrice, - StartTime= time, - EndTime= GetOfferEndTime(userID, time), - LoyaltyLevel= loyalLevel, - SellInOnePiece= isPackOffer, - Locked= false, + var offer = new RagfairOffer + { + Id = hashUtil.Generate(), + InternalId = offerCounter, + User = CreateUserDataForFleaOffer(userID, isTrader), + Root = items[0].Id, + Items = itemsClone, + ItemsCost = Math.Round((double)handbookHelper.GetTemplatePrice(items[0].Template)), // Handbook price + Requirements = offerRequirements, + RequirementsCost = Math.Round(singleItemListingPrice), + SummaryCost = roubleListingPrice, + StartTime = time, + EndTime = GetOfferEndTime(userID, time), + LoyaltyLevel = loyalLevel, + SellInOnePiece = isPackOffer, + Locked = false }; offerCounter++; @@ -157,40 +164,43 @@ public class RagfairOfferGenerator( protected RagfairOfferUser CreateUserDataForFleaOffer(string userID, bool isTrader) { // Trader offer - if (isTrader) { - return new RagfairOfferUser(){ + if (isTrader) + return new RagfairOfferUser() + { Id = userID, MemberType = MemberCategory.Trader }; - } var isPlayerOffer = profileHelper.IsPlayer(userID); - if (isPlayerOffer) { + if (isPlayerOffer) + { var playerProfile = profileHelper.GetPmcProfile(userID); - return new RagfairOfferUser { - Id= playerProfile.Id, - MemberType= playerProfile.Info.MemberCategory, - SelectedMemberCategory= playerProfile.Info.SelectedMemberCategory, - Nickname= playerProfile.Info.Nickname, - Rating= playerProfile.RagfairInfo.Rating ?? 0, - IsRatingGrowing= playerProfile.RagfairInfo.IsRatingGrowing, - Avatar= null, - Aid= playerProfile.Aid, + return new RagfairOfferUser + { + Id = playerProfile.Id, + MemberType = playerProfile.Info.MemberCategory, + SelectedMemberCategory = playerProfile.Info.SelectedMemberCategory, + Nickname = playerProfile.Info.Nickname, + Rating = playerProfile.RagfairInfo.Rating ?? 0, + IsRatingGrowing = playerProfile.RagfairInfo.IsRatingGrowing, + Avatar = null, + Aid = playerProfile.Aid }; } // Fake pmc offer - return new RagfairOfferUser(){ - Id= userID, - MemberType= MemberCategory.Default, - Nickname= botHelper.GetPmcNicknameOfMaxLength(botConfig.BotNameLengthLimit), - Rating= randomUtil.GetDouble( - (double) ragfairConfig.Dynamic.Rating.Min, - (double) ragfairConfig.Dynamic.Rating.Max + return new RagfairOfferUser() + { + Id = userID, + MemberType = MemberCategory.Default, + Nickname = botHelper.GetPmcNicknameOfMaxLength(botConfig.BotNameLengthLimit), + Rating = randomUtil.GetDouble( + (double)ragfairConfig.Dynamic.Rating.Min, + (double)ragfairConfig.Dynamic.Rating.Max ), - IsRatingGrowing= randomUtil.GetBool(), - Avatar= null, - Aid= hashUtil.GenerateAccountId(), + IsRatingGrowing = randomUtil.GetBool(), + Avatar = null, + Aid = hashUtil.GenerateAccountId() }; } @@ -199,13 +209,13 @@ public class RagfairOfferGenerator( * @param offerRequirements barter requirements for offer * @returns rouble cost of offer */ - protected int ConvertOfferRequirementsIntoRoubles(List offerRequirements) { + protected int ConvertOfferRequirementsIntoRoubles(List offerRequirements) + { var roublePrice = 0; - foreach (var requirement in offerRequirements) { - roublePrice += (int) (paymentHelper.IsMoneyTpl(requirement.Template) - ? Math.Round((double) CalculateRoublePrice((int) requirement.Count, requirement.Template)) + foreach (var requirement in offerRequirements) + roublePrice += (int)(paymentHelper.IsMoneyTpl(requirement.Template) + ? Math.Round((double)CalculateRoublePrice((int)requirement.Count, requirement.Template)) : ragfairPriceService.GetFleaPriceForItem(requirement.Template) * requirement.Count); // get flea price for barter offer items - } return roublePrice; } @@ -218,9 +228,7 @@ public class RagfairOfferGenerator( */ protected string GetAvatarUrl(bool isTrader, string userId) { - if (isTrader) { - return databaseService.GetTrader(userId).Base.Avatar; - } + if (isTrader) return databaseService.GetTrader(userId).Base.Avatar; return "/files/trader/avatar/unknown.jpg"; } @@ -233,9 +241,7 @@ public class RagfairOfferGenerator( */ protected int CalculateRoublePrice(int currencyCount, string currencyType) { - if (currencyType == Money.ROUBLES) { - return currencyCount; - } + if (currencyType == Money.ROUBLES) return currencyCount; return handbookHelper.InRUB(currencyCount, currencyType); } @@ -247,9 +253,7 @@ public class RagfairOfferGenerator( */ protected string GetTraderId(string userId) { - if (profileHelper.IsPlayer(userId)) { - return saveServer.GetProfile(userId).CharacterData.PmcData.Id; - } + if (profileHelper.IsPlayer(userId)) return saveServer.GetProfile(userId).CharacterData.PmcData.Id; return userId; } @@ -261,18 +265,16 @@ public class RagfairOfferGenerator( */ protected double? GetRating(string userId) { - if (profileHelper.IsPlayer(userId)) { + if (profileHelper.IsPlayer(userId)) // Player offer return saveServer.GetProfile(userId).CharacterData?.PmcData?.RagfairInfo?.Rating; - } - if (ragfairServerHelper.IsTrader(userId)) { + if (ragfairServerHelper.IsTrader(userId)) // Trader offer return 1; - } // Generated pmc offer - return randomUtil.GetDouble((double) ragfairConfig.Dynamic.Rating.Min, (double) ragfairConfig.Dynamic.Rating.Max); + return randomUtil.GetDouble((double)ragfairConfig.Dynamic.Rating.Min, (double)ragfairConfig.Dynamic.Rating.Max); } /** @@ -283,15 +285,12 @@ public class RagfairOfferGenerator( protected bool GetRatingGrowing(string userID) { if (profileHelper.IsPlayer(userID)) - { // player offer return saveServer.GetProfile(userID).CharacterData?.PmcData?.RagfairInfo?.IsRatingGrowing ?? false; - } - if (ragfairServerHelper.IsTrader(userID)) { + if (ragfairServerHelper.IsTrader(userID)) // trader offer return true; - } // generated offer // 50/50 growing/falling @@ -306,19 +305,21 @@ public class RagfairOfferGenerator( */ protected long GetOfferEndTime(string userID, long time) { - if (profileHelper.IsPlayer(userID)) { + if (profileHelper.IsPlayer(userID)) + { // Player offer = current time + offerDurationTimeInHour; var offerDurationTimeHours = databaseService.GetGlobals().Configuration.RagFair.OfferDurationTimeInHour; - return (long) (timeUtil.GetTimeStamp() + Math.Round((double) offerDurationTimeHours * TimeUtil.OneHourAsSeconds)); + return (long)(timeUtil.GetTimeStamp() + Math.Round((double)offerDurationTimeHours * TimeUtil.OneHourAsSeconds)); } - if (ragfairServerHelper.IsTrader(userID)) { + if (ragfairServerHelper.IsTrader(userID)) // Trader offer - return (long) databaseService.GetTrader(userID).Base.NextResupply; - } + return (long)databaseService.GetTrader(userID).Base.NextResupply; // Generated fake-player offer - return (long) Math.Round((double) (time + randomUtil.GetInt((int) ragfairConfig.Dynamic.EndTimeSeconds.Min, (int) ragfairConfig.Dynamic.EndTimeSeconds.Max))); + return (long)Math.Round( + (double)(time + randomUtil.GetInt((int)ragfairConfig.Dynamic.EndTimeSeconds.Min, (int)ragfairConfig.Dynamic.EndTimeSeconds.Max)) + ); } /** @@ -335,26 +336,18 @@ public class RagfairOfferGenerator( ? expiredOffers ?? [] : ragfairAssortGenerator.GetAssortItems(); stopwatch.Stop(); - if (logger.IsLogEnabled(LogLevel.Debug)) - { - logger.Debug($"Took {stopwatch.ElapsedMilliseconds}ms to GetRagfairAssorts"); - } + if (logger.IsLogEnabled(LogLevel.Debug)) logger.Debug($"Took {stopwatch.ElapsedMilliseconds}ms to GetRagfairAssorts"); stopwatch.Restart(); var tasks = new List(); foreach (var assortItem in assortItemsToProcess) - { tasks.Add( Task.Factory.StartNew( () => { CreateOffersFromAssort(assortItem, replacingExpiredOffers, ragfairConfig.Dynamic); } ) ); - } Task.WaitAll(tasks.ToArray()); stopwatch.Stop(); - if (logger.IsLogEnabled(LogLevel.Debug)) - { - logger.Debug($"Took {stopwatch.ElapsedMilliseconds}ms to CreateOffersFromAssort"); - } + if (logger.IsLogEnabled(LogLevel.Debug)) logger.Debug($"Took {stopwatch.ElapsedMilliseconds}ms to CreateOffersFromAssort"); } /** @@ -372,20 +365,17 @@ public class RagfairOfferGenerator( var isPreset = presetHelper.IsPreset(assortItemWithChildren[0].Upd.SptPresetId); // Only perform checks on newly generated items, skip expired items being refreshed - if (!(isExpiredOffer || ragfairServerHelper.IsItemValidRagfairItem(itemToSellDetails))) { - return; - } + if (!(isExpiredOffer || ragfairServerHelper.IsItemValidRagfairItem(itemToSellDetails))) return; // Armor presets can hold plates above the allowed flea level, remove if necessary - if (isPreset && ragfairConfig.Dynamic.Blacklist.EnableBsgList) { + if (isPreset && ragfairConfig.Dynamic.Blacklist.EnableBsgList) RemoveBannedPlatesFromPreset(assortItemWithChildren, ragfairConfig.Dynamic.Blacklist.ArmorPlate); - } // Get number of offers to create // Limit to 1 offer when processing expired - like-for-like replacement var offerCount = isExpiredOffer ? 1 - : randomUtil.GetInt((int) config.OfferItemCount.Min, (int) config.OfferItemCount.Max); + : randomUtil.GetInt((int)config.OfferItemCount.Min, (int)config.OfferItemCount.Max); /* TODO: ??????? if (ProgramStatics.DEBUG && !ProgramStatics.COMPILED) { @@ -393,7 +383,8 @@ public class RagfairOfferGenerator( } */ - for (var index = 0; index < offerCount; index++) { + for (var index = 0; index < offerCount; index++) + { // Clone the item so we don't have shared references and generate new item IDs var clonedAssort = cloner.Clone(assortItemWithChildren); itemHelper.ReparentItemAndChildren(clonedAssort[0], clonedAssort); @@ -417,26 +408,24 @@ public class RagfairOfferGenerator( ArmorPlateBlacklistSettings plateSettings ) { - if (!itemHelper.ArmorItemCanHoldMods(presetWithChildren[0].Template)) { + if (!itemHelper.ArmorItemCanHoldMods(presetWithChildren[0].Template)) // Cant hold armor inserts, skip return false; - } - var plateSlots = presetWithChildren.Where((item) => itemHelper.GetRemovablePlateSlotIds().Contains(item.SlotId?.ToLower())). ToList(); - if (plateSlots.Count == 0) { + var plateSlots = presetWithChildren.Where((item) => itemHelper.GetRemovablePlateSlotIds().Contains(item.SlotId?.ToLower())).ToList(); + if (plateSlots.Count == 0) // Has no plate slots e.g. "front_plate", exit return false; - } var removedPlate = false; - foreach (var plateSlot in plateSlots) { + foreach (var plateSlot in plateSlots) + { var plateDetails = itemHelper.GetItem(plateSlot.Template).Value; - if (plateSettings.IgnoreSlots.Contains(plateSlot.SlotId.ToLower())) { - continue; - } + if (plateSettings.IgnoreSlots.Contains(plateSlot.SlotId.ToLower())) continue; var plateArmorLevel = plateDetails.Properties.ArmorClass ?? 0; - if (plateArmorLevel > plateSettings.MaxProtectionLevel) { + if (plateArmorLevel > plateSettings.MaxProtectionLevel) + { presetWithChildren.Splice(presetWithChildren.IndexOf(plateSlot), 1); removedPlate = true; } @@ -492,15 +481,13 @@ public class RagfairOfferGenerator( // Latest first, to ensure we don't move later items off by 1 each time we remove an item below it var indexesToRemove = offerItemPlatesToRemove.Select(plateItem => itemWithChildren.IndexOf(plateItem)) .ToList(); - foreach (var index in indexesToRemove.OrderByDescending(x => x)) - { - itemWithChildren.RemoveAt(index); - } + foreach (var index in indexesToRemove.OrderByDescending(x => x)) itemWithChildren.RemoveAt(index); } } List barterScheme; - if (isPackOffer) { + if (isPackOffer) + { // Set pack size var stackSize = randomUtil.GetInt( ragfairConfig.Dynamic.Pack.ItemCountMin, @@ -510,14 +497,16 @@ public class RagfairOfferGenerator( // Don't randomise pack items barterScheme = CreateCurrencyBarterScheme(itemWithChildren, isPackOffer, stackSize); - } else if (isBarterOffer) { + } + else if (isBarterOffer) + { // Apply randomised properties RandomiseOfferItemUpdProperties(sellerId, itemWithChildren, itemToSellDetails); barterScheme = CreateBarterBarterScheme(itemWithChildren, ragfairConfig.Dynamic.Barter); - if (ragfairConfig.Dynamic.Barter.MakeSingleStackOnly) { - itemWithChildren[0].Upd.StackObjectsCount = 1; - } - } else { + if (ragfairConfig.Dynamic.Barter.MakeSingleStackOnly) itemWithChildren[0].Upd.StackObjectsCount = 1; + } + else + { // Apply randomised properties RandomiseOfferItemUpdProperties(sellerId, itemWithChildren, itemToSellDetails); barterScheme = CreateCurrencyBarterScheme(itemWithChildren, isPackOffer); @@ -547,7 +536,8 @@ public class RagfairOfferGenerator( var assortsClone = cloner.Clone(trader.Assort); // Trader assorts / assort items are missing - if (assortsClone?.Items?.Count is null or 0) { + if (assortsClone?.Items?.Count is null or 0) + { logger.Error( localisationService.GetText( "ragfair-no_trader_assorts_cant_generate_flea_offers", @@ -558,25 +548,25 @@ public class RagfairOfferGenerator( } var blacklist = ragfairConfig.Dynamic.Blacklist; - foreach (var item in assortsClone.Items) { + foreach (var item in assortsClone.Items) + { // We only want to process 'base/root' items, no children - if (item.SlotId != "hideout") { + if (item.SlotId != "hideout") // skip mod items continue; - } // Run blacklist check on trader offers - if (blacklist.TraderItems) { + if (blacklist.TraderItems) + { var itemDetails = itemHelper.GetItem(item.Template); - if (!itemDetails.Key) { + if (!itemDetails.Key) + { logger.Warning(localisationService.GetText("ragfair-tpl_not_a_valid_item", item.Template)); continue; } // Don't include items that BSG has blacklisted from flea - if (blacklist.EnableBsgList && !(itemDetails.Value?.Properties?.CanSellOnRagfair ?? false)) { - continue; - } + if (blacklist.EnableBsgList && !(itemDetails.Value?.Properties?.CanSellOnRagfair ?? false)) continue; } var isPreset = presetHelper.IsPreset(item.Id); @@ -617,17 +607,16 @@ public class RagfairOfferGenerator( // Add any missing properties to first item in array AddMissingConditions(itemWithMods[0]); - if (!(profileHelper.IsPlayer(userID) || ragfairServerHelper.IsTrader(userID))) { + if (!(profileHelper.IsPlayer(userID) || ragfairServerHelper.IsTrader(userID))) + { var parentId = GetDynamicConditionIdForTpl(itemDetails.Id); - if (string.IsNullOrEmpty(parentId)) { + if (string.IsNullOrEmpty(parentId)) // No condition details found, don't proceed with modifying item conditions return; - } // Roll random chance to randomise item condition - if (randomUtil.GetChance100(ragfairConfig.Dynamic.Condition[parentId].ConditionChance * 100)) { + if (randomUtil.GetChance100(ragfairConfig.Dynamic.Condition[parentId].ConditionChance * 100)) RandomiseItemCondition(parentId, itemWithMods, itemDetails); - } } } @@ -640,11 +629,9 @@ public class RagfairOfferGenerator( { // Get keys from condition config dictionary var configConditions = ragfairConfig.Dynamic.Condition.Keys; - foreach (var baseClass in configConditions) { - if (itemHelper.IsOfBaseclass(tpl, baseClass)) { + foreach (var baseClass in configConditions) + if (itemHelper.IsOfBaseclass(tpl, baseClass)) return baseClass; - } - } return null; } @@ -664,21 +651,23 @@ public class RagfairOfferGenerator( var rootItem = itemWithMods[0]; var itemConditionValues = ragfairConfig.Dynamic.Condition[conditionSettingsId]; - var maxMultiplier = randomUtil.GetDouble((double) itemConditionValues.Max.Min, (double) itemConditionValues.Max.Min); + var maxMultiplier = randomUtil.GetDouble((double)itemConditionValues.Max.Min, (double)itemConditionValues.Max.Min); var currentMultiplier = randomUtil.GetDouble( - (double) itemConditionValues.Current.Min, - (double) itemConditionValues.Current.Max + (double)itemConditionValues.Current.Min, + (double)itemConditionValues.Current.Max ); // Randomise armor + plates + armor related things if (itemHelper.ArmorItemCanHoldMods(rootItem.Template) || itemHelper.IsOfBaseclasses(rootItem.Template, [BaseClasses.ARMOR_PLATE, BaseClasses.ARMORED_EQUIPMENT]) - ) { + ) + { RandomiseArmorDurabilityValues(itemWithMods, currentMultiplier, maxMultiplier); // Add hits to visor var visorMod = itemWithMods.FirstOrDefault((item) => item.ParentId == BaseClasses.ARMORED_EQUIPMENT && item.SlotId == "mod_equipment_000"); - if (randomUtil.GetChance100(25) && visorMod != null) { + if (randomUtil.GetChance100(25) && visorMod != null) + { itemHelper.AddUpdObjectToItem(visorMod); visorMod.Upd.FaceShield = new UpdFaceShield() { Hits = randomUtil.GetInt(1, 3) }; @@ -688,26 +677,30 @@ public class RagfairOfferGenerator( } // Randomise Weapons - if (itemHelper.IsOfBaseclass(itemDetails.Id, BaseClasses.WEAPON)) { + if (itemHelper.IsOfBaseclass(itemDetails.Id, BaseClasses.WEAPON)) + { RandomiseWeaponDurability(itemWithMods[0], itemDetails, maxMultiplier, currentMultiplier); return; } - if (rootItem.Upd?.MedKit != null) { + if (rootItem.Upd?.MedKit != null) + { // Randomize health var hpResource = Math.Round((double)rootItem.Upd.MedKit.HpResource * maxMultiplier); rootItem.Upd.MedKit.HpResource = hpResource == 0D ? 1D : hpResource; return; } - if (rootItem.Upd?.Key != null && itemDetails.Properties.MaximumNumberOfUsage > 1) { + if (rootItem.Upd?.Key != null && itemDetails.Properties.MaximumNumberOfUsage > 1) + { // Randomize key uses rootItem.Upd.Key.NumberOfUsages = (int?)Math.Round(itemDetails.Properties.MaximumNumberOfUsage.Value * (1 - maxMultiplier)); return; } - if (rootItem.Upd?.FoodDrink != null) { + if (rootItem.Upd?.FoodDrink != null) + { // randomize food/drink value var hpPercent = Math.Round((double)itemDetails.Properties.MaxResource * maxMultiplier); rootItem.Upd.FoodDrink.HpPercent = hpPercent == 0D ? 1D : hpPercent; @@ -715,7 +708,8 @@ public class RagfairOfferGenerator( return; } - if (rootItem.Upd?.RepairKit != null) { + if (rootItem.Upd?.RepairKit != null) + { // randomize repair kit (armor/weapon) uses var resource = Math.Round((double)itemDetails.Properties.MaxRepairResource * maxMultiplier); rootItem.Upd.RepairKit.Resource = resource == 0D ? 1D : resource; @@ -723,9 +717,10 @@ public class RagfairOfferGenerator( return; } - if (itemHelper.IsOfBaseclass(itemDetails.Id, BaseClasses.FUEL)) { + if (itemHelper.IsOfBaseclass(itemDetails.Id, BaseClasses.FUEL)) + { var totalCapacity = itemDetails.Properties.MaxResource; - var remainingFuel = Math.Round((double) totalCapacity * maxMultiplier); + var remainingFuel = Math.Round((double)totalCapacity * maxMultiplier); rootItem.Upd.Resource = new UpdResource() { UnitsConsumed = totalCapacity - remainingFuel, Value = remainingFuel }; } @@ -748,7 +743,7 @@ public class RagfairOfferGenerator( // Max var baseMaxDurability = itemDbDetails.Properties.MaxDurability; var lowestMaxDurability = randomUtil.GetDouble(maxMultiplier, 1) * baseMaxDurability; - var chosenMaxDurability = Math.Round(randomUtil.GetDouble((double) lowestMaxDurability, (double) baseMaxDurability)); + var chosenMaxDurability = Math.Round(randomUtil.GetDouble((double)lowestMaxDurability, (double)baseMaxDurability)); // Current var lowestCurrentDurability = randomUtil.GetDouble(currentMultiplier, 1) * chosenMaxDurability; @@ -770,19 +765,22 @@ public class RagfairOfferGenerator( double maxMultiplier ) { - foreach (var armorItem in armorWithMods) { + foreach (var armorItem in armorWithMods) + { var itemDbDetails = itemHelper.GetItem(armorItem.Template).Value; - if (itemDbDetails.Properties.ArmorClass > 1) { + if (itemDbDetails.Properties.ArmorClass > 1) + { itemHelper.AddUpdObjectToItem(armorItem); var baseMaxDurability = itemDbDetails.Properties.MaxDurability; var lowestMaxDurability = randomUtil.GetDouble(maxMultiplier, 1) * baseMaxDurability; - var chosenMaxDurability = Math.Round(randomUtil.GetDouble((double) lowestMaxDurability,(double) baseMaxDurability)); + var chosenMaxDurability = Math.Round(randomUtil.GetDouble((double)lowestMaxDurability, (double)baseMaxDurability)); var lowestCurrentDurability = randomUtil.GetDouble(currentMultiplier, 1) * chosenMaxDurability; var chosenCurrentDurability = Math.Round(randomUtil.GetDouble(lowestCurrentDurability, chosenMaxDurability)); - armorItem.Upd.Repairable = new UpdRepairable() { + armorItem.Upd.Repairable = new UpdRepairable() + { Durability = chosenCurrentDurability == 0D ? 1D : chosenCurrentDurability, // Never var value become 0 MaxDurability = chosenMaxDurability }; @@ -796,7 +794,8 @@ public class RagfairOfferGenerator( * HpResource for medical items * @param item item to add conditions to */ - protected void AddMissingConditions(Item item) { + protected void AddMissingConditions(Item item) + { var props = itemHelper.GetItem(item.Template).Value.Properties; var isRepairable = props.Durability != null; var isMedkit = props.MaxHpResource != null; @@ -804,7 +803,8 @@ public class RagfairOfferGenerator( var isConsumable = props.MaxResource > 1 && props.FoodUseTime != null; var isRepairKit = props.MaxRepairResource != null; - if (isRepairable && props.Durability > 0) { + if (isRepairable && props.Durability > 0) + { item.Upd.Repairable = new UpdRepairable() { Durability = props.Durability, MaxDurability = props.Durability }; @@ -818,22 +818,22 @@ public class RagfairOfferGenerator( return; } - if (isKey) { - item.Upd.Key = new UpdKey(){ NumberOfUsages = 0 }; + if (isKey) + { + item.Upd.Key = new UpdKey() { NumberOfUsages = 0 }; return; } // Food/drink - if (isConsumable) { + if (isConsumable) + { item.Upd.FoodDrink = new UpdFoodDrink() { HpPercent = props.MaxResource }; return; } - if (isRepairKit) { - item.Upd.RepairKit = new UpdRepairKit() { Resource = props.MaxRepairResource }; - } + if (isRepairKit) item.Upd.RepairKit = new UpdRepairKit() { Resource = props.MaxRepairResource }; } /** @@ -852,9 +852,7 @@ public class RagfairOfferGenerator( ); // Dont make items under a designated rouble value into barter offers - if (priceOfOfferItem < barterConfig.MinRoubleCostToBecomeBarter) { - return CreateCurrencyBarterScheme(offerItems, false); - } + if (priceOfOfferItem < barterConfig.MinRoubleCostToBecomeBarter) return CreateCurrencyBarterScheme(offerItems, false); // Get a randomised number of barter items to list offer for var barterItemCount = randomUtil.GetInt(barterConfig.ItemCountMin, barterConfig.ItemCountMax); @@ -863,23 +861,22 @@ public class RagfairOfferGenerator( var desiredItemCostRouble = Math.Round(priceOfOfferItem / barterItemCount); // Rouble amount to go above/below when looking for an item (Wiggle cost of item a little) - var offerCostVarianceRoubles = (desiredItemCostRouble * barterConfig.PriceRangeVariancePercent) / 100; + var offerCostVarianceRoubles = desiredItemCostRouble * barterConfig.PriceRangeVariancePercent / 100; // Dict of items and their flea price (cached on first use) var itemFleaPrices = GetFleaPricesAsArray(); // Filter possible barters to items that match the price range + not itself var itemsInsidePriceBounds = itemFleaPrices.Where( - itemAndPrice => - itemAndPrice.Price >= desiredItemCostRouble - offerCostVarianceRoubles && - itemAndPrice.Price <= desiredItemCostRouble + offerCostVarianceRoubles && - itemAndPrice.Tpl != offerItems[0].Template // Don't allow the item being sold to be chosen - ).ToList(); + itemAndPrice => + itemAndPrice.Price >= desiredItemCostRouble - offerCostVarianceRoubles && + itemAndPrice.Price <= desiredItemCostRouble + offerCostVarianceRoubles && + itemAndPrice.Tpl != offerItems[0].Template // Don't allow the item being sold to be chosen + ) + .ToList(); // No items on flea have a matching price, fall back to currency - if (itemsInsidePriceBounds.Count == 0) { - return CreateCurrencyBarterScheme(offerItems, false); - } + if (itemsInsidePriceBounds.Count == 0) return CreateCurrencyBarterScheme(offerItems, false); // Choose random item from price-filtered flea items var randomItem = randomUtil.GetArrayValue(itemsInsidePriceBounds); @@ -894,7 +891,8 @@ public class RagfairOfferGenerator( protected List GetFleaPricesAsArray() { // Generate if needed - if (allowedFleaPriceItemsForBarter == null) { + if (allowedFleaPriceItemsForBarter == null) + { var fleaPrices = databaseService.GetPrices(); // Only get prices for items that also exist in items.json @@ -928,4 +926,3 @@ public class RagfairOfferGenerator( return [new BarterScheme() { Count = price, Template = currency }]; } } - diff --git a/Libraries/Core/Generators/RepeatableQuestGenerator.cs b/Libraries/Core/Generators/RepeatableQuestGenerator.cs index 7c22e060..11c60e24 100644 --- a/Libraries/Core/Generators/RepeatableQuestGenerator.cs +++ b/Libraries/Core/Generators/RepeatableQuestGenerator.cs @@ -31,8 +31,8 @@ public class RepeatableQuestGenerator( ICloner _cloner ) { - protected QuestConfig _questConfig = _configServer.GetConfig(); protected int _maxRandomNumberAttempts = 6; + protected QuestConfig _questConfig = _configServer.GetConfig(); /// /// This method is called by /GetClientRepeatableQuests/ and creates one element of quest type format (see @@ -101,7 +101,8 @@ public class RepeatableQuestGenerator( var locationsConfig = repeatableConfig.Locations; var targetsConfig = new ProbabilityObjectArray(_mathUtil, _cloner, eliminationConfig.Targets); var bodyPartsConfig = new ProbabilityObjectArray>(_mathUtil, _cloner, eliminationConfig.BodyParts); - var weaponCategoryRequirementConfig = new ProbabilityObjectArray>(_mathUtil, _cloner, eliminationConfig.WeaponCategoryRequirements); + var weaponCategoryRequirementConfig = + new ProbabilityObjectArray>(_mathUtil, _cloner, eliminationConfig.WeaponCategoryRequirements); var weaponRequirementConfig = new ProbabilityObjectArray>(_mathUtil, _cloner, eliminationConfig.WeaponRequirements); // the difficulty of the quest varies in difficulty depending on the condition @@ -178,9 +179,7 @@ public class RepeatableQuestGenerator( .ToList(); if (questTypePool.Pool.Elimination.Targets.GetByJsonProp(targetKey).Locations.Count == 0) - { questTypePool.Pool.Elimination.Targets.Remove(targetKey); - } } else { @@ -243,10 +242,13 @@ public class RepeatableQuestGenerator( if (eliminationConfig.DistanceProbability > rand.NextDouble() && isDistanceRequirementAllowed) { // Random distance with lower values more likely; simple distribution for starters... - distance = (int)Math.Floor(Math.Abs(rand.NextDouble() - rand.NextDouble()) * - (1 + eliminationConfig.MaxDistance - eliminationConfig.MinDistance) + - eliminationConfig.MinDistance ?? 0); - + distance = (int)Math.Floor( + Math.Abs(rand.NextDouble() - rand.NextDouble()) * + (1 + eliminationConfig.MaxDistance - eliminationConfig.MinDistance) + + eliminationConfig.MinDistance ?? + 0 + ); + distance = (int)Math.Ceiling((decimal)(distance / 5)) * 5; distanceDifficulty = (int)(maxDistDifficulty * distance / eliminationConfig.MaxDistance); } @@ -317,10 +319,7 @@ public class RepeatableQuestGenerator( var quest = GenerateRepeatableTemplate("Elimination", traderId, repeatableConfig.Side, sessionId); // ASSUMPTION: All fence quests are for scavs - if (traderId == Traders.FENCE) - { - quest.Side = "Scav"; - } + if (traderId == Traders.FENCE) quest.Side = "Scav"; var availableForFinishCondition = quest.Conditions.AvailableForFinish[0]; availableForFinishCondition.Counter.Id = _hashUtil.Generate(); @@ -372,14 +371,10 @@ public class RepeatableQuestGenerator( EliminationConfig eliminationConfig) { if (targetsConfig.Data(targetKey).IsBoss.GetValueOrDefault(false)) - { return _randomUtil.RandInt(eliminationConfig.MinBossKills.Value, eliminationConfig.MaxBossKills + 1); - } if (targetsConfig.Data(targetKey).IsPmc.GetValueOrDefault(false)) - { return _randomUtil.RandInt(eliminationConfig.MinPmcKills.Value, eliminationConfig.MaxPmcKills + 1); - } return _randomUtil.RandInt(eliminationConfig.MinKills.Value, eliminationConfig.MaxKills + 1); } @@ -448,22 +443,14 @@ public class RepeatableQuestGenerator( } // Has specific body part hit condition - if (targetedBodyParts is not null) - { - killConditionProps.BodyPart = targetedBodyParts; - } + if (targetedBodyParts is not null) killConditionProps.BodyPart = targetedBodyParts; // Don't allow distance + melee requirement if (distance is not null && allowedWeaponCategory != "5b5f7a0886f77409407a7f96") - { killConditionProps.Distance = new CounterConditionDistance { CompareMethod = ">=", Value = distance.Value }; - } // Has specific weapon requirement - if (allowedWeapon is not null) - { - killConditionProps.Weapon = [allowedWeapon]; - } + if (allowedWeapon is not null) killConditionProps.Weapon = [allowedWeapon]; // Has specific weapon category requirement if (allowedWeaponCategory?.Length > 0) @@ -637,11 +624,9 @@ public class RepeatableQuestGenerator( var x = (int)Math.Floor(roublesBudget / itemUnitPrice); maxValue = Math.Min(maxValue, x); if (maxValue > minValue) - { // If it doesn't blow the budget we have for the request, draw a random amount of the selected // Item type to be requested value = _randomUtil.RandInt(minValue, maxValue + 1); - } roublesBudget -= value * itemUnitPrice; @@ -654,10 +639,7 @@ public class RepeatableQuestGenerator( // Reduce the list possible items to fulfill the new budget constraint itemSelection = itemSelection.Where(dbItem => _itemHelper.GetItemPrice(dbItem.Id) < roublesBudget) .ToList(); - if (!itemSelection.Any()) - { - break; - } + if (!itemSelection.Any()) break; } else { @@ -694,15 +676,10 @@ public class RepeatableQuestGenerator( _itemHelper.IsOfBaseclass(itemTpl, BaseClasses.WEAPON) || _itemHelper.IsOfBaseclass(itemTpl, BaseClasses.ARMOR) ) - { minDurability = _randomUtil.GetArrayValue([60, 80]); - } // By default all collected items must be FiR, except dog tags - if (_itemHelper.IsDogtag(itemTpl)) - { - onlyFoundInRaid = false; - } + if (_itemHelper.IsDogtag(itemTpl)) onlyFoundInRaid = false; return new QuestCondition { diff --git a/Libraries/Core/Generators/RepeatableQuestRewardGenerator.cs b/Libraries/Core/Generators/RepeatableQuestRewardGenerator.cs index 5f32e3ee..71cec268 100644 --- a/Libraries/Core/Generators/RepeatableQuestRewardGenerator.cs +++ b/Libraries/Core/Generators/RepeatableQuestRewardGenerator.cs @@ -43,12 +43,12 @@ public class RepeatableQuestRewardGenerator( * - Items * - Trader Reputation * - Skill level experience - * + * * The reward is dependent on the player level as given by the wiki. The exact mapping of pmcLevel to * experience / money / items / trader reputation can be defined in QuestConfig.js - * + * * There's also a random variation of the reward the spread of which can be also defined in the config - * + * * Additionally, a scaling factor w.r.t. quest difficulty going from 0.2...1 can be used * @param pmcLevel Level of player reward is being generated for * @param difficulty Reward scaling factor from 0.2 to 1 @@ -130,19 +130,14 @@ public class RepeatableQuestRewardGenerator( var filteredRewardItemPool = inBudgetRewardItemPool.Where( item => !rewardTplBlacklist.Contains(item.Id) ); - if (filteredRewardItemPool.Count() > 0) - { - inBudgetRewardItemPool = filteredRewardItemPool.ToList(); - } + if (filteredRewardItemPool.Count() > 0) inBudgetRewardItemPool = filteredRewardItemPool.ToList(); } if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug( $"Generating: {repeatableConfig.Name} quest for: {traderId} with budget: {itemRewardBudget} totalling: {rewardParams.RewardNumItems} items" ); - } if (inBudgetRewardItemPool.Count > 0) { var itemsToReward = GetRewardableItemsFromPoolWithinBudget( @@ -177,10 +172,7 @@ public class RepeatableQuestRewardGenerator( rewards.Success.Add(reward); rewardIndex++; - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Adding: {rewardParams.RewardReputation} {traderId} trader reputation reward"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Adding: {rewardParams.RewardReputation} {traderId} trader reputation reward"); } // Chance of adding skill reward @@ -200,10 +192,7 @@ public class RepeatableQuestRewardGenerator( }; rewards.Success.Add(reward); - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Adding {rewardParams.SkillPointReward} skill points to {targetSkill}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Adding {rewardParams.SkillPointReward} skill points to {targetSkill}"); } return rewards; @@ -223,10 +212,7 @@ public class RepeatableQuestRewardGenerator( var reputationConfig = rewardScaling.Reputation; var effectiveDifficulty = difficulty is null ? 1 : difficulty; - if (difficulty is null) - { - _logger.Warning(_localisationService.GetText("repeatable-difficulty_was_nan")); - } + if (difficulty is null) _logger.Warning(_localisationService.GetText("repeatable-difficulty_was_nan")); return new QuestRewardValues { @@ -325,10 +311,7 @@ public class RepeatableQuestRewardGenerator( // Get a random item var chosenItemFromPool = exhausableItemPool.GetRandomValue(); - if (!exhausableItemPool.HasValues()) - { - break; - } + if (!exhausableItemPool.HasValues()) break; // Handle edge case - ammo if (_itemHelper.IsOfBaseclass(chosenItemFromPool.Id, BaseClasses.AMMO)) @@ -351,18 +334,13 @@ public class RepeatableQuestRewardGenerator( // 25% chance to double, triple or quadruple reward stack // (Only occurs when item is stackable and not weapon, armor or ammo) if (CanIncreaseRewardItemStackSize(chosenItemFromPool, 70000, 25)) - { rewardItemStackCount = GetRandomisedRewardItemStackSizeByPrice(chosenItemFromPool); - } itemsToReturn.Add(chosenItemFromPool, rewardItemStackCount); var itemCost = _presetHelper.GetDefaultPresetOrItemPrice(chosenItemFromPool.Id); var calculatedItemRewardBudget = itemRewardBudget - rewardItemStackCount * itemCost; - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Added item: {chosenItemFromPool.Id} with price: {rewardItemStackCount * itemCost}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Added item: {chosenItemFromPool.Id} with price: {rewardItemStackCount * itemCost}"); // If we still have budget narrow down possible items if (calculatedItemRewardBudget > 0) @@ -375,12 +353,8 @@ public class RepeatableQuestRewardGenerator( ); if (!exhausableItemPool.HasValues()) - { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug($"Reward pool empty with: {calculatedItemRewardBudget} roubles of budget remaining"); - } - } } // No budget for more items, end loop @@ -453,10 +427,7 @@ public class RepeatableQuestRewardGenerator( // Find the appropriate price tier and return a random stack size from its options var tier = priceTiers.FirstOrDefault(tier => rewardItemPrice < tier.Item1); - if (tier is null) - { - return 4; // Default to 2 if no tier matches - } + if (tier is null) return 4; // Default to 2 if no tier matches return _randomUtil.GetArrayValue(tier.Item2); } @@ -533,10 +504,7 @@ public class RepeatableQuestRewardGenerator( while (defaultPresetPool.HasValues()) { var randomPreset = defaultPresetPool.GetRandomValue(); - if (randomPreset is null) - { - continue; - } + if (randomPreset is null) continue; // Gather all tpls so we can get prices of them var tpls = randomPreset.Items.Select(item => item.Template).ToList(); @@ -560,7 +528,7 @@ public class RepeatableQuestRewardGenerator( /** * Helper to create a reward item structured as required by the client - * + * * @param {string} tpl ItemId of the rewarded item * @param {integer} count Amount of items to give * @param {integer} index All rewards will be appended to a list, for unknown reasons the client wants the index @@ -587,15 +555,9 @@ public class RepeatableQuestRewardGenerator( // Get presets root item var rootItem = preset.FirstOrDefault(item => item.Template == tpl); - if (rootItem is null) - { - _logger.Warning($"Root item of preset: {tpl} not found"); - } + if (rootItem is null) _logger.Warning($"Root item of preset: {tpl} not found"); - if (rootItem.Upd is not null) - { - rootItem.Upd.SpawnedInSession = foundInRaid; - } + if (rootItem.Upd is not null) rootItem.Upd.SpawnedInSession = foundInRaid; questRewardItem.Items = _itemHelper.ReparentItemAndChildren(rootItem, preset); questRewardItem.Target = rootItem.Id; // Target property and root items id must match @@ -605,7 +567,7 @@ public class RepeatableQuestRewardGenerator( /** * Helper to create a reward item structured as required by the client - * + * * @param {string} tpl ItemId of the rewarded item * @param {integer} count Amount of items to give * @param {integer} index All rewards will be appended to a list, for unknown reasons the client wants the index @@ -677,15 +639,9 @@ public class RepeatableQuestRewardGenerator( itemTemplate => { // Base "Item" item has no parent, ignore it - if (itemTemplate.Parent == "") - { - return false; - } + if (itemTemplate.Parent == "") return false; - if (seasonalItems.Contains(itemTemplate.Id)) - { - return false; - } + if (seasonalItems.Contains(itemTemplate.Id)) return false; var traderWhitelist = repeatableQuestConfig.TraderWhitelist.FirstOrDefault( trader => trader.TraderId == traderId @@ -711,10 +667,7 @@ public class RepeatableQuestRewardGenerator( List? itemBaseWhitelist = null) { // Return early if not valid item to give as reward - if (!_itemHelper.IsValidItem(tpl)) - { - return false; - } + if (!_itemHelper.IsValidItem(tpl)) return false; // Check item is not blacklisted if ( @@ -723,27 +676,16 @@ public class RepeatableQuestRewardGenerator( repeatableQuestConfig.RewardBlacklist.Contains(tpl) || _itemFilterService.IsItemBlacklisted(tpl) ) - { return false; - } // Item has blacklisted base types - if (_itemHelper.IsOfBaseclasses(tpl, repeatableQuestConfig.RewardBaseTypeBlacklist)) - { - return false; - } + if (_itemHelper.IsOfBaseclasses(tpl, repeatableQuestConfig.RewardBaseTypeBlacklist)) return false; // Skip boss items - if (_itemFilterService.IsBossItem(tpl)) - { - return false; - } + if (_itemFilterService.IsBossItem(tpl)) return false; // Trader has specific item base types they can give as rewards to player - if (itemBaseWhitelist is not null && !_itemHelper.IsOfBaseclasses(tpl, itemBaseWhitelist)) - { - return false; - } + if (itemBaseWhitelist is not null && !_itemHelper.IsOfBaseclasses(tpl, itemBaseWhitelist)) return false; return true; } diff --git a/Libraries/Core/Generators/ScavCaseRewardGenerator.cs b/Libraries/Core/Generators/ScavCaseRewardGenerator.cs index 0d51994b..9f956eb8 100644 --- a/Libraries/Core/Generators/ScavCaseRewardGenerator.cs +++ b/Libraries/Core/Generators/ScavCaseRewardGenerator.cs @@ -31,9 +31,9 @@ public class ScavCaseRewardGenerator( ICloner _cloner ) { - protected ScavCaseConfig _scavCaseConfig = _configServer.GetConfig(); - protected List _dbItemsCache = []; protected List _dbAmmoItemsCache = []; + protected List _dbItemsCache = []; + protected ScavCaseConfig _scavCaseConfig = _configServer.GetConfig(); /// /// Create an array of rewards that will be given to the player upon completing their scav case build @@ -93,26 +93,16 @@ public class ScavCaseRewardGenerator( // Get an array of seasonal items that should not be shown right now as seasonal event is not active var inactiveSeasonalItems = _seasonalEventService.GetInactiveSeasonalEventItems(); if (!_dbItemsCache.Any()) - { _dbItemsCache = _databaseService.GetItems() .Values.Where( item => { // Base "Item" item has no parent, ignore it - if (item.Parent == "") - { - return false; - } + if (item.Parent == "") return false; - if (item.Type == "Node") - { - return false; - } + if (item.Type == "Node") return false; - if (item.Properties.QuestItem ?? false) - { - return false; - } + if (item.Properties.QuestItem ?? false) return false; // Skip item if item id is on blacklist if ( @@ -120,98 +110,58 @@ public class ScavCaseRewardGenerator( _scavCaseConfig.RewardItemBlacklist.Contains(item.Id) || _itemFilterService.IsItemBlacklisted(item.Id) ) - { return false; - } // Globally reward-blacklisted - if (_itemFilterService.IsItemRewardBlacklisted(item.Id)) - { - return false; - } + if (_itemFilterService.IsItemRewardBlacklisted(item.Id)) return false; - if (!_scavCaseConfig.AllowBossItemsAsRewards && _itemFilterService.IsBossItem(item.Id)) - { - return false; - } + if (!_scavCaseConfig.AllowBossItemsAsRewards && _itemFilterService.IsBossItem(item.Id)) return false; // Skip item if parent id is blacklisted - if (_itemHelper.IsOfBaseclasses(item.Id, _scavCaseConfig.RewardItemParentBlacklist)) - { - return false; - } + if (_itemHelper.IsOfBaseclasses(item.Id, _scavCaseConfig.RewardItemParentBlacklist)) return false; - if (inactiveSeasonalItems.Contains(item.Id)) - { - return false; - } + if (inactiveSeasonalItems.Contains(item.Id)) return false; return true; } ) .ToList(); - } if (!_dbAmmoItemsCache.Any()) - { _dbAmmoItemsCache = _databaseService.GetItems() .Values.Where( item => { // Base "Item" item has no parent, ignore it - if (item.Parent == "") - { - return false; - } + if (item.Parent == "") return false; - if (item.Type != "Item") - { - return false; - } + if (item.Type != "Item") return false; // Not ammo, skip - if (!_itemHelper.IsOfBaseclass(item.Id, BaseClasses.AMMO)) - { - return false; - } + if (!_itemHelper.IsOfBaseclass(item.Id, BaseClasses.AMMO)) return false; // Skip item if item id is on blacklist if ( _scavCaseConfig.RewardItemBlacklist.Contains(item.Id) || _itemFilterService.IsItemBlacklisted(item.Id) ) - { return false; - } // Globally reward-blacklisted - if (_itemFilterService.IsItemRewardBlacklisted(item.Id)) - { - return false; - } + if (_itemFilterService.IsItemRewardBlacklisted(item.Id)) return false; - if (!_scavCaseConfig.AllowBossItemsAsRewards && _itemFilterService.IsBossItem(item.Id)) - { - return false; - } + if (!_scavCaseConfig.AllowBossItemsAsRewards && _itemFilterService.IsBossItem(item.Id)) return false; // Skip seasonal items - if (inactiveSeasonalItems.Contains(item.Id)) - { - return false; - } + if (inactiveSeasonalItems.Contains(item.Id)) return false; // Skip ammo that doesn't stack as high as value in config - if (item.Properties.StackMaxSize < _scavCaseConfig.AmmoRewards.MinStackSize) - { - return false; - } + if (item.Properties.StackMaxSize < _scavCaseConfig.AmmoRewards.MinStackSize) return false; return true; } ) .ToList(); - } } /// @@ -231,30 +181,22 @@ public class ScavCaseRewardGenerator( var rewardWasAmmo = false; var randomCount = _randomUtil.GetInt((int)itemFilters.MinCount, (int)itemFilters.MaxCount); for (var i = 0; i < randomCount; i++) - { if (RewardShouldBeMoney() && !rewardWasMoney) { // Only allow one reward to be money result.Add(GetRandomMoney()); - if (!_scavCaseConfig.AllowMultipleMoneyRewardsPerRarity) - { - rewardWasMoney = true; - } + if (!_scavCaseConfig.AllowMultipleMoneyRewardsPerRarity) rewardWasMoney = true; } else if (RewardShouldBeAmmo() && !rewardWasAmmo) { // Only allow one reward to be ammo result.Add(GetRandomAmmo(rarity)); - if (!_scavCaseConfig.AllowMultipleAmmoRewardsPerRarity) - { - rewardWasAmmo = true; - } + if (!_scavCaseConfig.AllowMultipleAmmoRewardsPerRarity) rewardWasAmmo = true; } else { result.Add(_randomUtil.GetArrayValue(items)); } - } return result; } @@ -308,18 +250,13 @@ public class ScavCaseRewardGenerator( handbookPrice >= _scavCaseConfig.AmmoRewards.AmmoRewardValueRangeRub[rarity].Min && handbookPrice <= _scavCaseConfig.AmmoRewards.AmmoRewardValueRangeRub[rarity].Max ) - { return true; - } return false; } ); - if (!possibleAmmoPool.Any()) - { - _logger.Warning("Unable to get a list of ammo that matches desired criteria for scav case reward"); - } + if (!possibleAmmoPool.Any()) _logger.Warning("Unable to get a list of ammo that matches desired criteria for scav case reward"); // Get a random ammo and return it return _randomUtil.GetArrayValue(possibleAmmoPool); @@ -337,7 +274,7 @@ public class ScavCaseRewardGenerator( List> result = []; foreach (var rewardItemDb in rewardItems) { - List resultItem = [new Item { Id = _hashUtil.Generate(), Template = rewardItemDb.Id, Upd = null }]; + List resultItem = [new() { Id = _hashUtil.Generate(), Template = rewardItemDb.Id, Upd = null }]; var rootItem = resultItem.FirstOrDefault(); if (_itemHelper.IsOfBaseclass(rewardItemDb.Id, BaseClasses.AMMO_BOX)) @@ -359,7 +296,7 @@ public class ScavCaseRewardGenerator( } // Ensure preset has unique ids and is cloned so we don't alter the preset data stored in memory - List presetAndMods = _itemHelper.ReplaceIDs(_cloner.Clone(preset.Items)); + var presetAndMods = _itemHelper.ReplaceIDs(_cloner.Clone(preset.Items)); _itemHelper.RemapRootItemId(presetAndMods); resultItem = presetAndMods; @@ -388,10 +325,7 @@ public class ScavCaseRewardGenerator( item => { var handbookPrice = _ragfairPriceService.GetStaticPriceForItem(item.Id); - if (handbookPrice >= itemFilters.MinPriceRub && handbookPrice <= itemFilters.MaxPriceRub) - { - return true; - } + if (handbookPrice >= itemFilters.MinPriceRub && handbookPrice <= itemFilters.MaxPriceRub) return true; return false; } @@ -443,14 +377,11 @@ public class ScavCaseRewardGenerator( { var amountToGive = 1; if (itemToCalculate.Parent == BaseClasses.AMMO) - { amountToGive = _randomUtil.GetInt( _scavCaseConfig.AmmoRewards.MinStackSize, itemToCalculate.Properties.StackMaxSize ?? 0 ); - } else if (itemToCalculate.Parent == BaseClasses.MONEY) - { amountToGive = itemToCalculate.Id switch { Money.ROUBLES => _randomUtil.GetInt( @@ -471,7 +402,6 @@ public class ScavCaseRewardGenerator( ), _ => amountToGive }; - } return amountToGive; } diff --git a/Libraries/Core/Generators/WeaponGen/Implementations/BarrelInvetoryMagGen.cs b/Libraries/Core/Generators/WeaponGen/Implementations/BarrelInvetoryMagGen.cs index 36c08929..b8ffb5a1 100644 --- a/Libraries/Core/Generators/WeaponGen/Implementations/BarrelInvetoryMagGen.cs +++ b/Libraries/Core/Generators/WeaponGen/Implementations/BarrelInvetoryMagGen.cs @@ -26,17 +26,13 @@ public class BarrelInvetoryMagGen( // Can't be done by _props.ammoType as grenade launcher shoots grenades with ammoType of "buckshot" double? randomisedAmmoStackSize = null; if (inventoryMagGen.GetAmmoTemplate().Properties.StackMaxRandom == 1) - { // doesnt stack randomisedAmmoStackSize = _randomUtil.GetInt(3, 6); - } else - { randomisedAmmoStackSize = _randomUtil.GetInt( (int)inventoryMagGen.GetAmmoTemplate().Properties.StackMinRandom, (int)inventoryMagGen.GetAmmoTemplate().Properties.StackMaxRandom ); - } _botWeaponGeneratorHelper.AddAmmoIntoEquipmentSlots( inventoryMagGen.GetAmmoTemplate().Id, diff --git a/Libraries/Core/Generators/WeaponGen/Implementations/ExternalInventoryMagGen.cs b/Libraries/Core/Generators/WeaponGen/Implementations/ExternalInventoryMagGen.cs index 0a9292f5..55520df1 100644 --- a/Libraries/Core/Generators/WeaponGen/Implementations/ExternalInventoryMagGen.cs +++ b/Libraries/Core/Generators/WeaponGen/Implementations/ExternalInventoryMagGen.cs @@ -19,7 +19,6 @@ public class ExternalInventoryMagGen( RandomUtil _randomUtil ) : InventoryMagGen, IInventoryMagGen { - public int GetPriority() { return 99; @@ -61,10 +60,8 @@ public class ExternalInventoryMagGen( ); if (fitsIntoInventory == ItemAddedResult.NO_CONTAINERS) - { // No containers to fit magazines, stop trying break; - } // No space for magazine and we haven't reached desired magazine count if (fitsIntoInventory == ItemAddedResult.NO_SPACE && i < randomizedMagazineCount) @@ -73,9 +70,7 @@ public class ExternalInventoryMagGen( if (fitAttempts > 5) { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug($"Failed {fitAttempts} times to add magazine {magazineTpl} to bot inventory, stopping"); - } break; } @@ -85,25 +80,19 @@ public class ExternalInventoryMagGen( * Temporary workaround to Killa spawning with no extra mags if he spawns with a drum mag */ if (magazineTpl == defaultMagazineTpl) - { // We were already on default - stop here to prevent infinite loop break; - } // Add failed magazine tpl to blacklist attemptedMagBlacklist.Add(magazineTpl); if (defaultMagazineTpl is null) - { // No default to fall back to, stop trying to add mags break; - } if (defaultMagazineTpl == BaseClasses.MAGAZINE) - { // Magazine base type, do not use break; - } // Set chosen magazine tpl to the weapons default magazine tpl and try to fit into inventory next loop magazineTpl = defaultMagazineTpl; @@ -128,15 +117,12 @@ public class ExternalInventoryMagGen( if (result?.Id is null) { // Highly likely shotgun has no external mags - if (isShotgun) - { - break; - } + if (isShotgun) break; if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Unable to add additional magazine into bot inventory: vest/pockets for weapon: {weapon.Name}, attempted: {fitAttempts} times. Reason: {fitsIntoInventory}"); - } + _logger.Debug( + $"Unable to add additional magazine into bot inventory: vest/pockets for weapon: {weapon.Name}, attempted: {fitAttempts} times. Reason: {fitsIntoInventory}" + ); break; } @@ -151,10 +137,8 @@ public class ExternalInventoryMagGen( } if (fitsIntoInventory == ItemAddedResult.SUCCESS) - { // Reset fit counter now it succeeded fitAttempts = 0; - } } } @@ -162,10 +146,7 @@ public class ExternalInventoryMagGen( { // The mag Slot data for the weapon var magSlot = _itemHelper.GetItem(weaponTpl).Value.Properties.Slots.FirstOrDefault((x) => x.Name == "mod_magazine"); - if (magSlot is null) - { - return null; - } + if (magSlot is null) return null; // All possible mags that fit into the weapon excluding blacklisted var magazinePool = magSlot.Props.Filters[0] @@ -173,17 +154,11 @@ public class ExternalInventoryMagGen( .Select( (x) => _itemHelper.GetItem(x).Value ); - if (magazinePool is null) - { - return null; - } + if (magazinePool is null) return null; // Non-internal magazines that fit into the weapon var externalMagazineOnlyPool = magazinePool.Where((x) => x.Properties.ReloadMagType != ReloadMode.InternalMagazine); - if (externalMagazineOnlyPool is null || externalMagazineOnlyPool?.Count() == 0) - { - return null; - } + if (externalMagazineOnlyPool is null || externalMagazineOnlyPool?.Count() == 0) return null; // Randomly chosen external magazine return _randomUtil.GetArrayValue(externalMagazineOnlyPool); diff --git a/Libraries/Core/Generators/WeaponGen/Implementations/UbglExternalMagGen.cs b/Libraries/Core/Generators/WeaponGen/Implementations/UbglExternalMagGen.cs index e058fe4e..506a94a1 100644 --- a/Libraries/Core/Generators/WeaponGen/Implementations/UbglExternalMagGen.cs +++ b/Libraries/Core/Generators/WeaponGen/Implementations/UbglExternalMagGen.cs @@ -7,7 +7,6 @@ namespace Core.Generators.WeaponGen.Implementations; [Injectable] public class UbglExternalMagGen( BotWeaponGeneratorHelper _botWeaponGeneratorHelper - ) : InventoryMagGen, IInventoryMagGen { public int GetPriority() diff --git a/Libraries/Core/Generators/WeaponGen/InventoryMagGen.cs b/Libraries/Core/Generators/WeaponGen/InventoryMagGen.cs index 00c3a1b6..7b4ea227 100644 --- a/Libraries/Core/Generators/WeaponGen/InventoryMagGen.cs +++ b/Libraries/Core/Generators/WeaponGen/InventoryMagGen.cs @@ -6,11 +6,11 @@ namespace Core.Generators.WeaponGen; [Injectable] public class InventoryMagGen() { - private GenerationData _magCounts; - private TemplateItem _magazineTemplate; - private TemplateItem _weaponTemplate; private TemplateItem _ammoTemplate; + private TemplateItem _magazineTemplate; + private GenerationData _magCounts; private BotBaseInventory _pmcInventory; + private TemplateItem _weaponTemplate; public InventoryMagGen ( diff --git a/Libraries/Core/Generators/WeatherGenerator.cs b/Libraries/Core/Generators/WeatherGenerator.cs index e43cf230..e9e10d0f 100644 --- a/Libraries/Core/Generators/WeatherGenerator.cs +++ b/Libraries/Core/Generators/WeatherGenerator.cs @@ -104,10 +104,7 @@ public class WeatherGenerator( protected SeasonalValues GetWeatherValuesBySeason(Season currentSeason) { var result = _weatherConfig.Weather.SeasonValues.TryGetValue(currentSeason.ToString(), out var value); - if (!result) - { - return _weatherConfig.Weather.SeasonValues["default"]; - } + if (!result) return _weatherConfig.Weather.SeasonValues["default"]; return value!; } diff --git a/Libraries/Core/Helpers/AssortHelper.cs b/Libraries/Core/Helpers/AssortHelper.cs index 9fa220b5..461807c4 100644 --- a/Libraries/Core/Helpers/AssortHelper.cs +++ b/Libraries/Core/Helpers/AssortHelper.cs @@ -47,17 +47,11 @@ public class AssortHelper( { // Get quest id that unlocks assort + statuses quest can be in to show assort var unlockValues = GetQuestIdAndStatusThatShowAssort(mergedQuestAssorts, assortId.Key); - if (unlockValues is null) - { - continue; - } + if (unlockValues is null) continue; // Remove assort if quest in profile does not have status that unlocks assort var questStatusInProfile = _questHelper.GetQuestStatus(pmcProfile, unlockValues.Value.Key); - if (!unlockValues.Value.Value.Contains(questStatusInProfile)) - { - strippedTraderAssorts = RemoveItemFromAssort(traderAssorts, assortId.Key, flea); - } + if (!unlockValues.Value.Value.Contains(questStatusInProfile)) strippedTraderAssorts = RemoveItemFromAssort(traderAssorts, assortId.Key, flea); } return strippedTraderAssorts; @@ -74,29 +68,23 @@ public class AssortHelper( string assortId) { if (mergedQuestAssorts.TryGetValue("started", out var dict1) && dict1.ContainsKey(assortId)) - { // Assort unlocked by starting quest, assort is visible to player when : started or ready to hand in + handed in return new KeyValuePair>( mergedQuestAssorts["started"][assortId], [QuestStatusEnum.Started, QuestStatusEnum.AvailableForFinish, QuestStatusEnum.Success] ); - } if (mergedQuestAssorts.TryGetValue("success", out var dict2) && dict2.ContainsKey(assortId)) - { return new KeyValuePair>( mergedQuestAssorts["success"][assortId], [QuestStatusEnum.Success] ); - } if (mergedQuestAssorts.TryGetValue("fail", out var dict3) && dict3.ContainsKey(assortId)) - { return new KeyValuePair>( mergedQuestAssorts["fail"][assortId], [QuestStatusEnum.Fail] ); - } return null; } @@ -122,12 +110,8 @@ public class AssortHelper( // Remove items restricted by loyalty levels above those reached by the player foreach (var item in assort.LoyalLevelItems) - { if (pmcProfile.TradersInfo.TryGetValue(traderId, out var info) && assort.LoyalLevelItems[item.Key] > info.LoyaltyLevel) - { strippedAssort = RemoveItemFromAssort(assort, item.Key); - } - } return strippedAssort; } @@ -145,12 +129,8 @@ public class AssortHelper( if (assort.BarterScheme.TryGetValue(itemID, out var lisToUse) && lisToUse is not null && flea) { foreach (var barterSchemes in lisToUse) - { - foreach (var barterScheme in barterSchemes) - { - barterScheme.SptQuestLocked = true; - } - } + foreach (var barterScheme in barterSchemes) + barterScheme.SptQuestLocked = true; return assort; } @@ -159,15 +139,9 @@ public class AssortHelper( assort.LoyalLevelItems.Remove(itemID); foreach (var i in idsToRemove) - { - foreach (var a in assort.Items.ToList()) - { - if (a.Id == i) - { - assort.Items.Remove(a); - } - } - } + foreach (var a in assort.Items.ToList()) + if (a.Id == i) + assort.Items.Remove(a); return assort; } diff --git a/Libraries/Core/Helpers/BotDifficultyHelper.cs b/Libraries/Core/Helpers/BotDifficultyHelper.cs index b16f0361..e948497b 100644 --- a/Libraries/Core/Helpers/BotDifficultyHelper.cs +++ b/Libraries/Core/Helpers/BotDifficultyHelper.cs @@ -22,7 +22,7 @@ public class BotDifficultyHelper( ) { protected PmcConfig _pmcConfig = _configServer.GetConfig(); - + /// /// Get difficulty settings for desired bot type, if not found use assault bot types /// @@ -33,7 +33,8 @@ public class BotDifficultyHelper( public DifficultyCategories GetBotDifficultySettings(string type, string desiredDifficulty, Bots botDb) { var desiredType = type.ToLower(); - if (!botDb.Types.ContainsKey(desiredType)) { + if (!botDb.Types.ContainsKey(desiredType)) + { // No bot found, get fallback difficulty values _logger.Warning(_localisationService.GetText("bot-unable_to_get_bot_fallback_to_assault", type)); botDb.Types[desiredType] = _cloner.Clone(botDb.Types["assault"]); @@ -42,13 +43,19 @@ public class BotDifficultyHelper( // Get settings from raw bot json template file var botTemplate = _botHelper.GetBotTemplate(desiredType); botTemplate.BotDifficulty.TryGetValue(desiredDifficulty, out var difficultySettings); - if (difficultySettings is null) { + if (difficultySettings is null) + { // No bot settings found, use 'assault' bot difficulty instead _logger.Warning( - _localisationService.GetText("bot-unable_to_get_bot_difficulty_fallback_to_assault", new { - botType = desiredType, - difficulty = desiredDifficulty, - })); + _localisationService.GetText( + "bot-unable_to_get_bot_difficulty_fallback_to_assault", + new + { + botType = desiredType, + difficulty = desiredDifficulty + } + ) + ); botDb.Types[desiredType].BotDifficulty[desiredDifficulty] = _cloner.Clone( botDb.Types["assault"].BotDifficulty[desiredDifficulty] ); @@ -82,7 +89,8 @@ public class BotDifficultyHelper( /// bot difficulty public string ConvertBotDifficultyDropdownToBotDifficulty(string dropDownDifficulty) { - switch (dropDownDifficulty.ToLower()) { + switch (dropDownDifficulty.ToLower()) + { case "medium": return "normal"; case "random": diff --git a/Libraries/Core/Helpers/BotGeneratorHelper.cs b/Libraries/Core/Helpers/BotGeneratorHelper.cs index ed6724fe..aa05deee 100644 --- a/Libraries/Core/Helpers/BotGeneratorHelper.cs +++ b/Libraries/Core/Helpers/BotGeneratorHelper.cs @@ -45,10 +45,7 @@ public class BotGeneratorHelper( var raidIsNight = raidSettings?.TimeVariant == DateTimeEnum.PAST; RandomisedResourceDetails randomisationSettings = null; - if (botRole is not null) - { - _botConfig.LootItemResourceRandomization.TryGetValue(botRole, out randomisationSettings); - } + if (botRole is not null) _botConfig.LootItemResourceRandomization.TryGetValue(botRole, out randomisationSettings); Upd itemProperties = new(); @@ -109,7 +106,7 @@ public class BotGeneratorHelper( HpPercent = GetRandomizedResourceValue( itemTemplate.Properties.MaxResource ?? 0, randomisationSettings?.Food - ), + ) }; hasProperties = true; } @@ -120,7 +117,7 @@ public class BotGeneratorHelper( var lightLaserActiveChance = raidIsNight ? GetBotEquipmentSettingFromConfig(botRole, "lightIsActiveNightChancePercent", 50) : GetBotEquipmentSettingFromConfig(botRole, "lightIsActiveDayChancePercent", 25); - itemProperties.Light = new UpdLight { IsActive = _randomUtil.GetChance100(lightLaserActiveChance), SelectedMode = 0, }; + itemProperties.Light = new UpdLight { IsActive = _randomUtil.GetChance100(lightLaserActiveChance), SelectedMode = 0 }; hasProperties = true; } else if (itemTemplate?.Parent == BaseClasses.TACTICAL_COMBO) @@ -134,7 +131,7 @@ public class BotGeneratorHelper( itemProperties.Light = new UpdLight { IsActive = _randomUtil.GetChance100(lightLaserActiveChance), - SelectedMode = 0, + SelectedMode = 0 }; hasProperties = true; } @@ -173,15 +170,9 @@ public class BotGeneratorHelper( /// Randomized value from maxHpResource private double GetRandomizedResourceValue(double maxResource, RandomisedResourceValues? randomizationValues) { - if (randomizationValues is null) - { - return maxResource; - } + if (randomizationValues is null) return maxResource; - if (_randomUtil.GetChance100(randomizationValues.ChanceMaxResourcePercent)) - { - return maxResource; - } + if (_randomUtil.GetChance100(randomizationValues.ChanceMaxResourcePercent)) return maxResource; return _randomUtil.GetInt( (int)_randomUtil.GetPercentOfValue(randomizationValues.ResourcePercent, maxResource, 0), @@ -198,10 +189,7 @@ public class BotGeneratorHelper( /// Percent chance to be active private double? GetBotEquipmentSettingFromConfig(string? botRole, string setting, double defaultValue) { - if (botRole is null) - { - return defaultValue; - } + if (botRole is null) return defaultValue; var botEquipmentSettings = _botConfig.Equipment[GetBotEquipmentRole(botRole)]; if (botEquipmentSettings is null) @@ -299,10 +287,7 @@ public class BotGeneratorHelper( { // Skip slots that have no incompatibilities List slotsToCheck = ["Scabbard", "Backpack", "SecureContainer", "Holster", "ArmBand"]; - if (slotsToCheck.Contains(equipmentSlot)) - { - return new ChooseRandomCompatibleModResult { Incompatible = false, Found = false, Reason = "" }; - } + if (slotsToCheck.Contains(equipmentSlot)) return new ChooseRandomCompatibleModResult { Incompatible = false, Found = false, Reason = "" }; // TODO: Can probably be optimized to cache itemTemplates as items are added to inventory var equippedItemsDb = itemsEquipped.Select(equippedItem => _itemHelper.GetItem(equippedItem.Template).Value).ToList(); @@ -316,7 +301,7 @@ public class BotGeneratorHelper( new { itemTpl = tplToCheck, - slot = equipmentSlot, + slot = equipmentSlot } ) ); @@ -333,7 +318,7 @@ public class BotGeneratorHelper( { id = itemToEquip?.Id, name = itemToEquip?.Name, - slot = equipmentSlot, + slot = equipmentSlot } ) ); @@ -347,20 +332,16 @@ public class BotGeneratorHelper( item => item?.Properties?.GetType().GetProperties().FirstOrDefault(x => x.Name.ToLower() == $"blocks{equipmentSlot}")?.GetValue(item) is not null ); if (blockingItem is not null) - { // this.logger.warning(`1 incompatibility found between - {itemToEquip[1]._name} and {blockingItem._name} - {equipmentSlot}`); - - return new() + return new ChooseRandomCompatibleModResult { Incompatible = true, Found = false, Reason = $"{tplToCheck} {itemToEquip.Name} in slot: {equipmentSlot} blocked by: {blockingItem.Id} {blockingItem.Name}", SlotBlocked = true }; - } // Check if any of the current inventory templates have the incoming item defined as incompatible blockingItem = templateItems.FirstOrDefault(x => x?.Properties?.ConflictingItems?.Contains(tplToCheck) ?? false); if (blockingItem is not null) - { // this.logger.warning(`2 incompatibility found between - {itemToEquip[1]._name} and {blockingItem._props.Name} - {equipmentSlot}`); return new ChooseRandomCompatibleModResult { @@ -369,14 +350,12 @@ public class BotGeneratorHelper( Reason = $"{tplToCheck} {itemToEquip.Name} in slot: {equipmentSlot} blocked by: {blockingItem.Id} {blockingItem.Name}", SlotBlocked = true }; - } // Does item being checked get blocked/block existing item if (itemToEquip.Properties.BlocksHeadwear ?? false) { var existingHeadwear = itemsEquipped.FirstOrDefault((x) => x.SlotId == "Headwear"); if (existingHeadwear is not null) - { return new ChooseRandomCompatibleModResult { Incompatible = true, @@ -384,7 +363,6 @@ public class BotGeneratorHelper( Reason = $"{tplToCheck} {itemToEquip.Name} is blocked by: {existingHeadwear.Template} in slot: {existingHeadwear.SlotId}", SlotBlocked = true }; - } } // Does item being checked get blocked/block existing item @@ -392,15 +370,13 @@ public class BotGeneratorHelper( { var existingFaceCover = itemsEquipped.FirstOrDefault((item) => item.SlotId == "FaceCover"); if (existingFaceCover is not null) - { return new ChooseRandomCompatibleModResult { Incompatible = true, Found = false, Reason = $"{tplToCheck} {itemToEquip.Name} is blocked by: {existingFaceCover.Template} in slot: {existingFaceCover.SlotId}", - SlotBlocked = true, + SlotBlocked = true }; - } } // Does item being checked get blocked/block existing item @@ -408,15 +384,13 @@ public class BotGeneratorHelper( { var existingEarpiece = itemsEquipped.FirstOrDefault((item) => item.SlotId == "Earpiece"); if (existingEarpiece is not null) - { return new ChooseRandomCompatibleModResult { Incompatible = true, Found = false, Reason = $"{tplToCheck} {itemToEquip.Name} is blocked by: {existingEarpiece.Template} in slot: {existingEarpiece.SlotId}", - SlotBlocked = true, + SlotBlocked = true }; - } } // Does item being checked get blocked/block existing item @@ -424,29 +398,25 @@ public class BotGeneratorHelper( { var existingArmorVest = itemsEquipped.FirstOrDefault((item) => item.SlotId == "ArmorVest"); if (existingArmorVest is not null) - { return new ChooseRandomCompatibleModResult { Incompatible = true, Found = false, Reason = $"{tplToCheck} {itemToEquip.Name} is blocked by: {existingArmorVest.Template} in slot: {existingArmorVest.SlotId}", - SlotBlocked = true, + SlotBlocked = true }; - } } // Check if the incoming item has any inventory items defined as incompatible var blockingInventoryItem = itemsEquipped.FirstOrDefault((x) => itemToEquip.Properties.ConflictingItems?.Contains(x.Template) ?? false); if (blockingInventoryItem is not null) - { // this.logger.warning(`3 incompatibility found between - {itemToEquip[1]._name} and {blockingInventoryItem._tpl} - {equipmentSlot}`) return new ChooseRandomCompatibleModResult { Incompatible = true, Found = false, - Reason = $"{tplToCheck} blocks existing item {blockingInventoryItem.Template} in slot {blockingInventoryItem.SlotId}", + Reason = $"{tplToCheck} blocks existing item {blockingInventoryItem.Template} in slot {blockingInventoryItem.SlotId}" }; - } return new ChooseRandomCompatibleModResult { Incompatible = false, Reason = "" }; } @@ -488,13 +458,10 @@ public class BotGeneratorHelper( var missingContainerCount = 0; foreach (var equipmentSlotId in equipmentSlots) { - if (containersIdFull?.Contains(equipmentSlotId.ToString()) ?? false) - { - continue; - } + if (containersIdFull?.Contains(equipmentSlotId.ToString()) ?? false) continue; // Get container to put item into - var container = (inventory.Items).FirstOrDefault(item => item.SlotId == equipmentSlotId.ToString()); + var container = inventory.Items.FirstOrDefault(item => item.SlotId == equipmentSlotId.ToString()); if (container is null) { missingContainerCount++; @@ -502,11 +469,9 @@ public class BotGeneratorHelper( { // Bot doesn't have any containers we want to add item to if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug( $"Unable to add item: {itemWithChildren.FirstOrDefault()?.Template} to bot as it lacks the following containers: {string.Join(",", equipmentSlots)}" ); - } return ItemAddedResult.NO_CONTAINERS; } @@ -526,10 +491,8 @@ public class BotGeneratorHelper( } if (value?.Properties?.Grids?.Count == 0) - { // Container has no slots to hold items continue; - } // Get x/y grid size of item var itemSize = _inventoryHelper.GetItemSize(rootItemTplId, rootItemId, itemWithChildren); @@ -543,16 +506,12 @@ public class BotGeneratorHelper( if (slotGrid.Props?.CellsH == 0 || slotGrid.Props?.CellsV == 0 || itemSize[0] * itemSize[1] > slotGrid.Props?.CellsV * slotGrid.Props?.CellsH) - { continue; - } // Can't put item type in grid, skip all grids as we're assuming they have the same rules if (!ItemAllowedInContainer(slotGrid, rootItemTplId)) - { // Multiple containers, maybe next one allows item, only break out of loop for the containers grids break; - } // Get all root items in found container var existingContainerItems = (inventory.Items ?? []).Where( @@ -591,7 +550,7 @@ public class BotGeneratorHelper( { X = findSlotResult.X, Y = findSlotResult.Y, - R = (findSlotResult.Rotation ?? false) ? 1 : 0, + R = findSlotResult.Rotation ?? false ? 1 : 0 } ; } @@ -603,10 +562,7 @@ public class BotGeneratorHelper( } // If we've checked all grids in container and reached this point, there's no space for item - if (currentGridCount >= totalSlotGridCount) - { - break; - } + if (currentGridCount >= totalSlotGridCount) break; currentGridCount++; // No space in this grid, move to next container grid and try again @@ -616,10 +572,7 @@ public class BotGeneratorHelper( if (containersIdFull is null) continue; // if the item was a one by one, we know it must be full. Or if the maps cant find a slot for a one by one - if (itemSize[0] == 1 && itemSize[1] == 1) - { - containersIdFull.Add(equipmentSlotId.ToString()); - } + if (itemSize[0] == 1 && itemSize[1] == 1) containersIdFull.Add(equipmentSlotId.ToString()); } return ItemAddedResult.NO_SPACE; @@ -660,31 +613,20 @@ public class BotGeneratorHelper( var filter = propFilters?.FirstOrDefault()?.Filter ?? []; if (propFilters?.Count == 0) - { // no filters, item is fine to add return true; - } // Check if item base type is excluded var itemDetails = _itemHelper.GetItem(itemTpl).Value; // if item to add is found in exclude filter, not allowed - if (excludedFilter.Contains(itemDetails?.Parent ?? string.Empty)) - { - return false; - } + if (excludedFilter.Contains(itemDetails?.Parent ?? string.Empty)) return false; // If Filter array only contains 1 filter and its for basetype 'item', allow it - if (filter.Count == 1 && filter.Contains(BaseClasses.ITEM)) - { - return true; - } + if (filter.Count == 1 && filter.Contains(BaseClasses.ITEM)) return true; // If allowed filter has something in it + filter doesnt have basetype 'item', not allowed - if (filter.Count > 0 && !filter.Contains(itemDetails?.Parent ?? string.Empty)) - { - return false; - } + if (filter.Count > 0 && !filter.Contains(itemDetails?.Parent ?? string.Empty)) return false; return true; } diff --git a/Libraries/Core/Helpers/BotHelper.cs b/Libraries/Core/Helpers/BotHelper.cs index ecf699f7..0a78a701 100644 --- a/Libraries/Core/Helpers/BotHelper.cs +++ b/Libraries/Core/Helpers/BotHelper.cs @@ -74,10 +74,7 @@ public class BotHelper( var friendlyBotTypesKey = "FRIENDLY_BOT_TYPES"; // Null guard - if (difficultySettings.Mind[friendlyBotTypesKey] is null) - { - difficultySettings.Mind[friendlyBotTypesKey] = new List(); - } + if (difficultySettings.Mind[friendlyBotTypesKey] is null) difficultySettings.Mind[friendlyBotTypesKey] = new List(); ((List)difficultySettings.Mind[friendlyBotTypesKey]).Add(typeToAdd); } @@ -92,25 +89,15 @@ public class BotHelper( var revengePropKey = "REVENGE_BOT_TYPES"; // Nothing to add - if (typesToAdd is null) - { - return; - } + if (typesToAdd is null) return; // Null guard - if (difficultySettings.Mind[revengePropKey] is null) - { - difficultySettings.Mind[revengePropKey] = new List(); - } + if (difficultySettings.Mind[revengePropKey] is null) difficultySettings.Mind[revengePropKey] = new List(); var revengeArray = (List)difficultySettings.Mind[revengePropKey]; foreach (var botTypeToAdd in typesToAdd) - { if (!revengeArray.Contains(botTypeToAdd)) - { revengeArray.Add(botTypeToAdd); - } - } } public bool RollChanceToBePmc(MinMax botConvertMinMax) @@ -121,10 +108,7 @@ public class BotHelper( protected Dictionary GetPmcConversionValuesForLocation(string location) { var result = _pmcConfig.ConvertIntoPmcChance[location.ToLower()]; - if (result is null) - { - _pmcConfig.ConvertIntoPmcChance = new(); - } + if (result is null) _pmcConfig.ConvertIntoPmcChance = new Dictionary>(); return result; } @@ -151,10 +135,7 @@ public class BotHelper( public RandomisationDetails GetBotRandomizationDetails(int botLevel, EquipmentFilters botEquipConfig) { // No randomisation details found, skip - if (botEquipConfig is null || botEquipConfig.Randomisation is null) - { - return null; - } + if (botEquipConfig is null || botEquipConfig.Randomisation is null) return null; return botEquipConfig.Randomisation.FirstOrDefault( (randDetails) => botLevel >= randDetails.LevelRange.Min && botLevel <= randDetails.LevelRange.Max @@ -203,7 +184,7 @@ public class BotHelper( /// name of PMC public string GetPmcNicknameOfMaxLength(int maxLength, string side = null) { - var randomType = (side is not null) ? side : (_randomUtil.GetInt(0, 1) == 0) ? "usec" : "bear"; + var randomType = side is not null ? side : _randomUtil.GetInt(0, 1) == 0 ? "usec" : "bear"; var allNames = _databaseService.GetBots().Types[randomType.ToLower()].FirstNames; var filteredNames = allNames.Where((name) => name.Length <= maxLength); if (filteredNames.Count() == 0) diff --git a/Libraries/Core/Helpers/BotWeaponGeneratorHelper.cs b/Libraries/Core/Helpers/BotWeaponGeneratorHelper.cs index 64adc54c..77cf935d 100644 --- a/Libraries/Core/Helpers/BotWeaponGeneratorHelper.cs +++ b/Libraries/Core/Helpers/BotWeaponGeneratorHelper.cs @@ -113,11 +113,11 @@ public class BotWeaponGeneratorHelper( equipmentSlotsToAddTo = [EquipmentSlots.TacticalVest, EquipmentSlots.Pockets]; var ammoItems = _itemHelper.SplitStack( - new() + new Item { Id = _hashUtil.Generate(), Template = ammoTpl, - Upd = new() { StackObjectsCount = cartridgeCount }, + Upd = new Upd { StackObjectsCount = cartridgeCount } } ); @@ -136,10 +136,8 @@ public class BotWeaponGeneratorHelper( _logger.Debug($"Unable to add ammo: {ammoItem.Template} to bot inventory, {result.ToString()}"); if (result == ItemAddedResult.NO_SPACE || result == ItemAddedResult.NO_CONTAINERS) - { // If there's no space for 1 stack or no containers to hold item, there's no space for the others break; - } } } } diff --git a/Libraries/Core/Helpers/ContainerHelper.cs b/Libraries/Core/Helpers/ContainerHelper.cs index 6da9610a..1ccb11c9 100644 --- a/Libraries/Core/Helpers/ContainerHelper.cs +++ b/Libraries/Core/Helpers/ContainerHelper.cs @@ -23,29 +23,20 @@ public class ContainerHelper var limitX = containerX - minVolume; // Every x+y slot taken up in container, exit - if (container2D.All((x) => x.All((y) =>y == 1))) - { - return new FindSlotResult(false); - } + if (container2D.All((x) => x.All((y) => y == 1))) return new FindSlotResult(false); // Down = y for (var y = 0; y < limitY; y++) { - if (container2D[y].All((x) => x == 1)) - { // Every item in row is full, skip row continue; - } // Try each slot on the row (across = x) for (var x = 0; x < limitX; x++) { var foundSlot = LocateSlot(container2D, containerX, containerY, x, y, itemWidth, itemHeight); - if (foundSlot) - { - return new FindSlotResult(true, x, y, rotation); - } + if (foundSlot) return new FindSlotResult(true, x, y, rotation); // Failed to find slot, rotate item and try again if (!foundSlot && ItemBiggerThan1X1(itemWidth, itemHeight)) @@ -118,10 +109,7 @@ public class ContainerHelper } } - if (!foundSlot) - { - break; - } + if (!foundSlot) break; } return foundSlot; @@ -149,20 +137,12 @@ public class ContainerHelper var itemHeight = rotate ? itemW : itemH; for (var tmpY = y; tmpY < y + itemHeight; tmpY++) - { - for (var tmpX = x; tmpX < x + itemWidth; tmpX++) - { - if (container2D[tmpY][tmpX] == 0) - { - // Flag slot as used - container2D[tmpY][tmpX] = 1; - } - else - { - throw new Exception($"Slot at({ x }, { y}) is already filled. Cannot fit a { itemW} by { itemH} item"); - } - } - } + for (var tmpX = x; tmpX < x + itemWidth; tmpX++) + if (container2D[tmpY][tmpX] == 0) + // Flag slot as used + container2D[tmpY][tmpX] = 1; + else + throw new Exception($"Slot at({x}, {y}) is already filled. Cannot fit a {itemW} by {itemH} item"); } } @@ -187,13 +167,13 @@ public class FindSlotResult [JsonPropertyName("success")] public bool? Success { get; set; } - + [JsonPropertyName("x")] public int? X { get; set; } - + [JsonPropertyName("y")] public int? Y { get; set; } - + [JsonPropertyName("rotation")] public bool? Rotation { get; set; } } diff --git a/Libraries/Core/Helpers/Dialogue/AbstractDialogChatBot.cs b/Libraries/Core/Helpers/Dialogue/AbstractDialogChatBot.cs index badecb68..eb3a28b6 100644 --- a/Libraries/Core/Helpers/Dialogue/AbstractDialogChatBot.cs +++ b/Libraries/Core/Helpers/Dialogue/AbstractDialogChatBot.cs @@ -30,14 +30,9 @@ public abstract class AbstractDialogChatBot( var commandos = _chatCommands.Where(c => c.GetCommandPrefix() == splitCommand.FirstOrDefault()); if (commandos.FirstOrDefault()?.GetCommands().Contains(splitCommand[1]) ?? false) - { return commandos.FirstOrDefault().Handle(splitCommand[1], GetChatBot(), sessionId, request); - } - if (splitCommand.FirstOrDefault()?.ToLower() == "help") - { - return SendPlayerHelpMessage(sessionId, request); - } + if (splitCommand.FirstOrDefault()?.ToLower() == "help") return SendPlayerHelpMessage(sessionId, request); _mailSendService.SendUserMessageToPlayer( sessionId, @@ -77,7 +72,6 @@ public abstract class AbstractDialogChatBot( () => { foreach (var subCommand in chatCommand.GetCommands()) - { _mailSendService.SendUserMessageToPlayer( sessionId, GetChatBot(), @@ -85,7 +79,6 @@ public abstract class AbstractDialogChatBot( [], null ); - } }, TimeSpan.FromSeconds(1) ); @@ -100,11 +93,9 @@ public abstract class AbstractDialogChatBot( public void RegisterChatCommand(IChatCommand chatCommand) { if (_chatCommands.Any(cc => cc.GetCommandPrefix() == chatCommand.GetCommandPrefix())) - { throw new Exception( $"The command \"{chatCommand.GetCommandPrefix()}\" attempting to be registered already exists." ); - } _chatCommands.Add(chatCommand); } diff --git a/Libraries/Core/Helpers/Dialogue/Commando/SptCommandoCommands.cs b/Libraries/Core/Helpers/Dialogue/Commando/SptCommandoCommands.cs index 29334768..828b22a8 100644 --- a/Libraries/Core/Helpers/Dialogue/Commando/SptCommandoCommands.cs +++ b/Libraries/Core/Helpers/Dialogue/Commando/SptCommandoCommands.cs @@ -11,8 +11,9 @@ namespace Core.Helpers.Dialog.Commando; [Injectable] public class SptCommandoCommands : IChatCommand { - protected List _sptCommands; protected LocalisationService _localisationService; + protected List _sptCommands; + public SptCommandoCommands( ConfigServer configServer, LocalisationService localisationService, @@ -31,19 +32,6 @@ public class SptCommandoCommands : IChatCommand } } - public void RegisterSptCommandoCommand(ISptCommand command) - { - if (_sptCommands.Any((c) => c.GetCommand() == command.GetCommand())) { - throw new Exception( - _localisationService.GetText( - "chat-unable_to_register_command_already_registered", - command.GetCommand() - ) - ); - } - _sptCommands.Add(command); - } - public string GetCommandPrefix() { return "spt"; @@ -65,4 +53,16 @@ public class SptCommandoCommands : IChatCommand .First((c) => c.GetCommand() == command) .PerformAction(commandHandler, sessionId, request); } + + public void RegisterSptCommandoCommand(ISptCommand command) + { + if (_sptCommands.Any((c) => c.GetCommand() == command.GetCommand())) + throw new Exception( + _localisationService.GetText( + "chat-unable_to_register_command_already_registered", + command.GetCommand() + ) + ); + _sptCommands.Add(command); + } } diff --git a/Libraries/Core/Helpers/Dialogue/Commando/SptCommands/GiveCommand/GiveSptCommand.cs b/Libraries/Core/Helpers/Dialogue/Commando/SptCommands/GiveCommand/GiveSptCommand.cs index 0e162fbc..2df4e53e 100644 --- a/Libraries/Core/Helpers/Dialogue/Commando/SptCommands/GiveCommand/GiveSptCommand.cs +++ b/Libraries/Core/Helpers/Dialogue/Commando/SptCommands/GiveCommand/GiveSptCommand.cs @@ -25,9 +25,8 @@ public class GiveSptCommand( ICloner _cloner ) : ISptCommand { - protected Dictionary _savedCommand = new(); - private static readonly Regex _commandRegex = new(@"^spt give (((([a-z]{2,5}) )?""(.+)""|\w+) )?([0-9]+)$"); private const double _acceptableConfidence = 0.9d; + private static readonly Regex _commandRegex = new(@"^spt give (((([a-z]{2,5}) )?""(.+)""|\w+) )?([0-9]+)$"); // Exception for flares protected readonly HashSet _excludedPresetItems = @@ -37,6 +36,8 @@ public class GiveSptCommand( ItemTpl.FLARE_RSP30_REACTIVE_SIGNAL_CARTRIDGE_YELLOW ]; + protected Dictionary _savedCommand = new(); + public string GetCommand() { return "give"; @@ -104,10 +105,7 @@ public class GiveSptCommand( else { // A new give request was entered, we need to ignore the old saved command - if (_savedCommand.ContainsKey(sessionId)) - { - _savedCommand.Remove(sessionId); - } + if (_savedCommand.ContainsKey(sessionId)) _savedCommand.Remove(sessionId); isItemName = result.Groups[5].Value != null; item = result.Groups[5].Value is not null ? result.Groups[5].Value : result.Groups[2].Value; diff --git a/Libraries/Core/Helpers/Dialogue/Commando/SptCommands/GiveCommand/SavedCommand.cs b/Libraries/Core/Helpers/Dialogue/Commando/SptCommands/GiveCommand/SavedCommand.cs index 726a3385..bd46c878 100644 --- a/Libraries/Core/Helpers/Dialogue/Commando/SptCommands/GiveCommand/SavedCommand.cs +++ b/Libraries/Core/Helpers/Dialogue/Commando/SptCommands/GiveCommand/SavedCommand.cs @@ -7,7 +7,6 @@ public class SavedCommand { public SavedCommand() { - } public SavedCommand(int quantity, List potentialItemNames, string locale) diff --git a/Libraries/Core/Helpers/Dialogue/Commando/SptCommands/GiveCommand/StringSimilarity.cs b/Libraries/Core/Helpers/Dialogue/Commando/SptCommands/GiveCommand/StringSimilarity.cs index 14de2da2..229a6b2b 100644 --- a/Libraries/Core/Helpers/Dialogue/Commando/SptCommands/GiveCommand/StringSimilarity.cs +++ b/Libraries/Core/Helpers/Dialogue/Commando/SptCommands/GiveCommand/StringSimilarity.cs @@ -9,22 +9,25 @@ public static class StringSimilarity */ public static double Match(string str1, string str2, int substringLength = 2, bool caseSensitive = false) { - if (!caseSensitive) { + if (!caseSensitive) + { str1 = str1.ToLower(); str2 = str2.ToLower(); } if (str1.Length < substringLength || str2.Length < substringLength) return 0; - + var map = new Dictionary(); - for (var i = 0; i < str1.Length - (substringLength - 1); i++) { + for (var i = 0; i < str1.Length - (substringLength - 1); i++) + { var substr1 = str1.Substring(i, substringLength); map.Add(substr1, map.TryGetValue(substr1, out var value) ? value + 1 : 1); } var match = 0; - for (var j = 0; j < str2.Length - (substringLength - 1); j++) { + for (var j = 0; j < str2.Length - (substringLength - 1); j++) + { var substr2 = str2.Substring(j, substringLength); var count = map.GetValueOrDefault(substr2, 0); if (count > 0) @@ -34,7 +37,6 @@ public static class StringSimilarity } } - return match * 2d / (str1.Length + str2.Length - ((substringLength - 1d) * 2d)); + return match * 2d / (str1.Length + str2.Length - (substringLength - 1d) * 2d); } - } diff --git a/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/AreYouABotMessageHandler.cs b/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/AreYouABotMessageHandler.cs index 1e820eb6..05c53f15 100644 --- a/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/AreYouABotMessageHandler.cs +++ b/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/AreYouABotMessageHandler.cs @@ -5,31 +5,31 @@ using Core.Services; using Core.Utils; using SptCommon.Annotations; -namespace Core.Helpers.Dialogue.SptMessageHandlers +namespace Core.Helpers.Dialogue.SptMessageHandlers; + +[Injectable] +public class AreYouABotMessageHandler( + MailSendService _mailSendService, + RandomUtil _randomUtil) : IChatMessageHandler { - [Injectable] - public class AreYouABotMessageHandler( - MailSendService _mailSendService, - RandomUtil _randomUtil) : IChatMessageHandler + public int GetPriority() { - public int GetPriority() - { - return 100; - } + return 100; + } - public bool CanHandle(string message) - { - return message.ToLower() == "are you a bot"; - } + public bool CanHandle(string message) + { + return message.ToLower() == "are you a bot"; + } - public void Process(string sessionId, UserDialogInfo sptFriendUser, PmcData sender) - { - _mailSendService.SendUserMessageToPlayer( - sessionId, - sptFriendUser, - _randomUtil.GetArrayValue(["beep boop", "**sad boop**", "probably", "sometimes", "yeah lol"]), - [], null - ); - } + public void Process(string sessionId, UserDialogInfo sptFriendUser, PmcData sender) + { + _mailSendService.SendUserMessageToPlayer( + sessionId, + sptFriendUser, + _randomUtil.GetArrayValue(["beep boop", "**sad boop**", "probably", "sometimes", "yeah lol"]), + [], + null + ); } } diff --git a/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/ForceChristmasMessageHandler.cs b/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/ForceChristmasMessageHandler.cs index 1facab52..432a3387 100644 --- a/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/ForceChristmasMessageHandler.cs +++ b/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/ForceChristmasMessageHandler.cs @@ -5,38 +5,39 @@ using Core.Services; using Core.Utils; using SptCommon.Annotations; -namespace Core.Helpers.Dialogue.SPTFriend.Commands +namespace Core.Helpers.Dialogue.SPTFriend.Commands; + +[Injectable] +public class ForceChristmasMessageHandler( + LocalisationService _localisationService, + MailSendService _mailSendService, + RandomUtil _randomUtil, + SeasonalEventService _seasonalEventService) : IChatMessageHandler { - [Injectable] - public class ForceChristmasMessageHandler( - LocalisationService _localisationService, - MailSendService _mailSendService, - RandomUtil _randomUtil, - SeasonalEventService _seasonalEventService) : IChatMessageHandler + public int GetPriority() { - public int GetPriority() - { - return 99; - } + return 99; + } - public bool CanHandle(string message) - { - return message.ToLower() == "hohoho"; - } + public bool CanHandle(string message) + { + return message.ToLower() == "hohoho"; + } - public void Process(string sessionId, UserDialogInfo sptFriendUser, PmcData sender) - { - var enableEventResult = _seasonalEventService.ForceSeasonalEvent(SeasonalEventType.Christmas); - if (enableEventResult) - { - _mailSendService.SendUserMessageToPlayer( + public void Process(string sessionId, UserDialogInfo sptFriendUser, PmcData sender) + { + var enableEventResult = _seasonalEventService.ForceSeasonalEvent(SeasonalEventType.Christmas); + if (enableEventResult) + _mailSendService.SendUserMessageToPlayer( sessionId, - sptFriendUser, - _randomUtil.GetArrayValue([ + sptFriendUser, + _randomUtil.GetArrayValue( + [ _localisationService.GetText("chatbot-forced_event_enabled", SeasonalEventType.Christmas) - ]), [], null - ); - } - } + ] + ), + [], + null + ); } } diff --git a/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/ForceHalloweenMessageHandler.cs b/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/ForceHalloweenMessageHandler.cs index 8301b95f..029896d0 100644 --- a/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/ForceHalloweenMessageHandler.cs +++ b/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/ForceHalloweenMessageHandler.cs @@ -5,40 +5,39 @@ using Core.Services; using Core.Utils; using SptCommon.Annotations; -namespace Core.Helpers.Dialogue.SPTFriend.Commands +namespace Core.Helpers.Dialogue.SPTFriend.Commands; + +[Injectable] +public class ForceHalloweenMessageHandler( + LocalisationService _localisationService, + MailSendService _mailSendService, + RandomUtil _randomUtil, + SeasonalEventService _seasonalEventService) : IChatMessageHandler { - [Injectable] - public class ForceHalloweenMessageHandler( - LocalisationService _localisationService, - MailSendService _mailSendService, - RandomUtil _randomUtil, - SeasonalEventService _seasonalEventService) : IChatMessageHandler + public int GetPriority() { - public int GetPriority() - { - return 99; - } + return 99; + } - public bool CanHandle(string message) - { - return message.ToLower() == "veryspooky"; - } + public bool CanHandle(string message) + { + return message.ToLower() == "veryspooky"; + } - public void Process(string sessionId, UserDialogInfo sptFriendUser, PmcData sender) - { - var enableEventResult = _seasonalEventService.ForceSeasonalEvent(SeasonalEventType.Halloween); - if (enableEventResult) - { - _mailSendService.SendUserMessageToPlayer( - sessionId, - sptFriendUser, - _randomUtil.GetArrayValue([ + public void Process(string sessionId, UserDialogInfo sptFriendUser, PmcData sender) + { + var enableEventResult = _seasonalEventService.ForceSeasonalEvent(SeasonalEventType.Halloween); + if (enableEventResult) + _mailSendService.SendUserMessageToPlayer( + sessionId, + sptFriendUser, + _randomUtil.GetArrayValue( + [ _localisationService.GetText("chatbot-forced_event_enabled", SeasonalEventType.Halloween) - ]), - [], - null - ); - } - } + ] + ), + [], + null + ); } } diff --git a/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/ForceSnowMessageHandler.cs b/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/ForceSnowMessageHandler.cs index f8036da2..3fda583d 100644 --- a/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/ForceSnowMessageHandler.cs +++ b/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/ForceSnowMessageHandler.cs @@ -7,38 +7,37 @@ using Core.Services; using Core.Utils; using SptCommon.Annotations; -namespace Core.Helpers.Dialogue.SPTFriend.Commands +namespace Core.Helpers.Dialogue.SPTFriend.Commands; + +[Injectable] +public class ForceSnowMessageHandler( + LocalisationService _localisationService, + MailSendService _mailSendService, + RandomUtil _randomUtil, + ConfigServer _configServer) : IChatMessageHandler { - [Injectable] - public class ForceSnowMessageHandler( - LocalisationService _localisationService, - MailSendService _mailSendService, - RandomUtil _randomUtil, - ConfigServer _configServer) : IChatMessageHandler + private WeatherConfig _weatherConfig = _configServer.GetConfig(); + + public int GetPriority() { - private WeatherConfig _weatherConfig = _configServer.GetConfig(); + return 99; + } - public int GetPriority() - { - return 99; - } + public bool CanHandle(string message) + { + return message.ToLower() == "itsonlysnowalan"; + } - public bool CanHandle(string message) - { - return message.ToLower() == "itsonlysnowalan"; - } + public void Process(string sessionId, UserDialogInfo sptFriendUser, PmcData sender) + { + _weatherConfig.OverrideSeason = Season.WINTER; - public void Process(string sessionId, UserDialogInfo sptFriendUser, PmcData sender) - { - _weatherConfig.OverrideSeason = Season.WINTER; - - _mailSendService.SendUserMessageToPlayer( + _mailSendService.SendUserMessageToPlayer( sessionId, sptFriendUser, - _randomUtil.GetArrayValue([_localisationService.GetText("chatbot-snow_enabled")]), + _randomUtil.GetArrayValue([_localisationService.GetText("chatbot-snow_enabled")]), [], null - ); - } + ); } } diff --git a/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/ForceSummerMessageHandler.cs b/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/ForceSummerMessageHandler.cs index 619aa5dc..19ef2cae 100644 --- a/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/ForceSummerMessageHandler.cs +++ b/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/ForceSummerMessageHandler.cs @@ -7,38 +7,37 @@ using Core.Services; using Core.Utils; using SptCommon.Annotations; -namespace Core.Helpers.Dialogue.SPTFriend.Commands +namespace Core.Helpers.Dialogue.SPTFriend.Commands; + +[Injectable] +public class ForceSummerMessageHandler( + LocalisationService _localisationService, + MailSendService _mailSendService, + RandomUtil _randomUtil, + ConfigServer _configServer) : IChatMessageHandler { - [Injectable] - public class ForceSummerMessageHandler( - LocalisationService _localisationService, - MailSendService _mailSendService, - RandomUtil _randomUtil, - ConfigServer _configServer) : IChatMessageHandler + private WeatherConfig _weatherConfig = _configServer.GetConfig(); + + public int GetPriority() { - private WeatherConfig _weatherConfig = _configServer.GetConfig(); + return 99; + } - public int GetPriority() - { - return 99; - } + public bool CanHandle(string message) + { + return message.ToLower() == "givemesunshine"; + } - public bool CanHandle(string message) - { - return message.ToLower() == "givemesunshine"; - } + public void Process(string sessionId, UserDialogInfo sptFriendUser, PmcData sender) + { + _weatherConfig.OverrideSeason = Season.SUMMER; - public void Process(string sessionId, UserDialogInfo sptFriendUser, PmcData sender) - { - _weatherConfig.OverrideSeason = Season.SUMMER; - - _mailSendService.SendUserMessageToPlayer( - sessionId, - sptFriendUser, - _randomUtil.GetArrayValue([_localisationService.GetText("chatbot-summer_enabled")]), - [], - null - ); - } + _mailSendService.SendUserMessageToPlayer( + sessionId, + sptFriendUser, + _randomUtil.GetArrayValue([_localisationService.GetText("chatbot-summer_enabled")]), + [], + null + ); } } diff --git a/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/GiveMeSpaceMessageHandler.cs b/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/GiveMeSpaceMessageHandler.cs index 86750766..5fc16dc5 100644 --- a/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/GiveMeSpaceMessageHandler.cs +++ b/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/GiveMeSpaceMessageHandler.cs @@ -37,7 +37,9 @@ public class GiveMeSpaceMessageHandler( _mailSendService.SendUserMessageToPlayer( sessionId, sptFriendUser, - _localisationService.GetText("chatbot-cannot_accept_any_more_of_gift"), [], null + _localisationService.GetText("chatbot-cannot_accept_any_more_of_gift"), + [], + null ); } else @@ -47,9 +49,13 @@ public class GiveMeSpaceMessageHandler( _mailSendService.SendUserMessageToPlayer( sessionId, sptFriendUser, - _randomUtil.GetArrayValue([ - _localisationService.GetText("chatbot-added_stash_rows_please_restart"), - ]), [], null + _randomUtil.GetArrayValue( + [ + _localisationService.GetText("chatbot-added_stash_rows_please_restart") + ] + ), + [], + null ); _profileHelper.FlagGiftReceivedInProfile(sessionId, stashRowGiftId, maxGiftsToSendCount); diff --git a/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/HelloMessageHandler.cs b/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/HelloMessageHandler.cs index f660caba..c36865ff 100644 --- a/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/HelloMessageHandler.cs +++ b/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/HelloMessageHandler.cs @@ -6,74 +6,33 @@ using Core.Services; using Core.Utils; using SptCommon.Annotations; -namespace Core.Helpers.Dialogue.SPTFriend.Commands +namespace Core.Helpers.Dialogue.SPTFriend.Commands; + +[Injectable] +public class HelloMessageHandler( + MailSendService _mailSendService, + RandomUtil _randomUtil) : IChatMessageHandler { - [Injectable] - public class HelloMessageHandler( - MailSendService _mailSendService, - RandomUtil _randomUtil) : IChatMessageHandler + protected List _listOfMessages = ["hello", "hi", "sup", "yo", "hey", "bonjour"]; + + + public int GetPriority() { - protected List _listOfMessages = ["hello", "hi", "sup", "yo", "hey", "bonjour"]; + return 100; + } + public bool CanHandle(string message) + { + return _listOfMessages.Contains(message, StringComparer.OrdinalIgnoreCase); + } - public string GetCommand() - { - return "hello"; - } - - public string GetAssociatedBotId() - { - return "6723fd51c5924c57ce0ca01f"; - } - - public string GetCommandHelp() - { - return "'hello' replies to the player with a random greeting"; - } - - public string PerformAction(UserDialogInfo commandHandler, string sessionId, SendMessageRequest request) - { - _mailSendService.SendUserMessageToPlayer( - sessionId, - commandHandler, - _randomUtil.GetArrayValue([ - "Howdy", - "Hi", - "Greetings", - "Hello", - "Bonjor", - "Yo", - "Sup", - "Heyyyyy", - "Hey there", - "OH its you" - ]), - [], null - ); - - return request.DialogId; - } - - - - - - public int GetPriority() - { - return 100; - } - - public bool CanHandle(string message) - { - return _listOfMessages.Contains(message, StringComparer.OrdinalIgnoreCase); - } - - public void Process(string sessionId, UserDialogInfo sptFriendUser, PmcData sender) - { - _mailSendService.SendUserMessageToPlayer( - sessionId, - sptFriendUser, - _randomUtil.GetArrayValue([ + public void Process(string sessionId, UserDialogInfo sptFriendUser, PmcData sender) + { + _mailSendService.SendUserMessageToPlayer( + sessionId, + sptFriendUser, + _randomUtil.GetArrayValue( + [ "Howdy", "Hi", "Greetings", @@ -84,10 +43,53 @@ namespace Core.Helpers.Dialogue.SPTFriend.Commands "Heyyyyy", "Hey there", "OH its you", - $"Hello {sender?.Info?.Nickname}", - ]), - [], null - ); - } + $"Hello {sender?.Info?.Nickname}" + ] + ), + [], + null + ); + } + + + public string GetCommand() + { + return "hello"; + } + + public string GetAssociatedBotId() + { + return "6723fd51c5924c57ce0ca01f"; + } + + public string GetCommandHelp() + { + return "'hello' replies to the player with a random greeting"; + } + + public string PerformAction(UserDialogInfo commandHandler, string sessionId, SendMessageRequest request) + { + _mailSendService.SendUserMessageToPlayer( + sessionId, + commandHandler, + _randomUtil.GetArrayValue( + [ + "Howdy", + "Hi", + "Greetings", + "Hello", + "Bonjor", + "Yo", + "Sup", + "Heyyyyy", + "Hey there", + "OH its you" + ] + ), + [], + null + ); + + return request.DialogId; } } diff --git a/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/LoveYouChatMessageHandler.cs b/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/LoveYouChatMessageHandler.cs index a88b2752..0a5b4f0c 100644 --- a/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/LoveYouChatMessageHandler.cs +++ b/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/LoveYouChatMessageHandler.cs @@ -27,12 +27,14 @@ public class LoveYouChatMessageHandler( _mailSendService.SendUserMessageToPlayer( sessionId, sptFriendUser, - _randomUtil.GetArrayValue([ - "That's quite forward but i love you too in a purely chatbot-human way", - "I love you too buddy :3!", - "uwu", - $"love you too {sender?.Info?.Nickname}", - ]), + _randomUtil.GetArrayValue( + [ + "That's quite forward but i love you too in a purely chatbot-human way", + "I love you too buddy :3!", + "uwu", + $"love you too {sender?.Info?.Nickname}" + ] + ), [], null ); diff --git a/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/NikitaMessageHandler.cs b/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/NikitaMessageHandler.cs index b1556cb7..56003e76 100644 --- a/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/NikitaMessageHandler.cs +++ b/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/NikitaMessageHandler.cs @@ -4,36 +4,39 @@ using Core.Services; using Core.Utils; using SptCommon.Annotations; -namespace Core.Helpers.Dialogue.SPTFriend.Commands +namespace Core.Helpers.Dialogue.SPTFriend.Commands; + +[Injectable] +public class NikitaMessageHandler( + MailSendService _mailSendService, + RandomUtil _randomUtil) : IChatMessageHandler { - [Injectable] - public class NikitaMessageHandler( - MailSendService _mailSendService, - RandomUtil _randomUtil) : IChatMessageHandler + public int GetPriority() { - public int GetPriority() - { - return 100; - } + return 100; + } - public bool CanHandle(string message) - { - return message.ToLower() == "nikita"; - } + public bool CanHandle(string message) + { + return message.ToLower() == "nikita"; + } - public void Process(string sessionId, UserDialogInfo sptFriendUser, PmcData sender) - { - _mailSendService.SendUserMessageToPlayer( - sessionId, - sptFriendUser, - _randomUtil.GetArrayValue([ + public void Process(string sessionId, UserDialogInfo sptFriendUser, PmcData sender) + { + _mailSendService.SendUserMessageToPlayer( + sessionId, + sptFriendUser, + _randomUtil.GetArrayValue( + [ "I know that guy!", "Cool guy, he made EFT!", "Legend", "The mastermind of my suffering", - "Remember when he said webel-webel-webel-webel, classic Nikita moment", - ]), [], null - ); - } + "Remember when he said webel-webel-webel-webel, classic Nikita moment" + ] + ), + [], + null + ); } } diff --git a/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/SendGiftMessageHandler.cs b/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/SendGiftMessageHandler.cs index de9dd124..a9d15b85 100644 --- a/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/SendGiftMessageHandler.cs +++ b/Libraries/Core/Helpers/Dialogue/SPTFriend/Commands/SendGiftMessageHandler.cs @@ -7,65 +7,64 @@ using Core.Services; using Core.Utils; using SptCommon.Annotations; -namespace Core.Helpers.Dialogue.SPTFriend.Commands +namespace Core.Helpers.Dialogue.SPTFriend.Commands; + +[Injectable] +public class SendGiftMessageHandler( + MailSendService _mailSendService, + RandomUtil _randomUtil, + GiftService _giftService, + ConfigServer _configServer) : IChatMessageHandler { - [Injectable] - public class SendGiftMessageHandler( - MailSendService _mailSendService, - RandomUtil _randomUtil, - GiftService _giftService, - ConfigServer _configServer) : IChatMessageHandler + private CoreConfig _coreConfig = _configServer.GetConfig(); + private string commandSent = string.Empty; + + public int GetPriority() { - private CoreConfig _coreConfig = _configServer.GetConfig(); - private string commandSent = string.Empty; + return 1; + } - public int GetPriority() + public bool CanHandle(string message) + { + return _giftService.GiftExists(message.ToLower()); + } + + public void Process(string sessionId, UserDialogInfo sptFriendUser, PmcData sender) + { + // Gifts may be disabled via config + if (!_coreConfig.Features.ChatbotFeatures.SptFriendGiftsEnabled) return; + + var giftSent = _giftService.SendGiftToPlayer(sessionId, commandSent); + switch (giftSent) { - return 1; - } - - public bool CanHandle(string message) - { - return _giftService.GiftExists(message.ToLower()); - } - - public void Process(string sessionId, UserDialogInfo sptFriendUser, PmcData sender) - { - // Gifts may be disabled via config - if (!_coreConfig.Features.ChatbotFeatures.SptFriendGiftsEnabled) - { - return; - } - - var giftSent = _giftService.SendGiftToPlayer(sessionId, commandSent); - switch (giftSent) - { - case GiftSentResult.SUCCESS: - _mailSendService.SendUserMessageToPlayer( - sessionId, - sptFriendUser, - _randomUtil.GetArrayValue([ + case GiftSentResult.SUCCESS: + _mailSendService.SendUserMessageToPlayer( + sessionId, + sptFriendUser, + _randomUtil.GetArrayValue( + [ "Hey! you got the right code!", "A secret code, how exciting!", "You found a gift code!", "A gift code! incredible", - "A gift! what could it be!"]), - [], - null - ); + "A gift! what could it be!" + ] + ), + [], + null + ); - return; - case GiftSentResult.FAILED_GIFT_ALREADY_RECEIVED: - _mailSendService.SendUserMessageToPlayer( - sessionId, - sptFriendUser, - _randomUtil.GetArrayValue(["Looks like you already used that code", "You already have that!!"]), - [], - null - ); + return; + case GiftSentResult.FAILED_GIFT_ALREADY_RECEIVED: + _mailSendService.SendUserMessageToPlayer( + sessionId, + sptFriendUser, + _randomUtil.GetArrayValue(["Looks like you already used that code", "You already have that!!"]), + [], + null + ); - return; - } + return; } } } diff --git a/Libraries/Core/Helpers/Dialogue/SptDialogueChatBot.cs b/Libraries/Core/Helpers/Dialogue/SptDialogueChatBot.cs index 84d6fa56..5f83b3d9 100644 --- a/Libraries/Core/Helpers/Dialogue/SptDialogueChatBot.cs +++ b/Libraries/Core/Helpers/Dialogue/SptDialogueChatBot.cs @@ -24,16 +24,8 @@ public class SptDialogueChatBot( { protected IEnumerable _chatMessageHandlers = ChatMessageHandlerSetup(chatMessageHandlers); - private static List ChatMessageHandlerSetup(IEnumerable components) - { - var chatMessageHandlers = components.ToList(); - chatMessageHandlers.Sort((a, b) => a.GetPriority() - b.GetPriority()); - - return chatMessageHandlers; - } - protected CoreConfig _coreConfig = _configServer.GetConfig(); - + public UserDialogInfo GetChatBot() { @@ -57,12 +49,9 @@ public class SptDialogueChatBot( var sender = _profileHelper.GetPmcProfile(sessionId); var sptFriendUser = GetChatBot(); - if (request.Text?.ToLower() == "help") - { - return SendPlayerHelpMessage(sessionId, request); - } + if (request.Text?.ToLower() == "help") return SendPlayerHelpMessage(sessionId, request); + - var handler = _chatMessageHandlers.FirstOrDefault((v) => v.CanHandle(request.Text)); if (handler is not null) { @@ -70,7 +59,7 @@ public class SptDialogueChatBot( return request.DialogId; } - + _mailSendService.SendUserMessageToPlayer( sessionId, @@ -83,6 +72,14 @@ public class SptDialogueChatBot( return request.DialogId; } + private static List ChatMessageHandlerSetup(IEnumerable components) + { + var chatMessageHandlers = components.ToList(); + chatMessageHandlers.Sort((a, b) => a.GetPriority() - b.GetPriority()); + + return chatMessageHandlers; + } + private string GetUnrecognizedCommandMessage() { return "Unknown command."; @@ -115,7 +112,6 @@ public class SptDialogueChatBot( () => { foreach (var subCommand in chatCommand.GetCommands()) - { _mailSendService.SendUserMessageToPlayer( sessionId, GetChatBot(), @@ -123,7 +119,6 @@ public class SptDialogueChatBot( [], null ); - } }, TimeSpan.FromSeconds(1) ); diff --git a/Libraries/Core/Helpers/DialogueHelper.cs b/Libraries/Core/Helpers/DialogueHelper.cs index d47d65ba..a54b137a 100644 --- a/Libraries/Core/Helpers/DialogueHelper.cs +++ b/Libraries/Core/Helpers/DialogueHelper.cs @@ -96,7 +96,7 @@ public class DialogueHelper( public Dictionary GetDialogsForProfile(string sessionId) { var profile = _profileHelper.GetFullProfile(sessionId); - return profile.DialogueRecords ?? (profile.DialogueRecords = new()); + return profile.DialogueRecords ?? (profile.DialogueRecords = new Dictionary()); } public Models.Eft.Profile.Dialogue? GetDialogueFromProfile(string profileId, string dialogueId) diff --git a/Libraries/Core/Helpers/DurabilityLimitsHelper.cs b/Libraries/Core/Helpers/DurabilityLimitsHelper.cs index 6175c5e4..886a620e 100644 --- a/Libraries/Core/Helpers/DurabilityLimitsHelper.cs +++ b/Libraries/Core/Helpers/DurabilityLimitsHelper.cs @@ -14,7 +14,6 @@ public class DurabilityLimitsHelper( BotHelper _botHelper, ConfigServer _configServer) { - private readonly BotConfig _botConfig = _configServer.GetConfig(); /// @@ -39,25 +38,13 @@ public class DurabilityLimitsHelper( public double GetRandomizedMaxArmorDurability(TemplateItem? itemTemplate, string? botRole = null) { var itemMaxDurability = itemTemplate.Properties.MaxDurability.Value; - if (botRole is null) - { - return itemMaxDurability; - } + if (botRole is null) return itemMaxDurability; - if (_botHelper.IsBotPmc(botRole)) - { - return GenerateMaxPmcArmorDurability(itemMaxDurability); - } + if (_botHelper.IsBotPmc(botRole)) return GenerateMaxPmcArmorDurability(itemMaxDurability); - if (_botHelper.IsBotBoss(botRole)) - { - return itemMaxDurability; - } + if (_botHelper.IsBotBoss(botRole)) return itemMaxDurability; - if (_botHelper.IsBotFollower(botRole)) - { - return itemMaxDurability; - } + if (_botHelper.IsBotFollower(botRole)) return itemMaxDurability; return itemMaxDurability; } @@ -83,30 +70,15 @@ public class DurabilityLimitsHelper( /// private string GetDurabilityRole(string? botRole) { - if (botRole is null) - { - return "default"; - } + if (botRole is null) return "default"; - if (_botHelper.IsBotPmc(botRole)) - { - return "pmc"; - } + if (_botHelper.IsBotPmc(botRole)) return "pmc"; - if (_botHelper.IsBotBoss(botRole)) - { - return "boss"; - } + if (_botHelper.IsBotBoss(botRole)) return "boss"; - if (_botHelper.IsBotFollower(botRole)) - { - return "follower"; - } + if (_botHelper.IsBotFollower(botRole)) return "follower"; - if (_botHelper.IsBotZombie(botRole)) - { - return "zombie"; - } + if (_botHelper.IsBotZombie(botRole)) return "zombie"; var roleExistsInConfig = _botConfig.Durability.BotDurabilities.ContainsKey(botRole); if (!roleExistsInConfig) @@ -152,15 +124,9 @@ public class DurabilityLimitsHelper( protected int GetLowestMaxWeaponFromConfig(string? botRole = null) { - if (botRole is null or "default") - { - return _botConfig.Durability.Default.Weapon.LowestMax; - } + if (botRole is null or "default") return _botConfig.Durability.Default.Weapon.LowestMax; - if (botRole == "pmc") - { - return _botConfig.Durability.Pmc.Weapon.LowestMax; - } + if (botRole == "pmc") return _botConfig.Durability.Pmc.Weapon.LowestMax; _botConfig.Durability.BotDurabilities.TryGetValue(botRole, out var durability); return durability.Weapon.LowestMax; @@ -168,15 +134,9 @@ public class DurabilityLimitsHelper( protected int GetHighestMaxWeaponDurabilityFromConfig(string? botRole = null) { - if (botRole is null or "default") - { - return _botConfig.Durability.Default.Weapon.HighestMax; - } + if (botRole is null or "default") return _botConfig.Durability.Default.Weapon.HighestMax; - if (botRole == "pmc") - { - return _botConfig.Durability.Pmc.Weapon.HighestMax; - } + if (botRole == "pmc") return _botConfig.Durability.Pmc.Weapon.HighestMax; _botConfig.Durability.BotDurabilities.TryGetValue(botRole, out var durability); return durability.Weapon.HighestMax; @@ -189,7 +149,8 @@ public class DurabilityLimitsHelper( var delta = _randomUtil.GetInt(minDelta, maxDelta); var result = maxDurability - delta; var durabilityValueMinLimit = Math.Round( - (GetMinWeaponLimitPercentFromConfig(botRole) / 100) * maxDurability); + GetMinWeaponLimitPercentFromConfig(botRole) / 100 * maxDurability + ); // Don't let weapon dura go below the percent defined in config return result >= durabilityValueMinLimit ? result : durabilityValueMinLimit; @@ -202,7 +163,8 @@ public class DurabilityLimitsHelper( var delta = _randomUtil.GetInt(minDelta, maxDelta); var result = maxDurability - delta; var durabilityValueMinLimit = Math.Round( - (GetMinArmorLimitPercentFromConfig(botRole) / 100) * maxDurability); + GetMinArmorLimitPercentFromConfig(botRole) / 100 * maxDurability + ); // Don't let armor dura go below the percent defined in config return result >= durabilityValueMinLimit ? result : durabilityValueMinLimit; @@ -210,15 +172,9 @@ public class DurabilityLimitsHelper( protected int GetMinWeaponDeltaFromConfig(string? botRole = null) { - if (botRole is null or "default") - { - return _botConfig.Durability.Default.Weapon.MinDelta; - } + if (botRole is null or "default") return _botConfig.Durability.Default.Weapon.MinDelta; - if (botRole == "pmc") - { - return _botConfig.Durability.Pmc.Weapon.MinDelta; - } + if (botRole == "pmc") return _botConfig.Durability.Pmc.Weapon.MinDelta; _botConfig.Durability.BotDurabilities.TryGetValue(botRole, out var value); @@ -227,15 +183,9 @@ public class DurabilityLimitsHelper( protected int GetMaxWeaponDeltaFromConfig(string? botRole = null) { - if (botRole is null or "default") - { - return _botConfig.Durability.Default.Weapon.MaxDelta; - } + if (botRole is null or "default") return _botConfig.Durability.Default.Weapon.MaxDelta; - if (botRole == "pmc") - { - return _botConfig.Durability.Pmc.Weapon.MaxDelta; - } + if (botRole == "pmc") return _botConfig.Durability.Pmc.Weapon.MaxDelta; _botConfig.Durability.BotDurabilities.TryGetValue(botRole, out var value); @@ -244,15 +194,9 @@ public class DurabilityLimitsHelper( protected int GetMinArmorDeltaFromConfig(string? botRole = null) { - if (botRole is null or "default") - { - return _botConfig.Durability.Default.Armor.MinDelta; - } + if (botRole is null or "default") return _botConfig.Durability.Default.Armor.MinDelta; - if (botRole == "pmc") - { - return _botConfig.Durability.Pmc.Armor.MinDelta; - } + if (botRole == "pmc") return _botConfig.Durability.Pmc.Armor.MinDelta; _botConfig.Durability.BotDurabilities.TryGetValue(botRole, out var value); @@ -261,15 +205,9 @@ public class DurabilityLimitsHelper( protected int GetMaxArmorDeltaFromConfig(string? botRole = null) { - if (botRole is null or "default") - { - return _botConfig.Durability.Default.Armor.MaxDelta; - } + if (botRole is null or "default") return _botConfig.Durability.Default.Armor.MaxDelta; - if (botRole == "pmc") - { - return _botConfig.Durability.Pmc.Armor.MaxDelta; - } + if (botRole == "pmc") return _botConfig.Durability.Pmc.Armor.MaxDelta; _botConfig.Durability.BotDurabilities.TryGetValue(botRole, out var value); @@ -278,15 +216,9 @@ public class DurabilityLimitsHelper( protected double GetMinArmorLimitPercentFromConfig(string? botRole = null) { - if (botRole is null or "default") - { - return _botConfig.Durability.Default.Armor.MinLimitPercent; - } + if (botRole is null or "default") return _botConfig.Durability.Default.Armor.MinLimitPercent; - if (botRole == "pmc") - { - return _botConfig.Durability.Pmc.Armor.MinLimitPercent; - } + if (botRole == "pmc") return _botConfig.Durability.Pmc.Armor.MinLimitPercent; _botConfig.Durability.BotDurabilities.TryGetValue(botRole, out var value); @@ -295,15 +227,9 @@ public class DurabilityLimitsHelper( protected double GetMinWeaponLimitPercentFromConfig(string? botRole = null) { - if (botRole is null or "default") - { - return _botConfig.Durability.Default.Weapon.MinLimitPercent; - } + if (botRole is null or "default") return _botConfig.Durability.Default.Weapon.MinLimitPercent; - if (botRole == "pmc") - { - return _botConfig.Durability.Pmc.Weapon.MinLimitPercent; - } + if (botRole == "pmc") return _botConfig.Durability.Pmc.Weapon.MinLimitPercent; _botConfig.Durability.BotDurabilities.TryGetValue(botRole, out var value); diff --git a/Libraries/Core/Helpers/GameEventHelper.cs b/Libraries/Core/Helpers/GameEventHelper.cs index cffa3e82..a96bae00 100644 --- a/Libraries/Core/Helpers/GameEventHelper.cs +++ b/Libraries/Core/Helpers/GameEventHelper.cs @@ -5,5 +5,4 @@ namespace Core.Helpers; [Injectable] public class GameEventHelper { - } diff --git a/Libraries/Core/Helpers/HandbookHelper.cs b/Libraries/Core/Helpers/HandbookHelper.cs index 8df6fef7..3648da4c 100644 --- a/Libraries/Core/Helpers/HandbookHelper.cs +++ b/Libraries/Core/Helpers/HandbookHelper.cs @@ -15,10 +15,10 @@ public class HandbookHelper( ICloner _cloner ) { + protected LookupCollection _handbookPriceCache = new(); protected ItemConfig _itemConfig = _configServer.GetConfig(); protected bool _lookupCacheGenerated = false; - protected LookupCollection _handbookPriceCache = new(); - + /// /// Create an in-memory cache of all items with associated handbook price in handbookPriceCache class /// @@ -26,16 +26,21 @@ public class HandbookHelper( { var handbook = _databaseService.GetHandbook(); // Add handbook overrides found in items.json config into db - foreach (var itemTplKey in _itemConfig.HandbookPriceOverride) { + foreach (var itemTplKey in _itemConfig.HandbookPriceOverride) + { var data = _itemConfig.HandbookPriceOverride[itemTplKey.Key]; var itemToUpdate = handbook.Items.FirstOrDefault(item => item.Id == itemTplKey.Key); - if (itemToUpdate is null) { - handbook.Items.Add( new HandbookItem { - Id = itemTplKey.Key, - ParentId = data.ParentId, - Price = data.Price, - }); + if (itemToUpdate is null) + { + handbook.Items.Add( + new HandbookItem + { + Id = itemTplKey.Key, + ParentId = data.ParentId, + Price = data.Price + } + ); itemToUpdate = handbook.Items.FirstOrDefault(item => item.Id == itemTplKey.Key); } @@ -43,22 +48,23 @@ public class HandbookHelper( } var handbookDbClone = _cloner.Clone(handbook); - foreach (var handbookItem in handbookDbClone.Items) { + foreach (var handbookItem in handbookDbClone.Items) + { _handbookPriceCache.Items.ById.TryAdd(handbookItem.Id, handbookItem.Price ?? 0); - if (!_handbookPriceCache.Items.ByParent.TryGetValue(handbookItem.ParentId, out var _)) { + if (!_handbookPriceCache.Items.ByParent.TryGetValue(handbookItem.ParentId, out _)) _handbookPriceCache.Items.ByParent.TryAdd(handbookItem.ParentId, []); - } _handbookPriceCache.Items.ByParent.TryGetValue(handbookItem.ParentId, out var array); array.Add(handbookItem.Id); } - foreach (var handbookCategory in handbookDbClone.Categories) { + foreach (var handbookCategory in handbookDbClone.Categories) + { _handbookPriceCache.Categories.ById.TryAdd(handbookCategory.Id, handbookCategory.ParentId); - if (handbookCategory.ParentId is not null) { - if (!_handbookPriceCache.Categories.ByParent.TryGetValue(handbookCategory.ParentId, out var _)) { + if (handbookCategory.ParentId is not null) + { + if (!_handbookPriceCache.Categories.ByParent.TryGetValue(handbookCategory.ParentId, out _)) _handbookPriceCache.Categories.ByParent.TryAdd(handbookCategory.ParentId, []); - } _handbookPriceCache.Categories.ByParent.TryGetValue(handbookCategory.ParentId, out var array); array.Add(handbookCategory.Id); @@ -80,28 +86,19 @@ public class HandbookHelper( _lookupCacheGenerated = true; } - if (_handbookPriceCache.Items.ById.TryGetValue(tpl, out var item)) - { - return item; - } + if (_handbookPriceCache.Items.ById.TryGetValue(tpl, out var item)) return item; - var handbookItem = _databaseService.GetHandbook().Items?.FirstOrDefault(item => item.Id == tpl); + var handbookItem = _databaseService.GetHandbook().Items?.FirstOrDefault(item => item.Id == tpl); if (handbookItem is null) { var newValue = 0; - if (!_handbookPriceCache.Items.ById.TryAdd(tpl, newValue)) - { - _handbookPriceCache.Items.ById[tpl] = newValue; - } + if (!_handbookPriceCache.Items.ById.TryAdd(tpl, newValue)) _handbookPriceCache.Items.ById[tpl] = newValue; return newValue; } - if (!_handbookPriceCache.Items.ById.TryAdd(tpl, handbookItem.Price ?? 0)) - { - _handbookPriceCache.Items.ById[tpl] = handbookItem.Price ?? 0; - } + if (!_handbookPriceCache.Items.ById.TryAdd(tpl, handbookItem.Price ?? 0)) _handbookPriceCache.Items.ById[tpl] = handbookItem.Price ?? 0; return handbookItem.Price.Value; } @@ -109,9 +106,7 @@ public class HandbookHelper( public double GetTemplatePriceForItems(List items) { var total = 0D; - foreach (var item in items) { - total += GetTemplatePrice(item.Template); - } + foreach (var item in items) total += GetTemplatePrice(item.Template); return total; } @@ -124,7 +119,7 @@ public class HandbookHelper( public List TemplatesWithParent(string parentId) { _handbookPriceCache.Items.ByParent.TryGetValue(parentId, out var template); - + return template ?? []; } @@ -135,7 +130,7 @@ public class HandbookHelper( /// true if exists in cache public bool IsCategory(string category) { - return _handbookPriceCache.Categories.ById.TryGetValue(category, out var _); + return _handbookPriceCache.Categories.ById.TryGetValue(category, out _); } /// @@ -157,9 +152,9 @@ public class HandbookHelper( /// Count in roubles public int InRUB(double nonRoubleCurrencyCount, string currencyTypeFrom) { - return (int) (currencyTypeFrom == Money.ROUBLES - ? nonRoubleCurrencyCount - : Math.Round(nonRoubleCurrencyCount * (GetTemplatePrice(currencyTypeFrom)))); + return (int)(currencyTypeFrom == Money.ROUBLES + ? nonRoubleCurrencyCount + : Math.Round(nonRoubleCurrencyCount * GetTemplatePrice(currencyTypeFrom))); } /// @@ -170,13 +165,11 @@ public class HandbookHelper( /// currency count in desired type public int FromRUB(double roubleCurrencyCount, string currencyTypeTo) { - if (currencyTypeTo == Money.ROUBLES) { - return (int) roubleCurrencyCount; - } + if (currencyTypeTo == Money.ROUBLES) return (int)roubleCurrencyCount; // Get price of currency from handbook var price = GetTemplatePrice(currencyTypeTo); - return (int) (price > 0 ? Math.Max(1, Math.Round(roubleCurrencyCount / price)) : 0); + return (int)(price > 0 ? Math.Max(1, Math.Round(roubleCurrencyCount / price)) : 0); } public HandbookCategory GetCategoryById(string handbookId) @@ -187,24 +180,24 @@ public class HandbookHelper( public class LookupItem { - public Dictionary ById { get; set; } - public Dictionary> ByParent { get; set; } - public LookupItem() { ById = new Dictionary(); ByParent = new Dictionary>(); } + + public Dictionary ById { get; set; } + public Dictionary> ByParent { get; set; } } public class LookupCollection { - public LookupItem Items { get; set; } - public LookupItem Categories { get; set; } - public LookupCollection() { Items = new LookupItem(); Categories = new LookupItem(); } + + public LookupItem Items { get; set; } + public LookupItem Categories { get; set; } } diff --git a/Libraries/Core/Helpers/HealthHelper.cs b/Libraries/Core/Helpers/HealthHelper.cs index 61262a60..b6c63787 100644 --- a/Libraries/Core/Helpers/HealthHelper.cs +++ b/Libraries/Core/Helpers/HealthHelper.cs @@ -39,7 +39,7 @@ public class HealthHelper( public void DefaultVitality(Vitality? vitality) { vitality ??= new Vitality { Health = null, Energy = 0, Temperature = 0, Hydration = 0 }; - + vitality.Health = new Dictionary { { @@ -47,7 +47,7 @@ public class HealthHelper( { Health = new CurrentMinMax { - Current = 0, + Current = 0 }, Effects = new Dictionary() } @@ -57,7 +57,7 @@ public class HealthHelper( { Health = new CurrentMinMax { - Current = 0, + Current = 0 }, Effects = new Dictionary() } @@ -67,7 +67,7 @@ public class HealthHelper( { Health = new CurrentMinMax { - Current = 0, + Current = 0 }, Effects = new Dictionary() } @@ -77,7 +77,7 @@ public class HealthHelper( { Health = new CurrentMinMax { - Current = 0, + Current = 0 }, Effects = new Dictionary() } @@ -87,7 +87,7 @@ public class HealthHelper( { Health = new CurrentMinMax { - Current = 0, + Current = 0 }, Effects = new Dictionary() } @@ -97,7 +97,7 @@ public class HealthHelper( { Health = new CurrentMinMax { - Current = 0, + Current = 0 }, Effects = new Dictionary() } @@ -107,7 +107,7 @@ public class HealthHelper( { Health = new CurrentMinMax { - Current = 0, + Current = 0 }, Effects = new Dictionary() } @@ -153,20 +153,15 @@ public class HealthHelper( { // Effects if (postRaidHealth.BodyParts[bodyPart.Key].Effects is not null) - { fullProfile.VitalityData.Health[bodyPart.Key].Effects = postRaidHealth.BodyParts[bodyPart.Key].Effects; - } // Limb hp if (!isDead) - { // Player alive, not is limb alive fullProfile.VitalityData.Health[bodyPart.Key].Health.Current = postRaidHealth.BodyParts[bodyPart.Key].Health.Current ?? 0; - } else - { - fullProfile.VitalityData.Health[bodyPart.Key].Health.Current = (pmcData.Health.BodyParts[bodyPart.Key].Health.Maximum * _healthConfig.HealthMultipliers.Death) ?? 0; - } + fullProfile.VitalityData.Health[bodyPart.Key].Health.Current = + pmcData.Health.BodyParts[bodyPart.Key].Health.Maximum * _healthConfig.HealthMultipliers.Death ?? 0; } TransferPostRaidLimbEffectsToProfile(postRaidHealth.BodyParts, pmcData); @@ -217,26 +212,19 @@ public class HealthHelper( if (profileBodyPartEffects.TryGetValue(effect.Key, out var dictEffect)) { if (effectsToIgnore.Contains(effect.Key)) - { // Get rid of certain effects we dont want to persist out of raid dictEffect = null; - } continue; } if (effectsToIgnore.Contains(effect.Key)) - { // Do not pass some effects to out of raid profile continue; - } var effectToAdd = new BodyPartEffectProperties { Time = effectDetails.Time ?? -1 }; // Add effect to server profile - if (profileBodyPartEffects.TryAdd(effect.Key, effectToAdd)) - { - profileBodyPartEffects[effect.Key] = effectToAdd; - } + if (profileBodyPartEffects.TryAdd(effect.Key, effectToAdd)) profileBodyPartEffects[effect.Key] = effectToAdd; } } } @@ -248,27 +236,16 @@ public class HealthHelper( /// Session id protected void SaveHealth(PmcData pmcData, string sessionID) { - if (!_healthConfig.Save.Health) { - return; - } - + if (!_healthConfig.Save.Health) return; + var profileHealth = _saveServer.GetProfile(sessionID).VitalityData; - if (profileHealth.Hydration > pmcData.Health.Hydration.Maximum) - { - profileHealth.Hydration = pmcData.Health.Hydration.Maximum; - } - - if (profileHealth.Energy > pmcData.Health.Energy.Maximum) - { - profileHealth.Energy = pmcData.Health.Energy.Maximum; - } - - if (profileHealth.Temperature > pmcData.Health.Temperature.Maximum) - { - profileHealth.Temperature = pmcData.Health.Temperature.Maximum; - } - + if (profileHealth.Hydration > pmcData.Health.Hydration.Maximum) profileHealth.Hydration = pmcData.Health.Hydration.Maximum; + + if (profileHealth.Energy > pmcData.Health.Energy.Maximum) profileHealth.Energy = pmcData.Health.Energy.Maximum; + + if (profileHealth.Temperature > pmcData.Health.Temperature.Maximum) profileHealth.Temperature = pmcData.Health.Temperature.Maximum; + pmcData.Health.Hydration.Current = Math.Round(profileHealth.Hydration ?? 0); pmcData.Health.Energy.Current = Math.Round(profileHealth.Energy ?? 0); pmcData.Health.Temperature.Current = Math.Round(profileHealth.Temperature ?? 0); @@ -276,15 +253,11 @@ public class HealthHelper( foreach (var bodyPart in pmcData.Health.BodyParts) { if (profileHealth.Health[bodyPart.Key].Health.Maximum > bodyPart.Value.Health.Maximum) - { profileHealth.Health[bodyPart.Key].Health.Maximum = bodyPart.Value.Health.Maximum; - } if (profileHealth.Health[bodyPart.Key].Health.Current == 0) - { profileHealth.Health[bodyPart.Key].Health.Current = bodyPart.Value.Health.Maximum * _healthConfig.HealthMultipliers.Blacked; - } - + bodyPart.Value.Health.Current = Math.Round(profileHealth.Health[bodyPart.Key].Health.Current ?? 0); } } @@ -305,29 +278,20 @@ public class HealthHelper( bool deleteExistingEffects = true) { // TODO: this will need to change, typing is all fucked up - if (!_healthConfig.Save.Effects) + if (!_healthConfig.Save.Effects) return; + + foreach (var bodyPart in bodyPartsWithEffects) { - return; - } - - foreach ( var bodyPart in bodyPartsWithEffects) { // clear effects from profile bodyPart - if (deleteExistingEffects) - { - pmcData.Health.BodyParts[bodyPart.Key].Effects = new Dictionary(); - } + if (deleteExistingEffects) pmcData.Health.BodyParts[bodyPart.Key].Effects = new Dictionary(); - foreach ( var effectType in bodyPartsWithEffects[bodyPart.Key].Effects) { - + foreach (var effectType in bodyPartsWithEffects[bodyPart.Key].Effects) + { var time = effectType.Value.Time; if (time is not null && time > 0) - { AddEffect(pmcData, effectType, time); - } else - { AddEffect(pmcData, effectType); - } } } } @@ -343,7 +307,7 @@ public class HealthHelper( { var profileBodyPart = pmcData.Health.BodyParts[effectType.Key]; profileBodyPart.Effects ??= new Dictionary(); - + profileBodyPart.Effects[effectType.Key] = new BodyPartEffectProperties { Time = duration }; } } diff --git a/Libraries/Core/Helpers/HideoutHelper.cs b/Libraries/Core/Helpers/HideoutHelper.cs index daa2fa46..d83a308d 100644 --- a/Libraries/Core/Helpers/HideoutHelper.cs +++ b/Libraries/Core/Helpers/HideoutHelper.cs @@ -33,14 +33,13 @@ public class HideoutHelper( ICloner _cloner ) { - protected HideoutConfig hideoutConfig = _configServer.GetConfig(); - public const string BitcoinFarm = "5d5c205bd582a50d042a3c0e"; public const string CultistCircleCraftId = "66827062405f392b203a44cf"; public const string BitcoinProductionId = "5d5c205bd582a50d042a3c0e"; public const string WaterCollector = "5d5589c1f934db045e6c5492"; public const int MaxSkillPoint = 5000; - protected List _idCheck = [HideoutHelper.BitcoinFarm, HideoutHelper.CultistCircleCraftId]; + protected List _idCheck = [BitcoinFarm, CultistCircleCraftId]; + protected HideoutConfig hideoutConfig = _configServer.GetConfig(); /// /// Add production to profiles' Hideout.Production array @@ -67,10 +66,7 @@ public class HideoutHelper( // @Important: Here we need to be very exact: // - normal recipe: Production time value is stored in attribute "productionType" with small "p" // - scav case recipe: Production time value is stored in attribute "ProductionType" with capital "P" - if (pmcData.Hideout?.Production is null) - { - pmcData.Hideout.Production = new Dictionary(); - } + if (pmcData.Hideout?.Production is null) pmcData.Hideout.Production = new Dictionary(); var modifiedProductionTime = GetAdjustedCraftTimeWithSkills(pmcData, body.RecipeId); @@ -99,7 +95,7 @@ public class HideoutHelper( { Id = _hashUtil.Generate(), Template = toolItem.Template, - Upd = toolItem.Upd, + Upd = toolItem.Upd } ); } @@ -133,10 +129,7 @@ public class HideoutHelper( // @Important: Here we need to be very exact: // - normal recipe: Production time value is stored in attribute "productionType" with small "p" // - scav case recipe: Production time value is stored in attribute "ProductionType" with capital "P" - if (pmcData.Hideout?.Production is null) - { - pmcData.Hideout.Production = new Dictionary(); - } + if (pmcData.Hideout?.Production is null) pmcData.Hideout.Production = new Dictionary(); var modifiedProductionTime = GetAdjustedCraftTimeWithSkills(pmcData, body.RecipeId); @@ -170,7 +163,7 @@ public class HideoutHelper( Interrupted = false, NeedFuelForAllProductionTime = needFuelForAllProductionTime, // Used when sending to client needFuelForAllProductionTime = needFuelForAllProductionTime, // used when stored in production.json - SkipTime = 0, + SkipTime = 0 }; } @@ -189,9 +182,7 @@ public class HideoutHelper( // Find stash item and adjust tpl to new tpl from bonus var stashItem = profileData.Inventory.Items.FirstOrDefault((x) => x.Id == profileData.Inventory.Stash); if (stashItem is null) - { _logger.Warning(_localisationService.GetText("hideout-unable_to_apply_stashsize_bonus_no_stash_found", profileData.Inventory.Stash)); - } stashItem.Template = bonus.TemplateId; @@ -211,10 +202,7 @@ public class HideoutHelper( // Add bonus to player bonuses array in profile // EnergyRegeneration, HealthRegeneration, RagfairCommission, ScavCooldownTimer, SkillGroupLevelingBoost, ExperienceRate, QuestMoneyReward etc - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Adding bonus: {bonus.Type} to profile, value: {bonus.Value}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Adding bonus: {bonus.Type} to profile, value: {bonus.Value}"); profileData.Bonuses.Add(bonus); } @@ -226,7 +214,7 @@ public class HideoutHelper( { var pmcData = _profileHelper.GetPmcProfile(sessionID); var hideoutProperties = GetHideoutProperties(pmcData); - + pmcData.Hideout.SptUpdateLastRunTimestamp ??= _timeUtil.GetTimeStamp(); UpdateAreasWithResources(sessionID, pmcData, hideoutProperties); @@ -250,7 +238,7 @@ public class HideoutHelper( IsGeneratorOn = pmcData.Hideout.Areas.FirstOrDefault((area) => area.Type == HideoutAreas.GENERATOR)?.Active ?? false, WaterCollectorHasFilter = DoesWaterCollectorHaveFilter( pmcData.Hideout.Areas.FirstOrDefault((area) => area.Type == HideoutAreas.WATER_COLLECTOR) - ), + ) }; return hideoutProperties; @@ -260,10 +248,8 @@ public class HideoutHelper( { // Can put filters in from L3 if (waterCollector.Level == 3) - { // Has filter in at least one slot return waterCollector.Slots.Any(slot => slot.Items is not null); - } // No Filter return false; @@ -301,10 +287,7 @@ public class HideoutHelper( } // Skip processing (Don't skip continious crafts like bitcoin farm or cultist circle) - if (IsCraftComplete(craft)) - { - continue; - } + if (IsCraftComplete(craft)) continue; // Special handling required if (IsCraftOfType(craft, HideoutAreas.SCAV_CASE)) @@ -366,9 +349,9 @@ public class HideoutHelper( switch (hideoutType) { case HideoutAreas.WATER_COLLECTOR: - return craft.RecipeId == HideoutHelper.WaterCollector; + return craft.RecipeId == WaterCollector; case HideoutAreas.BITCOIN_FARM: - return craft.RecipeId == HideoutHelper.BitcoinFarm; + return craft.RecipeId == BitcoinFarm; case HideoutAreas.SCAV_CASE: return craft.SptIsScavCase ?? false; case HideoutAreas.CIRCLE_OF_CULTISTS: @@ -387,10 +370,8 @@ public class HideoutHelper( /// True when craft is complete protected bool IsCraftComplete(Production craft) { - return ( - craft.Progress >= craft.ProductionTime && - !_idCheck.Contains(craft.RecipeId) - ); + return craft.Progress >= craft.ProductionTime && + !_idCheck.Contains(craft.RecipeId); } /// @@ -405,10 +386,7 @@ public class HideoutHelper( HideoutProperties hideoutProperties) { var timeElapsed = GetTimeElapsedSinceLastServerTick(pmcData, hideoutProperties.IsGeneratorOn); - if (hideoutProperties.WaterCollectorHasFilter) - { - pmcData.Hideout.Production[productionId].Progress += timeElapsed; - } + if (hideoutProperties.WaterCollectorHasFilter) pmcData.Hideout.Production[productionId].Progress += timeElapsed; } /// @@ -425,10 +403,7 @@ public class HideoutHelper( HideoutProperties hideoutProperties) { // Production is complete, no need to do any calculations - if (DoesProgressMatchProductionTime(pmcData, prodId)) - { - return; - } + if (DoesProgressMatchProductionTime(pmcData, prodId)) return; // Get seconds since last hideout update + now var timeElapsed = GetTimeElapsedSinceLastServerTick(pmcData, hideoutProperties.IsGeneratorOn, recipe); @@ -440,10 +415,8 @@ public class HideoutHelper( // Limit progress to total production time if progress is over (dont run for continious crafts)) if (!(recipe.Continuous ?? false)) - { // If progress is larger than prod time, return ProductionTime, hard cap the vaue production.Progress = Math.Min(production.Progress ?? 0, production.ProductionTime ?? 0); - } } protected void UpdateCultistCircleCraftProgress(PmcData pmcData, string prodId) @@ -451,10 +424,7 @@ public class HideoutHelper( var production = pmcData.Hideout.Production[prodId]; // Check if we're already complete, skip - if (production.AvailableForFinish ?? false) - { - return; - } + if (production.AvailableForFinish ?? false) return; // Get seconds since last hideout update var timeElapsedSeconds = _timeUtil.GetTimeStamp() - pmcData.Hideout.SptUpdateLastRunTimestamp; @@ -465,10 +435,7 @@ public class HideoutHelper( production.Progress += timeElapsedSeconds; // Check if craft is complete - if (production.Progress >= production.ProductionTime) - { - FlagCultistCircleCraftAsComplete(production); - } + if (production.Progress >= production.ProductionTime) FlagCultistCircleCraftAsComplete(production); return; } @@ -525,14 +492,10 @@ public class HideoutHelper( HideoutProperties hideoutProperties) { foreach (var area in pmcData.Hideout.Areas) - { switch (area.Type) { case HideoutAreas.GENERATOR: - if (hideoutProperties.IsGeneratorOn) - { - UpdateFuel(area, pmcData, hideoutProperties.IsGeneratorOn); - } + if (hideoutProperties.IsGeneratorOn) UpdateFuel(area, pmcData, hideoutProperties.IsGeneratorOn); break; case HideoutAreas.WATER_COLLECTOR: @@ -540,14 +503,10 @@ public class HideoutHelper( break; case HideoutAreas.AIR_FILTERING: - if (hideoutProperties.IsGeneratorOn) - { - UpdateAirFilters(area, pmcData, hideoutProperties.IsGeneratorOn); - } + if (hideoutProperties.IsGeneratorOn) UpdateAirFilters(area, pmcData, hideoutProperties.IsGeneratorOn); break; } - } } /// @@ -579,10 +538,7 @@ public class HideoutHelper( var combinedBonus = 1.0 - (fuelConsumptionBonusRate + hideoutManagementConsumptionBonusRate); // Sanity check, never let fuel consumption go negative, otherwise it returns fuel to the player - if (combinedBonus < 0) - { - combinedBonus = 0; - } + if (combinedBonus < 0) combinedBonus = 0; fuelUsedSinceLastTick *= combinedBonus; @@ -592,24 +548,18 @@ public class HideoutHelper( { var generatorSlot = generatorArea.Slots[i]; if (generatorSlot?.Items is null) - { // No item in slot, skip continue; - } var fuelItemInSlot = generatorSlot?.Items[0]; if (fuelItemInSlot is null) - { // No item in slot, skip continue; - } var fuelRemaining = fuelItemInSlot.Upd?.Resource?.Value; if (fuelRemaining == 0) - { // No fuel left, skip continue; - } // Undefined fuel, fresh fuel item and needs its max fuel amount looked up if (fuelRemaining is null) @@ -626,7 +576,7 @@ public class HideoutHelper( } // Round values to keep accuracy - fuelRemaining = Math.Round((fuelRemaining * 10000) ?? 0) / 10000; + fuelRemaining = Math.Round(fuelRemaining * 10000 ?? 0) / 10000; pointsConsumed = Math.Round(pointsConsumed * 10000) / 10000; // Fuel consumed / 10 is over 1, add hideout management skill point @@ -642,10 +592,7 @@ public class HideoutHelper( // Deducted all used fuel from this container, clean up and exit loop fuelItemInSlot.Upd = GetAreaUpdObject(1, fuelRemaining, pointsConsumed, isFuelItemFoundInRaid); - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Profile: {pmcData.Id} Generator has: {fuelRemaining} fuel left in slot {i + 1}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Profile: {pmcData.Id} Generator has: {fuelRemaining} fuel left in slot {i + 1}"); hasFuelRemaining = true; break; // Break to avoid updating all the fuel tanks @@ -655,17 +602,11 @@ public class HideoutHelper( // Ran out of fuel items to deduct fuel from fuelUsedSinceLastTick = Math.Abs(fuelRemaining ?? 0); - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Profile: {pmcData.Id} Generator ran out of fuel"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Profile: {pmcData.Id} Generator ran out of fuel"); } // Out of fuel, flag generator as offline - if (!hasFuelRemaining) - { - generatorArea.Active = false; - } + if (!hasFuelRemaining) generatorArea.Active = false; } protected void UpdateWaterCollector( @@ -675,18 +616,12 @@ public class HideoutHelper( HideoutProperties hideoutProperties) { // Skip water collector when not level 3 (cant collect until 3) - if (area.Level != 3) - { - return; - } + if (area.Level != 3) return; - if (!hideoutProperties.WaterCollectorHasFilter) - { - return; - } + if (!hideoutProperties.WaterCollectorHasFilter) return; // Canister with purified water craft exists - var purifiedWaterCraft = pmcData.Hideout.Production[HideoutHelper.WaterCollector]; + var purifiedWaterCraft = pmcData.Hideout.Production[WaterCollector]; if (purifiedWaterCraft is not null && purifiedWaterCraft.GetType() == typeof(Production)) { // Update craft time to account for increases in players craft time skill @@ -702,13 +637,13 @@ public class HideoutHelper( { // continuousProductionStart() // seem to not trigger consistently - HideoutSingleProductionStartRequestData recipe = new HideoutSingleProductionStartRequestData + var recipe = new HideoutSingleProductionStartRequestData { - RecipeId = HideoutHelper.WaterCollector, + RecipeId = WaterCollector, Action = "HideoutSingleProductionStart", Items = [], Tools = [], - Timestamp = _timeUtil.GetTimeStamp(), + Timestamp = _timeUtil.GetTimeStamp() }; RegisterProduction(pmcData, recipe, sessionId); @@ -742,8 +677,7 @@ public class HideoutHelper( var timeReductionSeconds = 0D; // Bitcoin farm is excluded from crafting skill cooldown reduction - if (recipeId != HideoutHelper.BitcoinFarm) - { + if (recipeId != BitcoinFarm) // Seconds to deduct from crafts total time timeReductionSeconds += GetSkillProductionTimeReduction( pmcData, @@ -751,30 +685,21 @@ public class HideoutHelper( SkillTypes.Crafting, globalSkillsDb.Crafting.ProductionTimeReductionPerLevel ?? 0 ); - } // Some crafts take into account hideout management, e.g. fuel, water/air filters if (applyHideoutManagementBonus) - { timeReductionSeconds += GetSkillProductionTimeReduction( pmcData, recipe.ProductionTime ?? 0, SkillTypes.HideoutManagement, globalSkillsDb.HideoutManagement.ConsumptionReductionPerLevel ?? 0 ); - } var modifiedProductionTime = recipe.ProductionTime - timeReductionSeconds; - if (modifiedProductionTime > 0 && _profileHelper.IsDeveloperAccount(pmcData.Id)) - { - modifiedProductionTime = 40; - } + if (modifiedProductionTime > 0 && _profileHelper.IsDeveloperAccount(pmcData.Id)) modifiedProductionTime = 40; // Sanity check, don't let anything craft in less than 5 seconds - if (modifiedProductionTime < 5) - { - modifiedProductionTime = 5; - } + if (modifiedProductionTime < 5) modifiedProductionTime = 5; return modifiedProductionTime; } @@ -793,7 +718,7 @@ public class HideoutHelper( PmcData pmcData) { var filterDrainRate = GetWaterFilterDrainRate(pmcData); - var craftProductionTime = GetTotalProductionTimeSeconds(HideoutHelper.WaterCollector); + var craftProductionTime = GetTotalProductionTimeSeconds(WaterCollector); var secondsSinceServerTick = GetTimeElapsedSinceLastServerTick(pmcData, isGeneratorOn); filterDrainRate = GetTimeAdjustedWaterFilterDrainRate( @@ -808,19 +733,14 @@ public class HideoutHelper( // Check progress against the productions craft time (dont use base time as it doesnt include any time bonuses profile has) if (production.Progress > production.ProductionTime) - { // Craft is complete nothing to do return; - } // Check all slots that take water filters until we find one with filter in it for (var i = 0; i < waterFilterArea.Slots.Count; i++) { // No water filter in slot, skip - if (waterFilterArea.Slots[i].Items is null) - { - continue; - } + if (waterFilterArea.Slots[i].Items is null) continue; var waterFilterItemInSlot = waterFilterArea.Slots[i].Items[0]; @@ -841,7 +761,7 @@ public class HideoutHelper( } // Round to get values to 3dp - resourceValue = Math.Round((resourceValue * 1000) ?? 0) / 1000; + resourceValue = Math.Round(resourceValue * 1000 ?? 0) / 1000; pointsConsumed = Math.Round(pointsConsumed * 1000) / 1000; // Check units consumed for possible increment of hideout mgmt skill point @@ -863,10 +783,7 @@ public class HideoutHelper( pointsConsumed, isWaterFilterFoundInRaid ); - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Water filter has: {resourceValue} units left in slot {i + 1}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Water filter has: {resourceValue} units left in slot {i + 1}"); break; // Break here to avoid iterating other filters now w're done } @@ -942,15 +859,13 @@ public class HideoutHelper( /// Seconds to produce item protected double GetTotalProductionTimeSeconds(string prodId) { - return ( - _databaseService.GetHideout() - .Production.Recipes.FirstOrDefault( - (prod) => - prod.Id == prodId - ) - ?.ProductionTime ?? - 0 - ); + return _databaseService.GetHideout() + .Production.Recipes.FirstOrDefault( + (prod) => + prod.Id == prodId + ) + ?.ProductionTime ?? + 0; } /// @@ -970,7 +885,7 @@ public class HideoutHelper( { StackObjectsCount = stackCount, Resource = new UpdResource { Value = resourceValue, UnitsConsumed = resourceUnitsConsumed }, - SpawnedInSession = isFoundInRaid, + SpawnedInSession = isFoundInRaid }; } @@ -991,7 +906,6 @@ public class HideoutHelper( var pointsConsumed = 0D; for (var i = 0; i < airFilterArea.Slots.Count; i++) - { if (airFilterArea.Slots[i].Items is not null) { var resourceValue = airFilterArea.Slots[i].Items[0].Upd?.Resource is not null @@ -1005,11 +919,11 @@ public class HideoutHelper( } else { - pointsConsumed = ((airFilterArea.Slots[i].Items[0].Upd.Resource.UnitsConsumed ?? 0) + filterDrainRate) ?? 0; + pointsConsumed = (airFilterArea.Slots[i].Items[0].Upd.Resource.UnitsConsumed ?? 0) + filterDrainRate ?? 0; resourceValue -= filterDrainRate; } - resourceValue = Math.Round((resourceValue * 10000) ?? 0) / 10000; + resourceValue = Math.Round(resourceValue * 10000 ?? 0) / 10000; pointsConsumed = Math.Round(pointsConsumed * 10000) / 10000; // check unit consumed for increment skill point @@ -1024,12 +938,9 @@ public class HideoutHelper( airFilterArea.Slots[i].Items[0].Upd = new Upd { StackObjectsCount = 1, - Resource = new UpdResource { Value = resourceValue, UnitsConsumed = pointsConsumed }, + Resource = new UpdResource { Value = resourceValue, UnitsConsumed = pointsConsumed } }; - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Air filter: {resourceValue} filter left on slot {i + 1}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Air filter: {resourceValue} filter left on slot {i + 1}"); break; // Break here to avoid updating all filters } @@ -1037,7 +948,6 @@ public class HideoutHelper( // Update remaining resources to be subtracted filterDrainRate = Math.Abs(resourceValue ?? 0); } - } } protected void UpdateBitcoinFarm( @@ -1047,10 +957,7 @@ public class HideoutHelper( bool isGeneratorOn) { var isBtcProd = btcProduction.GetType() == typeof(Production); - if (!isBtcProd) - { - return; - } + if (!isBtcProd) return; // The wiki has a wrong formula! // Do not change unless you validate it with the Client code files! @@ -1088,10 +995,8 @@ public class HideoutHelper( */ // Needs power to function if (!isGeneratorOn) - { // Return with no changes return; - } var coinSlotCount = GetBTCSlots(pmcData); @@ -1106,7 +1011,7 @@ public class HideoutHelper( var bitcoinProdData = _databaseService .GetHideout() - .Production.Recipes.FirstOrDefault((production) => production.Id == HideoutHelper.BitcoinProductionId); + .Production.Recipes.FirstOrDefault((production) => production.Id == BitcoinProductionId); // BSG finally fixed their settings, they now get loaded from the settings and used in the client var adjustedCraftTime = @@ -1116,21 +1021,15 @@ public class HideoutHelper( // The progress should be adjusted based on the GPU boost rate, but the target is still the base productionTime var timeMultiplier = bitcoinProdData.ProductionTime / adjustedCraftTime; var timeElapsedSeconds = GetTimeElapsedSinceLastServerTick(pmcData, isGeneratorOn); - btcProduction.Progress += Math.Floor((timeElapsedSeconds * timeMultiplier) ?? 0); + btcProduction.Progress += Math.Floor(timeElapsedSeconds * timeMultiplier ?? 0); while (btcProduction.Progress >= bitcoinProdData.ProductionTime) - { if (btcProduction.Products.Count < coinSlotCount) - { // Has space to add a coin to production rewards AddBtcToProduction(btcProduction, bitcoinProdData.ProductionTime ?? 0); - } else - { // Filled up bitcoin storage btcProduction.Progress = 0; - } - } btcProduction.StartTimestamp = _timeUtil.GetTimeStamp(); } @@ -1147,7 +1046,7 @@ public class HideoutHelper( { Id = _hashUtil.Generate(), Template = ItemTpl.BARTER_PHYSICAL_BITCOIN, - Upd = new Upd { StackObjectsCount = 1 }, + Upd = new Upd { StackObjectsCount = 1 } } ); @@ -1170,17 +1069,15 @@ public class HideoutHelper( // Reduce time elapsed (and progress) when generator is off var timeElapsed = _timeUtil.GetTimeStamp() - pmcData.Hideout.SptUpdateLastRunTimestamp; - if (recipe is not null) { + if (recipe is not null) + { var hideoutArea = _databaseService.GetHideout().Areas.FirstOrDefault((area) => area.Type == recipe.AreaType); - if (!(hideoutArea.NeedsFuel ?? false)) { + if (!(hideoutArea.NeedsFuel ?? false)) // e.g. Lavatory works at 100% when power is on / off return timeElapsed; - } } - if (!isGeneratorOn) { - timeElapsed *= (long)_databaseService.GetHideout().Settings.GeneratorSpeedWithoutFuel; - } + if (!isGeneratorOn) timeElapsed *= (long)_databaseService.GetHideout().Settings.GeneratorSpeedWithoutFuel; return timeElapsed; } @@ -1194,7 +1091,7 @@ public class HideoutHelper( { var bitcoinProductions = _databaseService .GetHideout() - .Production.Recipes.FirstOrDefault((production) => production.Id == HideoutHelper.BitcoinFarm); + .Production.Recipes.FirstOrDefault((production) => production.Id == BitcoinFarm); var productionSlots = bitcoinProductions?.ProductionLimitCount ?? 3; // Default to 3 if none found var hasManagementSkillSlots = _profileHelper.HasEliteSkillLevel(SkillTypes.HideoutManagement, pmcData); var managementSlotsCount = GetEliteSkillAdditionalBitcoinSlotCount() ?? 2; @@ -1207,7 +1104,8 @@ public class HideoutHelper( /// protected double? GetEliteSkillAdditionalBitcoinSlotCount() { - return _databaseService.GetGlobals().Configuration.SkillsSettings.HideoutManagement.EliteSlots.BitcoinFarm + return _databaseService.GetGlobals() + .Configuration.SkillsSettings.HideoutManagement.EliteSlots.BitcoinFarm .Container; } @@ -1220,22 +1118,19 @@ public class HideoutHelper( protected double? GetHideoutManagementConsumptionBonus(PmcData pmcData) { var hideoutManagementSkill = _profileHelper.GetSkillFromProfile(pmcData, SkillTypes.HideoutManagement); - if (hideoutManagementSkill is null || hideoutManagementSkill.Progress == 0) { - return 0; - } + if (hideoutManagementSkill is null || hideoutManagementSkill.Progress == 0) return 0; // If the level is 51 we need to round it at 50 so on elite you dont get 25.5% // at level 1 you already get 0.5%, so it goes up until level 50. For some reason the wiki // says that it caps at level 51 with 25% but as per dump data that is incorrect apparently - var roundedLevel = Math.Floor((hideoutManagementSkill.Progress / 100) ?? 0D); + var roundedLevel = Math.Floor(hideoutManagementSkill.Progress / 100 ?? 0D); roundedLevel = roundedLevel == 51 ? roundedLevel - 1 : roundedLevel; - return ( - (roundedLevel * - _databaseService.GetGlobals().Configuration.SkillsSettings.HideoutManagement - .ConsumptionReductionPerLevel) / - 100 - ); + return roundedLevel * + _databaseService.GetGlobals() + .Configuration.SkillsSettings.HideoutManagement + .ConsumptionReductionPerLevel / + 100; } /// @@ -1248,17 +1143,15 @@ public class HideoutHelper( protected double GetSkillBonusMultipliedBySkillLevel(PmcData pmcData, SkillTypes skill, double valuePerLevel) { var profileSkill = _profileHelper.GetSkillFromProfile(pmcData, skill); - if (profileSkill is null || profileSkill.Progress == 0) { - return 0; - } + if (profileSkill is null || profileSkill.Progress == 0) return 0; // If the level is 51 we need to round it at 50 so on elite you dont get 25.5% // at level 1 you already get 0.5%, so it goes up until level 50. For some reason the wiki // says that it caps at level 51 with 25% but as per dump data that is incorrect apparently - var roundedLevel = Math.Floor((profileSkill.Progress / 100) ?? 0D); + var roundedLevel = Math.Floor(profileSkill.Progress / 100 ?? 0D); roundedLevel = roundedLevel == 51 ? roundedLevel - 1 : roundedLevel; - return (roundedLevel * valuePerLevel) / 100; + return roundedLevel * valuePerLevel / 100; } /// @@ -1294,8 +1187,9 @@ public class HideoutHelper( ItemEventRouterResponse output) { // Get how many coins were crafted and ready to pick up - var craftedCoinCount = pmcData.Hideout.Production[HideoutHelper.BitcoinFarm]?.Products?.Count; - if (craftedCoinCount is null) { + var craftedCoinCount = pmcData.Hideout.Production[BitcoinFarm]?.Products?.Count; + if (craftedCoinCount is null) + { var errorMsg = _localisationService.GetText("hideout-no_bitcoins_to_collect"); _logger.Error(errorMsg); @@ -1305,41 +1199,41 @@ public class HideoutHelper( } List> itemsToAdd = []; - for (var index = 0; index < craftedCoinCount; index++) { - itemsToAdd.Add([new Item - { - Id = _hashUtil.Generate(), - Template = ItemTpl.BARTER_PHYSICAL_BITCOIN, - Upd = new Upd { StackObjectsCount = 1 }, - }, - ]); - } + for (var index = 0; index < craftedCoinCount; index++) + itemsToAdd.Add( + [ + new Item + { + Id = _hashUtil.Generate(), + Template = ItemTpl.BARTER_PHYSICAL_BITCOIN, + Upd = new Upd { StackObjectsCount = 1 } + } + ] + ); // Create request for what we want to add to stash - AddItemsDirectRequest addItemsRequest = new AddItemsDirectRequest { + var addItemsRequest = new AddItemsDirectRequest + { ItemsWithModsToAdd = itemsToAdd, FoundInRaid = true, UseSortingTable = false, - Callback = null, + Callback = null }; // Add FiR coins to player inventory _inventoryHelper.AddItemsToStash(sessionId, addItemsRequest, pmcData, output); - if (output.Warnings?.Count > 0) { - return; - } + if (output.Warnings?.Count > 0) return; // Is at max capacity + we collected all coins - reset production start time var coinSlotCount = GetBTCSlots(pmcData); - if (pmcData.Hideout.Production[HideoutHelper.BitcoinFarm].Products.Count >= coinSlotCount) { + if (pmcData.Hideout.Production[BitcoinFarm].Products.Count >= coinSlotCount) // Set start to now - pmcData.Hideout.Production[HideoutHelper.BitcoinFarm].StartTimestamp = _timeUtil + pmcData.Hideout.Production[BitcoinFarm].StartTimestamp = _timeUtil .GetTimeStamp(); - } // Remove crafted coins from production in profile now they've been collected // Can only collect all coins, not individially - pmcData.Hideout.Production[HideoutHelper.BitcoinFarm].Products = []; + pmcData.Hideout.Production[BitcoinFarm].Products = []; } /// @@ -1354,16 +1248,10 @@ public class HideoutHelper( var wall = profileHideoutAreas.FirstOrDefault((x) => x.Type == HideoutAreas.EMERGENCY_WALL); // No collector or med station, skip - if ((waterCollector is null && medStation is null)) - { - return; - } + if (waterCollector is null && medStation is null) return; // If med-station > level 1 AND water collector > level 1 AND wall is level 0 - if (waterCollector?.Level >= 1 && medStation?.Level >= 1 && wall?.Level <= 0) - { - wall.Level = 3; - } + if (waterCollector?.Level >= 1 && medStation?.Level >= 1 && wall?.Level <= 0) wall.Level = 3; } /// @@ -1384,16 +1272,11 @@ public class HideoutHelper( { foreach (var improvementId in profileData.Hideout.Improvements) { - if (!profileData.Hideout.Improvements.TryGetValue(improvementId.Key, out var improvementDetails)) - { - continue; - } + if (!profileData.Hideout.Improvements.TryGetValue(improvementId.Key, out var improvementDetails)) continue; if (improvementDetails.Completed == false && improvementDetails.ImproveCompleteTimestamp < _timeUtil.GetTimeStamp() ) - { improvementDetails.Completed = true; - } } } @@ -1411,9 +1294,10 @@ public class HideoutHelper( .Areas.FirstOrDefault((area) => area.Type == HideoutAreas.PLACE_OF_FAME); // Get SkillGroupLevelingBoost object - var combatBoostBonusDb = fameAreaDb.Stages[fameAreaProfile.Level.ToString()].Bonuses.FirstOrDefault( - (bonus) => bonus.Type.ToString() == "SkillGroupLevelingBoost" - ); + var combatBoostBonusDb = fameAreaDb.Stages[fameAreaProfile.Level.ToString()] + .Bonuses.FirstOrDefault( + (bonus) => bonus.Type.ToString() == "SkillGroupLevelingBoost" + ); // Get SkillGroupLevelingBoost object in profile var combatBonusProfile = pmcData.Bonuses.FirstOrDefault((bonus) => bonus.Id == combatBoostBonusDb.Id); @@ -1425,10 +1309,10 @@ public class HideoutHelper( var hideoutManagementSkill = _profileHelper.GetSkillFromProfile(pmcData, SkillTypes.HideoutManagement); var hideoutManagementSkillBonusPercent = 1 + hideoutManagementSkill.Progress / 10000; // 5100 becomes 0.51, add 1 to it, 1.51 var bonus = - GetDogtagCombatSkillBonusPercent(pmcData, activeDogtags) * hideoutManagementSkillBonusPercent; + GetDogtagCombatSkillBonusPercent(pmcData, activeDogtags) * hideoutManagementSkillBonusPercent; // Update bonus value to above calcualted value - combatBonusProfile.Value = Math.Round((bonus ?? 0), 2); + combatBonusProfile.Value = Math.Round(bonus ?? 0, 2); } /// @@ -1443,16 +1327,13 @@ public class HideoutHelper( // Not own dogtag // Side = opposite of player var result = 0D; - foreach (var dogtag in activeDogtags) { - if (dogtag.Upd.Dogtag is null) { - continue; - } + foreach (var dogtag in activeDogtags) + { + if (dogtag.Upd.Dogtag is null) continue; - if (int.Parse(dogtag.Upd.Dogtag?.AccountId) == pmcData.Aid) { - continue; - } + if (int.Parse(dogtag.Upd.Dogtag?.AccountId) == pmcData.Aid) continue; - result += (0.01 * dogtag.Upd.Dogtag.Level) ?? 0; + result += 0.01 * dogtag.Upd.Dogtag.Level ?? 0; } return result; @@ -1471,14 +1352,9 @@ public class HideoutHelper( // Get all bonus Ids that the wall adds List bonusIdsToRemove = []; - foreach (var bonus in wallBonuses) { - bonusIdsToRemove.Add(bonus.Id); - } + foreach (var bonus in wallBonuses) bonusIdsToRemove.Add(bonus.Id); - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Removing: {bonusIdsToRemove.Count} bonuses from profile"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Removing: {bonusIdsToRemove.Count} bonuses from profile"); // Remove the wall bonuses from profile by id pmcData.Bonuses = pmcData.Bonuses.Where((bonus) => !bonusIdsToRemove.Contains(bonus.Id)).ToList(); diff --git a/Libraries/Core/Helpers/HttpServerHelper.cs b/Libraries/Core/Helpers/HttpServerHelper.cs index 5541aa86..eb6ce1c8 100644 --- a/Libraries/Core/Helpers/HttpServerHelper.cs +++ b/Libraries/Core/Helpers/HttpServerHelper.cs @@ -46,7 +46,7 @@ public class HttpServerHelper(ConfigServer configServer) } /** Get websocket url + port */ - public string GetWebsocketUrl() + public string GetWebsocketUrl() { return $"ws://{BuildUrl()}"; } diff --git a/Libraries/Core/Helpers/InRaidHelper.cs b/Libraries/Core/Helpers/InRaidHelper.cs index b4c1153a..a3aee68a 100644 --- a/Libraries/Core/Helpers/InRaidHelper.cs +++ b/Libraries/Core/Helpers/InRaidHelper.cs @@ -18,8 +18,8 @@ public class InRaidHelper( DatabaseService _databaseService ) { - protected LostOnDeathConfig _lostOnDeathConfig = _configServer.GetConfig(); protected InRaidConfig _inRaidConfig = _configServer.GetConfig(); + protected LostOnDeathConfig _lostOnDeathConfig = _configServer.GetConfig(); protected List _pocketSlots = ["pocket1", "pocket2", "pocket3", "pocket4"]; /// @@ -28,10 +28,7 @@ public class InRaidHelper( /// Profile to update protected void ResetSkillPointsEarnedDuringRaid(PmcData profile) { - foreach (var skill in profile.Skills.Common) - { - skill.PointsEarnedDuringSession = 0.0; - } + foreach (var skill in profile.Skills.Common) skill.PointsEarnedDuringSession = 0.0; } /// @@ -75,10 +72,7 @@ public class InRaidHelper( // Handle Removing of FIR status if player did not survive + not transferring // Do after above filtering code to reduce work done - if (!isSurvived && !isTransfer && !_inRaidConfig.AlwaysKeepFoundInRaidOnRaidEnd) - { - RemoveFiRStatusFromCertainItems(postRaidProfile.Inventory.Items); - } + if (!isSurvived && !isTransfer && !_inRaidConfig.AlwaysKeepFoundInRaidOnRaidEnd) RemoveFiRStatusFromCertainItems(postRaidProfile.Inventory.Items); // Add items from client profile into server profile AddItemsToInventory(postRaidInventoryItems, serverProfile.Inventory.Items); @@ -102,24 +96,18 @@ public class InRaidHelper( item => { // Has upd object + upd.SpawnedInSession property + not a quest item - return ( - (item.Upd?.SpawnedInSession ?? false) && - !(dbItems[item.Template].Properties.QuestItem ?? false) && - !( - _inRaidConfig.KeepFiRSecureContainerOnDeath && - _itemHelper.ItemIsInsideContainer(item, "SecuredContainer", items) - ) - ); + return (item.Upd?.SpawnedInSession ?? false) && + !(dbItems[item.Template].Properties.QuestItem ?? false) && + !( + _inRaidConfig.KeepFiRSecureContainerOnDeath && + _itemHelper.ItemIsInsideContainer(item, "SecuredContainer", items) + ); } ); foreach (var item in itemsToRemovePropertyFrom) - { if (item.Upd is not null) - { item.Upd.SpawnedInSession = false; - } - } } /// @@ -160,10 +148,8 @@ public class InRaidHelper( // Get inventory item ids to remove from players profile var itemIdsToDeleteFromProfile = GetInventoryItemsLostOnDeath(pmcData).Select(item => item.Id); foreach (var itemIdToDelete in itemIdsToDeleteFromProfile) - { // Items inside containers are handled as part of function _inventoryHelper.RemoveItem(pmcData, itemIdToDelete, sessionId); - } // Remove contents of fast panel pmcData.Inventory.FastPanel = new Dictionary(); @@ -180,27 +166,16 @@ public class InRaidHelper( PmcData pmcData, string secureContainerSlotId) { - if (!pmcData.Inventory.Items.Any(item => item.SlotId == secureContainerSlotId)) - { - return; - } + if (!pmcData.Inventory.Items.Any(item => item.SlotId == secureContainerSlotId)) return; List itemsInsideContainer = []; foreach (var inventoryItem in pmcData.Inventory.Items.Where(item => item.Upd is not null && item.SlotId != "hideout")) - { if (_itemHelper.ItemIsInsideContainer(inventoryItem, secureContainerSlotId, pmcData.Inventory.Items)) - { itemsInsideContainer.Add(inventoryItem); - } - } foreach (var item in itemsInsideContainer) - { if (item.Upd.SpawnedInSession ?? false) - { item.Upd.SpawnedInSession = false; - } - } } /// @@ -214,28 +189,27 @@ public class InRaidHelper( var equipmentRootId = pmcProfile?.Inventory?.Equipment; var questRaidItemContainerId = pmcProfile?.Inventory?.QuestRaidItems; - return inventoryItems.Where(item => { - // Keep items flagged as kept after death - if (IsItemKeptAfterDeath(pmcProfile, item)) { - return false; - } + return inventoryItems.Where( + item => + { + // Keep items flagged as kept after death + if (IsItemKeptAfterDeath(pmcProfile, item)) return false; - // Remove normal items or quest raid items - if (item.ParentId == equipmentRootId || item.ParentId == questRaidItemContainerId) { - return true; - } + // Remove normal items or quest raid items + if (item.ParentId == equipmentRootId || item.ParentId == questRaidItemContainerId) return true; - // Pocket items are lost on death - // Ensure we dont pick up pocket items from manniquins - if ( - item.SlotId.StartsWith("pocket") && - _inventoryHelper.DoesItemHaveRootId(pmcProfile, item, pmcProfile.Inventory.Equipment) - ) { - return true; - } + // Pocket items are lost on death + // Ensure we dont pick up pocket items from manniquins + if ( + item.SlotId.StartsWith("pocket") && + _inventoryHelper.DoesItemHaveRootId(pmcProfile, item, pmcProfile.Inventory.Equipment) + ) + return true; - return false; - }).ToList(); + return false; + } + ) + .ToList(); } /// @@ -247,36 +221,28 @@ public class InRaidHelper( protected bool IsItemKeptAfterDeath(PmcData pmcData, Item itemToCheck) { // Base inventory items are always kept - if (itemToCheck.ParentId is null) { - return true; - } + if (itemToCheck.ParentId is null) return true; // Is item equipped on player - if (itemToCheck.ParentId == pmcData.Inventory.Equipment) { + if (itemToCheck.ParentId == pmcData.Inventory.Equipment) + { // Check slot id against config, true = delete, false = keep, undefined = delete - bool discard = _lostOnDeathConfig.Equipment.GetByJsonProp(itemToCheck.SlotId); - if (discard) { + var discard = _lostOnDeathConfig.Equipment.GetByJsonProp(itemToCheck.SlotId); + if (discard) // Lost on death return false; - } return true; } // Should we keep items in pockets on death - if (!_lostOnDeathConfig.Equipment.PocketItems && _pocketSlots.Contains(itemToCheck.SlotId)) { - return true; - } + if (!_lostOnDeathConfig.Equipment.PocketItems && _pocketSlots.Contains(itemToCheck.SlotId)) return true; // Is quest item + quest item not lost on death - if (itemToCheck.ParentId == pmcData.Inventory.QuestRaidItems && !_lostOnDeathConfig.QuestItems) { - return true; - } + if (itemToCheck.ParentId == pmcData.Inventory.QuestRaidItems && !_lostOnDeathConfig.QuestItems) return true; // special slots are always kept after death - if ((itemToCheck.SlotId?.Contains("SpecialSlot") ?? false) && _lostOnDeathConfig.SpecialSlotItems) { - return true; - } + if ((itemToCheck.SlotId?.Contains("SpecialSlot") ?? false) && _lostOnDeathConfig.SpecialSlotItems) return true; // All other cases item is lost return false; diff --git a/Libraries/Core/Helpers/InventoryHelper.cs b/Libraries/Core/Helpers/InventoryHelper.cs index 86503926..c3b32657 100644 --- a/Libraries/Core/Helpers/InventoryHelper.cs +++ b/Libraries/Core/Helpers/InventoryHelper.cs @@ -41,7 +41,7 @@ public class InventoryHelper( protected InventoryConfig _inventoryConfig = _configServer.GetConfig(); // Item types to ignore inside `GetSizeByInventoryItemHash` - List _itemBaseTypesToIgnore = [BaseClasses.BACKPACK, BaseClasses.SEARCHABLE_ITEM, BaseClasses.SIMPLE_CONTAINER]; + private List _itemBaseTypesToIgnore = [BaseClasses.BACKPACK, BaseClasses.SEARCHABLE_ITEM, BaseClasses.SIMPLE_CONTAINER]; /// /// Add multiple items to player stash (assuming they all fit) @@ -147,17 +147,15 @@ public class InventoryHelper( } // Add item + mods to output and profile inventory - + output.ProfileChanges[sessionId] .Items.NewItems.AddRange(itemWithModsToAddClone); pmcData.Inventory.Items.AddRange(itemWithModsToAddClone); if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug( $"Added {itemWithModsToAddClone[0].Upd?.StackObjectsCount ?? 1} item: {itemWithModsToAddClone[0].Template} with: {itemWithModsToAddClone.Count - 1} mods to inventory" ); - } } /// @@ -452,7 +450,6 @@ public class InventoryHelper( if (itemAndChildrenToRemove.Count == 0) { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug( _localisationService.GetText( "inventory-unable_to_remove_item_id_not_found", @@ -463,7 +460,6 @@ public class InventoryHelper( } ) ); - } return; } @@ -472,10 +468,7 @@ public class InventoryHelper( var insuredItems = profile.InsuredItems; // We have output object, inform client of root item deletion, not children - if (output is not null) - { - output.ProfileChanges[sessionId].Items.DeletedItems.Add( new Item{ Id = itemId }); - } + if (output is not null) output.ProfileChanges[sessionId].Items.DeletedItems.Add(new Item { Id = itemId }); foreach (var item in itemAndChildrenToRemove) { @@ -780,14 +773,10 @@ public class InventoryHelper( { ItemLocation? itemLocation; if (item.Location is JsonElement) - { itemLocation = ((JsonElement)item.Location).ToObject(); - } else - { itemLocation = (ItemLocation)item.Location; - } - + if (itemLocation is null) { // item has no location property @@ -1081,11 +1070,9 @@ public class InventoryHelper( } if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug( $"{moveRequest.Action} item: {moveRequest.Item} from slotid: {matchingInventoryItem.SlotId} to container: {moveRequest.To.Container}" ); - } // Don't move shells from camora to cartridges (happens when loading shells into mts-255 revolver shotgun) if (matchingInventoryItem.SlotId?.Contains("camora_") is null && moveRequest.To.Container == "cartridges") diff --git a/Libraries/Core/Helpers/ItemHelper.cs b/Libraries/Core/Helpers/ItemHelper.cs index 53d08fa9..587e73cf 100644 --- a/Libraries/Core/Helpers/ItemHelper.cs +++ b/Libraries/Core/Helpers/ItemHelper.cs @@ -100,23 +100,14 @@ public class ItemHelper( */ public bool IsSameItems(List item1, List item2, HashSet compareUpdProperties = null) { - if (item1.Count() != item2.Count) - { - return false; - } + if (item1.Count() != item2.Count) return false; foreach (var itemOf1 in item1) { var itemOf2 = item2.FirstOrDefault((i2) => i2.Template == itemOf1.Template); - if (itemOf2 is null) - { - return false; - } + if (itemOf2 is null) return false; - if (!IsSameItem(itemOf1, itemOf2, compareUpdProperties)) - { - return false; - } + if (!IsSameItem(itemOf1, itemOf2, compareUpdProperties)) return false; } return true; @@ -133,28 +124,16 @@ public class ItemHelper( public bool IsSameItem(Item item1, Item item2, HashSet? compareUpdProperties = null) { // Different tpl == different item - if (item1.Template != item2.Template) - { - return false; - } + if (item1.Template != item2.Template) return false; // Both lack upd object + same tpl = same - if (item1.Upd is null && item2.Upd is null) - { - return true; - } + if (item1.Upd is null && item2.Upd is null) return true; // item1 lacks upd, item2 has one - if (item1.Upd is null && item2.Upd is not null) - { - return false; - } + if (item1.Upd is null && item2.Upd is not null) return false; // item1 has upd, item2 lacks one - if (item1.Upd is not null && item2.Upd is null) - { - return false; - } + if (item1.Upd is not null && item2.Upd is null) return false; // key = Upd property Type as string, value = comparison function that returns bool var comparers = new Dictionary> @@ -177,15 +156,10 @@ public class ItemHelper( foreach (var propertyName in valuesToCompare) { if (!comparers.TryGetValue(propertyName, out var comparer)) - { // Key not found, skip continue; - } - if (!comparer(item1.Upd, item2.Upd)) - { - return false; - } + if (!comparer(item1.Upd, item2.Upd)) return false; } return true; @@ -202,65 +176,38 @@ public class ItemHelper( // armors, etc if (itemTemplate.Properties.MaxDurability is not null) - { - itemProperties.Repairable = new() + itemProperties.Repairable = new UpdRepairable { Durability = itemTemplate.Properties.MaxDurability, - MaxDurability = itemTemplate.Properties.MaxDurability, + MaxDurability = itemTemplate.Properties.MaxDurability }; - } - if (itemTemplate.Properties.HasHinge ?? false) - { - itemProperties.Togglable = new() { On = true }; - } + if (itemTemplate.Properties.HasHinge ?? false) itemProperties.Togglable = new UpdTogglable { On = true }; - if (itemTemplate.Properties.Foldable ?? false) - { - itemProperties.Foldable = new() { Folded = false }; - } + if (itemTemplate.Properties.Foldable ?? false) itemProperties.Foldable = new UpdFoldable { Folded = false }; if (itemTemplate.Properties.WeapFireType?.Any() ?? false) { if (itemTemplate.Properties.WeapFireType.Contains("fullauto")) - { - itemProperties.FireMode = new() { FireMode = "fullauto" }; - } + itemProperties.FireMode = new UpdFireMode { FireMode = "fullauto" }; else - { - itemProperties.FireMode = new() { FireMode = _randomUtil.GetArrayValue(itemTemplate.Properties.WeapFireType) }; - } + itemProperties.FireMode = new UpdFireMode { FireMode = _randomUtil.GetArrayValue(itemTemplate.Properties.WeapFireType) }; } - if (itemTemplate.Properties.MaxHpResource is not null) - { - itemProperties.MedKit = new() { HpResource = itemTemplate.Properties.MaxHpResource }; - } + if (itemTemplate.Properties.MaxHpResource is not null) itemProperties.MedKit = new UpdMedKit { HpResource = itemTemplate.Properties.MaxHpResource }; if (itemTemplate.Properties.MaxResource is not null && itemTemplate.Properties.FoodUseTime is not null) - { - itemProperties.FoodDrink = new() { HpPercent = itemTemplate.Properties.MaxResource }; - } + itemProperties.FoodDrink = new UpdFoodDrink { HpPercent = itemTemplate.Properties.MaxResource }; if (itemTemplate.Parent == BaseClasses.FLASHLIGHT) - { - itemProperties.Light = new() { IsActive = false, SelectedMode = 0 }; - } - else if (itemTemplate.Parent == BaseClasses.TACTICAL_COMBO) - { - itemProperties.Light = new() { IsActive = false, SelectedMode = 0 }; - } + itemProperties.Light = new UpdLight { IsActive = false, SelectedMode = 0 }; + else if (itemTemplate.Parent == BaseClasses.TACTICAL_COMBO) itemProperties.Light = new UpdLight { IsActive = false, SelectedMode = 0 }; - if (itemTemplate.Parent == BaseClasses.NIGHTVISION) - { - itemProperties.Togglable = new() { On = false }; - } + if (itemTemplate.Parent == BaseClasses.NIGHTVISION) itemProperties.Togglable = new UpdTogglable { On = false }; // Togglable face shield if ((itemTemplate.Properties.HasHinge ?? false) && (itemTemplate.Properties.FaceShieldComponent ?? false)) - { - itemProperties.Togglable = new() { On = false }; - } + itemProperties.Togglable = new UpdTogglable { On = false }; return itemProperties; } @@ -281,18 +228,13 @@ public class ItemHelper( var baseTypes = invalidBaseTypes ?? _defaultInvalidBaseTypes; var itemDetails = GetItem(tpl); - if (!itemDetails.Key) - { - return false; - } + if (!itemDetails.Key) return false; - return ( - !(itemDetails.Value.Properties.QuestItem ?? false) && - itemDetails.Value.Type == "Item" && - baseTypes.All((x) => !IsOfBaseclass(tpl, x)) && - GetItemPrice(tpl) > 0 && - !_itemFilterService.IsItemBlacklisted(tpl) - ); + return !(itemDetails.Value.Properties.QuestItem ?? false) && + itemDetails.Value.Type == "Item" && + baseTypes.All((x) => !IsOfBaseclass(tpl, x)) && + GetItemPrice(tpl) > 0 && + !_itemFilterService.IsItemBlacklisted(tpl); } // Check if the tpl / template Id provided is a descendent of the baseclass @@ -329,10 +271,7 @@ public class ItemHelper( // @returns True if item needs some kind of insert public bool ArmorItemHasRemovableOrSoftInsertSlots(string itemTpl) { - if (!ArmorItemCanHoldMods(itemTpl)) - { - return false; - } + if (!ArmorItemCanHoldMods(itemTpl)) return false; return ArmorItemHasRemovablePlateSlots(itemTpl) || ItemRequiresSoftInserts(itemTpl); } @@ -354,30 +293,18 @@ public class ItemHelper( public bool ItemRequiresSoftInserts(string itemTpl) { // not a slot that takes soft-inserts - if (!ArmorItemCanHoldMods(itemTpl)) - { - return false; - } + if (!ArmorItemCanHoldMods(itemTpl)) return false; // Check is an item var itemDbDetails = GetItem(itemTpl); - if (!itemDbDetails.Key) - { - return false; - } + if (!itemDbDetails.Key) return false; // Has no slots - if (!(itemDbDetails.Value.Properties.Slots ?? []).Any()) - { - return false; - } + if (!(itemDbDetails.Value.Properties.Slots ?? []).Any()) return false; // Check if item has slots that match soft insert name ids var softInsertIds = GetSoftInsertSlotIds(); - if (itemDbDetails.Value.Properties.Slots.Any((slot) => softInsertIds.Contains(slot.Name.ToLower()))) - { - return true; - } + if (itemDbDetails.Value.Properties.Slots.Any((slot) => softInsertIds.Contains(slot.Name.ToLower()))) return true; return false; } @@ -401,7 +328,7 @@ public class ItemHelper( "helmet_back", "helmet_eyes", "helmet_jaw", - "helmet_ears", + "helmet_ears" ]; } @@ -424,10 +351,7 @@ public class ItemHelper( public double? GetItemPrice(string tpl) { var handbookPrice = GetStaticItemPrice(tpl); - if (handbookPrice >= 1) - { - return handbookPrice; - } + if (handbookPrice >= 1) return handbookPrice; return GetDynamicItemPrice(tpl); } @@ -454,10 +378,7 @@ public class ItemHelper( public double GetStaticItemPrice(string tpl) { var handbookPrice = _handbookHelper.GetTemplatePrice(tpl); - if (handbookPrice >= 1) - { - return handbookPrice; - } + if (handbookPrice >= 1) return handbookPrice; return 0; } @@ -469,10 +390,7 @@ public class ItemHelper( /// Price in roubles (undefined if not found) public double? GetDynamicItemPrice(string tpl) { - if (_databaseService.GetPrices().TryGetValue(tpl, out var price)) - { - return price; - } + if (_databaseService.GetPrices().TryGetValue(tpl, out var price)) return price; return null; } @@ -485,7 +403,7 @@ public class ItemHelper( public Item FixItemStackCount(Item item) { // Ensure item has 'Upd' object - item.Upd ??= new() { StackObjectsCount = 1 }; + item.Upd ??= new Upd { StackObjectsCount = 1 }; // Ensure item has 'StackObjectsCount' property item.Upd.StackObjectsCount ??= 1; @@ -510,12 +428,9 @@ public class ItemHelper( public KeyValuePair GetItem(string itemTpl) { // -> Gets item from - if (_databaseService.GetItems().TryGetValue(itemTpl, out var item)) - { - return new(true, item); - } + if (_databaseService.GetItems().TryGetValue(itemTpl, out var item)) return new KeyValuePair(true, item); - return new(false, null); + return new KeyValuePair(false, null); } /** @@ -525,10 +440,7 @@ public class ItemHelper( */ public bool ItemHasSlots(string itemTpl) { - if (_databaseService.GetItems().TryGetValue(itemTpl, out var item)) - { - return GetItem(itemTpl).Value.Properties?.Slots?.Count() > 0; - } + if (_databaseService.GetItems().TryGetValue(itemTpl, out var item)) return GetItem(itemTpl).Value.Properties?.Slots?.Count() > 0; return false; } @@ -551,30 +463,22 @@ public class ItemHelper( */ public double GetItemQualityModifierForItems(List itemWithChildren, bool skipArmorItemsWithoutDurability = false) { - if (IsOfBaseclass(itemWithChildren[0].Template, BaseClasses.WEAPON)) - { - return Math.Round(GetItemQualityModifier(itemWithChildren[0]), 5); - } + if (IsOfBaseclass(itemWithChildren[0].Template, BaseClasses.WEAPON)) return Math.Round(GetItemQualityModifier(itemWithChildren[0]), 5); var qualityModifier = 0D; var itemsWithQualityCount = 0D; foreach (var item in itemWithChildren) { var result = GetItemQualityModifier(item, skipArmorItemsWithoutDurability); - if (result == -1) - { - continue; - } + if (result == -1) continue; qualityModifier += result; itemsWithQualityCount++; } if (itemsWithQualityCount == 0) - { // Can happen when rigs without soft inserts or plates are listed return 1; - } return Math.Min(Math.Round(qualityModifier / itemsWithQualityCount, 5), 1); } @@ -600,13 +504,9 @@ public class ItemHelper( return 1; } - if (skipArmorItemsWithoutDurability - && IsOfBaseclass(item.Template, BaseClasses.ARMOR) - && itemDetails?.Properties?.MaxDurability == 0 + if (skipArmorItemsWithoutDurability && IsOfBaseclass(item.Template, BaseClasses.ARMOR) && itemDetails?.Properties?.MaxDurability == 0 ) - { return -1; - } if (item.Upd is not null) { @@ -640,10 +540,8 @@ public class ItemHelper( } if (result == 0) - { // make item non-zero but still very low result = 0.01; - } return result; } @@ -694,12 +592,8 @@ public class ItemHelper( List list = []; foreach (var childitem in items) - { if (childitem.ParentId == baseItemId) - { list.AddRange(FindAndReturnChildrenByItems(items, childitem.Id)); - } - } list.Add(baseItemId); // Required, push original item id onto array @@ -726,16 +620,11 @@ public class ItemHelper( } // Is stored in parent and disallowed - if (modsOnly && childItem.Location is not null) - { - continue; - } + if (modsOnly && childItem.Location is not null) continue; // Items parentid matches root item AND returned items doesnt contain current child if (childItem.ParentId == baseItemId && !list.Any((item) => childItem.Id == item.Id)) - { list.AddRange(FindAndReturnChildrenAsItems(items, childItem.Id)); - } } return list; @@ -752,14 +641,12 @@ public class ItemHelper( List list = []; foreach (var itemFromAssort in assort) - { // Parent matches desired item + all items in list do not match if (itemFromAssort.ParentId == itemIdToFind && list.All(item => itemFromAssort.Id != item.Id)) { list.Add(itemFromAssort); list = list.Concat(FindAndReturnChildrenByAssort(itemFromAssort.Id, assort)).ToList(); } - } return list; } @@ -771,10 +658,7 @@ public class ItemHelper( */ public bool HasBuyRestrictions(Item itemToCheck) { - if (itemToCheck.Upd?.BuyRestrictionCurrent is not null && itemToCheck.Upd?.BuyRestrictionMax is not null) - { - return true; - } + if (itemToCheck.Upd?.BuyRestrictionCurrent is not null && itemToCheck.Upd?.BuyRestrictionMax is not null) return true; return false; } @@ -810,10 +694,7 @@ public class ItemHelper( /// SlotId OR slotid, locationX, locationY. public string GetChildId(Item item) { - if (item.Location is null) - { - return item.SlotId; - } + if (item.Location is null) return item.SlotId; var LocationTyped = (ItemLocation)item.Location; @@ -827,10 +708,7 @@ public class ItemHelper( /// True if it can be stacked. public bool? IsItemTplStackable(string tpl) { - if (!_databaseService.GetItems().TryGetValue(tpl, out var item)) - { - return null; - } + if (!_databaseService.GetItems().TryGetValue(tpl, out var item)) return null; return item.Properties.StackMaxSize > 1; } @@ -842,10 +720,7 @@ public class ItemHelper( /// List of root item + children. public List SplitStack(Item itemToSplit) { - if (itemToSplit?.Upd?.StackObjectsCount is null) - { - return [itemToSplit]; - } + if (itemToSplit?.Upd?.StackObjectsCount is null) return [itemToSplit]; var maxStackSize = GetItem(itemToSplit.Template).Value.Properties.StackMaxSize; var remainingCount = itemToSplit.Upd.StackObjectsCount; @@ -885,10 +760,7 @@ public class ItemHelper( var itemMaxStackSize = itemTemplate.Properties.StackMaxSize ?? 1; // item already within bounds of stack size, return it - if (itemToSplit.Upd?.StackObjectsCount <= itemMaxStackSize) - { - return [[itemToSplit]]; - } + if (itemToSplit.Upd?.StackObjectsCount <= itemMaxStackSize) return [[itemToSplit]]; // Split items stack into chunks List> result = []; @@ -928,10 +800,7 @@ public class ItemHelper( matchingItems.AddRange(filterResult); } - if (matchingItems.Count == 0) - { - _logger.Warning($"No items found for barter Id: {desiredBarterIds}"); - } + if (matchingItems.Count == 0) _logger.Warning($"No items found for barter Id: {desiredBarterIds}"); return matchingItems; } @@ -952,12 +821,8 @@ public class ItemHelper( // Update all parentIds of items attached to base item to use new id foreach (var item in itemWithChildren) - { if (item.ParentId == oldId) - { item.ParentId = newId; - } - } } public void ReplaceProfileInventoryIds(BotBaseInventory inventory, List? insuredItems = null) @@ -965,29 +830,25 @@ public class ItemHelper( // Blacklist var itemIdBlacklist = new HashSet(); itemIdBlacklist.UnionWith( - new List{ + new List + { inventory.Equipment, inventory.QuestRaidItems, inventory.QuestStashItems, inventory.SortingTable, inventory.Stash, inventory.HideoutCustomizationStashId - }); + } + ); itemIdBlacklist.UnionWith(inventory.HideoutAreaStashes.Values); // Add insured items ids to blacklist - if (insuredItems is not null) - { - itemIdBlacklist.UnionWith(insuredItems.Select(x => x.ItemId)); - } + if (insuredItems is not null) itemIdBlacklist.UnionWith(insuredItems.Select(x => x.ItemId)); foreach (var item in inventory.Items) { - if (itemIdBlacklist.Contains(item.Id)) - { - continue; - } + if (itemIdBlacklist.Contains(item.Id)) continue; // Generate new id var newId = _hashUtil.Generate(); @@ -1000,22 +861,13 @@ public class ItemHelper( // Find all children of item and update their parent ids to match var childItems = inventory.Items.Where(x => x.ParentId == originalId); - foreach (var childItem in childItems) - { - childItem.ParentId = newId; - } + foreach (var childItem in childItems) childItem.ParentId = newId; // Also replace in quick slot if the old ID exists. - if (inventory.FastPanel is null) - { - continue; - } + if (inventory.FastPanel is null) continue; // Update quickslot id - if (inventory.FastPanel.ContainsKey(originalId)) - { - inventory.FastPanel[originalId] = newId; - } + if (inventory.FastPanel.ContainsKey(originalId)) inventory.FastPanel[originalId] = newId; } } @@ -1023,7 +875,6 @@ public class ItemHelper( { foreach (var item in items) { - // Generate new id var newId = _hashUtil.Generate(); @@ -1035,10 +886,7 @@ public class ItemHelper( // Find all children of item and update their parent ids to match var childItems = items.Where(x => x.ParentId == originalId); - foreach (var childItem in childItems) - { - childItem.ParentId = newId; - } + foreach (var childItem in childItems) childItem.ParentId = newId; } return items; @@ -1065,31 +913,27 @@ public class ItemHelper( if (pmcData != null) { itemIdBlacklist.UnionWith( - new List{ + new List + { pmcData.Inventory.Equipment, pmcData.Inventory.QuestRaidItems, pmcData.Inventory.QuestStashItems, pmcData.Inventory.SortingTable, pmcData.Inventory.Stash, pmcData.Inventory.HideoutCustomizationStashId - }); + } + ); itemIdBlacklist.UnionWith(pmcData.Inventory.HideoutAreaStashes.Keys); } - + // Add insured items ids to blacklist - if (insuredItems is not null) - { - itemIdBlacklist.UnionWith(insuredItems.Select(x => x.ItemId)); - } + if (insuredItems is not null) itemIdBlacklist.UnionWith(insuredItems.Select(x => x.ItemId)); foreach (var item in originalItems) { - if (itemIdBlacklist.Contains(item.Id)) - { - continue; - } + if (itemIdBlacklist.Contains(item.Id)) continue; // Generate new id var newId = _hashUtil.Generate(); @@ -1102,22 +946,13 @@ public class ItemHelper( // Find all children of item and update their parent ids to match var childItems = originalItems.Where(x => x.ParentId == originalId); - foreach (var childItem in childItems) - { - childItem.ParentId = newId; - } + foreach (var childItem in childItems) childItem.ParentId = newId; // Also replace in quick slot if the old ID exists. - if (pmcData.Inventory.FastPanel is null) - { - continue; - } + if (pmcData.Inventory.FastPanel is null) continue; // Update quickslot id - if (pmcData.Inventory.FastPanel.ContainsKey(originalId)) - { - pmcData.Inventory.FastPanel[originalId] = newId; - } + if (pmcData.Inventory.FastPanel.ContainsKey(originalId)) pmcData.Inventory.FastPanel[originalId] = newId; } return originalItems; @@ -1133,11 +968,8 @@ public class ItemHelper( { foreach (var item in items) { - if (excludeCurrency && IsOfBaseclass(item.Template, BaseClasses.MONEY)) - { - continue; - } - item.Upd ??= new(); + if (excludeCurrency && IsOfBaseclass(item.Template, BaseClasses.MONEY)) continue; + item.Upd ??= new Upd(); item.Upd.SpawnedInSession = true; } } @@ -1150,12 +982,9 @@ public class ItemHelper( /// Skip adding FiR status to currency items public void SetFoundInRaid(Item item, bool excludeCurrency = true) { - if (excludeCurrency && IsOfBaseclass(item.Template, BaseClasses.MONEY)) - { - return; - } + if (excludeCurrency && IsOfBaseclass(item.Template, BaseClasses.MONEY)) return; - item.Upd ??= new(); + item.Upd ??= new Upd(); item.Upd.SpawnedInSession = true; } @@ -1278,7 +1107,7 @@ public class ItemHelper( { List check = ["hideout", "main"]; - return !(check.Contains(item.SlotId) || _slotsAsStrings.Contains(item.SlotId) || !int.TryParse(item.SlotId, out var _)); + return !(check.Contains(item.SlotId) || _slotsAsStrings.Contains(item.SlotId) || !int.TryParse(item.SlotId, out _)); } /** @@ -1303,10 +1132,7 @@ public class ItemHelper( while (currentItem is not null && !_slotsAsStrings.Contains(currentItem.SlotId)) { currentItem = itemsMap.GetValueOrDefault(currentItem.ParentId); - if (currentItem is null) - { - return null; - } + if (currentItem is null) return null; } return currentItem; @@ -1356,10 +1182,10 @@ public class ItemHelper( } } - return new() + return new ItemSize { Width = width ?? 0 + sizeLeft + sizeRight + forcedLeft + forcedRight, - Height = height ?? 0 + sizeUp + sizeDown + forcedUp + forcedDown, + Height = height ?? 0 + sizeUp + sizeDown + forcedUp + forcedDown }; } @@ -1394,10 +1220,7 @@ public class ItemHelper( var cartridgeMaxStackSize = cartridgeDetails.Value.Properties.StackMaxSize; // Exit if ammo already exists in box - if (ammoBox.Any((item) => item.Template == cartridgeTpl)) - { - return; - } + if (ammoBox.Any((item) => item.Template == cartridgeTpl)) return; // Add new stack-size-correct items to ammo box double? currentStoredCartridgeCount = 0; @@ -1420,10 +1243,7 @@ public class ItemHelper( ); // In live no ammo box has the first cartridge item with a location - if (location == 0) - { - cartridgeItemToAdd.Location = null; - } + if (location == 0) cartridgeItemToAdd.Location = null; ammoBox.Add(cartridgeItemToAdd); @@ -1464,15 +1284,10 @@ public class ItemHelper( // Get items parent var parent = items.FirstOrDefault((item) => item.Id == itemToCheck.ParentId); if (parent is null) - { // No parent, end of line, not inside container return false; - } - if (parent.SlotId == desiredContainerSlotId) - { - return true; - } + if (parent.SlotId == desiredContainerSlotId) return true; return ItemIsInsideContainer(parent, desiredContainerSlotId, items); } @@ -1499,24 +1314,19 @@ public class ItemHelper( var chosenCaliber = caliber ?? GetRandomValidCaliber(magTemplate); // Edge case for the Klin pp-9, it has a typo in its ammo caliber - if (chosenCaliber == "Caliber9x18PMM") - { - chosenCaliber = "Caliber9x18PM"; - } + if (chosenCaliber == "Caliber9x18PMM") chosenCaliber = "Caliber9x18PM"; // Chose a randomly weighted cartridge that fits var cartridgeTpl = DrawAmmoTpl( chosenCaliber, staticAmmoDist, defaultCartridgeTpl, - (weapon?.Properties?.Chambers?.FirstOrDefault()?.Props?.Filters?.FirstOrDefault()?.Filter) ?? null + weapon?.Properties?.Chambers?.FirstOrDefault()?.Props?.Filters?.FirstOrDefault()?.Filter ?? null ); if (cartridgeTpl is null) { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug($"Unable to fill item: {magazine.FirstOrDefault().Id} {magTemplate.Name} with cartridges, none found."); - } return; } @@ -1540,23 +1350,15 @@ public class ItemHelper( { var isUBGL = IsOfBaseclass(magTemplate.Id, BaseClasses.UBGL); if (isUBGL) - { // UBGL don't have mags return; - } // Get cartridge properties and max allowed stack size var cartridgeDetails = GetItem(cartridgeTpl); - if (!cartridgeDetails.Key) - { - _logger.Error(_localisationService.GetText("item-invalid_tpl_item", cartridgeTpl)); - } + if (!cartridgeDetails.Key) _logger.Error(_localisationService.GetText("item-invalid_tpl_item", cartridgeTpl)); var cartridgeMaxStackSize = cartridgeDetails.Value?.Properties?.StackMaxSize; - if (cartridgeMaxStackSize is null) - { - _logger.Error($"Item with tpl: {cartridgeTpl} lacks a _props or StackMaxSize property"); - } + if (cartridgeMaxStackSize is null) _logger.Error($"Item with tpl: {cartridgeTpl} lacks a _props or StackMaxSize property"); // Get max number of cartridges in magazine, choose random value between min/max var magProps = magTemplate.Properties; @@ -1577,10 +1379,7 @@ public class ItemHelper( (int)magazineCartridgeMaxCount ); - if (magazineWithChildCartridges.Count() > 1) - { - _logger.Warning($"Magazine {magTemplate.Name} already has cartridges defined, this may cause issues"); - } + if (magazineWithChildCartridges.Count() > 1) _logger.Warning($"Magazine {magTemplate.Name} already has cartridges defined, this may cause issues"); // Loop over cartridge count and add stacks to magazine double? currentStoredCartridgeCount = 0; @@ -1593,10 +1392,7 @@ public class ItemHelper( // Ensure we don't go over the max stackCount size var remainingSpace = desiredStackCount - currentStoredCartridgeCount; - if (cartridgeCountToAdd > remainingSpace) - { - cartridgeCountToAdd = (int)remainingSpace; - } + if (cartridgeCountToAdd > remainingSpace) cartridgeCountToAdd = (int)remainingSpace; // Add cartridge item object into items array magazineWithChildCartridges.Add( @@ -1614,10 +1410,7 @@ public class ItemHelper( } // Only one cartridge stack added, remove location property as it's only used for 2 or more stacks - if (location == 1) - { - magazineWithChildCartridges[1].Location = null; - } + if (location == 1) magazineWithChildCartridges[1].Location = null; } /// @@ -1667,13 +1460,12 @@ public class ItemHelper( } var ammoArray = new ProbabilityObjectArray(_mathUtil, _cloner); - foreach (var icd in ammos) { + foreach (var icd in ammos) + { // Whitelist exists and tpl not inside it, skip // Fixes 9x18mm kedr issues - if (cartridgeWhitelist is not null && !cartridgeWhitelist.Contains(icd.Tpl)) { - continue; - } - + if (cartridgeWhitelist is not null && !cartridgeWhitelist.Contains(icd.Tpl)) continue; + ammoArray.Add(new ProbabilityObject(icd.Tpl, (double)icd.RelativeProbability, null)); } @@ -1697,14 +1489,14 @@ public class ItemHelper( bool foundInRaid = false ) { - return new() + return new Item { Id = _hashUtil.Generate(), Template = ammoTpl!, ParentId = parentId, SlotId = "cartridges", Location = location, - Upd = new() { StackObjectsCount = stackCount, SpawnedInSession = foundInRaid }, + Upd = new Upd { StackObjectsCount = stackCount, SpawnedInSession = foundInRaid } }; } @@ -1715,10 +1507,7 @@ public class ItemHelper( /// size of stack public int GetItemStackSize(Item item) { - if (item.Upd?.StackObjectsCount is not null) - { - return (int)item.Upd.StackObjectsCount; - } + if (item.Upd?.StackObjectsCount is not null) return (int)item.Upd.StackObjectsCount; return 1; } @@ -1732,10 +1521,7 @@ public class ItemHelper( { var localeDb = _localeService.GetLocaleDb(); var result = localeDb[$"{itemTpl} Name"]; - if (result?.Length > 0) - { - return result; - } + if (result?.Length > 0) return result; return localeDb[$"{itemTpl} ShortName"]; } @@ -1782,23 +1568,17 @@ public class ItemHelper( // only roll chance to not include mod if dict exists and has value for this mod type (e.g. front_plate) var modSpawnChance = modSpawnChanceDict[slot.Name.ToLower()]; if (modSpawnChance is not null) - { if (!_randomUtil.GetChance100(modSpawnChance ?? 0)) - { continue; - } - } } var itemPool = slot.Props.Filters[0].Filter ?? []; if (itemPool.Count() == 0) { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug( $"Unable to choose a mod for slot: {slot.Name} on item: {itemToAddTemplate.Id} {itemToAddTemplate.Name}, parents' 'Filter' array is empty, skipping" ); - } continue; } @@ -1807,11 +1587,9 @@ public class ItemHelper( if (chosenTpl is null) { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug( $"Unable to choose a mod for slot: {slot.Name} on item: {itemToAddTemplate.Id} {itemToAddTemplate.Name}, no compatible tpl found in pool of {itemPool.Count()}, skipping" ); - } continue; } @@ -1822,7 +1600,7 @@ public class ItemHelper( Id = _hashUtil.Generate(), Template = chosenTpl, ParentId = result[0].Id, - SlotId = slot.Name, + SlotId = slot.Name }; // Add chosen item to weapon array @@ -1845,10 +1623,7 @@ public class ItemHelper( /// Chosen tpl or undefined public string GetCompatibleTplFromArray(List possibleTpls, HashSet incompatibleModTpls) { - if (!possibleTpls.Any()) - { - return null; - } + if (!possibleTpls.Any()) return null; string? chosenTpl = null; var count = 0; @@ -1860,10 +1635,7 @@ public class ItemHelper( { // Incompatible tpl was chosen, try again count++; - if (count >= possibleTpls.Count) - { - return null; - } + if (count >= possibleTpls.Count) return null; continue; } @@ -1904,30 +1676,20 @@ public class ItemHelper( foreach (var mod in itemWithChildren) { - if (!idMappings.ContainsKey(mod.Id)) - { - idMappings[mod.Id] = _hashUtil.Generate(); - } + if (!idMappings.ContainsKey(mod.Id)) idMappings[mod.Id] = _hashUtil.Generate(); // Has parentId + no remapping exists for its parent if (mod.ParentId is not null && (!idMappings.ContainsKey(mod.ParentId) || idMappings?[mod.ParentId] is null)) - { // Make remapping for items parentId idMappings[mod.ParentId] = _hashUtil.Generate(); - } mod.Id = idMappings[mod.Id]; - if (mod.ParentId is not null) - { - mod.ParentId = idMappings[mod.ParentId]; - } + if (mod.ParentId is not null) mod.ParentId = idMappings[mod.ParentId]; } // Force item's details into first location of presetItems if (itemWithChildren[0].Template != rootItem.Template) - { _logger.Warning($"Reassigning root item from {itemWithChildren[0].Template} to {rootItem.Template}"); - } itemWithChildren[0] = rootItem; @@ -1956,10 +1718,7 @@ public class ItemHelper( } // Child with parent of root, update - if (item.ParentId == rootItemExistingId) - { - item.ParentId = newId; - } + if (item.ParentId == rootItemExistingId) item.ParentId = newId; } return newId; @@ -2010,15 +1769,11 @@ public class ItemHelper( { if (item.Upd is null) { - item.Upd = new(); + item.Upd = new Upd(); if (warningMessageWhenMissing is not null) - { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug(warningMessageWhenMissing); - } - } return true; } @@ -2051,25 +1806,19 @@ public class ItemHelper( { var result = GetItem(tpl); if (!result.Key) - { // Not an item return null; - } var currentItem = result.Value; while (currentItem is not null) { if (currentItem.Type == "Node" && !rootOnly) - { // Hit first base type return currentItem.Id; - } if (currentItem.Parent is null) - { // No parent, reached root return currentItem.Id; - } // Get parent item and start loop again currentItem = GetItem(tpl).Value; @@ -2083,12 +1832,8 @@ public class ItemHelper( public void RemoveSpawnedInSessionPropertyFromItems(List items) { foreach (var item in items) - { if (item.Upd is not null) - { item.Upd.SpawnedInSession = null; - } - } } } diff --git a/Libraries/Core/Helpers/NotificationSendHelper.cs b/Libraries/Core/Helpers/NotificationSendHelper.cs index c7961c8b..b49f66ee 100644 --- a/Libraries/Core/Helpers/NotificationSendHelper.cs +++ b/Libraries/Core/Helpers/NotificationSendHelper.cs @@ -26,13 +26,9 @@ public class NotificationSendHelper( public void SendMessage(string sessionID, WsNotificationEvent notificationMessage) { if (_sptWebSocketConnectionHandler.IsWebSocketConnected(sessionID)) - { _sptWebSocketConnectionHandler.SendMessage(sessionID, notificationMessage); - } else - { _notificationService.Add(sessionID, notificationMessage); - } } /// @@ -51,7 +47,8 @@ public class NotificationSendHelper( var dialog = GetDialog(sessionId, messageType, senderDetails); dialog.New += 1; - Message message = new Message { + var message = new Message + { Id = _hashUtil.Generate(), UserId = dialog.Id, MessageType = messageType, @@ -59,15 +56,16 @@ public class NotificationSendHelper( Text = messageText, HasRewards = null, RewardCollected = null, - Items = null, + Items = null }; dialog.Messages.Add(message); - WsChatMessageReceived notification = new WsChatMessageReceived { + var notification = new WsChatMessageReceived + { EventType = NotificationEventType.new_message, EventIdentifier = message.Id, DialogId = message.UserId, - Message = message, + Message = message }; SendMessage(sessionId, notification); } diff --git a/Libraries/Core/Helpers/NotifierHelper.cs b/Libraries/Core/Helpers/NotifierHelper.cs index fdd3f72b..f7187134 100644 --- a/Libraries/Core/Helpers/NotifierHelper.cs +++ b/Libraries/Core/Helpers/NotifierHelper.cs @@ -7,8 +7,12 @@ namespace Core.Helpers; [Injectable(InjectionType.Singleton)] public class NotifierHelper(HttpServerHelper _httpServerHelper) { - protected WsPing ping = new WsPing(); - public WsNotificationEvent GetDefaultNotification() => ping; + protected WsPing ping = new(); + + public WsNotificationEvent GetDefaultNotification() + { + return ping; + } /** * Create a new notification that displays the "Your offer was sold!" prompt and removes sold offer from "My Offers" on clientside @@ -20,7 +24,8 @@ public class NotifierHelper(HttpServerHelper _httpServerHelper) Message dialogueMessage, MessageContentRagfair ragfairData) { - return new WsRagfairOfferSold{ + return new WsRagfairOfferSold + { EventType = NotificationEventType.RagfairOfferSold, EventIdentifier = dialogueMessage.Id, OfferId = ragfairData.OfferId, @@ -36,11 +41,12 @@ public class NotifierHelper(HttpServerHelper _httpServerHelper) */ public WsChatMessageReceived CreateNewMessageNotification(Message dialogueMessage) { - return new WsChatMessageReceived { + return new WsChatMessageReceived + { EventType = NotificationEventType.new_message, EventIdentifier = dialogueMessage.Id, DialogId = dialogueMessage.UserId, - Message = dialogueMessage, + Message = dialogueMessage }; } diff --git a/Libraries/Core/Helpers/PaymentHelper.cs b/Libraries/Core/Helpers/PaymentHelper.cs index c785a065..176b5dc7 100644 --- a/Libraries/Core/Helpers/PaymentHelper.cs +++ b/Libraries/Core/Helpers/PaymentHelper.cs @@ -8,9 +8,9 @@ namespace Core.Helpers; [Injectable] public class PaymentHelper(ConfigServer _configServer) { + protected bool _addedCustomMoney; protected InventoryConfig _inventoryConfig = _configServer.GetConfig(); protected List _moneyTpls = [Money.DOLLARS, Money.EUROS, Money.ROUBLES, Money.GP]; - protected bool _addedCustomMoney; /// /// Is the passed in tpl money (also checks custom currencies in inventoryConfig.customMoneyTpls) diff --git a/Libraries/Core/Helpers/PresetHelper.cs b/Libraries/Core/Helpers/PresetHelper.cs index 1973b601..5ddbb508 100644 --- a/Libraries/Core/Helpers/PresetHelper.cs +++ b/Libraries/Core/Helpers/PresetHelper.cs @@ -13,12 +13,13 @@ public class PresetHelper( ICloner _cloner ) { + protected Dictionary _defaultEquipmentPresets; + protected Dictionary? _defaultWeaponPresets; + /// /// Preset cache - key = item tpl, value = preset ids /// protected Dictionary> _lookup = new(); - protected Dictionary _defaultEquipmentPresets; - protected Dictionary? _defaultWeaponPresets; public void HydratePresetStore(Dictionary> input) { @@ -112,18 +113,12 @@ public class PresetHelper( public List GetPresets(string templateId) { - if (!HasPreset(templateId)) - { - return []; - } + if (!HasPreset(templateId)) return []; List presets = []; var ids = _lookup[templateId]; - foreach (var id in ids) - { - presets.Add(GetPreset(id)); - } + foreach (var id in ids) presets.Add(GetPreset(id)); return presets; } @@ -135,20 +130,13 @@ public class PresetHelper( */ public Preset? GetDefaultPreset(string templateId) { - if (!HasPreset(templateId)) - { - return null; - } + if (!HasPreset(templateId)) return null; var allPresets = GetPresets(templateId); foreach (var preset in allPresets) - { if (preset.Encyclopedia is not null) - { return preset; - } - } return allPresets[0]; } @@ -160,12 +148,8 @@ public class PresetHelper( var preset = GetPreset(presetId); foreach (var item in preset.Items) - { if (preset.Parent == item.Id) - { return item.Template; - } - } } return ""; diff --git a/Libraries/Core/Helpers/ProfileHelper.cs b/Libraries/Core/Helpers/ProfileHelper.cs index a4088805..302b7f2a 100644 --- a/Libraries/Core/Helpers/ProfileHelper.cs +++ b/Libraries/Core/Helpers/ProfileHelper.cs @@ -27,6 +27,7 @@ public class ProfileHelper( ConfigServer _configServer ) { + protected readonly List gameEditions = ["edge_of_darkness", "unheard_edition"]; protected InventoryConfig _inventoryConfig = _configServer.GetConfig(); /// @@ -87,10 +88,7 @@ public class ProfileHelper( { // Remove `loyaltyLevel` from `TradersInfo`, as otherwise it causes the client to not // properly calculate the player's `loyaltyLevel` - foreach (var trader in clonedProfile.CharacterData.PmcData.TradersInfo.Values) - { - trader.LoyaltyLevel = null; - } + foreach (var trader in clonedProfile.CharacterData.PmcData.TradersInfo.Values) trader.LoyaltyLevel = null; } /// @@ -160,9 +158,7 @@ public class ProfileHelper( if (playerLevel >= expTable.Length) // make sure to not go out of bounds playerLevel = expTable.Length - 1; - for (var i = 0; i < playerLevel; i++) { - exp += expTable[i].Experience; - } + for (var i = 0; i < playerLevel; i++) exp += expTable[i].Experience; return exp; } @@ -182,15 +178,15 @@ public class ProfileHelper( /// Spt public Spt GetDefaultSptDataObject() { - return new() + return new Spt { Version = _watermark.GetVersionTag(true), - Mods = new(), - ReceivedGifts = new(), - BlacklistedItemTemplates = new(), - FreeRepeatableRefreshUsedCount = new(), - Migrations = new(), - CultistRewards = new() + Mods = new List(), + ReceivedGifts = new List(), + BlacklistedItemTemplates = new List(), + FreeRepeatableRefreshUsedCount = new Dictionary(), + Migrations = new Dictionary(), + CultistRewards = new Dictionary() }; } @@ -239,11 +235,11 @@ public class ProfileHelper( /// public SearchFriendResponse? GetChatRoomMemberFromPmcProfile(PmcData pmcProfile) { - return new() + return new SearchFriendResponse { Id = pmcProfile.Id, Aid = pmcProfile.Aid, - Info = new() + Info = new UserDialogDetails { Nickname = pmcProfile.Info.Nickname, Side = pmcProfile.Info.Side, @@ -293,29 +289,30 @@ public class ProfileHelper( /// Default profile Stats object public Stats GetDefaultCounters() { - return new() + return new Stats { - Eft = new() + Eft = new EftStats { - CarriedQuestItems = new(), - DamageHistory = new() { LethalDamagePart = "Head", LethalDamage = null, BodyParts = new() }, - DroppedItems = new(), + CarriedQuestItems = new List(), + DamageHistory = new DamageHistory { LethalDamagePart = "Head", LethalDamage = null, BodyParts = new BodyPartsDamageHistory() }, + DroppedItems = new List(), ExperienceBonusMult = 0, - FoundInRaidItems = new(), + FoundInRaidItems = new List(), LastPlayerState = null, LastSessionDate = 0, - OverallCounters = new() + OverallCounters = new OverallCounters { Items = [] }, - SessionCounters = new(){ + SessionCounters = new SessionCounters + { Items = [] }, SessionExperienceMult = 0, SurvivorClass = "Unknown", TotalInGameTime = 0, TotalSessionExperience = 0, - Victims = new() + Victims = new List() } }; } @@ -362,7 +359,7 @@ public class ProfileHelper( public void FlagGiftReceivedInProfile(string playerId, string giftId, int maxCount) { var profileToUpdate = GetFullProfile(playerId); - profileToUpdate.SptData.ReceivedGifts ??= new(); + profileToUpdate.SptData.ReceivedGifts ??= new List(); var giftData = profileToUpdate.SptData.ReceivedGifts.FirstOrDefault(g => g.GiftId == giftId); if (giftData != null) @@ -374,7 +371,7 @@ public class ProfileHelper( // Player has never received gift, make a new object profileToUpdate.SptData.ReceivedGifts.Add( - new() + new ReceivedGift { GiftId = giftId, TimestampLastAccepted = _timeUtil.GetTimeStamp(), @@ -395,10 +392,7 @@ public class ProfileHelper( var profile = GetFullProfile(playerId); if (profile == null) { - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Unable to gift {giftId}, Profile: {playerId} does not exist"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Unable to gift {giftId}, Profile: {playerId} does not exist"); return false; } @@ -484,7 +478,7 @@ public class ProfileHelper( pointsToAddToSkill *= skillProgressRate; } - if (_inventoryConfig.SkillGainMultipliers.TryGetValue(skill.ToString(), out var _)) + if (_inventoryConfig.SkillGainMultipliers.TryGetValue(skill.ToString(), out _)) pointsToAddToSkill *= _inventoryConfig.SkillGainMultipliers[skill.ToString()]; profileSkill.Progress += pointsToAddToSkill; @@ -527,9 +521,8 @@ public class ProfileHelper( var profile = GetPmcProfile(sessionId); var existingBonus = profile?.Bonuses?.FirstOrDefault(b => b.Type == BonusType.StashRows); if (existingBonus != null) - { profile?.Bonuses?.Add( - new() + new Bonus { Id = _hashUtil.Generate(), Value = rowsToAdd, @@ -539,11 +532,8 @@ public class ProfileHelper( IsProduction = false } ); - } else - { existingBonus.Value += rowsToAdd; - } } /// @@ -568,8 +558,6 @@ public class ProfileHelper( return pmcProfile?.Info?.Bans?.Any(b => b.BanType == BanType.RAGFAIR && currentTimestamp < b.DateTime) ?? false; } - protected readonly List gameEditions = ["edge_of_darkness", "unheard_edition"]; - public bool HasAccessToRepeatableFreeRefreshSystem(PmcData pmcProfile) { return gameEditions.Contains(pmcProfile.Info.GameVersion); @@ -591,10 +579,7 @@ public class ProfileHelper( return; } - foreach (var pocket in pockets) - { - pocket.Template = newPocketTpl; - } + foreach (var pocket in pockets) pocket.Template = newPocketTpl; } /// @@ -636,7 +621,7 @@ public class ProfileHelper( public void AddHideoutCustomisationUnlock(SptProfile fullProfile, Reward reward, string source) { if (fullProfile?.CustomisationUnlocks == null) - fullProfile.CustomisationUnlocks = new(); + fullProfile.CustomisationUnlocks = new List(); if (fullProfile?.CustomisationUnlocks?.Any(u => u.Id == (string)reward.Target) ?? false) { diff --git a/Libraries/Core/Helpers/QuestConditionHelper.cs b/Libraries/Core/Helpers/QuestConditionHelper.cs index 34058924..7727b85b 100644 --- a/Libraries/Core/Helpers/QuestConditionHelper.cs +++ b/Libraries/Core/Helpers/QuestConditionHelper.cs @@ -39,14 +39,16 @@ public class QuestConditionHelper string questType, Func>? furtherFilter = null) { - var filteredQuests = questConditions.Where((c) => { - if (c.ConditionType == questType) - { - // return true or run the passed in function - return furtherFilter is null || furtherFilter(c).Any(); - } - return false; - }).ToList(); + var filteredQuests = questConditions.Where( + (c) => + { + if (c.ConditionType == questType) + // return true or run the passed in function + return furtherFilter is null || furtherFilter(c).Any(); + return false; + } + ) + .ToList(); return filteredQuests; } diff --git a/Libraries/Core/Helpers/QuestHelper.cs b/Libraries/Core/Helpers/QuestHelper.cs index d6a32363..63a9754e 100644 --- a/Libraries/Core/Helpers/QuestHelper.cs +++ b/Libraries/Core/Helpers/QuestHelper.cs @@ -38,8 +38,8 @@ public class QuestHelper( ICloner _cloner ) { - protected QuestConfig _questConfig = _configServer.GetConfig(); protected List _newlyQuestCheck = [QuestStatusEnum.Started, QuestStatusEnum.AvailableForFinish]; + protected QuestConfig _questConfig = _configServer.GetConfig(); /// /// Get status of a quest in player profile by its id @@ -62,10 +62,7 @@ public class QuestHelper( /// true if player level is greater than or equal to quest public bool DoesPlayerLevelFulfilCondition(double playerLevel, QuestCondition condition) { - if (condition.ConditionType != "Level") - { - return true; - } + if (condition.ConditionType != "Level") return true; var conditionValue = double.Parse(condition.Value.ToString()); switch (condition.CompareMethod) @@ -98,15 +95,10 @@ public class QuestHelper( public List GetDeltaQuests(List before, List after) { List knownQuestsIds = []; - foreach (var quest in before) { - knownQuestsIds.Add(quest.Id); - } + foreach (var quest in before) knownQuestsIds.Add(quest.Id); - if (knownQuestsIds.Count != 0) { - return after.Where((q) => { - return knownQuestsIds.IndexOf(q.Id) == -1; - }).ToList(); - } + if (knownQuestsIds.Count != 0) + return after.Where((q) => { return knownQuestsIds.IndexOf(q.Id) == -1; }).ToList(); return after; } @@ -122,12 +114,10 @@ public class QuestHelper( var currentLevel = Math.Floor((double)(profileSkill.Progress / 100)); // Only run this if the current level is under 9 - if (currentLevel >= 9) { - return progressAmount; - } + if (currentLevel >= 9) return progressAmount; // This calculates how much progress we have in the skill's starting level - var startingLevelProgress = (profileSkill.Progress % 100) * ((currentLevel + 1) / 10); + var startingLevelProgress = profileSkill.Progress % 100 * ((currentLevel + 1) / 10); // The code below assumes a 1/10th progress skill amount var remainingProgress = progressAmount / 10; @@ -135,19 +125,14 @@ public class QuestHelper( // We have to do this loop to handle edge cases where the provided XP bumps your level up // See "CalculateExpOnFirstLevels" in client for original logic var adjustedSkillProgress = 0; - while (remainingProgress > 0 && currentLevel < 9) { + while (remainingProgress > 0 && currentLevel < 9) + { // Calculate how much progress to add, limiting it to the current level max progress var currentLevelRemainingProgress = (currentLevel + 1) * 10 - startingLevelProgress; - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"currentLevelRemainingProgress: {currentLevelRemainingProgress}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"currentLevelRemainingProgress: {currentLevelRemainingProgress}"); var progressToAdd = Math.Min(remainingProgress, currentLevelRemainingProgress ?? 0); - var adjustedProgressToAdd = (10 / (currentLevel + 1)) * progressToAdd; - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Progress To Add: {progressToAdd} Adjusted for level: {adjustedProgressToAdd}"); - } + var adjustedProgressToAdd = 10 / (currentLevel + 1) * progressToAdd; + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Progress To Add: {progressToAdd} Adjusted for level: {adjustedProgressToAdd}"); // Add the progress amount adjusted by level adjustedSkillProgress += (int)adjustedProgressToAdd; @@ -157,9 +142,7 @@ public class QuestHelper( } // If there's any remaining progress, add it. This handles if you go from level 8 -> 9 - if (remainingProgress > 0) { - adjustedSkillProgress += remainingProgress; - } + if (remainingProgress > 0) adjustedSkillProgress += remainingProgress; return adjustedSkillProgress; } @@ -190,11 +173,9 @@ public class QuestHelper( : questProperties.Target.List.FirstOrDefault(), out var trader )) - { _logger.Error( _localisationService.GetText("quest-unable_to_find_trader_in_profile", questProperties.Target) ); - } return CompareAvailableForValues( trader.LoyaltyLevel.Value, @@ -218,11 +199,9 @@ public class QuestHelper( : questProperties.Target.List.FirstOrDefault(), out var trader )) - { _logger.Error( _localisationService.GetText("quest-unable_to_find_trader_in_profile", questProperties.Target) ); - } return CompareAvailableForValues(trader.Standing ?? 1, requiredLoyaltyLevel, questProperties.CompareMethod); } @@ -269,38 +248,33 @@ public class QuestHelper( existingQuest.StatusTimers[newState] = currentTimestamp; existingQuest.CompletedConditions = []; - if (existingQuest.AvailableAfter is not null) - { - existingQuest.AvailableAfter = null; - } + if (existingQuest.AvailableAfter is not null) existingQuest.AvailableAfter = null; return existingQuest; } // Quest doesn't exists, add it - QuestStatus newQuest = new QuestStatus + var newQuest = new QuestStatus { QId = acceptedQuest.QuestId, StartTime = currentTimestamp, Status = newState, - StatusTimers = new Dictionary(), + StatusTimers = new Dictionary() }; // Check if quest has a prereq to be placed in a 'pending' state, otherwise set status timers value var questDbData = GetQuestFromDb(acceptedQuest.QuestId, pmcData); if (questDbData is null) - { _logger.Error( _localisationService.GetText( "quest-unable_to_find_quest_in_db", new { questId = acceptedQuest.QuestId, - questType = acceptedQuest.Type, + questType = acceptedQuest.Type } ) ); - } var waitTime = questDbData?.Conditions.AvailableForStart.FirstOrDefault(x => x.AvailableAfter > 0); if (waitTime is not null && acceptedQuest.Type != "repeatable") @@ -328,7 +302,7 @@ public class QuestHelper( public List GetNewlyAccessibleQuestsWhenStartingQuest(string startedQuestId, string sessionID) { // Get quest acceptance data from profile - PmcData profile = _profileHelper.GetPmcProfile(sessionID); + var profile = _profileHelper.GetPmcProfile(sessionID); var startedQuestInProfile = profile.Quests.FirstOrDefault(profileQuest => profileQuest.QId == startedQuestId); // Get quests that @@ -341,66 +315,42 @@ public class QuestHelper( var acceptedQuestCondition = quest.Conditions.AvailableForStart.FirstOrDefault( condition => { - return ( - condition.ConditionType == "Quest" && - ((condition.Target?.Item?.Contains(startedQuestId) ?? false) || (condition.Target?.List?.Contains(startedQuestId) ?? false))&& - (condition.Status?.Contains(QuestStatusEnum.Started) ?? false) - ); + return condition.ConditionType == "Quest" && + ((condition.Target?.Item?.Contains(startedQuestId) ?? false) || + (condition.Target?.List?.Contains(startedQuestId) ?? false)) && + (condition.Status?.Contains(QuestStatusEnum.Started) ?? false); } ); // Not found, skip quest - if (acceptedQuestCondition is null) - { - return false; - } + if (acceptedQuestCondition is null) return false; // Skip locked event quests - if (!ShowEventQuestToPlayer(quest.Id)) - { - return false; - } + if (!ShowEventQuestToPlayer(quest.Id)) return false; // Skip quest if its flagged as for other side - if (QuestIsForOtherSide(profile.Info.Side, quest.Id)) - { - return false; - } + if (QuestIsForOtherSide(profile.Info.Side, quest.Id)) return false; - if (QuestIsProfileBlacklisted(profile.Info.GameVersion, quest.Id)) - { - return false; - } + if (QuestIsProfileBlacklisted(profile.Info.GameVersion, quest.Id)) return false; - if (QuestIsProfileWhitelisted(profile.Info.GameVersion, quest.Id)) - { - return false; - } + if (QuestIsProfileWhitelisted(profile.Info.GameVersion, quest.Id)) return false; var standingRequirements = _questConditionHelper.GetStandingConditions( quest.Conditions.AvailableForStart ); foreach (var condition in standingRequirements) - { if (!TraderStandingRequirementCheck(condition, profile)) - { return false; - } - } var loyaltyRequirements = _questConditionHelper.GetLoyaltyConditions( quest.Conditions.AvailableForStart ); foreach (var condition in loyaltyRequirements) - { if (!TraderLoyaltyLevelRequirementCheck(condition, profile)) - { return false; - } - } // Include if quest found in profile and is started or ready to hand in - return ((startedQuestInProfile is not null) && _newlyQuestCheck.Contains((QuestStatusEnum)startedQuestInProfile.Status)); + return startedQuestInProfile is not null && _newlyQuestCheck.Contains((QuestStatusEnum)startedQuestInProfile.Status); } ); @@ -420,23 +370,17 @@ public class QuestHelper( // Not christmas + quest is for christmas if (!isChristmasEventActive && _seasonalEventService.IsQuestRelatedToEvent(questId, SeasonalEventType.Christmas)) - { return false; - } // Not halloween + quest is for halloween if (!isHalloweenEventActive && _seasonalEventService.IsQuestRelatedToEvent(questId, SeasonalEventType.Halloween)) - { return false; - } // Should non-season event quests be shown to player if (!(_questConfig.ShowNonSeasonalEventQuests ?? false) && _seasonalEventService.IsQuestRelatedToEvent(questId, SeasonalEventType.None)) - { return false; - } return true; } @@ -450,16 +394,12 @@ public class QuestHelper( { var isUsec = playerSide.ToLower() == "usec"; if (isUsec && _questConfig.BearOnlyQuests.Contains(questId)) - { // Player is usec and quest is bear only, skip return true; - } if (!isUsec && _questConfig.UsecOnlyQuests.Contains(questId)) - { // Player is bear and quest is usec only, skip return true; - } return false; } @@ -475,10 +415,8 @@ public class QuestHelper( { var questBlacklist = _questConfig.ProfileBlacklist?.GetValueOrDefault(gameVersion); if (questBlacklist is null) - { // Not blacklisted return false; - } return questBlacklist.Contains(questId); } @@ -494,10 +432,8 @@ public class QuestHelper( { var questBlacklist = _questConfig.ProfileBlacklist.GetValueOrDefault(gameVersion); if (questBlacklist is null) - { // Not blacklisted return false; - } return questBlacklist.Contains(questId); } @@ -523,20 +459,14 @@ public class QuestHelper( c.Status[0] == QuestStatusEnum.Fail ); - if (acceptedQuestCondition is null) - { - return false; - } + if (acceptedQuestCondition is null) return false; return profileQuest is not null && profileQuest.Status == QuestStatusEnum.Fail; } ) .ToList(); - if (quests.Any()) - { - return quests; - } + if (quests.Any()) return quests; return GetQuestsWithOnlyLevelRequirementStartCondition(quests); } @@ -578,7 +508,7 @@ public class QuestHelper( { // this case is probably dead Code right now, since the only calling function // checks explicitly for Value > 0. - output.ProfileChanges[sessionID].Items.DeletedItems.Add(new() { Id = itemId }); + output.ProfileChanges[sessionID].Items.DeletedItems.Add(new Item { Id = itemId }); pmcData.Inventory.Items.RemoveAt(inventoryItemIndex); } } @@ -603,7 +533,7 @@ public class QuestHelper( ParentId = item.ParentId, SlotId = item.SlotId, Location = (ItemLocation)item.Location, - Upd = new Upd { StackObjectsCount = item.Upd.StackObjectsCount }, + Upd = new Upd { StackObjectsCount = item.Upd.StackObjectsCount } } ); } @@ -650,10 +580,7 @@ public class QuestHelper( var updatedOutput = output; // Prepare response to send back to client - if (updatedOutput is null) - { - updatedOutput = _eventOutputHolder.GetOutput(sessionID); - } + if (updatedOutput is null) updatedOutput = _eventOutputHolder.GetOutput(sessionID); UpdateQuestState(pmcData, QuestStatusEnum.Fail, failRequest.QuestId); var questRewards = _questRewardHelper.ApplyQuestReward( @@ -675,9 +602,7 @@ public class QuestHelper( // Quest found and no repeatable found if (quest is not null && matchingRepeatableQuest is null) - { if (quest.FailMessageText.Trim().Count() > 0) - { _mailSendService.SendLocalisedNpcMessageToPlayer( sessionID, _traderHelper.GetTraderById(quest?.TraderId ?? matchingRepeatableQuest?.TraderId) @@ -687,8 +612,6 @@ public class QuestHelper( questRewards.ToList(), _timeUtil.GetHoursAsSeconds((int)GetMailItemRedeemTimeHoursForProfile(pmcData)) ); - } - } updatedOutput.ProfileChanges[sessionID].Quests.AddRange(FailedUnlocked(failRequest.QuestId, sessionID)); } @@ -712,10 +635,7 @@ public class QuestHelper( public Quest GetQuestFromDb(string questId, PmcData pmcData) { // Maybe a repeatable quest? - if (_databaseService.GetQuests().TryGetValue(questId, out var quest)) - { - return quest; - } + if (_databaseService.GetQuests().TryGetValue(questId, out var quest)) return quest; // Check daily/weekly objects return pmcData.RepeatableQuests @@ -739,9 +659,7 @@ public class QuestHelper( startedMessageText.ToLower() == "test" || startedMessageText.Length == 24 ) - { return questDescriptionId; - } return startedMessageTextId; } @@ -790,21 +708,14 @@ public class QuestHelper( questToUpdate.Status = newQuestState; // Only set start time when quest is being started - if (newQuestState == QuestStatusEnum.Started) - { - questToUpdate.StartTime = currentTimestamp; - } + if (newQuestState == QuestStatusEnum.Started) questToUpdate.StartTime = currentTimestamp; questToUpdate.StatusTimers[newQuestState] = currentTimestamp; // Delete all status timers after applying new status foreach (var statusKey in questToUpdate.StatusTimers) - { if (statusKey.Key > newQuestState) - { questToUpdate.StatusTimers.Remove(statusKey.Key); - } - } // Remove all completed conditions questToUpdate.CompletedConditions = []; @@ -829,10 +740,7 @@ public class QuestHelper( var questInDb = allQuests.FirstOrDefault((x) => x.Id == questId); if (questInDb is null) { - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Unable to find quest: {questId} in db, cannot get 'FindItem' condition, skipping"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Unable to find quest: {questId} in db, cannot get 'FindItem' condition, skipping"); continue; } @@ -863,17 +771,11 @@ public class QuestHelper( foreach (var (key, questData) in quests) { // Quest from db matches quests in profile, skip - if (pmcProfile.Quests.Any((x) => x.QId == questData.Id)) - { - continue; - } + if (pmcProfile.Quests.Any((x) => x.QId == questData.Id)) continue; // Create dict of status to add to quest in profile var statusesDict = new Dictionary(); - foreach (var status in statuses) - { - statusesDict.Add(status, _timeUtil.GetTimeStamp()); - } + foreach (var status in statuses) statusesDict.Add(status, _timeUtil.GetTimeStamp()); var questRecordToAdd = new QuestStatus { @@ -882,7 +784,7 @@ public class QuestHelper( Status = statuses[^1], // Get last status in list as currently active status StatusTimers = statusesDict, CompletedConditions = [], - AvailableAfter = 0, + AvailableAfter = 0 }; // Check if the quest already exists in the profile @@ -923,10 +825,7 @@ public class QuestHelper( (quest) => { // No fail conditions, exit early - if (quest.Conditions.Fail is null || quest.Conditions.Fail.Count == 0) - { - return false; - } + if (quest.Conditions.Fail is null || quest.Conditions.Fail.Count == 0) return false; return quest.Conditions.Fail.Any( condition => @@ -948,10 +847,7 @@ public class QuestHelper( public double? GetMailItemRedeemTimeHoursForProfile(PmcData pmcData) { var value = _questConfig.MailRedeemTimeHours.GetValueOrDefault(pmcData.Info.GameVersion); - if (value is null) - { - return 0; - } + if (value is null) return 0; return value; } @@ -959,7 +855,7 @@ public class QuestHelper( public ItemEventRouterResponse CompleteQuest(PmcData pmcData, CompleteQuestRequestData body, string sessionID) { var completeQuestResponse = _eventOutputHolder.GetOutput(sessionID); - + var preCompleteProfileQuests = _cloner.Clone(pmcData.Quests); var completedQuestId = body.QuestId; @@ -978,10 +874,7 @@ public class QuestHelper( // Check for linked failed + unrestartable quests (only get quests not already failed var questsToFail = GetQuestsFromProfileFailedByCompletingQuest(completedQuestId, pmcData); - if (questsToFail?.Count > 0) - { - FailQuests(sessionID, pmcData, questsToFail, completeQuestResponse); - } + if (questsToFail?.Count > 0) FailQuests(sessionID, pmcData, questsToFail, completeQuestResponse); // Show modal on player screen SendSuccessDialogMessageOnQuestComplete(sessionID, pmcData, completedQuestId, questRewards.ToList()); @@ -1002,22 +895,15 @@ public class QuestHelper( (activeRepeatable) => activeRepeatable.Id == completedQuestId ); if (repeatableQuest is not null) - { // Need to remove redundant scav quest object as its no longer necessary, is tracked in pmc profile if (repeatableQuest.Side == "Scav") - { RemoveQuestFromScavProfile(sessionID, repeatableQuest.Id); - } - } } // Hydrate client response questsStatus array with data var questStatusChanges = GetQuestsWithDifferentStatuses(preCompleteProfileQuests, pmcData.Quests); - if (questStatusChanges is not null) - { - completeQuestResponse.ProfileChanges[sessionID].QuestsStatus.AddRange(questStatusChanges); - } - + if (questStatusChanges is not null) completeQuestResponse.ProfileChanges[sessionID].QuestsStatus.AddRange(questStatusChanges); + return completeQuestResponse; } @@ -1052,31 +938,20 @@ public class QuestHelper( } // Filter out bear quests for USEC and vice versa - if (QuestIsForOtherSide(profile.Info.Side, quest.Id)) - { - continue; - } + if (QuestIsForOtherSide(profile.Info.Side, quest.Id)) continue; - if (!ShowEventQuestToPlayer(quest.Id)) - { - continue; - } + if (!ShowEventQuestToPlayer(quest.Id)) continue; // Don't add quests that have a level higher than the user's - if (!PlayerLevelFulfillsQuestRequirement(quest, profile.Info.Level.Value)) - { - continue; - } + if (!PlayerLevelFulfillsQuestRequirement(quest, profile.Info.Level.Value)) continue; // Player can use trader mods then remove them, leaving quests behind if (!profile.TradersInfo.TryGetValue(quest.TraderId, out var trader)) { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug( $"Unable to show quest: {quest.QuestName} as its for a trader: {quest.TraderId} that no longer exists." ); - } continue; } @@ -1100,9 +975,9 @@ public class QuestHelper( // If the previous quest isn't in the user profile, it hasn't been completed or started var questIdsToFulfil = (conditionToFulfil.Target.IsList ? conditionToFulfil.Target.List - : (conditionToFulfil.Target.Item == null + : conditionToFulfil.Target.Item == null ? null - : [conditionToFulfil.Target.Item])) ?? + : [conditionToFulfil.Target.Item]) ?? []; var prerequisiteQuest = profile.Quests.FirstOrDefault(profileQuest => questIdsToFulfil.Contains(profileQuest.QId)); @@ -1131,39 +1006,30 @@ public class QuestHelper( ); var unlockTime = previousQuestCompleteTime + conditionToFulfil.AvailableAfter; if (unlockTime > _timeUtil.GetTimeStamp()) - { _logger.Debug( $"Quest {quest.QuestName} is locked for another: {unlockTime - _timeUtil.GetTimeStamp()} seconds" ); - } } } // Previous quest not completed, skip - if (!haveCompletedPreviousQuest) - { - continue; - } + if (!haveCompletedPreviousQuest) continue; var passesLoyaltyRequirements = true; foreach (var condition in loyaltyRequirements) - { if (!TraderLoyaltyLevelRequirementCheck(condition, profile)) { passesLoyaltyRequirements = false; break; } - } var passesStandingRequirements = true; foreach (var condition in standingRequirements) - { if (!TraderStandingRequirementCheck(condition, profile)) { passesStandingRequirements = false; break; } - } if (haveCompletedPreviousQuest && passesLoyaltyRequirements && passesStandingRequirements) { @@ -1193,7 +1059,7 @@ public class QuestHelper( { if (rewardType.Value is null) continue; - + propsAsDict[rewardType.Key] = ((List)propsAsDict[rewardType.Key]) .Where( reward => @@ -1218,18 +1084,12 @@ public class QuestHelper( quest => { // No fail conditions, skip - if (quest.Conditions.Fail is null || quest.Conditions.Fail.Count == 0) - { - return false; - } + if (quest.Conditions.Fail is null || quest.Conditions.Fail.Count == 0) return false; // Quest already failed in profile, skip - if (pmcProfile.Quests.Any(profileQuest => profileQuest.QId == quest.Id && profileQuest.Status == QuestStatusEnum.Fail)) - { - return false; - } + if (pmcProfile.Quests.Any(profileQuest => profileQuest.QId == quest.Id && profileQuest.Status == QuestStatusEnum.Fail)) return false; - return quest.Conditions.Fail.Any(condition => (condition.Target?.List?.Contains(completedQuestId) ?? false)); + return quest.Conditions.Fail.Any(condition => condition.Target?.List?.Contains(completedQuestId) ?? false); } ) .ToList(); @@ -1253,21 +1113,18 @@ public class QuestHelper( foreach (var questToFail in questsToFail) { // Skip failing a quest that has a fail status of something other than success - if (questToFail.Conditions.Fail?.Any(x => x.Status?.Any(status => status != QuestStatusEnum.Success) ?? false) ?? false) - { - continue; - } + if (questToFail.Conditions.Fail?.Any(x => x.Status?.Any(status => status != QuestStatusEnum.Success) ?? false) ?? false) continue; var isActiveQuestInPlayerProfile = pmcData.Quests.FirstOrDefault(quest => quest.QId == questToFail.Id); if (isActiveQuestInPlayerProfile is not null) { if (isActiveQuestInPlayerProfile.Status != QuestStatusEnum.Fail) { - FailQuestRequestData failBody = new FailQuestRequestData + var failBody = new FailQuestRequestData { Action = "QuestFail", QuestId = questToFail.Id, - RemoveExcessItems = true, + RemoveExcessItems = true }; FailQuest(pmcData, failBody, sessionID, output); } @@ -1275,20 +1132,17 @@ public class QuestHelper( else { // Failing an entirely new quest that doesn't exist in profile - Dictionary statusTimers = new Dictionary(); + var statusTimers = new Dictionary(); - if (!statusTimers.TryGetValue(QuestStatusEnum.Fail, out var _)) - { - statusTimers.Add(QuestStatusEnum.Fail, 0); - } + if (!statusTimers.TryGetValue(QuestStatusEnum.Fail, out _)) statusTimers.Add(QuestStatusEnum.Fail, 0); statusTimers[QuestStatusEnum.Fail] = _timeUtil.GetTimeStamp(); - QuestStatus questData = new QuestStatus + var questData = new QuestStatus { QId = questToFail.Id, StartTime = _timeUtil.GetTimeStamp(), StatusTimers = statusTimers, - Status = QuestStatusEnum.Fail, + Status = QuestStatusEnum.Fail } ; pmcData.Quests.Add(questData); @@ -1365,7 +1219,7 @@ public class QuestHelper( { { QuestStatusEnum.AvailableAfter, _timeUtil.GetTimeStamp() } }, - AvailableAfter = availableAfterTimestamp, + AvailableAfter = availableAfterTimestamp } ); } @@ -1417,16 +1271,10 @@ public class QuestHelper( { // Add quest if status differs or quest not found var preQuest = preQuestStatuses.FirstOrDefault(x => x.QId == quest.QId); - if (preQuest is null || preQuest.Status != quest.Status) - { - result.Add(quest); - } + if (preQuest is null || preQuest.Status != quest.Status) result.Add(quest); } - if (result.Count == 0) - { - return null; - } + if (result.Count == 0) return null; return result; } @@ -1440,23 +1288,15 @@ public class QuestHelper( protected bool PlayerLevelFulfillsQuestRequirement(Quest quest, double playerLevel) { if (quest.Conditions is null) - { // No conditions return true; - } var levelConditions = _questConditionHelper.GetLevelConditions(quest.Conditions.AvailableForStart); if (levelConditions is not null) - { foreach (var levelCondition in levelConditions) - { if (!DoesPlayerLevelFulfilCondition(playerLevel, levelCondition)) - { // Not valid, exit out return false; - } - } - } // All conditions passed / has no level requirement, valid return true; diff --git a/Libraries/Core/Helpers/QuestRewardHelper.cs b/Libraries/Core/Helpers/QuestRewardHelper.cs index 033556c7..eded86c0 100644 --- a/Libraries/Core/Helpers/QuestRewardHelper.cs +++ b/Libraries/Core/Helpers/QuestRewardHelper.cs @@ -75,7 +75,8 @@ public class QuestRewardHelper( fullProfile, profileData, questId, - questResponse); + questResponse + ); } /** @@ -89,7 +90,6 @@ public class QuestRewardHelper( // May be a repeatable quest var quest = _databaseService.GetQuests()[questId]; if (quest == null) - { // Check daily/weekly objects foreach (var repeatableQuest in pmcData.RepeatableQuests) { @@ -97,7 +97,6 @@ public class QuestRewardHelper( if (quest != null) break; } - } return quest; } @@ -120,8 +119,8 @@ public class QuestRewardHelper( // 5100 becomes 0.51, add 1 to it, 1.51 // We multiply the money reward bonuses by the hideout management skill multipler, giving the new result - var hideoutManagementBonusMultiplier = (hideoutManagementSkill != null) - ? (1 + hideoutManagementSkill.Progress / 1000) + var hideoutManagementBonusMultiplier = hideoutManagementSkill != null + ? 1 + hideoutManagementSkill.Progress / 1000 : 1; // e.g 15% * 1.4 @@ -142,7 +141,7 @@ public class QuestRewardHelper( .GetProperties() .FirstOrDefault(p => p.Name == questStatus.ToString()) .GetValue(quest.Rewards) ?? - new(); + new List(); var currencyRewards = rewards.Where( r => r.Type.ToString() == "Item" && diff --git a/Libraries/Core/Helpers/RagfairHelper.cs b/Libraries/Core/Helpers/RagfairHelper.cs index fadb8b97..647e8c0f 100644 --- a/Libraries/Core/Helpers/RagfairHelper.cs +++ b/Libraries/Core/Helpers/RagfairHelper.cs @@ -23,7 +23,7 @@ public class RagfairHelper( ) { protected RagfairConfig ragfairConfig = configServer.GetConfig(); - + /** * Gets currency TAG from TPL * @param {string} currency @@ -31,7 +31,8 @@ public class RagfairHelper( */ public string GetCurrencyTag(string currency) { - switch (currency) { + switch (currency) + { case Money.EUROS: return "EUR"; case Money.DOLLARS: @@ -50,25 +51,24 @@ public class RagfairHelper( var result = new List(); // Case: weapon builds - if (request.BuildCount > 0) { - return request.BuildItems.Keys.ToList(); - } + if (request.BuildCount > 0) return request.BuildItems.Keys.ToList(); // Case: search - if (!string.IsNullOrEmpty(request.LinkedSearchId)) { + if (!string.IsNullOrEmpty(request.LinkedSearchId)) + { var data = ragfairLinkedItemService.GetLinkedItems(request.LinkedSearchId); result = data == null ? [] : [..data]; } // Case: category - if (!string.IsNullOrEmpty(request.HandbookId)) { + if (!string.IsNullOrEmpty(request.HandbookId)) + { var handbook = GetCategoryList(request.HandbookId); - if (result.Count != null && result.Count > 0) { + if (result.Count != null && result.Count > 0) result = utilityHelper.ArrayIntersect(result, handbook); - } else { + else result = handbook; - } } return result; @@ -78,11 +78,9 @@ public class RagfairHelper( { var result = new Dictionary(); - foreach (var traderID in databaseService.GetTraders().Keys) { - if (ragfairConfig.Traders.ContainsKey(traderID)) { + foreach (var traderID in databaseService.GetTraders().Keys) + if (ragfairConfig.Traders.ContainsKey(traderID)) result[traderID] = traderAssortHelper.GetAssort(sessionID, traderID, true); - } - } return result; } @@ -92,24 +90,22 @@ public class RagfairHelper( var result = new List(); // if its "mods" great-parent category, do double recursive loop - if (handbookId == "5b5f71a686f77447ed5636ab") { - foreach (var categ in handbookHelper.ChildrenCategories(handbookId)) { - foreach (var subcateg in handbookHelper.ChildrenCategories(categ)) { - result = [..result, ..handbookHelper.TemplatesWithParent(subcateg)]; - } - } + if (handbookId == "5b5f71a686f77447ed5636ab") + { + foreach (var categ in handbookHelper.ChildrenCategories(handbookId)) + foreach (var subcateg in handbookHelper.ChildrenCategories(categ)) + result = [..result, ..handbookHelper.TemplatesWithParent(subcateg)]; return result; } // item is in any other category - if (handbookHelper.IsCategory(handbookId)) { + if (handbookHelper.IsCategory(handbookId)) + { // list all item of the category result = handbookHelper.TemplatesWithParent(handbookId); - foreach (var categ in handbookHelper.ChildrenCategories(handbookId)) { - result = [..result, ..handbookHelper.TemplatesWithParent(categ)]; - } + foreach (var categ in handbookHelper.ChildrenCategories(handbookId)) result = [..result, ..handbookHelper.TemplatesWithParent(categ)]; return result; } @@ -128,19 +124,26 @@ public class RagfairHelper( var list = new List(); Item rootItem = null; - foreach (var item in items) { + foreach (var item in items) + { var itemFixed = itemHelper.FixItemStackCount(item); var isChild = items.Any(it => it.Id == itemFixed.ParentId); - if (!isChild) { - if (rootItem == null) { + if (!isChild) + { + if (rootItem == null) + { rootItem = cloner.Clone(itemFixed); rootItem.Upd.OriginalStackObjectsCount = rootItem.Upd.StackObjectsCount; - } else { + } + else + { rootItem.Upd.StackObjectsCount += itemFixed.Upd.StackObjectsCount; list.Add(itemFixed); } - } else { + } + else + { list.Add(itemFixed); } } diff --git a/Libraries/Core/Helpers/RagfairOfferHelper.cs b/Libraries/Core/Helpers/RagfairOfferHelper.cs index 10168a59..a2a05efa 100644 --- a/Libraries/Core/Helpers/RagfairOfferHelper.cs +++ b/Libraries/Core/Helpers/RagfairOfferHelper.cs @@ -42,9 +42,9 @@ public class RagfairOfferHelper( EventOutputHolder _eventOutputHolder, ConfigServer _configServer) { - protected RagfairConfig _ragfairConfig = _configServer.GetConfig(); - protected BotConfig _botConfig = _configServer.GetConfig(); protected static string _goodSoldTemplate = "5bdabfb886f7743e152e867e 0"; // Your {soldItem} {itemCount} items were bought by {buyerNickname}. + protected BotConfig _botConfig = _configServer.GetConfig(); + protected RagfairConfig _ragfairConfig = _configServer.GetConfig(); /// /// Passthrough to ragfairOfferService.getOffers(), get flea offers a player should see @@ -67,10 +67,7 @@ public class RagfairOfferHelper( .Where( offer => { - if (!PassesSearchFilterCriteria(searchRequest, offer, pmcData)) - { - return false; - } + if (!PassesSearchFilterCriteria(searchRequest, offer, pmcData)) return false; var isDisplayable = IsDisplayableOffer( searchRequest, @@ -81,21 +78,16 @@ public class RagfairOfferHelper( playerIsFleaBanned ); - if (!isDisplayable) - { - return false; - } + if (!isDisplayable) return false; // Not trader offer + tiered flea enabled if (tieredFlea.Enabled && !OfferIsFromTrader(offer)) - { CheckAndLockOfferFromPlayerTieredFlea( tieredFlea, offer, tieredFleaLimitTypes.Keys.ToList(), pmcData.Info.Level.Value ); - } return true; } @@ -118,41 +110,32 @@ public class RagfairOfferHelper( { var offerItemTpl = offer.Items.FirstOrDefault().Template; if (tieredFlea.AmmoTplUnlocks is not null && _itemHelper.IsOfBaseclass(offerItemTpl, BaseClasses.AMMO)) - { if (tieredFlea.AmmoTplUnlocks.TryGetValue(offerItemTpl, out var unlockLevel) && playerLevel < unlockLevel) { offer.Locked = true; return; } - } // Check for a direct level requirement for the offer item if (tieredFlea.UnlocksTpl.TryGetValue(offerItemTpl, out var itemLevelRequirement)) - { if (playerLevel < itemLevelRequirement) { offer.Locked = true; return; } - } // Optimisation - Ensure the item has at least one of the limited base types if (_itemHelper.IsOfBaseclasses(offerItemTpl, tieredFleaLimitTypes)) - { // Loop over flea types foreach (var tieredItemType in tieredFleaLimitTypes .Where(tieredItemType => _itemHelper.IsOfBaseclass(offerItemTpl, tieredItemType))) { - if (playerLevel < tieredFlea.UnlocksType[tieredItemType]) - { - offer.Locked = true; - } + if (playerLevel < tieredFlea.UnlocksType[tieredItemType]) offer.Locked = true; break; } - } } /// @@ -171,20 +154,15 @@ public class RagfairOfferHelper( return requiredOffers.Where( offer => { - if (!PassesSearchFilterCriteria(searchRequest, offer, pmcData)) - { - return false; - } + if (!PassesSearchFilterCriteria(searchRequest, offer, pmcData)) return false; if (tieredFlea.Enabled && !OfferIsFromTrader(offer)) - { CheckAndLockOfferFromPlayerTieredFlea( tieredFlea, offer, tieredFleaLimitTypes.Keys.ToList(), pmcData.Info.Level.Value ); - } return true; } @@ -216,23 +194,15 @@ public class RagfairOfferHelper( { var matchingOffers = _ragfairOfferService.GetOffersOfType(desiredItemTpl.Key); if (matchingOffers is null) - { // No offers found for this item, skip continue; - } foreach (var offer in matchingOffers) { // Don't show pack offers - if (offer.SellInOnePiece.GetValueOrDefault(false)) - { - continue; - } + if (offer.SellInOnePiece.GetValueOrDefault(false)) continue; - if (!PassesSearchFilterCriteria(searchRequest, offer, pmcData)) - { - continue; - } + if (!PassesSearchFilterCriteria(searchRequest, offer, pmcData)) continue; if ( !IsDisplayableOffer( @@ -244,31 +214,17 @@ public class RagfairOfferHelper( playerIsFleaBanned ) ) - { continue; - } if (OfferIsFromTrader(offer)) { - if (TraderBuyRestrictionReached(offer)) - { - continue; - } + if (TraderBuyRestrictionReached(offer)) continue; - if (TraderOutOfStock(offer)) - { - continue; - } + if (TraderOutOfStock(offer)) continue; - if (TraderOfferItemQuestLocked(offer, traderAssorts)) - { - continue; - } + if (TraderOfferItemQuestLocked(offer, traderAssorts)) continue; - if (TraderOfferLockedBehindLoyaltyLevel(offer, pmcData)) - { - continue; - } + if (TraderOfferLockedBehindLoyaltyLevel(offer, pmcData)) continue; } // Tiered flea and not trader offer @@ -282,17 +238,11 @@ public class RagfairOfferHelper( ); // Do not add offer to build if user does not have access to it - if (offer.Locked.GetValueOrDefault(false)) - { - continue; - } + if (offer.Locked.GetValueOrDefault(false)) continue; } var key = offer.Items[0].Template; - if (!offersMap.ContainsKey(key)) - { - offersMap.Add(key, []); - } + if (!offersMap.ContainsKey(key)) offersMap.Add(key, []); offersMap[key].Add(offer); } @@ -349,49 +299,36 @@ public class RagfairOfferHelper( var moneyTypeTpl = offer.Requirements[0].Template; var isTraderOffer = _databaseService.GetTraders().ContainsKey(offer.User.Id); - if (!isTraderOffer && playerIsFleaBanned) - { - return false; - } + if (!isTraderOffer && playerIsFleaBanned) return false; // Offer root items tpl not in searched for array if (!itemsToAdd.Contains(offerRootItem.Template)) - { // skip items we shouldn't include return false; - } // Performing a required search and offer doesn't have requirement for item if ( !string.IsNullOrEmpty(searchRequest.NeededSearchId) && !offer.Requirements.Any(requirement => requirement.Template == searchRequest.NeededSearchId) ) - { return false; - } // Weapon/equipment search + offer is preset if ( searchRequest.BuildItems.Count == 0 && // Prevent equipment loadout searches filtering out presets searchRequest.BuildCount.GetValueOrDefault(0) > 0 && _presetHelper.HasPreset(offerRootItem.Template)) - { return false; - } // commented out as required search "which is for checking offers that are barters" // has info.removeBartering as true, this if statement removed barter items. if (searchRequest.RemoveBartering.GetValueOrDefault(false) && !_paymentHelper.IsMoneyTpl(moneyTypeTpl)) - { // Don't include barter offers return false; - } if (offer.RequirementsCost is null) - { // Don't include offers with undefined or NaN in it return false; - } // Handle trader items to remove items that are not available to the user right now // e.g. required search for "lamp" shows 4 items, 3 of which are not available to a new player @@ -399,18 +336,14 @@ public class RagfairOfferHelper( if (isTraderOffer) { if (!traderAssorts.ContainsKey(offer.User.Id)) - { // trader not visible on flea market return false; - } if ( - !traderAssorts[offer.User.Id].Items.Any(item => { return item.Id == offer.Root; }) - ) - { + !traderAssorts[offer.User.Id].Items.Any(item => { return item.Id == offer.Root; }) + ) // skip (quest) locked items return false; - } } return true; @@ -432,12 +365,8 @@ public class RagfairOfferHelper( OfferIsFromTrader(offer) && offer.BuyRestrictionCurrent >= offer.BuyRestrictionMax ) - { if (offer.BuyRestrictionCurrent >= offer.BuyRestrictionMax) - { return false; - } - } // Doesnt have buy limits, retrun offer return true; @@ -502,9 +431,7 @@ public class RagfairOfferHelper( .Any(subBarter => subBarter.SptQuestLocked.GetValueOrDefault(false)) ) )) - { return true; - } } // Fallback, nothing found @@ -518,10 +445,7 @@ public class RagfairOfferHelper( /// true if out of stock protected bool TraderOutOfStock(RagfairOffer offer) { - if (offer?.Items?.Count == 0) - { - return true; - } + if (offer?.Items?.Count == 0) return true; return offer.Items[0]?.Upd?.StackObjectsCount == 0; } @@ -550,23 +474,15 @@ public class RagfairOfferHelper( } if (assortData.Upd is null) - { // No Upd = no chance of limits return false; - } // No restriction values // Can't use !assortData.upd.BuyRestrictionX as value could be 0 - if (assortData.Upd.BuyRestrictionMax is null || assortData.Upd.BuyRestrictionCurrent is null) - { - return false; - } + if (assortData.Upd.BuyRestrictionMax is null || assortData.Upd.BuyRestrictionCurrent is null) return false; // Current equals max, limit reached - if (assortData.Upd.BuyRestrictionCurrent >= assortData.Upd.BuyRestrictionMax) - { - return true; - } + if (assortData.Upd.BuyRestrictionCurrent >= assortData.Upd.BuyRestrictionMax) return true; return false; } @@ -577,9 +493,7 @@ public class RagfairOfferHelper( foreach (var offer in offers.Where(offer => OfferIsFromTrader(offer))) if (pmcProfile.TradersInfo.TryGetValue(offer.User.Id, out var traderDetails) && traderDetails.LoyaltyLevel < offer.LoyaltyLevel) - { loyaltyLockedOffers.Add(offer.Id); - } return loyaltyLockedOffers; } @@ -595,10 +509,7 @@ public class RagfairOfferHelper( var profileOffers = GetProfileOffers(sessionId); // No offers, don't do anything - if (profileOffers?.Count == 0) - { - return true; - } + if (profileOffers?.Count == 0) return true; // Index backwards as CompleteOffer() can delete offer object for (var index = profileOffers.Count - 1; index >= 0; index--) @@ -679,10 +590,7 @@ public class RagfairOfferHelper( { var profile = _profileHelper.GetPmcProfile(sessionId); - if (profile.RagfairInfo?.Offers is null) - { - return []; - } + if (profile.RagfairInfo?.Offers is null) return []; return profile.RagfairInfo.Offers; } @@ -696,15 +604,9 @@ public class RagfairOfferHelper( { var profileRagfairInfo = _profileHelper.GetPmcProfile(sessionId).RagfairInfo; var offerIndex = profileRagfairInfo.Offers.FindIndex(o => o.Id == offerId); - if (offerIndex == -1) - { - _logger.Warning($"Unable to find offer: {offerId} in profile: {sessionId}, unable to delete"); - } + if (offerIndex == -1) _logger.Warning($"Unable to find offer: {offerId} in profile: {sessionId}, unable to delete"); - if (offerIndex >= 0) - { - profileRagfairInfo.Offers.Splice(offerIndex, 1); - } + if (offerIndex >= 0) profileRagfairInfo.Offers.Splice(offerIndex, 1); // Also delete from ragfair @@ -747,7 +649,7 @@ public class RagfairOfferHelper( { Id = _hashUtil.Generate(), Template = requirement.Template, - Upd = new Upd { StackObjectsCount = requirement.Count * boughtAmount }, + Upd = new Upd { StackObjectsCount = requirement.Count * boughtAmount } }; var stacks = _itemHelper.SplitStack(requestedItem); @@ -759,10 +661,7 @@ public class RagfairOfferHelper( if (requirement.OnlyFunctional.GetValueOrDefault(false)) { var presetItems = _ragfairServerHelper.GetPresetItemsByTpl(item); - if (presetItems.Count > 0) - { - outItems.Add(presetItems[0]); - } + if (presetItems.Count > 0) outItems.Add(presetItems[0]); } paymentItemsToSendToPlayer.AddRange(outItems); @@ -807,11 +706,9 @@ public class RagfairOfferHelper( // Generate a message to inform that item was sold var globalLocales = _localeService.GetLocaleDb(); if (!globalLocales.TryGetValue(_goodSoldTemplate, out var soldMessageLocaleGuid)) - { _logger.Error( _localisationService.GetText("ragfair-unable_to_find_locale_by_key", _goodSoldTemplate) ); - } // Used to replace tokens in sold message sent to player var messageKey = $"{itemTpl} Name"; @@ -821,7 +718,7 @@ public class RagfairOfferHelper( { SoldItem = hasKey ? value : itemTpl, BuyerNickname = _botHelper.GetPmcNicknameOfMaxLength(_botConfig.BotNameLengthLimit), - ItemCount = boughtAmount, + ItemCount = boughtAmount }; // Node searches for anything inside {property}: e.g.: "Your {soldItem} {itemCount} items were bought by {buyerNickname}." @@ -851,49 +748,35 @@ public class RagfairOfferHelper( var isTraderOffer = OfferIsFromTrader(offer); if (pmcData.Info.Level < _databaseService.GetGlobals().Configuration.RagFair.MinUserLevel && isDefaultUserOffer) - { // Skip item if player is < global unlock level (default is 15) and item is from a dynamically generated source return false; - } if (searchRequest.OfferOwnerType == OfferOwnerType.TRADEROWNERTYPE && !isTraderOffer) - { // don't include player offers return false; - } if (searchRequest.OfferOwnerType == OfferOwnerType.PLAYEROWNERTYPE && isTraderOffer) - { // don't include trader offers return false; - } if ( - searchRequest.OneHourExpiration.GetValueOrDefault(false) && - offer.EndTime - _timeUtil.GetTimeStamp() > TimeUtil.OneHourAsSeconds - ) - { + searchRequest.OneHourExpiration.GetValueOrDefault(false) && + offer.EndTime - _timeUtil.GetTimeStamp() > TimeUtil.OneHourAsSeconds + ) // offer expires within an hour return false; - } if (searchRequest.QuantityFrom > 0 && offerRootItem.Upd.StackObjectsCount < searchRequest.QuantityFrom) - { // too little items to offer return false; - } if (searchRequest.QuantityTo > 0 && offerRootItem.Upd.StackObjectsCount > searchRequest.QuantityTo) - { // Too many items to offer return false; - } if (searchRequest.OnlyFunctional.GetValueOrDefault(false) && !IsItemFunctional(offerRootItem, offer)) - { // Don't include non-functional items return false; - } if (offer.Items.Count == 1) { @@ -903,22 +786,14 @@ public class RagfairOfferHelper( IsConditionItem(offerRootItem) && !ItemQualityInRange(offerRootItem, searchRequest.ConditionFrom.Value, searchRequest.ConditionTo.Value) ) - { return false; - } } else { var itemQualityPercent = _itemHelper.GetItemQualityModifierForItems(offer.Items) * 100; - if (itemQualityPercent < searchRequest.ConditionFrom) - { - return false; - } + if (itemQualityPercent < searchRequest.ConditionFrom) return false; - if (itemQualityPercent > searchRequest.ConditionTo) - { - return false; - } + if (itemQualityPercent > searchRequest.ConditionTo) return false; } if (searchRequest.Currency > 0 && _paymentHelper.IsMoneyTpl(offerMoneyTypeTpl)) @@ -926,23 +801,17 @@ public class RagfairOfferHelper( // Use 'currencies' as mapping for the money choice dropdown, e.g. 0 = all, 2 = "USD; string[] currencies = ["all", "RUB", "USD", "EUR"]; if (_ragfairHelper.GetCurrencyTag(offerMoneyTypeTpl) != currencies[searchRequest.Currency.Value]) - { // Don't include item paid in wrong currency return false; - } } if (searchRequest.PriceFrom > 0 && searchRequest.PriceFrom >= offer.RequirementsCost) - { // price is too low return false; - } if (searchRequest.PriceTo > 0 && searchRequest.PriceTo <= offer.RequirementsCost) - { // price is too high return false; - } // Passes above checks, search criteria filters have not filtered offer out return true; @@ -957,10 +826,7 @@ public class RagfairOfferHelper( public bool IsItemFunctional(Item offerRootItem, RagfairOffer offer) { // Non-preset weapons/armor are always functional - if (!_presetHelper.HasPreset(offerRootItem.Template)) - { - return true; - } + if (!_presetHelper.HasPreset(offerRootItem.Template)) return true; // For armor items that can hold mods, make sure the item count is at least the amount of required plates if (_itemHelper.ArmorItemCanHoldMods(offerRootItem.Template)) @@ -986,10 +852,7 @@ public class RagfairOfferHelper( { // thanks typescript, undefined assertion is not returnable since it // tries to return a multi-type object - if (item.Upd is null) - { - return false; - } + if (item.Upd is null) return false; return item.Upd.MedKit is not null || item.Upd.Repairable is not null || @@ -1010,16 +873,12 @@ public class RagfairOfferHelper( { var itemQualityPercentage = 100 * _itemHelper.GetItemQualityModifier(item); if (min > 0 && min > itemQualityPercentage) - { // Item condition too low return false; - } if (max < 100 && max <= itemQualityPercentage) - { // Item condition too high return false; - } return true; } diff --git a/Libraries/Core/Helpers/RagfairSellHelper.cs b/Libraries/Core/Helpers/RagfairSellHelper.cs index d5426e2d..e072707a 100644 --- a/Libraries/Core/Helpers/RagfairSellHelper.cs +++ b/Libraries/Core/Helpers/RagfairSellHelper.cs @@ -17,8 +17,8 @@ public class RagfairSellHelper( DatabaseService _databaseService, ConfigServer _configServer) { - protected RagfairConfig _ragfairConfig = _configServer.GetConfig(); + /// /// Get the percent chance to sell an item based on its average listed price vs player chosen listing price /// @@ -37,20 +37,14 @@ public class RagfairSellHelper( var baseSellChancePercent = sellConfig.Base * qualityMultiplier; // Modifier gets applied twice to either penalize or incentivize over/under pricing (Probably a cleaner way to do this) - var sellModifier = (averageOfferPriceRub / playerListedPriceRub) * sellConfig.SellMultiplier; + var sellModifier = averageOfferPriceRub / playerListedPriceRub * sellConfig.SellMultiplier; var sellChance = Math.Round(baseSellChancePercent * sellModifier * Math.Pow(sellModifier, 3) + 10); // Power of 3 // Adjust sell chance if below config value - if (sellChance < sellConfig.MinSellChancePercent) - { - sellChance = sellConfig.MinSellChancePercent; - } + if (sellChance < sellConfig.MinSellChancePercent) sellChance = sellConfig.MinSellChancePercent; // Adjust sell chance if above config value - if (sellChance > sellConfig.MaxSellChancePercent) - { - sellChance = sellConfig.MaxSellChancePercent; - } + if (sellChance > sellConfig.MaxSellChancePercent) sellChance = sellConfig.MaxSellChancePercent; return sellChance; } @@ -83,16 +77,10 @@ public class RagfairSellHelper( _logger.Warning($"Sell chance was not a number: {sellChancePercent}, defaulting to {_ragfairConfig.Sell.Chance.Base}%"); } - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Rolling to sell: { itemSellCount}items(chance: { effectiveSellChance}%)"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Rolling to sell: {itemSellCount}items(chance: {effectiveSellChance}%)"); // No point rolling for a sale on a 0% chance item, exit early - if (effectiveSellChance == 0) - { - return result; - } + if (effectiveSellChance == 0) return result; while (remainingCount > 0 && sellTimestamp < endTime) { @@ -102,34 +90,24 @@ public class RagfairSellHelper( // Passed roll check, item will be sold // Weight time to sell towards selling faster based on how cheap the item sold var weighting = (100 - effectiveSellChance) / 100; - var maximumTime = weighting * (_ragfairConfig.Sell.Time.Max * 60); + var maximumTime = weighting * _ragfairConfig.Sell.Time.Max * 60; var minimumTime = _ragfairConfig.Sell.Time.Min * 60; - if (maximumTime < minimumTime) - { - maximumTime = minimumTime + 5; - } + if (maximumTime < minimumTime) maximumTime = minimumTime + 5; // Sell time will be random between min/max var random = new Random(); var newSellTime = Math.Floor(random.NextDouble() * (maximumTime.Value - minimumTime.Value) + minimumTime.Value); if (newSellTime == 0) - { // Ensure all sales don't occur the same exact time newSellTime += 1; - } sellTimestamp += (long)newSellTime; - result.Add( new SellResult{ SellTime = sellTimestamp, Amount = boughtAmount }); + result.Add(new SellResult { SellTime = sellTimestamp, Amount = boughtAmount }); if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Offer will sell at: { _timeUtil.GetDateTimeFromTimeStamp(sellTimestamp).ToLocalTime().ToString()}, bought: {boughtAmount}"); - } + _logger.Debug($"Offer will sell at: {_timeUtil.GetDateTimeFromTimeStamp(sellTimestamp).ToLocalTime().ToString()}, bought: {boughtAmount}"); } else { - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Offer rolled not to sell, item count: { boughtAmount}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Offer rolled not to sell, item count: {boughtAmount}"); } remainingCount -= boughtAmount; diff --git a/Libraries/Core/Helpers/RagfairServerHelper.cs b/Libraries/Core/Helpers/RagfairServerHelper.cs index 25d49f3f..155e6daa 100644 --- a/Libraries/Core/Helpers/RagfairServerHelper.cs +++ b/Libraries/Core/Helpers/RagfairServerHelper.cs @@ -28,10 +28,10 @@ public class RagfairServerHelper( ICloner cloner ) { - protected RagfairConfig ragfairConfig = configServer.GetConfig(); - protected QuestConfig questConfig = configServer.GetConfig(); protected static string goodsReturnedTemplate = "5bdabfe486f7743e1665df6e 0"; // Your item was not sold - + protected QuestConfig questConfig = configServer.GetConfig(); + protected RagfairConfig ragfairConfig = configServer.GetConfig(); + /** * Is item valid / on blacklist / quest item * @param itemDetails @@ -42,21 +42,16 @@ public class RagfairServerHelper( var blacklistConfig = ragfairConfig.Dynamic.Blacklist; // Skip invalid items - if (!itemDetails.Key) { - return false; - } + if (!itemDetails.Key) return false; - if (!itemHelper.IsValidItem(itemDetails.Value.Id)) { - return false; - } + if (!itemHelper.IsValidItem(itemDetails.Value.Id)) return false; // Skip bsg blacklisted items - if (blacklistConfig.EnableBsgList && !(itemDetails.Value?.Properties?.CanSellOnRagfair ?? false)) { - return false; - } + if (blacklistConfig.EnableBsgList && !(itemDetails.Value?.Properties?.CanSellOnRagfair ?? false)) return false; // Skip custom blacklisted items and flag as unsellable by players - if (IsItemOnCustomFleaBlacklist(itemDetails.Value.Id)) { + if (IsItemOnCustomFleaBlacklist(itemDetails.Value.Id)) + { itemDetails.Value.Properties.CanSellOnRagfair = false; return false; @@ -66,23 +61,19 @@ public class RagfairServerHelper( if ( blacklistConfig.EnableCustomItemCategoryList && IsItemCategoryOnCustomFleaBlacklist(itemDetails.Value.Parent) - ) { + ) return false; - } // Skip quest items - if (blacklistConfig.EnableQuestList && itemHelper.IsQuestItem(itemDetails.Value.Id)) { - return false; - } + if (blacklistConfig.EnableQuestList && itemHelper.IsQuestItem(itemDetails.Value.Id)) return false; // Don't include damaged ammo packs if ( ragfairConfig.Dynamic.Blacklist.DamagedAmmoPacks && itemDetails.Value.Parent == BaseClasses.AMMO_BOX && itemDetails.Value.Name.Contains("_damaged") - ) { + ) return false; - } return true; } @@ -102,7 +93,8 @@ public class RagfairServerHelper( * @param parentId Parent Id to check is blacklisted * @returns true if blacklisted */ - protected bool IsItemCategoryOnCustomFleaBlacklist(string itemParentId) { + protected bool IsItemCategoryOnCustomFleaBlacklist(string itemParentId) + { return ragfairConfig.Dynamic.Blacklist.CustomItemCategoryList.Contains(itemParentId); } @@ -111,7 +103,8 @@ public class RagfairServerHelper( * @param traderId * @returns True if id was a trader */ - public bool IsTrader(string traderId) { + public bool IsTrader(string traderId) + { return databaseService.GetTraders().ContainsKey(traderId); } @@ -126,9 +119,9 @@ public class RagfairServerHelper( sessionID, traderHelper.GetTraderById(Traders.RAGMAN).ToString(), MessageType.MESSAGE_WITH_ITEMS, - RagfairServerHelper.goodsReturnedTemplate, + goodsReturnedTemplate, returnedItems, - timeUtil.GetHoursAsSeconds((int) databaseService.GetGlobals().Configuration.RagFair.YourOfferDidNotSellMaxStorageTimeInHour) + timeUtil.GetHoursAsSeconds((int)databaseService.GetGlobals().Configuration.RagFair.YourOfferDidNotSellMaxStorageTimeInHour) ); } @@ -138,31 +131,25 @@ public class RagfairServerHelper( // Lookup item details - check if item not found var itemDetails = itemHelper.GetItem(tplId); - if (!itemDetails.Key) { + if (!itemDetails.Key) throw new Exception( localisationService.GetText( "ragfair-item_not_in_db_unable_to_generate_dynamic_stack_count", tplId ) ); - } // Item Types to return one of if (isWeaponPreset || itemHelper.IsOfBaseclasses(itemDetails.Value.Id, ragfairConfig.Dynamic.ShowAsSingleStack) - ) - { + ) return 1; - } // Get max possible stack count var maxStackSize = itemDetails.Value?.Properties?.StackMaxSize ?? 1; // non-stackable - use different values to calculate stack size - if (maxStackSize == 1) - { - return (int)randomUtil.GetDouble(config.NonStackableCount.Min.Value, config.NonStackableCount.Max.Value); - } + if (maxStackSize == 1) return (int)randomUtil.GetDouble(config.NonStackableCount.Min.Value, config.NonStackableCount.Max.Value); // Get a % to get of stack size var stackPercent = randomUtil.GetDouble(config.StackablePercent.Min.Value, config.StackablePercent.Max.Value); @@ -180,13 +167,11 @@ public class RagfairServerHelper( var currencies = ragfairConfig.Dynamic.Currencies; var bias = new List(); - foreach (var item in currencies.Keys) { - for (var i = 0; i < currencies[item]; i++) { + foreach (var item in currencies.Keys) + for (var i = 0; i < currencies[item]; i++) bias.Add(item); - } - } - var index = Math.Min((int)Math.Floor((randomUtil.RandNum(0, 1, 14) * bias.Count)), 99); + var index = Math.Min((int)Math.Floor(randomUtil.RandNum(0, 1, 14) * bias.Count), 99); return bias[index]; } @@ -210,12 +195,13 @@ public class RagfairServerHelper( public List GetPresetItemsByTpl(Item item) { var presets = new List(); - foreach (var itemId in databaseService.GetGlobals().ItemPresets.Keys) { - if (databaseService.GetGlobals().ItemPresets[itemId].Items[0].Template == item.Template) { + foreach (var itemId in databaseService.GetGlobals().ItemPresets.Keys) + if (databaseService.GetGlobals().ItemPresets[itemId].Items[0].Template == item.Template) + { var presetItems = cloner.Clone(databaseService.GetGlobals().ItemPresets[itemId].Items); presets.AddRange(itemHelper.ReparentItemAndChildren(item, presetItems)); } - } + return presets; } } diff --git a/Libraries/Core/Helpers/RagfairSortHelper.cs b/Libraries/Core/Helpers/RagfairSortHelper.cs index 21f4ecd5..4ea3a123 100644 --- a/Libraries/Core/Helpers/RagfairSortHelper.cs +++ b/Libraries/Core/Helpers/RagfairSortHelper.cs @@ -47,10 +47,7 @@ public class RagfairSortHelper( } // 0=ASC 1=DESC - if (direction == 1) - { - offers.Reverse(); - } + if (direction == 1) offers.Reverse(); return offers; } diff --git a/Libraries/Core/Helpers/RepairHelper.cs b/Libraries/Core/Helpers/RepairHelper.cs index 5c1eb931..f7eefcea 100644 --- a/Libraries/Core/Helpers/RepairHelper.cs +++ b/Libraries/Core/Helpers/RepairHelper.cs @@ -43,10 +43,7 @@ public class RepairHelper( bool applyMaxDurabilityDegradation = true ) { - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Adding {amountToRepair} to {itemToRepairDetails.Name} using kit: {useRepairKit}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Adding {amountToRepair} to {itemToRepairDetails.Name} using kit: {useRepairKit}"); var itemMaxDurability = _cloner.Clone(itemToRepair.Upd.Repairable.MaxDurability); var itemCurrentDurability = _cloner.Clone(itemToRepair.Upd.Repairable.Durability); @@ -56,48 +53,42 @@ public class RepairHelper( var newCurrentMaxDurability = itemCurrentMaxDurability + amountToRepair; // Ensure new max isnt above items max - if (newCurrentMaxDurability > itemMaxDurability) { - newCurrentMaxDurability = itemMaxDurability; - } + if (newCurrentMaxDurability > itemMaxDurability) newCurrentMaxDurability = itemMaxDurability; // Ensure new current isnt above items max - if (newCurrentDurability > itemMaxDurability) { - newCurrentDurability = itemMaxDurability; - } + if (newCurrentDurability > itemMaxDurability) newCurrentDurability = itemMaxDurability; // Update Repairable properties with new values after repair itemToRepair.Upd.Repairable = new UpdRepairable { Durability = newCurrentDurability, MaxDurability = newCurrentMaxDurability }; // when modders set the repair coefficient to 0 it means that they dont want to lose durability on items // the code below generates a random degradation on the weapon durability - if (applyMaxDurabilityDegradation) { + if (applyMaxDurabilityDegradation) + { var randomisedWearAmount = isArmor ? GetRandomisedArmorRepairDegradationValue( - itemToRepairDetails.Properties.ArmorMaterial.Value, - useRepairKit, - itemCurrentMaxDurability ?? 0, - traderQualityMultipler - ) + itemToRepairDetails.Properties.ArmorMaterial.Value, + useRepairKit, + itemCurrentMaxDurability ?? 0, + traderQualityMultipler + ) : GetRandomisedWeaponRepairDegradationValue( - itemToRepairDetails.Properties, - useRepairKit, - itemCurrentMaxDurability ?? 0, - traderQualityMultipler - ); + itemToRepairDetails.Properties, + useRepairKit, + itemCurrentMaxDurability ?? 0, + traderQualityMultipler + ); // Apply wear to durability itemToRepair.Upd.Repairable.MaxDurability -= randomisedWearAmount; // After adjusting max durability with degradation, ensure current dura isnt above max - if (itemToRepair.Upd.Repairable.Durability > itemToRepair.Upd.Repairable.MaxDurability) { + if (itemToRepair.Upd.Repairable.Durability > itemToRepair.Upd.Repairable.MaxDurability) itemToRepair.Upd.Repairable.Durability = itemToRepair.Upd.Repairable.MaxDurability; - } } // Repair mask cracks - if (itemToRepair.Upd.FaceShield is not null && itemToRepair.Upd.FaceShield?.Hits > 0) { - itemToRepair.Upd.FaceShield.Hits = 0; - } + if (itemToRepair.Upd.FaceShield is not null && itemToRepair.Upd.FaceShield?.Hits > 0) itemToRepair.Upd.FaceShield.Hits = 0; } /// @@ -117,9 +108,7 @@ public class RepairHelper( { // Degradation value is based on the armor material if (!_databaseService.GetGlobals().Configuration.ArmorMaterials.TryGetValue(material, out var armorMaterialSettings)) - { _logger.Error($"Unable to find armor with a type of: {material}"); - } var minMultiplier = isRepairKit ? armorMaterialSettings.MinRepairKitDegradation @@ -154,9 +143,7 @@ public class RepairHelper( var maxRepairDeg = isRepairKit ? itemProps.MaxRepairKitDegradation : itemProps.MaxRepairDegradation; // WORKAROUND: Some items are always 0 when repairkit is true - if (maxRepairDeg == 0) { - maxRepairDeg = itemProps.MaxRepairDegradation; - } + if (maxRepairDeg == 0) maxRepairDeg = itemProps.MaxRepairDegradation; var duraLossPercent = _randomUtil.GetDouble((double)minRepairDeg, (double)maxRepairDeg); var duraLossMultipliedByTraderMultiplier = duraLossPercent * weaponMax * traderQualityMultipler; diff --git a/Libraries/Core/Helpers/RewardHelper.cs b/Libraries/Core/Helpers/RewardHelper.cs index ae23ceb2..56b31ba5 100644 --- a/Libraries/Core/Helpers/RewardHelper.cs +++ b/Libraries/Core/Helpers/RewardHelper.cs @@ -10,416 +10,389 @@ using Core.Utils; using Core.Utils.Cloners; using SptCommon.Annotations; -namespace Core.Helpers +namespace Core.Helpers; + +[Injectable] +public class RewardHelper( + ISptLogger _logger, + HashUtil _hashUtil, + TimeUtil _timeUtil, + ItemHelper _itemHelper, + DatabaseService _databaseService, + ProfileHelper _profileHelper, + LocalisationService _localisationService, + TraderHelper _traderHelper, + PresetHelper _presetHelper, + ICloner _cloner, + PlayerService _playerService +) { - [Injectable] - public class RewardHelper( - ISptLogger _logger, - HashUtil _hashUtil, - TimeUtil _timeUtil, - ItemHelper _itemHelper, - DatabaseService _databaseService, - ProfileHelper _profileHelper, - LocalisationService _localisationService, - TraderHelper _traderHelper, - PresetHelper _presetHelper, - ICloner _cloner, - PlayerService _playerService + /** + * Apply the given rewards to the passed in profile + * @param rewards List of rewards to apply + * @param source The source of the rewards (Achievement, quest) + * @param fullProfile The full profile to apply the rewards to + * @param questId The quest or achievement ID, used for finding production unlocks + * @param questResponse Response to quest completion when a production is unlocked + * @returns List of items that were rewarded + */ + public List ApplyRewards( + List rewards, + string source, + SptProfile fullProfile, + PmcData profileData, + string questId, + ItemEventRouterResponse questResponse = null ) { - /** - * Apply the given rewards to the passed in profile - * @param rewards List of rewards to apply - * @param source The source of the rewards (Achievement, quest) - * @param fullProfile The full profile to apply the rewards to - * @param questId The quest or achievement ID, used for finding production unlocks - * @param questResponse Response to quest completion when a production is unlocked - * @returns List of items that were rewarded - */ - public List ApplyRewards( - List rewards, - string source, - SptProfile fullProfile, - PmcData profileData, - string questId, - ItemEventRouterResponse questResponse = null - ) + var sessionId = fullProfile?.ProfileInfo?.ProfileId; + var pmcProfile = fullProfile?.CharacterData.PmcData; + if (pmcProfile is null) { - var sessionId = fullProfile?.ProfileInfo?.ProfileId; - var pmcProfile = fullProfile?.CharacterData.PmcData; - if (pmcProfile is null) - { - _logger.Error($"Unable to get pmc profile for: {sessionId}, no rewards given"); - return []; - } - - var gameVersion = pmcProfile.Info.GameVersion; - - foreach (var reward in rewards) - { - // Handle reward availability for different game versions, notAvailableInGameEditions currently not used - if (!RewardIsForGameEdition(reward, gameVersion)) - { - continue; - } - - switch (reward.Type) - { - case RewardType.Skill: - // This needs to use the passed in profileData, as it could be the scav profile - _profileHelper.AddSkillPointsToPlayer( - profileData, - Enum.Parse(reward.Target), - reward.Value as double? - ); - break; - case RewardType.Experience: - _profileHelper.AddExperienceToPmc( - sessionId, - int.Parse(reward.Value.ToString()) - ); // this must occur first as the output object needs to take the modified profile exp value - // Recalculate level in event player leveled up - pmcProfile.Info.Level = _playerService.CalculateLevel(pmcProfile); - break; - case RewardType.TraderStanding: - _traderHelper.AddStandingToTrader( - sessionId, - reward.Target, - double.Parse(reward.Value.ToString()) - ); - break; - case RewardType.TraderUnlock: - _traderHelper.SetTraderUnlockedState(reward.Target, true, sessionId); - break; - case RewardType.Item: - // Item rewards are retrieved by getRewardItems() below, and returned to be handled by caller - break; - case RewardType.AssortmentUnlock: - // Handled by getAssort(), locked assorts are stripped out by `assortHelper.stripLockedLoyaltyAssort()` before being sent to player - break; - case RewardType.Achievement: - AddAchievementToProfile(fullProfile, reward.Target); - break; - case RewardType.StashRows: - _profileHelper.AddStashRowsBonusToProfile( - sessionId, - (int)reward.Value - ); // Add specified stash rows from reward - requires client restart - break; - case RewardType.ProductionScheme: - FindAndAddHideoutProductionIdToProfile(pmcProfile, reward, questId, sessionId, questResponse); - break; - case RewardType.Pockets: - _profileHelper.ReplaceProfilePocketTpl(pmcProfile, reward.Target); - break; - case RewardType.CustomizationDirect: - _profileHelper.AddHideoutCustomisationUnlock(fullProfile, reward, source); - break; - default: - _logger.Error( - _localisationService.GetText( - "reward-type_not_handled", - new - { - rewardType = reward.Type, - questId = questId, - } - ) - ); - break; - } - } - - return GetRewardItems(rewards, gameVersion); + _logger.Error($"Unable to get pmc profile for: {sessionId}, no rewards given"); + return []; } - /** - * Does the provided reward have a game version requirement to be given and does it match - * @param reward Reward to check - * @param gameVersion Version of game to check reward against - * @returns True if it has requirement, false if it doesnt pass check + var gameVersion = pmcProfile.Info.GameVersion; + + foreach (var reward in rewards) + { + // Handle reward availability for different game versions, notAvailableInGameEditions currently not used + if (!RewardIsForGameEdition(reward, gameVersion)) continue; + + switch (reward.Type) + { + case RewardType.Skill: + // This needs to use the passed in profileData, as it could be the scav profile + _profileHelper.AddSkillPointsToPlayer( + profileData, + Enum.Parse(reward.Target), + reward.Value as double? + ); + break; + case RewardType.Experience: + _profileHelper.AddExperienceToPmc( + sessionId, + int.Parse(reward.Value.ToString()) + ); // this must occur first as the output object needs to take the modified profile exp value + // Recalculate level in event player leveled up + pmcProfile.Info.Level = _playerService.CalculateLevel(pmcProfile); + break; + case RewardType.TraderStanding: + _traderHelper.AddStandingToTrader( + sessionId, + reward.Target, + double.Parse(reward.Value.ToString()) + ); + break; + case RewardType.TraderUnlock: + _traderHelper.SetTraderUnlockedState(reward.Target, true, sessionId); + break; + case RewardType.Item: + // Item rewards are retrieved by getRewardItems() below, and returned to be handled by caller + break; + case RewardType.AssortmentUnlock: + // Handled by getAssort(), locked assorts are stripped out by `assortHelper.stripLockedLoyaltyAssort()` before being sent to player + break; + case RewardType.Achievement: + AddAchievementToProfile(fullProfile, reward.Target); + break; + case RewardType.StashRows: + _profileHelper.AddStashRowsBonusToProfile( + sessionId, + (int)reward.Value + ); // Add specified stash rows from reward - requires client restart + break; + case RewardType.ProductionScheme: + FindAndAddHideoutProductionIdToProfile(pmcProfile, reward, questId, sessionId, questResponse); + break; + case RewardType.Pockets: + _profileHelper.ReplaceProfilePocketTpl(pmcProfile, reward.Target); + break; + case RewardType.CustomizationDirect: + _profileHelper.AddHideoutCustomisationUnlock(fullProfile, reward, source); + break; + default: + _logger.Error( + _localisationService.GetText( + "reward-type_not_handled", + new + { + rewardType = reward.Type, + questId = questId + } + ) + ); + break; + } + } + + return GetRewardItems(rewards, gameVersion); + } + + /** + * Does the provided reward have a game version requirement to be given and does it match + * @param reward Reward to check + * @param gameVersion Version of game to check reward against + * @returns True if it has requirement, false if it doesnt pass check + */ + public bool RewardIsForGameEdition(Reward reward, string gameVersion) + { + if (reward.AvailableInGameEditions?.Count > 0 && !reward.AvailableInGameEditions.Contains(gameVersion)) + // Reward has edition whitelist and game version isn't in it + return false; + + if (reward.NotAvailableInGameEditions?.Count > 0 && + reward.NotAvailableInGameEditions.Contains(gameVersion)) + // Reward has edition blacklist and game version is in it + return false; + + // No whitelist/blacklist or reward isn't blacklisted/whitelisted + return true; + } + + /** + * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile + * also update client response recipeUnlocked array with craft id + * @param pmcData Player profile + * @param craftUnlockReward Reward with craft unlock details + * @param questId Quest or achievement ID with craft unlock reward + * @param sessionID Session id + * @param response Response to send back to client */ - public bool RewardIsForGameEdition(Reward reward, string gameVersion) + protected void FindAndAddHideoutProductionIdToProfile( + PmcData pmcData, + Reward craftUnlockReward, + string questId, + string sessionID, + ItemEventRouterResponse response) + { + var matchingProductions = GetRewardProductionMatch(craftUnlockReward, questId); + if (matchingProductions.Count != 1) { - if (reward.AvailableInGameEditions?.Count > 0 && !reward.AvailableInGameEditions.Contains(gameVersion)) - { - // Reward has edition whitelist and game version isn't in it - return false; - } + _logger.Error( + _localisationService.GetText( + "reward-unable_to_find_matching_hideout_production", + new + { + questId = questId, + matchCount = matchingProductions.Count + } + ) + ); - if (reward.NotAvailableInGameEditions?.Count > 0 && - reward.NotAvailableInGameEditions.Contains(gameVersion)) - { - // Reward has edition blacklist and game version is in it - return false; - } - - // No whitelist/blacklist or reward isn't blacklisted/whitelisted - return true; + return; } - /** - * WIP - Find hideout craft id and add to unlockedProductionRecipe array in player profile - * also update client response recipeUnlocked array with craft id - * @param pmcData Player profile - * @param craftUnlockReward Reward with craft unlock details - * @param questId Quest or achievement ID with craft unlock reward - * @param sessionID Session id - * @param response Response to send back to client - */ - protected void FindAndAddHideoutProductionIdToProfile( - PmcData pmcData, - Reward craftUnlockReward, - string questId, - string sessionID, - ItemEventRouterResponse response) + // Add above match to pmc profile + client response + var matchingCraftId = matchingProductions[0].Id; + pmcData.UnlockedInfo.UnlockedProductionRecipe.Add(matchingCraftId); + if (response is not null) { - var matchingProductions = GetRewardProductionMatch(craftUnlockReward, questId); - if (matchingProductions.Count != 1) - { - _logger.Error( - _localisationService.GetText( - "reward-unable_to_find_matching_hideout_production", - new - { - questId = questId, - matchCount = matchingProductions.Count, - } - ) - ); - - return; - } - - // Add above match to pmc profile + client response - var matchingCraftId = matchingProductions[0].Id; - pmcData.UnlockedInfo.UnlockedProductionRecipe.Add(matchingCraftId); - if (response is not null) - { - response.ProfileChanges[sessionID].RecipeUnlocked ??= new Dictionary(); - response.ProfileChanges[sessionID].RecipeUnlocked[matchingCraftId] = true; - } + response.ProfileChanges[sessionID].RecipeUnlocked ??= new Dictionary(); + response.ProfileChanges[sessionID].RecipeUnlocked[matchingCraftId] = true; } + } - /** - * Find hideout craft for the specified reward - * @param craftUnlockReward Reward with craft unlock details - * @param questId Quest or achievement ID with craft unlock reward - * @returns Hideout craft - */ - public List GetRewardProductionMatch(Reward craftUnlockReward, string questId) - { - // Get hideout crafts and find those that match by areatype/required level/end product tpl - hope for just one match - var craftingRecipes = _databaseService.GetHideout().Production.Recipes; + /** + * Find hideout craft for the specified reward + * @param craftUnlockReward Reward with craft unlock details + * @param questId Quest or achievement ID with craft unlock reward + * @returns Hideout craft + */ + public List GetRewardProductionMatch(Reward craftUnlockReward, string questId) + { + // Get hideout crafts and find those that match by areatype/required level/end product tpl - hope for just one match + var craftingRecipes = _databaseService.GetHideout().Production.Recipes; - // Area that will be used to craft unlocked item - var desiredHideoutAreaType = (HideoutAreas)int.Parse(craftUnlockReward.TraderId.ToString()); + // Area that will be used to craft unlocked item + var desiredHideoutAreaType = (HideoutAreas)int.Parse(craftUnlockReward.TraderId.ToString()); - var matchingProductions = craftingRecipes.Where( + var matchingProductions = craftingRecipes.Where( + (prod) => + prod.AreaType == desiredHideoutAreaType && + //prod.requirements.some((requirement) => requirement.questId == questId) && // BSG don't store the quest id in requirement any more! + prod.Requirements.Any((requirement) => requirement.Type == "QuestComplete") && + prod.Requirements.Any( + (requirement) => requirement.RequiredLevel == craftUnlockReward.LoyaltyLevel + ) && + prod.EndProduct == craftUnlockReward.Items.FirstOrDefault().Template + ) + .ToList(); + + // More/less than single match, above filtering wasn't strict enough + if (matchingProductions.Count() != 1) + // Multiple matches were found, last ditch attempt to match by questid (value we add manually to production.json via `gen:productionquests` command) + matchingProductions = matchingProductions.Where( (prod) => - prod.AreaType == desiredHideoutAreaType && - //prod.requirements.some((requirement) => requirement.questId == questId) && // BSG don't store the quest id in requirement any more! - prod.Requirements.Any((requirement) => requirement.Type == "QuestComplete") && - prod.Requirements.Any( - (requirement) => requirement.RequiredLevel == craftUnlockReward.LoyaltyLevel - ) && - prod.EndProduct == craftUnlockReward.Items.FirstOrDefault().Template + prod.Requirements.Any((requirement) => requirement.QuestId == questId) ) .ToList(); - // More/less than single match, above filtering wasn't strict enough - if (matchingProductions.Count() != 1) - { - // Multiple matches were found, last ditch attempt to match by questid (value we add manually to production.json via `gen:productionquests` command) - matchingProductions = matchingProductions.Where( - (prod) => - prod.Requirements.Any((requirement) => requirement.QuestId == questId) - ) - .ToList(); - } + return matchingProductions; + } - return matchingProductions; + /** + * Gets a flat list of reward items from the given rewards for the specified game version + * @param rewards Array of rewards to get the items from + * @param gameVersion The game version of the profile + * @returns array of items with the correct maxStack + */ + protected List GetRewardItems(List rewards, string gameVersion) + { + // Iterate over all rewards with the desired status, flatten out items that have a type of Item + var rewardItems = rewards.SelectMany( + (reward) => + reward.Type == RewardType.Item && RewardIsForGameEdition(reward, gameVersion) + ? ProcessReward(reward) + : [] + ); + + return rewardItems.ToList(); + } + + /** + * Take reward item and set FiR status + fix stack sizes + fix mod Ids + * @param reward Reward item to fix + * @returns Fixed rewards + */ + protected List ProcessReward(Reward reward) + { + /** item with mods to return */ + List rewardItems = []; + List targets = []; + List mods = []; + + // Is armor item that may need inserts / plates + if (reward.Items.Count == 1 && _itemHelper.ArmorItemCanHoldMods(reward.Items[0].Template)) + // Only process items with slots + if (_itemHelper.ItemHasSlots(reward.Items.FirstOrDefault().Template)) + // Attempt to pull default preset from globals and add child items to reward (clones reward.items) + GenerateArmorRewardChildSlots(reward.Items.FirstOrDefault(), reward); + + foreach (var rewardItem in reward.Items) + { + _itemHelper.AddUpdObjectToItem(rewardItem); + + // Reward items are granted Found in Raid status + _itemHelper.SetFoundInRaid(rewardItem); + + // Is root item, fix stacks + if (rewardItem.Id == reward.Target) + { + // Is base reward item + if ( + rewardItem.ParentId != null && + rewardItem.ParentId == "hideout" && // Has parentId of hideout + rewardItem.Upd != null && + rewardItem.Upd.StackObjectsCount != null && // Has upd with stackobject count + rewardItem.Upd.StackObjectsCount > 1 // More than 1 item in stack + ) + rewardItem.Upd.StackObjectsCount = 1; + + targets = _itemHelper.SplitStack(rewardItem); + // splitStack created new ids for the new stacks. This would destroy the relation to possible children. + // Instead, we reset the id to preserve relations and generate a new id in the downstream loop, where we are also reparenting if required + foreach (var target in targets) target.Id = rewardItem.Id; + } + else + { + // Is child mod + if (reward.Items.FirstOrDefault().Upd.SpawnedInSession.GetValueOrDefault(false)) + // Propigate FiR status into child items + rewardItem.Upd.SpawnedInSession = reward.Items.FirstOrDefault()?.Upd.SpawnedInSession; + + mods.Add(rewardItem); + } } - /** - * Gets a flat list of reward items from the given rewards for the specified game version - * @param rewards Array of rewards to get the items from - * @param gameVersion The game version of the profile - * @returns array of items with the correct maxStack + // Add mods to the base items, fix ids + foreach (var target in targets) + { + // This has all the original id relations since we reset the id to the original after the splitStack + var itemsClone = new List { _cloner.Clone(target) }; + // Here we generate a new id for the root item + target.Id = _hashUtil.Generate(); + + // Add cloned mods to root item array + var clonedMods = _cloner.Clone(mods); + foreach (var mod in clonedMods) itemsClone.Add(mod); + + // Re-parent items + generate new ids to ensure valid ids + var itemsToAdd = _itemHelper.ReparentItemAndChildren(target, itemsClone); + rewardItems.AddRange(itemsToAdd); + } + + return rewardItems; + } + + /** + * Add missing mod items to an armor reward + * @param originalRewardRootItem Original armor reward item from IReward.items object + * @param reward Armor reward + */ + protected void GenerateArmorRewardChildSlots(Item originalRewardRootItem, Reward reward) + { + // Look for a default preset from globals for armor + var defaultPreset = _presetHelper.GetDefaultPreset(originalRewardRootItem.Template); + if (defaultPreset is not null) + { + // Found preset, use mods to hydrate reward item + var presetAndMods = _itemHelper.ReplaceIDs(_cloner.Clone(defaultPreset.Items)); + var newRootId = _itemHelper.RemapRootItemId(presetAndMods); + + reward.Items = presetAndMods; + + // Find root item and set its stack count + var rootItem = reward.Items.FirstOrDefault((item) => item.Id == newRootId); + + // Remap target id to the new presets root id + reward.Target = rootItem.Id; + + // Copy over stack count otherwise reward shows as missing in client + _itemHelper.AddUpdObjectToItem(rootItem); + rootItem.Upd.StackObjectsCount = originalRewardRootItem.Upd.StackObjectsCount; + return; + } + + _logger.Warning( + "Unable to find default preset for armor {originalRewardRootItem._tpl}, adding mods manually" + ); + var itemDbData = _itemHelper.GetItem(originalRewardRootItem.Template).Value; + + // Hydrate reward with only 'required' mods - necessary for things like helmets otherwise you end up with nvgs/visors etc + reward.Items = _itemHelper.AddChildSlotItems(reward.Items, itemDbData, null, true); + } + + /** + * Add an achievement to player profile and handle any rewards for the achievement + * Triggered from a quest, or another achievement + * @param fullProfile Profile to add achievement to + * @param achievementId Id of achievement to add */ - protected List GetRewardItems(List rewards, string gameVersion) - { - // Iterate over all rewards with the desired status, flatten out items that have a type of Item - var rewardItems = rewards.SelectMany( - (reward) => - reward.Type == RewardType.Item && RewardIsForGameEdition(reward, gameVersion) - ? ProcessReward(reward) - : [] - ); + public void AddAchievementToProfile(SptProfile fullProfile, string achievementId) + { + // Add achievement id to profile with timestamp it was unlocked + fullProfile.CharacterData.PmcData.Achievements[achievementId] = _timeUtil.GetTimeStamp(); - return rewardItems.ToList(); - } + // Check for any customisation unlocks + var achievementDataDb = _databaseService + .GetTemplates() + .Achievements.FirstOrDefault((achievement) => achievement.Id == achievementId); + if (achievementDataDb is null) return; - /** - * Take reward item and set FiR status + fix stack sizes + fix mod Ids - * @param reward Reward item to fix - * @returns Fixed rewards - */ - protected List ProcessReward(Reward reward) - { - /** item with mods to return */ - List rewardItems = []; - List targets = []; - List mods = []; - - // Is armor item that may need inserts / plates - if (reward.Items.Count == 1 && _itemHelper.ArmorItemCanHoldMods(reward.Items[0].Template)) - { - // Only process items with slots - if (_itemHelper.ItemHasSlots(reward.Items.FirstOrDefault().Template)) - { - // Attempt to pull default preset from globals and add child items to reward (clones reward.items) - GenerateArmorRewardChildSlots(reward.Items.FirstOrDefault(), reward); - } - } - - foreach (var rewardItem in reward.Items) - { - _itemHelper.AddUpdObjectToItem(rewardItem); - - // Reward items are granted Found in Raid status - _itemHelper.SetFoundInRaid(rewardItem); - - // Is root item, fix stacks - if (rewardItem.Id == reward.Target) - { - // Is base reward item - if ( - rewardItem.ParentId != null && - rewardItem.ParentId == "hideout" && // Has parentId of hideout - rewardItem.Upd != null && - rewardItem.Upd.StackObjectsCount != null && // Has upd with stackobject count - rewardItem.Upd.StackObjectsCount > 1 // More than 1 item in stack - ) - { - rewardItem.Upd.StackObjectsCount = 1; - } - - targets = _itemHelper.SplitStack(rewardItem); - // splitStack created new ids for the new stacks. This would destroy the relation to possible children. - // Instead, we reset the id to preserve relations and generate a new id in the downstream loop, where we are also reparenting if required - foreach (var target in targets) - { - target.Id = rewardItem.Id; - } - } - else - { - // Is child mod - if (reward.Items.FirstOrDefault().Upd.SpawnedInSession.GetValueOrDefault(false)) - { - // Propigate FiR status into child items - rewardItem.Upd.SpawnedInSession = reward.Items.FirstOrDefault()?.Upd.SpawnedInSession; - } - - mods.Add(rewardItem); - } - } - - // Add mods to the base items, fix ids - foreach (var target in targets) - { - // This has all the original id relations since we reset the id to the original after the splitStack - var itemsClone = new List { _cloner.Clone(target) }; - // Here we generate a new id for the root item - target.Id = _hashUtil.Generate(); - - // Add cloned mods to root item array - var clonedMods = _cloner.Clone(mods); - foreach (var mod in clonedMods) - { - itemsClone.Add(mod); - } - - // Re-parent items + generate new ids to ensure valid ids - var itemsToAdd = _itemHelper.ReparentItemAndChildren(target, itemsClone); - rewardItems.AddRange(itemsToAdd); - } - - return rewardItems; - } - - /** - * Add missing mod items to an armor reward - * @param originalRewardRootItem Original armor reward item from IReward.items object - * @param reward Armor reward - */ - protected void GenerateArmorRewardChildSlots(Item originalRewardRootItem, Reward reward) - { - // Look for a default preset from globals for armor - var defaultPreset = _presetHelper.GetDefaultPreset(originalRewardRootItem.Template); - if (defaultPreset is not null) - { - // Found preset, use mods to hydrate reward item - var presetAndMods = _itemHelper.ReplaceIDs(_cloner.Clone(defaultPreset.Items)); - var newRootId = _itemHelper.RemapRootItemId(presetAndMods); - - reward.Items = presetAndMods; - - // Find root item and set its stack count - var rootItem = reward.Items.FirstOrDefault((item) => item.Id == newRootId); - - // Remap target id to the new presets root id - reward.Target = rootItem.Id; - - // Copy over stack count otherwise reward shows as missing in client - _itemHelper.AddUpdObjectToItem(rootItem); - rootItem.Upd.StackObjectsCount = originalRewardRootItem.Upd.StackObjectsCount; - return; - } - - _logger.Warning( - "Unable to find default preset for armor {originalRewardRootItem._tpl}, adding mods manually" - ); - var itemDbData = _itemHelper.GetItem(originalRewardRootItem.Template).Value; - - // Hydrate reward with only 'required' mods - necessary for things like helmets otherwise you end up with nvgs/visors etc - reward.Items = _itemHelper.AddChildSlotItems(reward.Items, itemDbData, null, true); - } - - /** - * Add an achievement to player profile and handle any rewards for the achievement - * Triggered from a quest, or another achievement - * @param fullProfile Profile to add achievement to - * @param achievementId Id of achievement to add - */ - public void AddAchievementToProfile(SptProfile fullProfile, string achievementId) - { - // Add achievement id to profile with timestamp it was unlocked - fullProfile.CharacterData.PmcData.Achievements[achievementId] = _timeUtil.GetTimeStamp(); - - // Check for any customisation unlocks - var achievementDataDb = _databaseService - .GetTemplates() - .Achievements.FirstOrDefault((achievement) => achievement.Id == achievementId); - if (achievementDataDb is null) - { - return; - } - - // Note: At the moment, we don't know the exact quest and achievement data layout for an achievement - // that is triggered by a quest, that gives an item, because BSG has only done this once. However - // based on deduction, I am going to assume that the *quest* will handle the initial item reward, - // and the achievement reward should only be handled post-wipe. - // All of that is to say, we are going to ignore the list of returned reward items here - var pmcProfile = fullProfile.CharacterData.PmcData; - ApplyRewards( - achievementDataDb.Rewards, - CustomisationSource.ACHIEVEMENT, - fullProfile, - pmcProfile, - achievementDataDb.Id - ); - } + // Note: At the moment, we don't know the exact quest and achievement data layout for an achievement + // that is triggered by a quest, that gives an item, because BSG has only done this once. However + // based on deduction, I am going to assume that the *quest* will handle the initial item reward, + // and the achievement reward should only be handled post-wipe. + // All of that is to say, we are going to ignore the list of returned reward items here + var pmcProfile = fullProfile.CharacterData.PmcData; + ApplyRewards( + achievementDataDb.Rewards, + CustomisationSource.ACHIEVEMENT, + fullProfile, + pmcProfile, + achievementDataDb.Id + ); } } diff --git a/Libraries/Core/Helpers/SecureContainerHelper.cs b/Libraries/Core/Helpers/SecureContainerHelper.cs index 2399c1c2..d38dc471 100644 --- a/Libraries/Core/Helpers/SecureContainerHelper.cs +++ b/Libraries/Core/Helpers/SecureContainerHelper.cs @@ -16,9 +16,7 @@ public class SecureContainerHelper(ItemHelper _itemHelper) var secureContainer = items.First((x) => x.SlotId == "SecuredContainer"); // No container found, drop out - if (secureContainer is null) { - return []; - } + if (secureContainer is null) return []; var itemsInSecureContainer = _itemHelper.FindAndReturnChildrenByItems(items, secureContainer.Id); diff --git a/Libraries/Core/Helpers/TradeHelper.cs b/Libraries/Core/Helpers/TradeHelper.cs index 0dbdc6d5..1838222a 100644 --- a/Libraries/Core/Helpers/TradeHelper.cs +++ b/Libraries/Core/Helpers/TradeHelper.cs @@ -36,8 +36,8 @@ public class TradeHelper( ICloner _cloner ) { - protected TraderConfig _traderConfig = _configServer.GetConfig(); protected InventoryConfig _inventoryConfig = _configServer.GetConfig(); + protected TraderConfig _traderConfig = _configServer.GetConfig(); /// /// Buy item from flea or trader @@ -60,7 +60,7 @@ public class TradeHelper( if (buyRequestData.TransactionId.ToLower() == "ragfair") { - buyCallback = (buyCount => + buyCallback = buyCount => { var allOffers = _ragfairServer.GetOffers(); @@ -82,7 +82,7 @@ public class TradeHelper( ); // Decrement trader item count - PurchaseDetails itemPurchaseDetails = new PurchaseDetails + var itemPurchaseDetails = new PurchaseDetails { Items = [ @@ -96,8 +96,8 @@ public class TradeHelper( }; _traderHelper.AddTraderPurchasesToPlayerProfile(sessionID, itemPurchaseDetails, itemPurchased); } - }); - + }; + // buyCallback = BuyCallback1; // Get raw offer from ragfair, clone to prevent altering offer itself var allOffers = _ragfairServer.GetOffers(); @@ -106,7 +106,7 @@ public class TradeHelper( } else if (buyRequestData.TransactionId == Traders.FENCE) { - buyCallback = (buyCount => + buyCallback = buyCount => { // Update assort/flea item values var traderAssorts = _traderHelper.GetTraderAssortsByTraderId(buyRequestData.TransactionId).Items; @@ -116,16 +116,13 @@ public class TradeHelper( itemPurchased.Upd.StackObjectsCount -= buyCount; _fenceService.AmendOrRemoveFenceOffer(buyRequestData.ItemId, buyCount); - }); + }; var fenceItems = _fenceService.GetRawFenceAssorts().Items; var rootItemIndex = fenceItems.FindIndex(item => item.Id == buyRequestData.ItemId); if (rootItemIndex == -1) { - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Tried to buy item {buyRequestData.ItemId} from fence that no longer exists"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Tried to buy item {buyRequestData.ItemId} from fence that no longer exists"); var message = _localisationService.GetText("ragfair-offer_no_longer_exists"); _httpResponseUtil.AppendErrorToOutput(output, message); @@ -136,7 +133,7 @@ public class TradeHelper( } else { - buyCallback = (buyCount => + buyCallback = buyCount => { // Update assort/flea item values var traderAssorts = _traderHelper.GetTraderAssortsByTraderId(buyRequestData.TransactionId).Items; @@ -145,7 +142,6 @@ public class TradeHelper( // Ensure purchase does not exceed trader item limit var assortHasBuyRestrictions = _itemHelper.HasBuyRestrictions(itemPurchased); if (assortHasBuyRestrictions) - { // Will throw error if check fails CheckPurchaseIsWithinTraderItemLimit( sessionID, @@ -155,15 +151,12 @@ public class TradeHelper( buyRequestData.ItemId, buyCount ); - } // Check if trader has enough stock if (itemPurchased.Upd.StackObjectsCount < buyCount) - { throw new Exception( $"Unable to purchase {buyCount} items, this would exceed the remaining stock left {itemPurchased.Upd.StackObjectsCount} from the traders assort: {buyRequestData.TransactionId} this refresh" ); - } // Decrement trader item count itemPurchased.Upd.StackObjectsCount -= buyCount; @@ -185,17 +178,14 @@ public class TradeHelper( _traderHelper.AddTraderPurchasesToPlayerProfile(sessionID, itemPurchaseDat, itemPurchased); } - }); - + }; + // Get all trader assort items var traderItems = _traderAssortHelper.GetAssort(sessionID, buyRequestData.TransactionId).Items; // Get item + children for purchase var relevantItems = _itemHelper.FindAndReturnChildrenAsItems(traderItems, buyRequestData.ItemId); - if (relevantItems.Count == 0) - { - _logger.Error($"Purchased trader: {buyRequestData.TransactionId} offer: {buyRequestData.ItemId} has no items"); - } + if (relevantItems.Count == 0) _logger.Error($"Purchased trader: {buyRequestData.TransactionId} offer: {buyRequestData.ItemId} has no items"); offerItems.AddRange(relevantItems); } @@ -217,10 +207,7 @@ public class TradeHelper( // Prevent any collisions _itemHelper.RemapRootItemId(offerClone); - if (offerClone.Count > 1) - { - _itemHelper.ReparentItemAndChildren(offerClone.FirstOrDefault(), offerClone); - } + if (offerClone.Count > 1) _itemHelper.ReparentItemAndChildren(offerClone.FirstOrDefault(), offerClone); itemsToSendToPlayer.Add(offerClone); @@ -229,7 +216,7 @@ public class TradeHelper( } // Construct request - AddItemsDirectRequest request = new AddItemsDirectRequest + var request = new AddItemsDirectRequest { ItemsWithModsToAdd = itemsToSendToPlayer, FoundInRaid = foundInRaid, @@ -239,10 +226,7 @@ public class TradeHelper( // Add items + their children to stash _inventoryHelper.AddItemsToStash(sessionID, request, pmcData, output); - if (output.Warnings?.Count > 0) - { - return; - } + if (output.Warnings?.Count > 0) return; /// Pay for purchase _paymentService.PayMoney(pmcData, buyRequestData, sessionID, output); @@ -252,7 +236,7 @@ public class TradeHelper( _httpResponseUtil.AppendErrorToOutput(output, errorMessage, BackendErrorCodes.UnknownTradingError); } } - + /// /// Sell item to trader /// @@ -273,10 +257,8 @@ public class TradeHelper( // Try to reduce perf hit as this is expensive to do every sale // MUST OCCUR PRIOR TO ITEMS BEING REMOVED FROM INVENTORY if (sellRequest.TransactionId == Traders.RAGMAN) - { // Edge case, `Circulate` quest needs to track when certain items are sold to him IncrementCirculateSoldToTraderCounter(profileWithItemsToSell, profileToReceiveMoney, sellRequest); - } var pattern = @"\s+"; @@ -296,18 +278,13 @@ public class TradeHelper( return; } - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Selling: id: {matchingItemInInventory.Id} tpl: {matchingItemInInventory.Template}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Selling: id: {matchingItemInInventory.Id} tpl: {matchingItemInInventory.Template}"); if (sellRequest.TransactionId == Traders.FENCE) - { _fenceService.AddItemsToFenceAssort( profileWithItemsToSell.Inventory.Items, matchingItemInInventory ); - } // Remove item from inventory + any child items it has _inventoryHelper.RemoveItem(profileWithItemsToSell, itemToBeRemoved.Id, sessionID, output); @@ -329,10 +306,7 @@ public class TradeHelper( ); // Player not on Circulate quest ,exit - if (activeCirculateQuest is null) - { - return; - } + if (activeCirculateQuest is null) return; // Find related task condition var taskCondition = profileToReceiveMoney.TaskConditionCounters.Values.FirstOrDefault( @@ -349,7 +323,7 @@ public class TradeHelper( // Condition exists in profile var circulateQuestDb = _databaseService.GetQuests(); - if (!circulateQuestDb.TryGetValue(circulateQuestId, out var _)) + if (!circulateQuestDb.TryGetValue(circulateQuestId, out _)) { _logger.Error($"Unable to find quest: {circulateQuestId} in db, skipping"); @@ -386,10 +360,7 @@ public class TradeHelper( } // Is sold item on the increment list - if (itemsTplsThatIncrement.List.Contains(itemDetails.Template)) - { - taskCondition.Value += itemSoldToTrader.Count; - } + if (itemsTplsThatIncrement.List.Contains(itemDetails.Template)) taskCondition.Value += itemSoldToTrader.Count; } } @@ -420,12 +391,10 @@ public class TradeHelper( (double)assortBeingPurchased.Upd?.BuyRestrictionMax, pmcData.Info.GameVersion ); - if (((traderPurchaseData?.PurchaseCount ?? 0) + count) > traderItemPurchaseLimit) - { + if ((traderPurchaseData?.PurchaseCount ?? 0) + count > traderItemPurchaseLimit) throw new Exception( $"Unable to purchase: {count} items, this would exceed your purchase limit of {traderItemPurchaseLimit} from the trader: {traderId} assort: {assortId} this refresh" ); - } } } diff --git a/Libraries/Core/Helpers/TraderAssortHelper.cs b/Libraries/Core/Helpers/TraderAssortHelper.cs index 5eb8dbbe..ead2c1b0 100644 --- a/Libraries/Core/Helpers/TraderAssortHelper.cs +++ b/Libraries/Core/Helpers/TraderAssortHelper.cs @@ -32,8 +32,8 @@ public class TraderAssortHelper( ICloner _cloner ) { + protected Dictionary> _mergedQuestAssorts = new(); protected TraderConfig _traderConfig = _configServer.GetConfig(); - protected Dictionary> _mergedQuestAssorts = new Dictionary>(); protected bool createdMergedQuestAssorts = false; /// @@ -51,16 +51,10 @@ public class TraderAssortHelper( var fullProfile = _profileHelper.GetFullProfile(sessionId); var pmcProfile = fullProfile?.CharacterData?.PmcData; - if (traderId == Traders.FENCE) - { - return _fenceService.GetFenceAssorts(pmcProfile); - } + if (traderId == Traders.FENCE) return _fenceService.GetFenceAssorts(pmcProfile); // Strip assorts player should not see yet - if (!showLockedAssorts) - { - traderClone.Assort = _assortHelper.StripLockedLoyaltyAssort(pmcProfile, traderId, traderClone.Assort); - } + if (!showLockedAssorts) traderClone.Assort = _assortHelper.StripLockedLoyaltyAssort(pmcProfile, traderId, traderClone.Assort); ResetBuyRestrictionCurrentValue(traderClone.Assort.Items); @@ -80,9 +74,7 @@ public class TraderAssortHelper( if (assortToAdjust is null) { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug($"Cannot find trader: {traderClone.Base.Nickname} assort: {assortId} to adjust BuyRestrictionCurrent value, skipping"); - } continue; } @@ -90,11 +82,9 @@ public class TraderAssortHelper( if (assortToAdjust.Upd is null) { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug( $"Unable to adjust assort {assortToAdjust.Id} item: {assortToAdjust.Template} BuyRestrictionCurrent value, assort has a null upd object" ); - } continue; } @@ -103,10 +93,10 @@ public class TraderAssortHelper( } // Get rid of quest locked assorts - if (!this.createdMergedQuestAssorts) + if (!createdMergedQuestAssorts) { HydrateMergedQuestAssorts(); - this.createdMergedQuestAssorts = true; + createdMergedQuestAssorts = true; } traderClone.Assort = _assortHelper.StripLockedQuestAssort( @@ -118,10 +108,7 @@ public class TraderAssortHelper( ); // Filter out root assorts that are blacklisted for this profile - if (fullProfile.SptData.BlacklistedItemTemplates?.Count > 0) - { - RemoveItemsFromAssort(traderClone.Assort, fullProfile.SptData.BlacklistedItemTemplates); - } + if (fullProfile.SptData.BlacklistedItemTemplates?.Count > 0) RemoveItemsFromAssort(traderClone.Assort, fullProfile.SptData.BlacklistedItemTemplates); return traderClone.Assort; } @@ -150,10 +137,7 @@ public class TraderAssortHelper( foreach (var assort in assortItems.Where(item => item.SlotId == "hideout")) { // no value to adjust - if (assort.Upd.BuyRestrictionCurrent is null) - { - continue; - } + if (assort.Upd.BuyRestrictionCurrent is null) continue; assort.Upd.BuyRestrictionCurrent = 0; } @@ -171,23 +155,16 @@ public class TraderAssortHelper( // Trader has quest assort data var trader = traders[traderId.Key]; if (trader.QuestAssort is not null) - { // Started/Success/fail foreach (var questStatus in trader.QuestAssort) - { // Each assort to quest id record - foreach (var assortId in trader.QuestAssort[questStatus.Key]) - { - // Null guard - if (!_mergedQuestAssorts.TryGetValue(questStatus.Key, out var _)) - { - _mergedQuestAssorts.TryAdd(questStatus.Key, new Dictionary()); - } + foreach (var assortId in trader.QuestAssort[questStatus.Key]) + { + // Null guard + if (!_mergedQuestAssorts.TryGetValue(questStatus.Key, out _)) _mergedQuestAssorts.TryAdd(questStatus.Key, new Dictionary()); - _mergedQuestAssorts[questStatus.Key][assortId.Key] = trader.QuestAssort[questStatus.Key][assortId.Key]; - } + _mergedQuestAssorts[questStatus.Key][assortId.Key] = trader.QuestAssort[questStatus.Key][assortId.Key]; } - } } } diff --git a/Libraries/Core/Helpers/TraderHelper.cs b/Libraries/Core/Helpers/TraderHelper.cs index 692d6b03..87ab5a98 100644 --- a/Libraries/Core/Helpers/TraderHelper.cs +++ b/Libraries/Core/Helpers/TraderHelper.cs @@ -30,9 +30,9 @@ public class TraderHelper( ConfigServer _configServer ) { - protected TraderConfig _traderConfig = _configServer.GetConfig(); - protected Dictionary _highestTraderPriceItems = new(); protected List _gameVersions = [GameEditions.EDGE_OF_DARKNESS, GameEditions.UNHEARD]; + protected Dictionary _highestTraderPriceItems = new(); + protected TraderConfig _traderConfig = _configServer.GetConfig(); /// @@ -45,12 +45,10 @@ public class TraderHelper( public TraderBase? GetTrader(string traderID, string sessionID) { if (traderID == "ragfair") - { - return new() + return new TraderBase { Currency = CurrencyType.RUB }; - } var pmcData = _profileHelper.GetPmcProfile(sessionID); if (pmcData == null) @@ -94,10 +92,7 @@ public class TraderHelper( var traderAssorts = GetTraderAssortsByTraderId(traderId); if (traderAssorts is null) { - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"No assorts on trader: {traderId} found"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"No assorts on trader: {traderId} found"); return null; } @@ -106,10 +101,7 @@ public class TraderHelper( var purchasedAssort = traderAssorts.Items.FirstOrDefault(item => item.Id == assortId); if (purchasedAssort is null) { - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"No assort {assortId} on trader: {traderId} found"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"No assort {assortId} on trader: {traderId} found"); return null; } @@ -129,15 +121,12 @@ public class TraderHelper( var trader = _databaseService.GetTrader(traderID); var fullProfile = _profileHelper.GetFullProfile(sessionID); - if (fullProfile is null) - { - throw new Exception(_localisationService.GetText("trader-unable_to_find_profile_by_id", sessionID)); - } + if (fullProfile is null) throw new Exception(_localisationService.GetText("trader-unable_to_find_profile_by_id", sessionID)); var pmcData = fullProfile.CharacterData.PmcData; - ProfileTraderTemplate rawProfileTemplate = profiles.GetByJsonProp(fullProfile.ProfileInfo.Edition) - .GetByJsonProp(pmcData.Info.Side.ToLower()) - .Trader; + var rawProfileTemplate = profiles.GetByJsonProp(fullProfile.ProfileInfo.Edition) + .GetByJsonProp(pmcData.Info.Side.ToLower()) + .Trader; var newTraderData = new TraderInfo { @@ -149,30 +138,22 @@ public class TraderHelper( Unlocked = trader.Base.UnlockedByDefault }; - if (!pmcData.TradersInfo.TryAdd(traderID, newTraderData)) - { - pmcData.TradersInfo[traderID] = newTraderData; - } + if (!pmcData.TradersInfo.TryAdd(traderID, newTraderData)) pmcData.TradersInfo[traderID] = newTraderData; // Check if trader should be locked by default - if (rawProfileTemplate.LockedByDefaultOverride?.Contains(traderID) ?? false) - { - pmcData.TradersInfo[traderID].Unlocked = true; - } + if (rawProfileTemplate.LockedByDefaultOverride?.Contains(traderID) ?? false) pmcData.TradersInfo[traderID].Unlocked = true; if (rawProfileTemplate.PurchaseAllClothingByDefaultForTrader?.Contains(traderID) ?? false) { // Get traders clothing var clothing = _databaseService.GetTrader(traderID).Suits; if (clothing?.Count > 0) - { // Force suit ids into profile AddSuitsToProfile( fullProfile, clothing.Select(suit => suit.SuiteId).ToList() ); - } } if ((rawProfileTemplate.FleaBlockedDays ?? 0) > 0) @@ -180,11 +161,8 @@ public class TraderHelper( var newBanDateTime = _timeUtil.GetTimeStampFromNowDays(rawProfileTemplate.FleaBlockedDays ?? 0); var existingBan = pmcData.Info.Bans.FirstOrDefault(ban => ban.BanType == BanType.RAGFAIR); if (existingBan is not null) - { existingBan.DateTime = newBanDateTime; - } else - { pmcData.Info.Bans.Add( new Ban { @@ -192,13 +170,9 @@ public class TraderHelper( DateTime = newBanDateTime } ); - } } - if (traderID == Traders.JAEGER) - { - pmcData.TradersInfo[traderID].Unlocked = rawProfileTemplate.JaegerUnlocked; - } + if (traderID == Traders.JAEGER) pmcData.TradersInfo[traderID].Unlocked = rawProfileTemplate.JaegerUnlocked; } /// @@ -212,10 +186,7 @@ public class TraderHelper( if (rawProfileTemplate.InitialStanding.TryGetValue(traderId, out var standing)) { // Edge case for Lightkeeper, 0 standing means seeing `Make Amends - Buyout` quest - if (traderId == Traders.LIGHTHOUSEKEEPER && standing == 0) - { - return 0.01; - } + if (traderId == Traders.LIGHTHOUSEKEEPER && standing == 0) return 0.01; return standing; } @@ -230,19 +201,12 @@ public class TraderHelper( /// Suit Ids to add protected void AddSuitsToProfile(SptProfile fullProfile, List suitIds) { - if (fullProfile.Suits is null) - { - fullProfile.Suits = []; - } + if (fullProfile.Suits is null) fullProfile.Suits = []; foreach (var suitId in suitIds) - { // Don't add dupes if (!fullProfile.Suits.Contains(suitId)) - { fullProfile.Suits.Add(suitId); - } - } } /// @@ -280,12 +244,10 @@ public class TraderHelper( pmcTraderInfo.Standing = AddStandingValuesTogether(pmcTraderInfo.Standing, standingToAdd); if (traderId == Traders.FENCE) - { // Must add rep to scav profile to ensure consistency fullProfile.CharacterData.ScavData.TradersInfo[traderId].Standing = pmcTraderInfo.Standing; - } - this.LevelUp(traderId, fullProfile.CharacterData.PmcData); + LevelUp(traderId, fullProfile.CharacterData.PmcData); } /// @@ -310,10 +272,7 @@ public class TraderHelper( { var profile = _profileHelper.GetPmcProfile(sessionId); var traders = _databaseService.GetTraders(); - foreach (var trader in traders) - { - this.LevelUp(trader.Key, profile); - } + foreach (var trader in traders) LevelUp(trader.Key, profile); } /// @@ -333,20 +292,16 @@ public class TraderHelper( var targetLevel = 0; // Round standing to 2 decimal places to address floating point inaccuracies - pmcData.TradersInfo[traderID].Standing = Math.Round(((pmcData.TradersInfo[traderID].Standing * 100) ?? 0), 2) / 100; + pmcData.TradersInfo[traderID].Standing = Math.Round(pmcData.TradersInfo[traderID].Standing * 100 ?? 0, 2) / 100; foreach (var loyaltyLevel in loyaltyLevels) - { if (loyaltyLevel.MinLevel <= pmcData.Info.Level && loyaltyLevel.MinSalesSum <= pmcData.TradersInfo[traderID].SalesSum && loyaltyLevel.MinStanding <= pmcData.TradersInfo[traderID].Standing && targetLevel < 4 ) - { // level reached targetLevel++; - } - } // set level pmcData.TradersInfo[traderID].LoyaltyLevel = targetLevel; @@ -380,7 +335,7 @@ public class TraderHelper( new { traderId = traderId, - updateTime = _traderConfig.UpdateTimeDefault, + updateTime = _traderConfig.UpdateTimeDefault } ) ); @@ -405,22 +360,13 @@ public class TraderHelper( var traderBase = _databaseService.GetTrader(traderID).Base; int? loyaltyLevel = null; - if (pmcData.TradersInfo.TryGetValue(traderID, out var traderInfo)) - { - loyaltyLevel = traderInfo.LoyaltyLevel; - } + if (pmcData.TradersInfo.TryGetValue(traderID, out var traderInfo)) loyaltyLevel = traderInfo.LoyaltyLevel; - if (loyaltyLevel is null or < 1) - { - loyaltyLevel = 1; - } + if (loyaltyLevel is null or < 1) loyaltyLevel = 1; - if (loyaltyLevel > traderBase.LoyaltyLevels.Count) - { - loyaltyLevel = traderBase.LoyaltyLevels.Count; - } + if (loyaltyLevel > traderBase.LoyaltyLevels.Count) loyaltyLevel = traderBase.LoyaltyLevels.Count; - return traderBase.LoyaltyLevels[(loyaltyLevel - 1) ?? 1]; + return traderBase.LoyaltyLevels[loyaltyLevel - 1 ?? 1]; } /// @@ -448,13 +394,13 @@ public class TraderHelper( // Null guard when dict doesnt exist - if (profile.TraderPurchases[traderId][purchasedItem.ItemId].PurchaseCount is null - || profile.TraderPurchases[traderId][purchasedItem.ItemId].PurchaseTimestamp is null) + if (profile.TraderPurchases[traderId][purchasedItem.ItemId].PurchaseCount is null || + profile.TraderPurchases[traderId][purchasedItem.ItemId].PurchaseTimestamp is null) { profile.TraderPurchases[traderId][purchasedItem.ItemId] = new TraderPurchaseData { PurchaseCount = purchasedItem.Count, - PurchaseTimestamp = currentTime, + PurchaseTimestamp = currentTime }; continue; @@ -466,18 +412,16 @@ public class TraderHelper( profile.CharacterData.PmcData.Info.GameVersion ) ) - { throw new Exception( _localisationService.GetText( "trader-unable_to_purchase_item_limit_reached", new { traderId = traderId, - limit = itemPurchased.Upd.BuyRestrictionMax, + limit = itemPurchased.Upd.BuyRestrictionMax } ) ); - } profile.TraderPurchases[traderId][purchasedItem.ItemId].PurchaseCount += purchasedItem.Count; profile.TraderPurchases[traderId][purchasedItem.ItemId].PurchaseTimestamp = currentTime; @@ -492,10 +436,7 @@ public class TraderHelper( /// buyRestrictionMax value public double GetAccountTypeAdjustedTraderPurchaseLimit(double buyRestrictionMax, string gameVersion) { - if (_gameVersions.Contains(gameVersion)) - { - return Math.Floor(buyRestrictionMax * 1.2); - } + if (_gameVersions.Contains(gameVersion)) return Math.Floor(buyRestrictionMax * 1.2); return buyRestrictionMax; } @@ -508,31 +449,19 @@ public class TraderHelper( /// highest rouble cost for item public double GetHighestTraderPriceRouble(string tpl) { - if (_highestTraderPriceItems is not null) - { - return (double)_highestTraderPriceItems[tpl]; - } + if (_highestTraderPriceItems is not null) return (double)_highestTraderPriceItems[tpl]; - if (_highestTraderPriceItems is null) - { - _highestTraderPriceItems = new Dictionary(); - } + if (_highestTraderPriceItems is null) _highestTraderPriceItems = new Dictionary(); // Init dict and fill foreach (var traderName in Traders.TradersDictionary) { // Skip some traders - if (traderName.Value == Traders.FENCE) - { - continue; - } + if (traderName.Value == Traders.FENCE) continue; // Get assorts for trader, skip trader if no assorts found var traderAssorts = _databaseService.GetTrader(traderName.Value).Assort; - if (traderAssorts is null) - { - continue; - } + if (traderAssorts is null) continue; // Get all item assorts that have parentid of hideout (base item and not a mod of other item) foreach (var item in traderAssorts.Items.Where(x => x.ParentId == "hideout")) @@ -546,10 +475,7 @@ public class TraderHelper( : _handbookHelper.InRUB(barterScheme.Count ?? 1, barterScheme.Template); // Existing price smaller in dict than current iteration, overwrite - if ((_highestTraderPriceItems[item.Template] ?? 0) < roubleAmount) - { - _highestTraderPriceItems[item.Template] = (int)roubleAmount; - } + if ((_highestTraderPriceItems[item.Template] ?? 0) < roubleAmount) _highestTraderPriceItems[item.Template] = (int)roubleAmount; } } @@ -571,10 +497,7 @@ public class TraderHelper( var traderBase = _databaseService.GetTrader(trader.Value).Base; // Skip traders that dont sell - if (traderBase is null || !_itemHelper.IsOfBaseclasses(tpl, traderBase.ItemsBuy.Category)) - { - continue; - } + if (traderBase is null || !_itemHelper.IsOfBaseclasses(tpl, traderBase.ItemsBuy.Category)) continue; // Get loyalty level details player has achieved with this trader // Uses lowest loyalty level as this function is used before a player has logged into server @@ -585,10 +508,7 @@ public class TraderHelper( var priceTraderBuysItemAt = _randomUtil.GetPercentOfValue(traderBuyBackPricePercent ?? 0, itemHandbookPrice, 0); // Price from this trader is higher than highest found, update - if (priceTraderBuysItemAt > highestPrice) - { - highestPrice = (int)priceTraderBuysItemAt; - } + if (priceTraderBuysItemAt > highestPrice) highestPrice = (int)priceTraderBuysItemAt; } return highestPrice; @@ -630,8 +550,7 @@ public class TraderHelper( public string GetValidTraderIdByEnumValue(string traderEnumValue) { var traderId = _databaseService.GetTraders(); - var id = traderId.FirstOrDefault(x => x.Value.Base.Id == traderEnumValue - || x.Value.Base.Nickname.ToLower() == traderEnumValue.ToLower()).Key; + var id = traderId.FirstOrDefault(x => x.Value.Base.Id == traderEnumValue || x.Value.Base.Nickname.ToLower() == traderEnumValue.ToLower()).Key; return id; } diff --git a/Libraries/Core/Helpers/UtilityHelper.cs b/Libraries/Core/Helpers/UtilityHelper.cs index 4e0f205e..e30f1d9c 100644 --- a/Libraries/Core/Helpers/UtilityHelper.cs +++ b/Libraries/Core/Helpers/UtilityHelper.cs @@ -9,7 +9,7 @@ public class UtilityHelper { //a.Intersect(x => b.Contains(x)).ToList(); // gives error Delegate type could not be infered - + return a.Where(x => b.Contains(x)).ToList(); } } diff --git a/Libraries/Core/Helpers/WeightedRandomHelper.cs b/Libraries/Core/Helpers/WeightedRandomHelper.cs index bc44be15..d15f2ec5 100644 --- a/Libraries/Core/Helpers/WeightedRandomHelper.cs +++ b/Libraries/Core/Helpers/WeightedRandomHelper.cs @@ -41,44 +41,28 @@ public class WeightedRandomHelper( /// Dictionary with item and index public WeightedRandomResult WeightedRandom(List items, List weights) { - if (items.Count == 0) - { - _logger.Error("Items must not be empty"); - } + if (items.Count == 0) _logger.Error("Items must not be empty"); - if (weights.Count == 0) - { - _logger.Error("Item weights must not be empty"); - } + if (weights.Count == 0) _logger.Error("Item weights must not be empty"); - if (items.Count != weights.Count) - { - _logger.Error("Items and weight inputs must be of the same length"); - } + if (items.Count != weights.Count) _logger.Error("Items and weight inputs must be of the same length"); // Preparing the cumulative weights list. List cumulativeWeights = []; - for (var i = 0; i < weights.Count; i++) - { - cumulativeWeights.Add((int)(weights[i]) + (i > 0 ? (cumulativeWeights[i - 1]) : 0)); - } + for (var i = 0; i < weights.Count; i++) cumulativeWeights.Add((int)weights[i] + (i > 0 ? cumulativeWeights[i - 1] : 0)); // Getting the random number in a range of [0...sum(weights)] - int maxCumulativeWeight = cumulativeWeights[cumulativeWeights.Count - 1]; - double randomNumber = maxCumulativeWeight * new Random().NextDouble(); + var maxCumulativeWeight = cumulativeWeights[cumulativeWeights.Count - 1]; + var randomNumber = maxCumulativeWeight * new Random().NextDouble(); // Picking the random item based on its weight. - for (int itemIndex = 0; itemIndex < items.Count; itemIndex++) - { + for (var itemIndex = 0; itemIndex < items.Count; itemIndex++) if (cumulativeWeights[itemIndex] >= randomNumber) - { return new WeightedRandomResult() { Item = items[itemIndex], - Index = itemIndex, + Index = itemIndex }; - } - } throw new InvalidOperationException("No item was picked."); } @@ -90,10 +74,7 @@ public class WeightedRandomHelper( public void ReduceWeightValues(Dictionary weightedDict) { // No values, nothing to reduce - if (weightedDict.Count == 0) - { - return; - } + if (weightedDict.Count == 0) return; // Only one value, set to 1 and exit if (weightedDict.Count == 1) @@ -108,14 +89,9 @@ public class WeightedRandomHelper( var commonDivisor = CommonDivisor(weights); // No point in dividing by 1 - if (commonDivisor == 1) - { - return; - } + if (commonDivisor == 1) return; - foreach (var kvp in weightedDict) { - weightedDict[kvp.Key] /= commonDivisor; - } + foreach (var kvp in weightedDict) weightedDict[kvp.Key] /= commonDivisor; } /** @@ -124,10 +100,7 @@ public class WeightedRandomHelper( protected double CommonDivisor(List numbers) { var result = numbers[0]; - for (var i = 1; i < numbers.Count; i++) - { - result = Gcd(result, numbers[i]); - } + for (var i = 1; i < numbers.Count; i++) result = Gcd(result, numbers[i]); return result; } @@ -142,6 +115,7 @@ public class WeightedRandomHelper( y = x % y; x = temp; } + return x; } } diff --git a/Libraries/Core/Loaders/PostDBModLoader.cs b/Libraries/Core/Loaders/PostDBModLoader.cs index 26360550..d3abc472 100644 --- a/Libraries/Core/Loaders/PostDBModLoader.cs +++ b/Libraries/Core/Loaders/PostDBModLoader.cs @@ -14,10 +14,7 @@ public class PostDBModLoader( public async Task OnLoad() { _logger.Info("Loading PostDBLoadMod..."); - foreach (var postDbLoadMod in _postDbLoadMods) - { - postDbLoadMod.PostDBLoad(); - } + foreach (var postDbLoadMod in _postDbLoadMods) postDbLoadMod.PostDBLoad(); _logger.Info("Finished loading PostDBLoadMod..."); } diff --git a/Libraries/Core/Loaders/PostSptModLoader.cs b/Libraries/Core/Loaders/PostSptModLoader.cs index 25e048e5..68e18fc8 100644 --- a/Libraries/Core/Loaders/PostSptModLoader.cs +++ b/Libraries/Core/Loaders/PostSptModLoader.cs @@ -15,15 +15,14 @@ public class PostSptModLoader( { public async Task OnLoad() { - if (ProgramStatics.MODS()) { + if (ProgramStatics.MODS()) + { // await _postSptModLoader.load(); // TODO: Huh? } + _logger.Info("Loading PostSptMods..."); - foreach (var postSptLoadMod in _postSptLoadMods) - { - postSptLoadMod.PostSptLoad(); - } + foreach (var postSptLoadMod in _postSptLoadMods) postSptLoadMod.PostSptLoad(); _logger.Info("Finished loading PostSptMods..."); } diff --git a/Libraries/Core/Models/Common/MinMax.cs b/Libraries/Core/Models/Common/MinMax.cs index 04f23661..61efeb5a 100644 --- a/Libraries/Core/Models/Common/MinMax.cs +++ b/Libraries/Core/Models/Common/MinMax.cs @@ -12,12 +12,11 @@ public record MinMax public MinMax() { - } [JsonPropertyName("type")] public string? Type { get; set; } - + [JsonPropertyName("max")] public double? Max { get; set; } diff --git a/Libraries/Core/Models/Eft/Common/Globals.cs b/Libraries/Core/Models/Eft/Common/Globals.cs index 574517b5..9ef29fbf 100644 --- a/Libraries/Core/Models/Eft/Common/Globals.cs +++ b/Libraries/Core/Models/Eft/Common/Globals.cs @@ -8,7 +8,6 @@ using System.Text.Json.Serialization; public record Globals { - [JsonPropertyName("config")] public Config? Configuration { get; set; } @@ -1293,13 +1292,13 @@ public record Mastering { [JsonPropertyName("Id")] public string? Id { get; set; } - + [JsonPropertyName("Name")] public string? Name { get; set; } [JsonPropertyName("Templates")] public List? Templates { get; set; } - + [JsonPropertyName("Progress")] public double? Progress { get; set; } @@ -1353,6 +1352,7 @@ public record WildBody [JsonPropertyName("isNotRandom")] public bool? IsNotRandom { get; set; } } + public record WildFeet { [JsonPropertyName("feet")] diff --git a/Libraries/Core/Models/Eft/Common/LocationBase.cs b/Libraries/Core/Models/Eft/Common/LocationBase.cs index 532c216a..b96738c1 100644 --- a/Libraries/Core/Models/Eft/Common/LocationBase.cs +++ b/Libraries/Core/Models/Eft/Common/LocationBase.cs @@ -242,7 +242,7 @@ public record LocationBase [JsonPropertyName("SpawnPointParams")] public List? SpawnPointParams { get; set; } - + [JsonPropertyName("areas")] public Dictionary? Areas { get; set; } @@ -280,7 +280,7 @@ public record LocationBase [JsonPropertyName("ForceOnlineRaidInPVE")] public bool? ForceOnlineRaidInPVE { get; set; } - + [JsonPropertyName("ExitZones")] public string? ExitZones { get; set; } @@ -772,10 +772,10 @@ public record Exit [JsonPropertyName("Name")] public string? Name { get; set; } - + [JsonPropertyName("_Name")] public string? _Name { get; set; } - + [JsonPropertyName("_name")] public string? _NameLower { get; set; } @@ -929,19 +929,19 @@ public record Area { [JsonPropertyName("center")] public XYZ? Center { get; set; } - + [JsonPropertyName("infiltrationZone")] public string? InfiltrationZone { get; set; } - + [JsonPropertyName("orientation")] public double? Orientation { get; set; } - + [JsonPropertyName("position")] public XYZ? Position { get; set; } - + [JsonPropertyName("sides")] public List? Sides { get; set; } - + [JsonPropertyName("size")] public XYZ? Size { get; set; } } diff --git a/Libraries/Core/Models/Eft/Common/PmcData.cs b/Libraries/Core/Models/Eft/Common/PmcData.cs index 643d60a6..fc8521b0 100644 --- a/Libraries/Core/Models/Eft/Common/PmcData.cs +++ b/Libraries/Core/Models/Eft/Common/PmcData.cs @@ -9,9 +9,9 @@ public record PmcData : BotBase [JsonPropertyName("Prestige")] [JsonConverter(typeof(ArrayToObjectFactoryConverter))] public Dictionary? Prestige { get; set; } - + public Dictionary? CheckedMagazines { get; set; } - + public object CheckedChambers { get; set; } } diff --git a/Libraries/Core/Models/Eft/Common/Tables/BotBase.cs b/Libraries/Core/Models/Eft/Common/Tables/BotBase.cs index 2f424c4c..86a56460 100644 --- a/Libraries/Core/Models/Eft/Common/Tables/BotBase.cs +++ b/Libraries/Core/Models/Eft/Common/Tables/BotBase.cs @@ -160,34 +160,45 @@ public record Info ///Experience the bot has gained public int? Experience { get; set; } + public List? Bans { get; set; } public bool? BannedState { get; set; } public long? BannedUntil { get; set; } public bool? IsStreamerModeAvailable { get; set; } + [JsonConverter(typeof(StringToNumberFactoryConverter))] public int? RegistrationDate { get; set; } + public string? GameVersion { get; set; } public MemberCategory? MemberCategory { get; set; } public MemberCategory? SelectedMemberCategory { get; set; } + [JsonPropertyName("lockedMoveCommands")] public bool? LockedMoveCommands { get; set; } + public double? SavageLockTime { get; set; } public long? LastTimePlayedAsSavage { get; set; } public BotInfoSettings? Settings { get; set; } public List? NeedWipeOptions { get; set; } + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] [JsonPropertyName("lastCompletedWipe")] public LastCompleted? LastCompletedWipe { get; set; } + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] [JsonPropertyName("lastWipeTimestamp")] public LastCompleted? LastWipeTimestamp { get; set; } + public double? AccountType { get; set; } public long? NicknameChangeDate { get; set; } + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] [JsonPropertyName("lastCompletedEvent")] public LastCompleted? LastCompletedEvent { get; set; } + [JsonPropertyName("isMigratedSkills")] public bool? IsMigratedSkills { get; set; } + public double? GroupId { get; set; } public double? TeamId { get; set; } public bool? HasCoopExtension { get; set; } @@ -246,6 +257,7 @@ public record BotBaseHealth [JsonConverter(typeof(ArrayToObjectFactoryConverter))] [JsonPropertyName("BodyParts")] public Dictionary? BodyParts { get; set; } + public double? UpdateTime { get; set; } public bool? Immortal { get; set; } } @@ -345,7 +357,6 @@ public record BaseSkill public record Common : BaseSkill { - } public record Mastering : BaseSkill @@ -371,6 +382,7 @@ public record EftStats [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public Aggressor? Aggressor { get; set; } + public List? DroppedItems { get; set; } public List? FoundInRaidItems { get; set; } public DamageHistory? DamageHistory { get; set; } @@ -378,6 +390,7 @@ public record EftStats [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public LastPlayerState? LastPlayerState { get; set; } + public long? TotalInGameTime { get; set; } public string? SurvivorClass { get; set; } @@ -413,7 +426,8 @@ public record Victim public string? ColliderType { get; set; } public string? Role { get; set; } public string? Location { get; set; } - [JsonExtensionData] + + [JsonExtensionData] public Dictionary OtherProperties { get; set; } } @@ -436,13 +450,16 @@ public record CounterKeyValue public record Aggressor { public double? PrestigeLevel { get; set; } + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public string? AccountId { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public string? ProfileId { get; set; } + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public string? MainProfileNickname { get; set; } + public string? Name { get; set; } public string? Side { get; set; } public string? BodyPart { get; set; } @@ -451,7 +468,8 @@ public record Aggressor public string? Category { get; set; } public string? ColliderType { get; set; } public string? Role { get; set; } - [JsonExtensionData] + + [JsonExtensionData] public Dictionary OtherProperties { get; set; } } @@ -484,8 +502,10 @@ public record DamageStats public double? Amount { get; set; } public string? Type { get; set; } public string? SourceId { get; set; } + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public string? OverDamageFrom { get; set; } + public bool? Blunt { get; set; } public double? ImpactsCount { get; set; } } @@ -542,14 +562,16 @@ public record Hideout public Dictionary? Production { get; set; } public List? Areas { get; set; } public Dictionary? Improvements { get; set; } - + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public HideoutCounters? HideoutCounters { get; set; } + public double? Seed { get; set; } public Dictionary? MannequinPoses { get; set; } [JsonPropertyName("sptUpdateLastRunTimestamp")] public long? SptUpdateLastRunTimestamp { get; set; } + public Dictionary? Customization { get; set; } } @@ -624,7 +646,7 @@ public record Production // use this instead of productive and scavcase // Craft is cultist circle sacrifice [JsonPropertyName("sptIsCultistCircle")] public bool? SptIsCultistCircle { get; set; } - + public string? RecipeId { get; set; } } diff --git a/Libraries/Core/Models/Eft/Common/Tables/BotType.cs b/Libraries/Core/Models/Eft/Common/Tables/BotType.cs index cced7e66..f17c6540 100644 --- a/Libraries/Core/Models/Eft/Common/Tables/BotType.cs +++ b/Libraries/Core/Models/Eft/Common/Tables/BotType.cs @@ -316,40 +316,40 @@ public record GenerationWeightingItems { [JsonPropertyName("grenades")] public GenerationData Grenades { get; set; } - + [JsonPropertyName("healing")] public GenerationData Healing { get; set; } - + [JsonPropertyName("drugs")] public GenerationData Drugs { get; set; } - + [JsonPropertyName("food")] public GenerationData Food { get; set; } - + [JsonPropertyName("drink")] public GenerationData Drink { get; set; } - + [JsonPropertyName("currency")] public GenerationData Currency { get; set; } - + [JsonPropertyName("stims")] public GenerationData Stims { get; set; } - + [JsonPropertyName("backpackLoot")] public GenerationData BackpackLoot { get; set; } - + [JsonPropertyName("pocketLoot")] public GenerationData PocketLoot { get; set; } - + [JsonPropertyName("vestLoot")] public GenerationData VestLoot { get; set; } - + [JsonPropertyName("magazines")] public GenerationData Magazines { get; set; } - + [JsonPropertyName("specialItems")] public GenerationData SpecialItems { get; set; } - + [JsonPropertyName("looseLoot")] public GenerationData LooseLoot { get; set; } } diff --git a/Libraries/Core/Models/Eft/Common/Tables/CustomizationItem.cs b/Libraries/Core/Models/Eft/Common/Tables/CustomizationItem.cs index ea329f3a..73e2962e 100644 --- a/Libraries/Core/Models/Eft/Common/Tables/CustomizationItem.cs +++ b/Libraries/Core/Models/Eft/Common/Tables/CustomizationItem.cs @@ -93,5 +93,4 @@ public class CustomizationProps [JsonPropertyName("HideGarbage")] public bool? HideGarbage { get; set; } - } diff --git a/Libraries/Core/Models/Eft/Common/Tables/GlobalTablesUsings.cs b/Libraries/Core/Models/Eft/Common/Tables/GlobalTablesUsings.cs index aa4ce584..bac47306 100644 --- a/Libraries/Core/Models/Eft/Common/Tables/GlobalTablesUsings.cs +++ b/Libraries/Core/Models/Eft/Common/Tables/GlobalTablesUsings.cs @@ -1,2 +1,3 @@ global using GlobalAmmo = System.Collections.Generic.Dictionary>; -global using GlobalMods = System.Collections.Generic.Dictionary>>; +global using GlobalMods = + System.Collections.Generic.Dictionary>>; diff --git a/Libraries/Core/Models/Eft/Common/Tables/Item.cs b/Libraries/Core/Models/Eft/Common/Tables/Item.cs index c3225246..ee2a80b1 100644 --- a/Libraries/Core/Models/Eft/Common/Tables/Item.cs +++ b/Libraries/Core/Models/Eft/Common/Tables/Item.cs @@ -44,13 +44,13 @@ public record HideoutItem { [JsonPropertyName("id")] public string? Id { get; set; } - + [JsonPropertyName("_tpl")] public string? Template { get; set; } - + [JsonPropertyName("upd")] public Upd? Upd { get; set; } - + [JsonPropertyName("count")] public double? Count { get; set; } @@ -60,7 +60,7 @@ public record HideoutItem { Id = Id, Template = Template, - Upd = Upd, + Upd = Upd }; } } @@ -184,7 +184,7 @@ public record UpdFaceShield { [JsonPropertyName("Hits")] public int? Hits { get; set; } - + [JsonPropertyName("HitSeed")] public int? HitSeed { get; set; } } @@ -220,7 +220,7 @@ public record UpdSight [JsonPropertyName("SelectedScope")] public int? SelectedScope { get; set; } - + public double? ScopeZoomValue { get; set; } } diff --git a/Libraries/Core/Models/Eft/Common/Tables/ProfileTemplate.cs b/Libraries/Core/Models/Eft/Common/Tables/ProfileTemplate.cs index 4370b5d9..44a2aeb0 100644 --- a/Libraries/Core/Models/Eft/Common/Tables/ProfileTemplate.cs +++ b/Libraries/Core/Models/Eft/Common/Tables/ProfileTemplate.cs @@ -62,10 +62,10 @@ public record TemplateSide [JsonPropertyName("trader")] public ProfileTraderTemplate? Trader { get; set; } - + [JsonPropertyName("equipmentBuilds")] public object? EquipmentBuilds { get; set; } - + [JsonPropertyName("weaponbuilds")] public object? WeaponBuilds { get; set; } } diff --git a/Libraries/Core/Models/Eft/Common/Tables/Quest.cs b/Libraries/Core/Models/Eft/Common/Tables/Quest.cs index fe9623da..9c4c2679 100644 --- a/Libraries/Core/Models/Eft/Common/Tables/Quest.cs +++ b/Libraries/Core/Models/Eft/Common/Tables/Quest.cs @@ -122,13 +122,13 @@ public record Quest /// [JsonPropertyName("sptStatus")] public QuestStatusEnum? SptStatus { get; set; } - + [JsonPropertyName("questStatus")] public QuestStatus? QuestStatus { get; set; } - + [JsonPropertyName("changeCost")] public List ChangeCost { get; set; } - + [JsonPropertyName("changeStandingCost")] public double ChangeStandingCost { get; set; } } @@ -140,25 +140,25 @@ public record QuestStatus { [JsonPropertyName("id")] public string? Id { get; set; } - + [JsonPropertyName("uid")] public string? Uid { get; set; } - + [JsonPropertyName("qid")] public string? QId { get; set; } - + [JsonPropertyName("startTime")] public double? StartTime { get; set; } - + [JsonPropertyName("status")] public QuestStatusEnum? Status { get; set; } - + [JsonPropertyName("statusTimers")] public Dictionary? StatusTimers { get; set; } - + [JsonPropertyName("completedConditions")] public List? CompletedConditions { get; set; } - + [JsonPropertyName("availableAfter")] public double? AvailableAfter { get; set; } } @@ -276,46 +276,45 @@ public record QuestCondition [JsonPropertyName("areaType")] public HideoutAreas? AreaType { get; set; } - + [JsonPropertyName("baseAccuracy")] public ValueCompare? BaseAccuracy { get; set; } - + [JsonPropertyName("containsItems")] public List? ContainsItems { get; set; } - + [JsonPropertyName("durability")] public ValueCompare? Durability { get; set; } - + [JsonPropertyName("effectiveDistance")] public ValueCompare? EffectiveDistance { get; set; } - + [JsonPropertyName("emptyTacticalSlot")] public ValueCompare? EmptyTacticalSlot { get; set; } - + [JsonPropertyName("ergonomics")] public ValueCompare? Ergonomics { get; set; } - + [JsonPropertyName("height")] public ValueCompare? Height { get; set; } - + [JsonPropertyName("hasItemFromCategory")] public List? HasItemFromCategory { get; set; } - + [JsonPropertyName("magazineCapacity")] public ValueCompare? MagazineCapacity { get; set; } - + [JsonPropertyName("muzzleVelocity")] public ValueCompare? MuzzleVelocity { get; set; } - + [JsonPropertyName("recoil")] public ValueCompare? Recoil { get; set; } - + [JsonPropertyName("weight")] public ValueCompare? Weight { get; set; } - + [JsonPropertyName("width")] public ValueCompare? Width { get; set; } - } public record QuestConditionCounter @@ -403,19 +402,18 @@ public record QuestConditionCounterCondition [JsonPropertyName("resetOnSessionEnd")] public bool? ResetOnSessionEnd { get; set; } - + [JsonPropertyName("bodyPartsWithEffects")] public List? BodyPartsWithEffects { get; set; } - + [JsonPropertyName("IncludeNotEquippedItems")] public bool? IncludeNotEquippedItems { get; set; } - + [JsonPropertyName("equipmentExclusive")] public List>? EquipmentExclusive { get; set; } - + [JsonPropertyName("zoneIds")] public List? Zones { get; set; } - } public record EnemyHealthEffect diff --git a/Libraries/Core/Models/Eft/Common/Tables/RepeatableQuests.cs b/Libraries/Core/Models/Eft/Common/Tables/RepeatableQuests.cs index 33b30934..590f1fad 100644 --- a/Libraries/Core/Models/Eft/Common/Tables/RepeatableQuests.cs +++ b/Libraries/Core/Models/Eft/Common/Tables/RepeatableQuests.cs @@ -78,7 +78,7 @@ public record RepeatableTemplates [JsonPropertyName("Exploration")] public RepeatableQuest? Exploration { get; set; } - + [JsonPropertyName("Pickup")] public RepeatableQuest? Pickup { get; set; } } diff --git a/Libraries/Core/Models/Eft/Common/Tables/Reward.cs b/Libraries/Core/Models/Eft/Common/Tables/Reward.cs index e593b0e4..cc458232 100644 --- a/Libraries/Core/Models/Eft/Common/Tables/Reward.cs +++ b/Libraries/Core/Models/Eft/Common/Tables/Reward.cs @@ -10,7 +10,7 @@ public record Reward [JsonPropertyName("id")] public string? Id { get; set; } - + [JsonPropertyName("type")] [JsonConverter(typeof(JsonStringEnumConverter))] public RewardType? Type { get; set; } @@ -50,11 +50,11 @@ public record Reward /** Game editions blacklisted from getting reward */ [JsonPropertyName("notAvailableInGameEditions")] public List? NotAvailableInGameEditions { get; set; } - + // This is always Null atm in the achievements.json [JsonPropertyName("illustrationConfig")] public object? IllustrationConfig { get; set; } - + [JsonPropertyName("isHidden")] public bool? IsHidden { get; set; } } diff --git a/Libraries/Core/Models/Eft/Common/Tables/TemplateItem.cs b/Libraries/Core/Models/Eft/Common/Tables/TemplateItem.cs index 9d02dc73..87093ae0 100644 --- a/Libraries/Core/Models/Eft/Common/Tables/TemplateItem.cs +++ b/Libraries/Core/Models/Eft/Common/Tables/TemplateItem.cs @@ -184,10 +184,10 @@ public record Props [JsonPropertyName("MetascoreGroup")] public string? MetaScoreGroup { get; set; } - + [JsonPropertyName("NpcCompressorSendLevel")] public double? NpcCompressorSendLevel { get; set; } - + [JsonPropertyName("ObservedPlayerCompressorSendLevel")] public double? ObservedPlayerCompressorSendLevel { get; set; } @@ -680,7 +680,7 @@ public record Props [JsonPropertyName("ShotgunDispersion")] public double? ShotgunDispersion { get; set; } - + [JsonPropertyName("shotgunDispersion")] public double? shotgunDispersion { get; set; } @@ -906,10 +906,10 @@ public record Props [JsonPropertyName("CompressorGain")] public double? CompressorGain { get; set; } - + [JsonPropertyName("EQBand1Frequency")] public double? EQBand1Frequency { get; set; } - + [JsonPropertyName("EQBand1Gain")] public double? EQBand1Gain { get; set; } @@ -1322,7 +1322,7 @@ public record Props [JsonPropertyName("ExplDelay")] public double? ExplDelay { get; set; } - + [JsonPropertyName("explDelay")] public double? explDelay { get; set; } @@ -1403,13 +1403,13 @@ public record Props [JsonPropertyName("TradersDiscountPVE")] public double? TradersDiscountPVE { get; set; } - + [JsonPropertyName("AvailableAsDefault")] public bool? AvailableAsDefault { get; set; } - + [JsonPropertyName("ProfileVersions")] public List? ProfileVersions { get; set; } - + [JsonPropertyName("Side")] public List? Side { get; set; } @@ -1631,10 +1631,10 @@ public record SlotFilter [JsonPropertyName("AnimationIndex")] public double? AnimationIndex { get; set; } - + [JsonPropertyName("MaxStackCount")] public double? MaxStackCount { get; set; } - + [JsonPropertyName("bluntDamageReduceFromSoftArmor")] public bool? BluntDamageReduceFromSoftArmor { get; set; } } @@ -1721,7 +1721,7 @@ public record EffectsHealthProps { [JsonPropertyName("value")] public double? Value { get; set; } - + [JsonPropertyName("delay")] public double? Delay { get; set; } @@ -1757,7 +1757,7 @@ public record EffectDamageProps { [JsonPropertyName("value")] public double? Value { get; set; } - + [JsonPropertyName("delay")] public double? Delay { get; set; } diff --git a/Libraries/Core/Models/Eft/Common/Tables/Trader.cs b/Libraries/Core/Models/Eft/Common/Tables/Trader.cs index 8223cdd6..fe0a8091 100644 --- a/Libraries/Core/Models/Eft/Common/Tables/Trader.cs +++ b/Libraries/Core/Models/Eft/Common/Tables/Trader.cs @@ -205,10 +205,9 @@ public record TraderRepair [JsonPropertyName("quality")] [JsonConverter(typeof(StringToNumberFactoryConverter))] public double? Quality { get; set; } - + [JsonPropertyName("price_rate")] public double? PriceRate { get; set; } - } public record TraderAssort diff --git a/Libraries/Core/Models/Eft/Dialog/FriendRequestData.cs b/Libraries/Core/Models/Eft/Dialog/FriendRequestData.cs index 465a6fee..b1bf2b94 100644 --- a/Libraries/Core/Models/Eft/Dialog/FriendRequestData.cs +++ b/Libraries/Core/Models/Eft/Dialog/FriendRequestData.cs @@ -13,7 +13,7 @@ public record FriendRequestData : IRequestData [JsonPropertyName("retryAfter")] public int? RetryAfter { get; set; } - + [JsonPropertyName("to")] public string? To { get; set; } } diff --git a/Libraries/Core/Models/Eft/Game/SendSurveyOpinionRequest.cs b/Libraries/Core/Models/Eft/Game/SendSurveyOpinionRequest.cs index 7ef29ea6..e8a31194 100644 --- a/Libraries/Core/Models/Eft/Game/SendSurveyOpinionRequest.cs +++ b/Libraries/Core/Models/Eft/Game/SendSurveyOpinionRequest.cs @@ -7,7 +7,7 @@ public record SendSurveyOpinionRequest : IRequestData { [JsonPropertyName("resultJson")] public string? ResultJson { get; set; } - + [JsonPropertyName("surveyId")] public int? SurveyId { get; set; } diff --git a/Libraries/Core/Models/Eft/Health/Effect.cs b/Libraries/Core/Models/Eft/Health/Effect.cs index aa2830ba..c134ed7f 100644 --- a/Libraries/Core/Models/Eft/Health/Effect.cs +++ b/Libraries/Core/Models/Eft/Health/Effect.cs @@ -7,4 +7,4 @@ public enum Effect HeavyBleeding, MildMusclePain, SevereMusclePain -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Eft/Health/HealthTreatmentRequestData.cs b/Libraries/Core/Models/Eft/Health/HealthTreatmentRequestData.cs index 837a43ce..9d7967f4 100644 --- a/Libraries/Core/Models/Eft/Health/HealthTreatmentRequestData.cs +++ b/Libraries/Core/Models/Eft/Health/HealthTreatmentRequestData.cs @@ -7,7 +7,6 @@ namespace Core.Models.Eft.Health; public record HealthTreatmentRequestData : InventoryBaseActionRequestData { - [JsonPropertyName("trader")] public string? Trader { get; set; } @@ -62,6 +61,7 @@ public record BodyParts public record BodyPartEffects { public double Health { get; set; } + /** Effects in array to be removed */ public List Effects { get; set; } } diff --git a/Libraries/Core/Models/Eft/Health/OffraidHealRequestData.cs b/Libraries/Core/Models/Eft/Health/OffraidHealRequestData.cs index aafb2a29..5b4a74c5 100644 --- a/Libraries/Core/Models/Eft/Health/OffraidHealRequestData.cs +++ b/Libraries/Core/Models/Eft/Health/OffraidHealRequestData.cs @@ -7,13 +7,13 @@ public record OffraidHealRequestData : InventoryBaseActionRequestData { [JsonPropertyName("item")] public string? Item { get; set; } - + [JsonPropertyName("part")] public string? Part { get; set; } - + [JsonPropertyName("count")] public int? Count { get; set; } - + [JsonPropertyName("time")] public long? Time { get; set; } } diff --git a/Libraries/Core/Models/Eft/Hideout/HideoutArea.cs b/Libraries/Core/Models/Eft/Hideout/HideoutArea.cs index 4a1082bd..5d4e5710 100644 --- a/Libraries/Core/Models/Eft/Hideout/HideoutArea.cs +++ b/Libraries/Core/Models/Eft/Hideout/HideoutArea.cs @@ -181,7 +181,7 @@ public record StageRequirement [JsonPropertyName("skillLevel")] public int? SkillLevel { get; set; } - + [JsonPropertyName("type")] public string? Type { get; set; } } diff --git a/Libraries/Core/Models/Eft/Hideout/HideoutCancelProductionRequestData.cs b/Libraries/Core/Models/Eft/Hideout/HideoutCancelProductionRequestData.cs index 967efc4a..97a25b23 100644 --- a/Libraries/Core/Models/Eft/Hideout/HideoutCancelProductionRequestData.cs +++ b/Libraries/Core/Models/Eft/Hideout/HideoutCancelProductionRequestData.cs @@ -7,7 +7,7 @@ public record HideoutCancelProductionRequestData : BaseInteractionRequestData { [JsonPropertyName("recipeId")] public string? RecipeId { get; set; } - + [JsonPropertyName("timestamp")] public long? Timestamp { get; set; } } diff --git a/Libraries/Core/Models/Eft/Hideout/HideoutContinuousProductionStartRequestData.cs b/Libraries/Core/Models/Eft/Hideout/HideoutContinuousProductionStartRequestData.cs index 4e4e3eb6..d94bf9a3 100644 --- a/Libraries/Core/Models/Eft/Hideout/HideoutContinuousProductionStartRequestData.cs +++ b/Libraries/Core/Models/Eft/Hideout/HideoutContinuousProductionStartRequestData.cs @@ -17,5 +17,5 @@ public record HideoutProperties { public int? BtcFarmGcs { get; set; } public bool IsGeneratorOn { get; set; } - public bool WaterCollectorHasFilter { get; set; } + public bool WaterCollectorHasFilter { get; set; } } diff --git a/Libraries/Core/Models/Eft/Hideout/HideoutCustomizationApplyRequestData.cs b/Libraries/Core/Models/Eft/Hideout/HideoutCustomizationApplyRequestData.cs index 30c54b48..8eaaabd6 100644 --- a/Libraries/Core/Models/Eft/Hideout/HideoutCustomizationApplyRequestData.cs +++ b/Libraries/Core/Models/Eft/Hideout/HideoutCustomizationApplyRequestData.cs @@ -6,7 +6,6 @@ namespace Core.Models.Eft.Hideout; public record HideoutCustomizationApplyRequestData : InventoryBaseActionRequestData { - /// /// Id of the newly picked item to apply to hideout /// diff --git a/Libraries/Core/Models/Eft/Hideout/HideoutProduction.cs b/Libraries/Core/Models/Eft/Hideout/HideoutProduction.cs index 32bc2ad6..27064b51 100644 --- a/Libraries/Core/Models/Eft/Hideout/HideoutProduction.cs +++ b/Libraries/Core/Models/Eft/Hideout/HideoutProduction.cs @@ -87,7 +87,7 @@ public record Requirement [JsonPropertyName("gameVersions")] public List? GameVersions { get; set; } - + [JsonPropertyName("type")] public string? Type { get; set; } } diff --git a/Libraries/Core/Models/Eft/Hideout/HideoutPutItemInRequestData.cs b/Libraries/Core/Models/Eft/Hideout/HideoutPutItemInRequestData.cs index a937b246..72614334 100644 --- a/Libraries/Core/Models/Eft/Hideout/HideoutPutItemInRequestData.cs +++ b/Libraries/Core/Models/Eft/Hideout/HideoutPutItemInRequestData.cs @@ -8,7 +8,6 @@ namespace Core.Models.Eft.Hideout; public record HideoutPutItemInRequestData : InventoryBaseActionRequestData { - [JsonPropertyName("areaType")] public HideoutAreas? AreaType { get; set; } diff --git a/Libraries/Core/Models/Eft/Hideout/HideoutUpgradeCompleteRequestData.cs b/Libraries/Core/Models/Eft/Hideout/HideoutUpgradeCompleteRequestData.cs index 25bad14a..417f202e 100644 --- a/Libraries/Core/Models/Eft/Hideout/HideoutUpgradeCompleteRequestData.cs +++ b/Libraries/Core/Models/Eft/Hideout/HideoutUpgradeCompleteRequestData.cs @@ -7,7 +7,6 @@ namespace Core.Models.Eft.Hideout; public record HideoutUpgradeCompleteRequestData : InventoryBaseActionRequestData { - [JsonPropertyName("areaType")] public HideoutAreas? AreaType { get; set; } diff --git a/Libraries/Core/Models/Eft/Hideout/HideoutUpgradeRequestData.cs b/Libraries/Core/Models/Eft/Hideout/HideoutUpgradeRequestData.cs index 5b532439..c7cfd73f 100644 --- a/Libraries/Core/Models/Eft/Hideout/HideoutUpgradeRequestData.cs +++ b/Libraries/Core/Models/Eft/Hideout/HideoutUpgradeRequestData.cs @@ -8,7 +8,6 @@ namespace Core.Models.Eft.Hideout; public record HideoutUpgradeRequestData : InventoryBaseActionRequestData { - [JsonPropertyName("areaType")] public HideoutAreas? AreaType { get; set; } diff --git a/Libraries/Core/Models/Eft/ItemEvent/ItemEventRouterRequest.cs b/Libraries/Core/Models/Eft/ItemEvent/ItemEventRouterRequest.cs index d6d0bfef..e77f091f 100644 --- a/Libraries/Core/Models/Eft/ItemEvent/ItemEventRouterRequest.cs +++ b/Libraries/Core/Models/Eft/ItemEvent/ItemEventRouterRequest.cs @@ -24,22 +24,22 @@ public record Daum [JsonPropertyName("item")] public string? Item { get; set; } - + [JsonPropertyName("items")] public List? Items { get; set; } [JsonPropertyName("to")] public To? To { get; set; } - + [JsonPropertyName("with")] public string? With { get; set; } - + [JsonPropertyName("fromOwner")] public FromOwner? FromOwner { get; set; } - + [JsonPropertyName("qid")] public string? Qid { get; set; } - + [JsonPropertyName("offer")] public string? Offer { get; set; } } @@ -48,7 +48,7 @@ public record FromOwner { [JsonPropertyName("id")] public string? Id { get; set; } - + [JsonPropertyName("type")] public string? Type { get; set; } } diff --git a/Libraries/Core/Models/Eft/Launcher/MiniProfile.cs b/Libraries/Core/Models/Eft/Launcher/MiniProfile.cs index 40d640ce..b092f141 100644 --- a/Libraries/Core/Models/Eft/Launcher/MiniProfile.cs +++ b/Libraries/Core/Models/Eft/Launcher/MiniProfile.cs @@ -36,7 +36,7 @@ public record MiniProfile [JsonPropertyName("sptData")] public Profile.Spt? SptData { get; set; } - + [JsonPropertyName("hasPassword")] public bool? HasPassword { get; set; } } diff --git a/Libraries/Core/Models/Eft/Match/GetRaidConfigurationRequestData.cs b/Libraries/Core/Models/Eft/Match/GetRaidConfigurationRequestData.cs index 6639b50a..6153dcbc 100644 --- a/Libraries/Core/Models/Eft/Match/GetRaidConfigurationRequestData.cs +++ b/Libraries/Core/Models/Eft/Match/GetRaidConfigurationRequestData.cs @@ -11,7 +11,7 @@ public record GetRaidConfigurationRequestData : RaidSettings, IRequestData [JsonPropertyName("MaxGroupCount")] public int? MaxGroupCount { get; set; } - + [JsonPropertyName("transitionType")] [JsonConverter(typeof(JsonStringEnumConverter))] public TransitionType TransitionType { get; set; } diff --git a/Libraries/Core/Models/Eft/PresetBuild/PresetBuildActionRequestData.cs b/Libraries/Core/Models/Eft/PresetBuild/PresetBuildActionRequestData.cs index 36590735..0792cb3f 100644 --- a/Libraries/Core/Models/Eft/PresetBuild/PresetBuildActionRequestData.cs +++ b/Libraries/Core/Models/Eft/PresetBuild/PresetBuildActionRequestData.cs @@ -4,7 +4,7 @@ using Core.Models.Utils; namespace Core.Models.Eft.PresetBuild; -public record PresetBuildActionRequestData : IRequestData +public record PresetBuildActionRequestData : IRequestData { [JsonPropertyName("Action")] public string? Action { get; set; } diff --git a/Libraries/Core/Models/Eft/Prestige/ObtainPrestigeRequest.cs b/Libraries/Core/Models/Eft/Prestige/ObtainPrestigeRequest.cs index 1af2ab6a..fb5f44e6 100644 --- a/Libraries/Core/Models/Eft/Prestige/ObtainPrestigeRequest.cs +++ b/Libraries/Core/Models/Eft/Prestige/ObtainPrestigeRequest.cs @@ -1,34 +1,32 @@ using System.Text.Json.Serialization; using Core.Models.Utils; -namespace Core.Models.Eft.Prestige +namespace Core.Models.Eft.Prestige; + +public class ObtainPrestigeRequestList : List, IRequestData { - public class ObtainPrestigeRequestList : List, IRequestData - { - - } - - public record ObtainPrestigeRequest : IRequestData - { - [JsonPropertyName("id")] - public string Id { get; set; } - - [JsonPropertyName("location")] - public Location Location { get; set; } - } - - public record Location - { - [JsonPropertyName("x")] - public int X { get; set; } - - [JsonPropertyName("y")] - public int Y { get; set; } - - [JsonPropertyName("z")] - public int Z { get; set; } - - [JsonPropertyName("r")] - public string R { get; set; } - } +} + +public record ObtainPrestigeRequest : IRequestData +{ + [JsonPropertyName("id")] + public string Id { get; set; } + + [JsonPropertyName("location")] + public Location Location { get; set; } +} + +public record Location +{ + [JsonPropertyName("x")] + public int X { get; set; } + + [JsonPropertyName("y")] + public int Y { get; set; } + + [JsonPropertyName("z")] + public int Z { get; set; } + + [JsonPropertyName("r")] + public string R { get; set; } } diff --git a/Libraries/Core/Models/Eft/Profile/SptProfile.cs b/Libraries/Core/Models/Eft/Profile/SptProfile.cs index 19aa95e8..bb1451e0 100644 --- a/Libraries/Core/Models/Eft/Profile/SptProfile.cs +++ b/Libraries/Core/Models/Eft/Profile/SptProfile.cs @@ -409,13 +409,13 @@ public record Vitality { [JsonPropertyName("Hydration")] public double? Hydration { get; set; } - + [JsonPropertyName("Energy")] public double? Energy { get; set; } - + [JsonPropertyName("Temperature")] public double? Temperature { get; set; } - + [JsonPropertyName("Health")] // This now does health and effects to each bodypart public Dictionary? Health { get; set; } } diff --git a/Libraries/Core/Models/Eft/Ws/NotificationEventType.cs b/Libraries/Core/Models/Eft/Ws/NotificationEventType.cs index 7c068e06..b90196bf 100644 --- a/Libraries/Core/Models/Eft/Ws/NotificationEventType.cs +++ b/Libraries/Core/Models/Eft/Ws/NotificationEventType.cs @@ -39,5 +39,5 @@ public enum NotificationEventType ProfileLockTimer, StashRows, SkillPoints, - tournamentWarning, + tournamentWarning } diff --git a/Libraries/Core/Models/Enums/AirdropType.cs b/Libraries/Core/Models/Enums/AirdropType.cs index 43dd6985..471e12fc 100644 --- a/Libraries/Core/Models/Enums/AirdropType.cs +++ b/Libraries/Core/Models/Enums/AirdropType.cs @@ -15,4 +15,4 @@ public enum SptAirdropTypeEnum foodMedical, weaponArmor, radar -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/ArmorMaterial.cs b/Libraries/Core/Models/Enums/ArmorMaterial.cs index e33a785f..fa661979 100644 --- a/Libraries/Core/Models/Enums/ArmorMaterial.cs +++ b/Libraries/Core/Models/Enums/ArmorMaterial.cs @@ -1,14 +1,13 @@ -namespace Core.Models.Enums +namespace Core.Models.Enums; + +public enum ArmorMaterial { - public enum ArmorMaterial - { - UHMWPE, - Aramid, - Combined, - Titan, - Aluminium, - ArmoredSteel, - Ceramic, - Glass - } + UHMWPE, + Aramid, + Combined, + Titan, + Aluminium, + ArmoredSteel, + Ceramic, + Glass } diff --git a/Libraries/Core/Models/Enums/BaseClasses.cs b/Libraries/Core/Models/Enums/BaseClasses.cs index 597579d8..232b4589 100644 --- a/Libraries/Core/Models/Enums/BaseClasses.cs +++ b/Libraries/Core/Models/Enums/BaseClasses.cs @@ -113,4 +113,3 @@ public record BaseClasses public static string COMB_MUZZLE_DEVICE = "550aa4dd4bdc2dc9348b4569 "; public static string HIDEOUT_AREA_CONTAINER = "63da6da4784a55176c018dba"; } - diff --git a/Libraries/Core/Models/Enums/BonusSkillType.cs b/Libraries/Core/Models/Enums/BonusSkillType.cs index 3f1e1783..eeb20db9 100644 --- a/Libraries/Core/Models/Enums/BonusSkillType.cs +++ b/Libraries/Core/Models/Enums/BonusSkillType.cs @@ -7,4 +7,4 @@ public enum BonusSkillType Special, Practical, Mental -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/BonusType.cs b/Libraries/Core/Models/Enums/BonusType.cs index 74f06ff6..6007db0d 100644 --- a/Libraries/Core/Models/Enums/BonusType.cs +++ b/Libraries/Core/Models/Enums/BonusType.cs @@ -33,4 +33,4 @@ public enum BonusType TextBonus, SkillGroupLevelingBoost, StashRows -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/CurrencyType.cs b/Libraries/Core/Models/Enums/CurrencyType.cs index 0b088cdf..e04d71be 100644 --- a/Libraries/Core/Models/Enums/CurrencyType.cs +++ b/Libraries/Core/Models/Enums/CurrencyType.cs @@ -1,10 +1,9 @@ -namespace Core.Models.Enums +namespace Core.Models.Enums; + +public enum CurrencyType { - public enum CurrencyType - { - RUB, - USD, - EUR, - GP - } + RUB, + USD, + EUR, + GP } diff --git a/Libraries/Core/Models/Enums/DamageEffectType.cs b/Libraries/Core/Models/Enums/DamageEffectType.cs index f89d84a7..df59c700 100644 --- a/Libraries/Core/Models/Enums/DamageEffectType.cs +++ b/Libraries/Core/Models/Enums/DamageEffectType.cs @@ -1,15 +1,14 @@ -namespace Core.Models.Enums +namespace Core.Models.Enums; + +public enum DamageEffectType { - public enum DamageEffectType - { - HeavyBleeding, - LightBleeding, - Fracture, - Contusion, - Intoxication, - LethalIntoxication, - RadExposure, - Pain, - DestroyedPart - } + HeavyBleeding, + LightBleeding, + Fracture, + Contusion, + Intoxication, + LethalIntoxication, + RadExposure, + Pain, + DestroyedPart } diff --git a/Libraries/Core/Models/Enums/DogtagExchangeSide.cs b/Libraries/Core/Models/Enums/DogtagExchangeSide.cs index a4a5b97e..1832841c 100644 --- a/Libraries/Core/Models/Enums/DogtagExchangeSide.cs +++ b/Libraries/Core/Models/Enums/DogtagExchangeSide.cs @@ -5,4 +5,4 @@ public enum DogtagExchangeSide Usec, Bear, Any -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/ELocationName.cs b/Libraries/Core/Models/Enums/ELocationName.cs index 5dcd0e53..6f30e8a4 100644 --- a/Libraries/Core/Models/Enums/ELocationName.cs +++ b/Libraries/Core/Models/Enums/ELocationName.cs @@ -14,4 +14,4 @@ public enum ELocationName RezervBase, TarkovStreets, any -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/EventType.cs b/Libraries/Core/Models/Enums/EventType.cs index eeec61bd..321bd63a 100644 --- a/Libraries/Core/Models/Enums/EventType.cs +++ b/Libraries/Core/Models/Enums/EventType.cs @@ -1,10 +1,9 @@ -namespace Core.Models.Enums +namespace Core.Models.Enums; + +public enum EventType { - public enum EventType - { - None, - Halloween, - Christmas, - HalloweenIllumination - } + None, + Halloween, + Christmas, + HalloweenIllumination } diff --git a/Libraries/Core/Models/Enums/ExfiltrationType.cs b/Libraries/Core/Models/Enums/ExfiltrationType.cs index 03d1fe55..4f324a6b 100644 --- a/Libraries/Core/Models/Enums/ExfiltrationType.cs +++ b/Libraries/Core/Models/Enums/ExfiltrationType.cs @@ -1,9 +1,8 @@ -namespace Core.Models.Enums +namespace Core.Models.Enums; + +public enum ExfiltrationType { - public enum ExfiltrationType - { - Individual, - SharedTimer, - Manual - } + Individual, + SharedTimer, + Manual } diff --git a/Libraries/Core/Models/Enums/ExitStatus.cs b/Libraries/Core/Models/Enums/ExitStatus.cs index 3c19762b..6c106f66 100644 --- a/Libraries/Core/Models/Enums/ExitStatus.cs +++ b/Libraries/Core/Models/Enums/ExitStatus.cs @@ -8,4 +8,4 @@ public enum ExitStatus RUNNER, MISSINGINACTION, TRANSIT -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/FleaOfferType.cs b/Libraries/Core/Models/Enums/FleaOfferType.cs index b41d2b29..7ad43177 100644 --- a/Libraries/Core/Models/Enums/FleaOfferType.cs +++ b/Libraries/Core/Models/Enums/FleaOfferType.cs @@ -1,10 +1,9 @@ -namespace Core.Models.Enums +namespace Core.Models.Enums; + +public enum FleaOfferType { - public enum FleaOfferType - { - SINGLE = 0, - MULTI = 1, - PACK = 2, - UNKNOWN = 3 - } + SINGLE = 0, + MULTI = 1, + PACK = 2, + UNKNOWN = 3 } diff --git a/Libraries/Core/Models/Enums/GiftSenderType.cs b/Libraries/Core/Models/Enums/GiftSenderType.cs index f3762599..55021499 100644 --- a/Libraries/Core/Models/Enums/GiftSenderType.cs +++ b/Libraries/Core/Models/Enums/GiftSenderType.cs @@ -5,4 +5,4 @@ public enum GiftSenderType System, Trader, User -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/GiftSentResult.cs b/Libraries/Core/Models/Enums/GiftSentResult.cs index 4c953436..28efcc74 100644 --- a/Libraries/Core/Models/Enums/GiftSentResult.cs +++ b/Libraries/Core/Models/Enums/GiftSentResult.cs @@ -5,5 +5,5 @@ public enum GiftSentResult FAILED_UNKNOWN = 1, FAILED_GIFT_ALREADY_RECEIVED = 2, FAILED_GIFT_DOESNT_EXIST = 3, - SUCCESS = 4, + SUCCESS = 4 } diff --git a/Libraries/Core/Models/Enums/HealthFactor.cs b/Libraries/Core/Models/Enums/HealthFactor.cs index 7e50dd54..e17eefe1 100644 --- a/Libraries/Core/Models/Enums/HealthFactor.cs +++ b/Libraries/Core/Models/Enums/HealthFactor.cs @@ -1,14 +1,13 @@ -namespace Core.Models.Enums +namespace Core.Models.Enums; + +public enum HealthFactor { - public enum HealthFactor - { - None, - Health, - Hydration, - Energy, - Radiation, - Temperature, - Poisoning, - Effect - } + None, + Health, + Hydration, + Energy, + Radiation, + Temperature, + Poisoning, + Effect } diff --git a/Libraries/Core/Models/Enums/Hideout/CircleRewardType.cs b/Libraries/Core/Models/Enums/Hideout/CircleRewardType.cs index 053c534c..f192fd23 100644 --- a/Libraries/Core/Models/Enums/Hideout/CircleRewardType.cs +++ b/Libraries/Core/Models/Enums/Hideout/CircleRewardType.cs @@ -4,4 +4,4 @@ public enum CircleRewardType { RANDOM = 0, HIDEOUT_TASK = 1 -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/Hideout/QteActivityType.cs b/Libraries/Core/Models/Enums/Hideout/QteActivityType.cs index 30e20b7e..424c1d2e 100644 --- a/Libraries/Core/Models/Enums/Hideout/QteActivityType.cs +++ b/Libraries/Core/Models/Enums/Hideout/QteActivityType.cs @@ -3,4 +3,4 @@ namespace Core.Models.Enums.Hideout; public enum QteActivityType { GYM = 0 -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/Hideout/QteEffectType.cs b/Libraries/Core/Models/Enums/Hideout/QteEffectType.cs index d49c3af9..19736f9e 100644 --- a/Libraries/Core/Models/Enums/Hideout/QteEffectType.cs +++ b/Libraries/Core/Models/Enums/Hideout/QteEffectType.cs @@ -5,4 +5,4 @@ public enum QteEffectType finishEffect, singleSuccessEffect, singleFailEffect -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/Hideout/QteResultType.cs b/Libraries/Core/Models/Enums/Hideout/QteResultType.cs index bf04aa61..8a87d16e 100644 --- a/Libraries/Core/Models/Enums/Hideout/QteResultType.cs +++ b/Libraries/Core/Models/Enums/Hideout/QteResultType.cs @@ -4,4 +4,4 @@ public enum QteResultType { None, Exit -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/Hideout/QteRewardType.cs b/Libraries/Core/Models/Enums/Hideout/QteRewardType.cs index 98f223e2..bd3b4137 100644 --- a/Libraries/Core/Models/Enums/Hideout/QteRewardType.cs +++ b/Libraries/Core/Models/Enums/Hideout/QteRewardType.cs @@ -6,4 +6,4 @@ public enum QteRewardType HealthEffect, MusclePain, GymArmTrauma -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/Hideout/QteType.cs b/Libraries/Core/Models/Enums/Hideout/QteType.cs index 129e0aff..5b0b13b6 100644 --- a/Libraries/Core/Models/Enums/Hideout/QteType.cs +++ b/Libraries/Core/Models/Enums/Hideout/QteType.cs @@ -3,4 +3,4 @@ namespace Core.Models.Enums.Hideout; public enum QteType { ShrinkingCircle -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/Hideout/RequirementType.cs b/Libraries/Core/Models/Enums/Hideout/RequirementType.cs index a8dce8db..f0552f2d 100644 --- a/Libraries/Core/Models/Enums/Hideout/RequirementType.cs +++ b/Libraries/Core/Models/Enums/Hideout/RequirementType.cs @@ -12,4 +12,4 @@ public enum RequirementType QuestComplete, Health, BodyPartBuff -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/HideoutAreas.cs b/Libraries/Core/Models/Enums/HideoutAreas.cs index 6545172e..94fe223d 100644 --- a/Libraries/Core/Models/Enums/HideoutAreas.cs +++ b/Libraries/Core/Models/Enums/HideoutAreas.cs @@ -31,4 +31,4 @@ public enum HideoutAreas WEAPON_STAND_SECONDARY = 25, EQUIPMENT_PRESETS_STAND = 26, CIRCLE_OF_CULTISTS = 27 -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/ItemAddedResult.cs b/Libraries/Core/Models/Enums/ItemAddedResult.cs index 15c6f825..0c14751c 100644 --- a/Libraries/Core/Models/Enums/ItemAddedResult.cs +++ b/Libraries/Core/Models/Enums/ItemAddedResult.cs @@ -6,5 +6,5 @@ public enum ItemAddedResult SUCCESS = 1, NO_SPACE = 2, NO_CONTAINERS = 3, - INCOMPATIBLE_ITEM = 4, + INCOMPATIBLE_ITEM = 4 } diff --git a/Libraries/Core/Models/Enums/ItemDropSoundType.cs b/Libraries/Core/Models/Enums/ItemDropSoundType.cs index d7296ce1..6dc79461 100644 --- a/Libraries/Core/Models/Enums/ItemDropSoundType.cs +++ b/Libraries/Core/Models/Enums/ItemDropSoundType.cs @@ -1,10 +1,9 @@ -namespace Core.Models.Enums +namespace Core.Models.Enums; + +public enum ItemDropSoundType { - public enum ItemDropSoundType - { - None, - Pistol, - SubMachineGun, - Rifle - } + None, + Pistol, + SubMachineGun, + Rifle } diff --git a/Libraries/Core/Models/Enums/ItemEventActions.cs b/Libraries/Core/Models/Enums/ItemEventActions.cs index 7ee9aa15..eb4338fa 100644 --- a/Libraries/Core/Models/Enums/ItemEventActions.cs +++ b/Libraries/Core/Models/Enums/ItemEventActions.cs @@ -28,13 +28,13 @@ public record ItemEventActions public const string REMOVE_EQUIPMENT_BUILD = "RemoveEquipmentBuild"; public const string REDEEM_PROFILE_REWARD = "RedeemProfileReward"; public const string SET_FAVORITE_ITEMS = "SetFavoriteItems"; - public const string QUEST_FAIL = "QuestFail"; + public const string QUEST_FAIL = "QuestFail"; public const string PIN_LOCK = "PinLock"; public const string ADD_NOTE = "AddNote"; public const string EDIT_NOTE = "EditNote"; public const string DELETE_NOTE = "DeleteNote"; public const string REPEATABLE_QUEST_CHANGE = "RepeatableQuestChange"; - public const string QUEST_HANDOVER = "QuestHandover"; + public const string QUEST_HANDOVER = "QuestHandover"; public const string QUEST_COMPLETE = "QuestComplete"; public const string QUEST_ACCEPT = "QuestAccept"; public const string RAGFAIR_RENEW_OFFER = "RagFairRenewOffer"; diff --git a/Libraries/Core/Models/Enums/LootRarity.cs b/Libraries/Core/Models/Enums/LootRarity.cs index 05329bdc..2686247b 100644 --- a/Libraries/Core/Models/Enums/LootRarity.cs +++ b/Libraries/Core/Models/Enums/LootRarity.cs @@ -1,10 +1,9 @@ -namespace Core.Models.Enums +namespace Core.Models.Enums; + +public enum LootRarity { - public enum LootRarity - { - Not_exist = -1, - Common, - Rare, - Superrare - } + Not_exist = -1, + Common, + Rare, + Superrare } diff --git a/Libraries/Core/Models/Enums/MessageType.cs b/Libraries/Core/Models/Enums/MessageType.cs index 891e58e5..97a996f2 100644 --- a/Libraries/Core/Models/Enums/MessageType.cs +++ b/Libraries/Core/Models/Enums/MessageType.cs @@ -17,4 +17,4 @@ public enum MessageType MESSAGE_WITH_ITEMS = 13, INITIAL_SUPPORT = 14, BTR_ITEMS_DELIVERY = 15 -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/ModSpawn.cs b/Libraries/Core/Models/Enums/ModSpawn.cs index bc437fc4..b647dffa 100644 --- a/Libraries/Core/Models/Enums/ModSpawn.cs +++ b/Libraries/Core/Models/Enums/ModSpawn.cs @@ -10,4 +10,4 @@ public enum ModSpawn /** Item should not be chosen */ SKIP = 2 -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/PlayerSideMask.cs b/Libraries/Core/Models/Enums/PlayerSideMask.cs index 33c45431..6a826f9b 100644 --- a/Libraries/Core/Models/Enums/PlayerSideMask.cs +++ b/Libraries/Core/Models/Enums/PlayerSideMask.cs @@ -1,12 +1,11 @@ -namespace Core.Models.Enums +namespace Core.Models.Enums; + +public enum PlayerSideMask { - public enum PlayerSideMask - { - None, - Usec, - Bear, - Savage, - Pmc, - All - } + None, + Usec, + Bear, + Savage, + Pmc, + All } diff --git a/Libraries/Core/Models/Enums/ProfileStatus.cs b/Libraries/Core/Models/Enums/ProfileStatus.cs index 08708398..99c08035 100644 --- a/Libraries/Core/Models/Enums/ProfileStatus.cs +++ b/Libraries/Core/Models/Enums/ProfileStatus.cs @@ -7,4 +7,4 @@ public enum ProfileStatus BUSY, LEAVING, TRANSFER -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/QuestTypeEnum.cs b/Libraries/Core/Models/Enums/QuestTypeEnum.cs index 9aed8428..f620d6b5 100644 --- a/Libraries/Core/Models/Enums/QuestTypeEnum.cs +++ b/Libraries/Core/Models/Enums/QuestTypeEnum.cs @@ -15,4 +15,4 @@ public enum QuestTypeEnum Skill, Multi, WeaponAssembly -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/RagfairSort.cs b/Libraries/Core/Models/Enums/RagfairSort.cs index efc17775..48bb3e80 100644 --- a/Libraries/Core/Models/Enums/RagfairSort.cs +++ b/Libraries/Core/Models/Enums/RagfairSort.cs @@ -8,4 +8,4 @@ public enum RagfairSort OFFER_TITLE = 4, PRICE = 5, EXPIRY = 6 -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/RaidMode.cs b/Libraries/Core/Models/Enums/RaidMode.cs index 428f33c1..c3c3792a 100644 --- a/Libraries/Core/Models/Enums/RaidMode.cs +++ b/Libraries/Core/Models/Enums/RaidMode.cs @@ -5,4 +5,4 @@ public enum RaidMode ONLINE, LOCAL, COOP -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/RaidSettings/TimeAndWeather/CloudinessType.cs b/Libraries/Core/Models/Enums/RaidSettings/TimeAndWeather/CloudinessType.cs index afeb8aa9..d3643ed5 100644 --- a/Libraries/Core/Models/Enums/RaidSettings/TimeAndWeather/CloudinessType.cs +++ b/Libraries/Core/Models/Enums/RaidSettings/TimeAndWeather/CloudinessType.cs @@ -8,4 +8,4 @@ public enum CloudinessType CLOUDY_WITH_GAPS, HEAVY_CLOUD_COVER, THUNDER_CLOUD -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/ReloadMode.cs b/Libraries/Core/Models/Enums/ReloadMode.cs index 8712d465..10ae8c5a 100644 --- a/Libraries/Core/Models/Enums/ReloadMode.cs +++ b/Libraries/Core/Models/Enums/ReloadMode.cs @@ -1,10 +1,9 @@ -namespace Core.Models.Enums +namespace Core.Models.Enums; + +public enum ReloadMode { - public enum ReloadMode - { - ExternalMagazine, - InternalMagazine, - OnlyBarrel, - ExternalMagazineWithInternalReloadSupport - } + ExternalMagazine, + InternalMagazine, + OnlyBarrel, + ExternalMagazineWithInternalReloadSupport } diff --git a/Libraries/Core/Models/Enums/RepairStrategyType.cs b/Libraries/Core/Models/Enums/RepairStrategyType.cs index fb0e53e5..38b77b72 100644 --- a/Libraries/Core/Models/Enums/RepairStrategyType.cs +++ b/Libraries/Core/Models/Enums/RepairStrategyType.cs @@ -1,9 +1,8 @@ -namespace Core.Models.Enums +namespace Core.Models.Enums; + +public enum RepairStrategyType { - public enum RepairStrategyType - { - MeleeWeapon, - Firearms, - Armor - } + MeleeWeapon, + Firearms, + Armor } diff --git a/Libraries/Core/Models/Enums/RequirementState.cs b/Libraries/Core/Models/Enums/RequirementState.cs index 7b88c97a..36f2ca7e 100644 --- a/Libraries/Core/Models/Enums/RequirementState.cs +++ b/Libraries/Core/Models/Enums/RequirementState.cs @@ -1,20 +1,19 @@ -namespace Core.Models.Enums +namespace Core.Models.Enums; + +public enum RequirementState { - public enum RequirementState - { - None, - Empty, - TransferItem, - WorldEvent, - NotEmpty, - HasItem, - WearsItem, - EmptyOrSize, - SkillLevel, - Reference, - ScavCooperation, - Train, - Timer, - SecretTransferItem - } + None, + Empty, + TransferItem, + WorldEvent, + NotEmpty, + HasItem, + WearsItem, + EmptyOrSize, + SkillLevel, + Reference, + ScavCooperation, + Train, + Timer, + SecretTransferItem } diff --git a/Libraries/Core/Models/Enums/Season.cs b/Libraries/Core/Models/Enums/Season.cs index 2bb3f6f4..f4177c52 100644 --- a/Libraries/Core/Models/Enums/Season.cs +++ b/Libraries/Core/Models/Enums/Season.cs @@ -9,4 +9,4 @@ public enum Season AUTUMN_LATE = 4, SPRING_EARLY = 5, STORM = 6 -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/SeasonalEventType.cs b/Libraries/Core/Models/Enums/SeasonalEventType.cs index 03c15f70..c8448542 100644 --- a/Libraries/Core/Models/Enums/SeasonalEventType.cs +++ b/Libraries/Core/Models/Enums/SeasonalEventType.cs @@ -8,4 +8,4 @@ public enum SeasonalEventType NewYears, Promo, AprilFools -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/SkillTypes.cs b/Libraries/Core/Models/Enums/SkillTypes.cs index a864a25a..b31f9a6a 100644 --- a/Libraries/Core/Models/Enums/SkillTypes.cs +++ b/Libraries/Core/Models/Enums/SkillTypes.cs @@ -76,4 +76,4 @@ public enum SkillTypes AimMaster, Physical, Combat -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/ThrowWeapType.cs b/Libraries/Core/Models/Enums/ThrowWeapType.cs index e7dd4825..da1f2b94 100644 --- a/Libraries/Core/Models/Enums/ThrowWeapType.cs +++ b/Libraries/Core/Models/Enums/ThrowWeapType.cs @@ -1,13 +1,12 @@ -namespace Core.Models.Enums +namespace Core.Models.Enums; + +public enum ThrowWeapType { - public enum ThrowWeapType - { - frag_grenade, - flash_grenade, - stun_grenade, - smoke_grenade, - gas_grenade, - incendiary_grenade, - sonar - } + frag_grenade, + flash_grenade, + stun_grenade, + smoke_grenade, + gas_grenade, + incendiary_grenade, + sonar } diff --git a/Libraries/Core/Models/Enums/TraderServiceType.cs b/Libraries/Core/Models/Enums/TraderServiceType.cs index 1b03b8e5..0bda5363 100644 --- a/Libraries/Core/Models/Enums/TraderServiceType.cs +++ b/Libraries/Core/Models/Enums/TraderServiceType.cs @@ -9,4 +9,4 @@ public enum TraderServiceType PlayerTaxi, BtrBotCover, TransitItemsDelivery -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/Traders.cs b/Libraries/Core/Models/Enums/Traders.cs index 3d66acbd..9bfef9d6 100644 --- a/Libraries/Core/Models/Enums/Traders.cs +++ b/Libraries/Core/Models/Enums/Traders.cs @@ -16,17 +16,17 @@ public static class Traders public static Dictionary TradersDictionary { get; set; } = new() { - {TradersEnum.Prapor, "54cb50c76803fa8b248b4571"}, - {TradersEnum.Therapist, "54cb57776803fa99248b456e"}, - {TradersEnum.Fence, "579dc571d53a0658a154fbec"}, - {TradersEnum.Skier, "58330581ace78e27b8b10cee"}, - {TradersEnum.Peacekeeper, "5935c25fb3acc3127c3d8cd9"}, - {TradersEnum.Mechanic, "5a7c2eca46aef81a7ca2145d"}, - {TradersEnum.Ragman, "5ac3b934156ae10c4430e83c"}, - {TradersEnum.Jaeger, "5c0647fdd443bc2504c2d371"}, - {TradersEnum.LighthouseKeeper, "638f541a29ffd1183d187f57"}, - {TradersEnum.Btr, "656f0f98d80a697f855d34b1"}, - {TradersEnum.Ref, "6617beeaa9cfa777ca915b7c"} + { TradersEnum.Prapor, "54cb50c76803fa8b248b4571" }, + { TradersEnum.Therapist, "54cb57776803fa99248b456e" }, + { TradersEnum.Fence, "579dc571d53a0658a154fbec" }, + { TradersEnum.Skier, "58330581ace78e27b8b10cee" }, + { TradersEnum.Peacekeeper, "5935c25fb3acc3127c3d8cd9" }, + { TradersEnum.Mechanic, "5a7c2eca46aef81a7ca2145d" }, + { TradersEnum.Ragman, "5ac3b934156ae10c4430e83c" }, + { TradersEnum.Jaeger, "5c0647fdd443bc2504c2d371" }, + { TradersEnum.LighthouseKeeper, "638f541a29ffd1183d187f57" }, + { TradersEnum.Btr, "656f0f98d80a697f855d34b1" }, + { TradersEnum.Ref, "6617beeaa9cfa777ca915b7c" } }; } diff --git a/Libraries/Core/Models/Enums/TransitionType.cs b/Libraries/Core/Models/Enums/TransitionType.cs index 044463cf..97c4bf59 100644 --- a/Libraries/Core/Models/Enums/TransitionType.cs +++ b/Libraries/Core/Models/Enums/TransitionType.cs @@ -5,4 +5,4 @@ public enum TransitionType NONE = 0, COMMON = 1, EVENT = 2 -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/Enums/WindDirection.cs b/Libraries/Core/Models/Enums/WindDirection.cs index 2aae4013..6b44b1eb 100644 --- a/Libraries/Core/Models/Enums/WindDirection.cs +++ b/Libraries/Core/Models/Enums/WindDirection.cs @@ -10,4 +10,4 @@ public enum WindDirection SW = 6, NW = 7, NE = 8 -} \ No newline at end of file +} diff --git a/Libraries/Core/Models/RadioStationType.cs b/Libraries/Core/Models/RadioStationType.cs index f5a8c59b..e8c33c07 100644 --- a/Libraries/Core/Models/RadioStationType.cs +++ b/Libraries/Core/Models/RadioStationType.cs @@ -1,17 +1,16 @@ -namespace Core.Models +namespace Core.Models; + +public enum RadioStationType { - public enum RadioStationType - { - None, - Christmas, - RunddansEvent, - HipHop, - Acoustic, - EDM, - Rock, - LoFi, - Metal, - Punk, - Pop - } + None, + Christmas, + RunddansEvent, + HipHop, + Acoustic, + EDM, + Rock, + LoFi, + Metal, + Punk, + Pop } diff --git a/Libraries/Core/Models/Spt/Config/BotConfig.cs b/Libraries/Core/Models/Spt/Config/BotConfig.cs index 190fef95..e1fa7343 100644 --- a/Libraries/Core/Models/Spt/Config/BotConfig.cs +++ b/Libraries/Core/Models/Spt/Config/BotConfig.cs @@ -248,7 +248,7 @@ public record PresetBatch [JsonPropertyName("shooterBTR")] public int ShooterBTR { get; set; } - + [JsonExtensionData] public IDictionary AdditionalData { get; set; } } @@ -458,7 +458,7 @@ public record NighttimeChanges /// [JsonPropertyName("equipmentModsModifiers")] public Dictionary EquipmentModsModifiers { get; set; } - + [JsonPropertyName("weaponModsModifiers")] public Dictionary WeaponModsModifiers { get; set; } // TODO: currently not in use anywhere } diff --git a/Libraries/Core/Models/Spt/Config/GiftsConfig.cs b/Libraries/Core/Models/Spt/Config/GiftsConfig.cs index cfa0210c..de60443e 100644 --- a/Libraries/Core/Models/Spt/Config/GiftsConfig.cs +++ b/Libraries/Core/Models/Spt/Config/GiftsConfig.cs @@ -73,8 +73,8 @@ public record Gift [JsonPropertyName("maxToSendPlayer")] public int? MaxToSendPlayer { get; set; } - - + + [JsonPropertyName("maxToSendToPlayer")] public int? MaxToSendToPlayer { get; set; } } diff --git a/Libraries/Core/Models/Spt/Config/HideoutConfig.cs b/Libraries/Core/Models/Spt/Config/HideoutConfig.cs index dc34a73b..84d1a1be 100644 --- a/Libraries/Core/Models/Spt/Config/HideoutConfig.cs +++ b/Libraries/Core/Models/Spt/Config/HideoutConfig.cs @@ -56,7 +56,6 @@ public record HideoutCraftToAdd [JsonPropertyName("craftOutputTpl")] public string CraftOutputTpl { get; set; } - } public record CultistCircleSettings diff --git a/Libraries/Core/Models/Spt/Config/InventoryConfig.cs b/Libraries/Core/Models/Spt/Config/InventoryConfig.cs index 26e00565..2b21db13 100644 --- a/Libraries/Core/Models/Spt/Config/InventoryConfig.cs +++ b/Libraries/Core/Models/Spt/Config/InventoryConfig.cs @@ -35,7 +35,7 @@ public record RewardDetails { [JsonPropertyName("_type")] public string? Type { get; set; } - + [JsonPropertyName("rewardCount")] public int RewardCount { get; set; } diff --git a/Libraries/Core/Models/Spt/Config/MatchConfig.cs b/Libraries/Core/Models/Spt/Config/MatchConfig.cs index 67c75388..73d3aac6 100644 --- a/Libraries/Core/Models/Spt/Config/MatchConfig.cs +++ b/Libraries/Core/Models/Spt/Config/MatchConfig.cs @@ -9,7 +9,7 @@ public record MatchConfig : BaseConfig [JsonPropertyName("enabled")] public bool Enabled { get; set; } - + [JsonPropertyName("randomiseMapContainers")] public Dictionary RandomiseMapContainers { get; set; } } diff --git a/Libraries/Core/Models/Spt/Config/PmcConfig.cs b/Libraries/Core/Models/Spt/Config/PmcConfig.cs index 4692f666..34da9688 100644 --- a/Libraries/Core/Models/Spt/Config/PmcConfig.cs +++ b/Libraries/Core/Models/Spt/Config/PmcConfig.cs @@ -55,7 +55,7 @@ public record PmcConfig : BaseConfig [JsonPropertyName("_isUsec")] public string? IsUsecDescription { get; set; } - + /** Percentage chance PMC will be USEC */ [JsonPropertyName("isUsec")] public double IsUsec { get; set; } @@ -112,10 +112,10 @@ public record PmcConfig : BaseConfig /** Should secure container loot from usec.json/bear.json be added to pmc bots secure */ [JsonPropertyName("addSecureContainerLootFromBotConfig")] public bool AddSecureContainerLootFromBotConfig { get; set; } - + [JsonPropertyName("addPrefixToSameNamePMCAsPlayerChance")] public int? AddPrefixToSameNamePMCAsPlayerChance { get; set; } - + [JsonPropertyName("lootItemLimitsRub")] public List? LootItemLimitsRub { get; set; } } diff --git a/Libraries/Core/Models/Spt/Config/RagfairConfig.cs b/Libraries/Core/Models/Spt/Config/RagfairConfig.cs index 66396f83..a0372606 100644 --- a/Libraries/Core/Models/Spt/Config/RagfairConfig.cs +++ b/Libraries/Core/Models/Spt/Config/RagfairConfig.cs @@ -140,7 +140,7 @@ public record Dynamic [JsonPropertyName("_currencies")] public string? CurrenciesDescription { get; set; } - + [JsonPropertyName("currencies")] /** Percentages to sell offers in each currency */ public Dictionary Currencies { get; set; } @@ -358,7 +358,7 @@ public record UnreasonableModPrices /// [JsonPropertyName("newPriceHandbookMultiplier")] public int NewPriceHandbookMultiplier { get; set; } - + [JsonPropertyName("itemType")] public string ItemType { get; set; } } @@ -397,7 +397,7 @@ public record TieredFlea [JsonPropertyName("ammoTplUnlocks")] public Dictionary? AmmoTplUnlocks { get; set; } - + [JsonPropertyName("ammoTiersEnabled")] public bool AmmoTiersEnabled { get; set; } } diff --git a/Libraries/Core/Models/Spt/Config/RepairConfig.cs b/Libraries/Core/Models/Spt/Config/RepairConfig.cs index 81cc3d33..05820555 100644 --- a/Libraries/Core/Models/Spt/Config/RepairConfig.cs +++ b/Libraries/Core/Models/Spt/Config/RepairConfig.cs @@ -82,10 +82,10 @@ public record RepairKit [JsonPropertyName("weapon")] public BonusSettings Weapon { get; set; } - + [JsonPropertyName("vest")] public BonusSettings Vest { get; set; } - + [JsonPropertyName("headwear")] public BonusSettings Headwear { get; set; } } diff --git a/Libraries/Core/Models/Spt/Config/SeasonalEventConfig.cs b/Libraries/Core/Models/Spt/Config/SeasonalEventConfig.cs index 60fa2397..6c41ccb9 100644 --- a/Libraries/Core/Models/Spt/Config/SeasonalEventConfig.cs +++ b/Libraries/Core/Models/Spt/Config/SeasonalEventConfig.cs @@ -78,59 +78,61 @@ public record SeasonalEvent [JsonPropertyName("settings")] public SeasonalEventSettings? Settings { get; set; } - + [JsonPropertyName("setting")] - public SeasonalEventSettings? SettingsDoNOTUse { set => Settings = value; } + public SeasonalEventSettings? SettingsDoNOTUse + { + set => Settings = value; + } } public record SeasonalEventSettings { [JsonPropertyName("enableSummoning")] public bool? EnableSummoning { get; set; } - + [JsonPropertyName("enableHalloweenHideout")] public bool? EnableHalloweenHideout { get; set; } - + [JsonPropertyName("enableChristmasHideout")] public bool? EnableChristmasHideout { get; set; } - + [JsonPropertyName("enableSanta")] public bool? EnableSanta { get; set; } - + [JsonPropertyName("adjustBotAppearances")] public bool? AdjustBotAppearances { get; set; } - + [JsonPropertyName("addEventGearToBots")] public bool? AddEventGearToBots { get; set; } - + [JsonPropertyName("addEventLootToBots")] public bool? AddEventLootToBots { get; set; } - + [JsonPropertyName("removeEntryRequirement")] public List? RemoveEntryRequirement { get; set; } - + [JsonPropertyName("replaceBotHostility")] public bool? ReplaceBotHostility { get; set; } - + [JsonPropertyName("forceSeason")] public Season? ForceSeason { get; set; } - + [JsonPropertyName("zombieSettings")] public ZombieSettings? ZombieSettings { get; set; } - + [JsonPropertyName("disableBosses")] public List? DisableBosses { get; set; } - + [JsonPropertyName("disableWaves")] public List? DisableWaves { get; set; } - } public record ZombieSettings { [JsonPropertyName("enabled")] public bool? Enabled { get; set; } - + [JsonPropertyName("mapInfectionAmount")] public Dictionary? MapInfectionAmount { get; set; } diff --git a/Libraries/Core/Models/Spt/Config/TraderConfig.cs b/Libraries/Core/Models/Spt/Config/TraderConfig.cs index c37f3c4d..ec6896fa 100644 --- a/Libraries/Core/Models/Spt/Config/TraderConfig.cs +++ b/Libraries/Core/Models/Spt/Config/TraderConfig.cs @@ -142,7 +142,7 @@ public record CoopExtractReward : LootRequest { [JsonPropertyName("sendGift")] public bool SendGift { get; set; } - + [JsonPropertyName("useRewarditemBlacklist")] public bool UseRewarditemBlacklist { get; set; } diff --git a/Libraries/Core/Models/Spt/Dialog/SendMessageDetails.cs b/Libraries/Core/Models/Spt/Dialog/SendMessageDetails.cs index ddd1615c..64ea17b8 100644 --- a/Libraries/Core/Models/Spt/Dialog/SendMessageDetails.cs +++ b/Libraries/Core/Models/Spt/Dialog/SendMessageDetails.cs @@ -97,7 +97,7 @@ public record ProfileChangeEvent [JsonPropertyName("entity")] public string? Entity { get; set; } - + [JsonPropertyName("data")] public string? Data { get; set; } } diff --git a/Libraries/Core/Models/Spt/Logging/LogBackgroundColor.cs b/Libraries/Core/Models/Spt/Logging/LogBackgroundColor.cs index 7a6509e6..f45f58a4 100644 --- a/Libraries/Core/Models/Spt/Logging/LogBackgroundColor.cs +++ b/Libraries/Core/Models/Spt/Logging/LogBackgroundColor.cs @@ -15,3 +15,5 @@ // TODO: this likely wont be used anymore, so commenting out insteaad of reimplementing + + diff --git a/Libraries/Core/Models/Spt/Logging/LogTextColor.cs b/Libraries/Core/Models/Spt/Logging/LogTextColor.cs index 2997d23f..8b2b7d8c 100644 --- a/Libraries/Core/Models/Spt/Logging/LogTextColor.cs +++ b/Libraries/Core/Models/Spt/Logging/LogTextColor.cs @@ -15,3 +15,5 @@ // TODO: this likely wont be used anymore, so commenting out insteaad of reimplementing + + diff --git a/Libraries/Core/Models/Spt/Mod/NewItemDetails.cs b/Libraries/Core/Models/Spt/Mod/NewItemDetails.cs index d3c19b04..86513ab4 100644 --- a/Libraries/Core/Models/Spt/Mod/NewItemDetails.cs +++ b/Libraries/Core/Models/Spt/Mod/NewItemDetails.cs @@ -54,6 +54,12 @@ public record LocaleDetails public record CreateItemResult { + public CreateItemResult() + { + Success = false; + Errors = new List(); + } + [JsonPropertyName("success")] public bool? Success { get; set; } @@ -62,12 +68,6 @@ public record CreateItemResult [JsonPropertyName("errors")] public List? Errors { get; set; } - - public CreateItemResult() - { - Success = false; - Errors = new List(); - } } // TODO: This needs to be reworked with however we do it for this project diff --git a/Libraries/Core/Models/Spt/Server/DatabaseTables.cs b/Libraries/Core/Models/Spt/Server/DatabaseTables.cs index 5a960808..f5802e66 100644 --- a/Libraries/Core/Models/Spt/Server/DatabaseTables.cs +++ b/Libraries/Core/Models/Spt/Server/DatabaseTables.cs @@ -6,22 +6,22 @@ namespace Core.Models.Spt.Server; public record DatabaseTables { public Bots.Bots? Bots { get; set; } - + public Hideout.Hideout? Hideout { get; set; } - + public LocaleBase? Locales { get; set; } - + public Locations? Locations { get; set; } - + public Match? Match { get; set; } - + public Templates.Templates? Templates { get; set; } - + public Dictionary? Traders { get; set; } - + public Globals? Globals { get; set; } - + public ServerBase? Server { get; set; } - + public SettingsBase? Settings { get; set; } } diff --git a/Libraries/Core/Models/Spt/Server/Locations.cs b/Libraries/Core/Models/Spt/Server/Locations.cs index 512df15b..bf43bf24 100644 --- a/Libraries/Core/Models/Spt/Server/Locations.cs +++ b/Libraries/Core/Models/Spt/Server/Locations.cs @@ -5,6 +5,53 @@ namespace Core.Models.Spt.Server; public record Locations { + private Dictionary? _locationDictionaryCache; + + // sometimes we get the key or value given so save changing logic in each place + // have it key both + private Dictionary _locationMappings = new() + { + // EFT + { "factory4_day", "Factory4Day" }, + { "bigmap", "Bigmap" }, + { "develop", "Develop" }, + { "factory4_night", "Factory4Night" }, + { "hideout", "Hideout" }, + { "interchange", "Interchange" }, + { "laboratory", "Laboratory" }, + { "lighthouse", "Lighthouse" }, + { "privatearea", "PrivateArea" }, + { "rezervbase", "RezervBase" }, + { "shoreline", "Shoreline" }, + { "suburbs", "Suburbs" }, + { "tarkovstreets", "TarkovStreets" }, + { "terminal", "Terminal" }, + { "town", "Town" }, + { "woods", "Woods" }, + { "sandbox", "Sandbox" }, + { "sandbox_high", "SandboxHigh" }, + + // SPT + { "Factory4Day", "Factory4Day" }, + { "Bigmap", "Bigmap" }, + { "Develop", "Develop" }, + { "Factory4Night", "Factory4Night" }, + { "Hideout", "Hideout" }, + { "Interchange", "Interchange" }, + { "Laboratory", "Laboratory" }, + { "Lighthouse", "Lighthouse" }, + { "PrivateArea", "PrivateArea" }, + { "RezervBase", "RezervBase" }, + { "Shoreline", "Shoreline" }, + { "Suburbs", "Suburbs" }, + { "TarkovStreets", "TarkovStreets" }, + { "Terminal", "Terminal" }, + { "Town", "Town" }, + { "Woods", "Woods" }, + { "Sandbox", "Sandbox" }, + { "SandboxHigh", "SandboxHigh" } + }; + [JsonPropertyName("bigmap")] public Eft.Common.Location? Bigmap { get; set; } @@ -63,8 +110,6 @@ public record Locations [JsonPropertyName("base")] public LocationsBase? Base { get; set; } - private Dictionary? _locationDictionaryCache; - /// /// Get map locations as a dictionary, keyed by its name e.g. Factory4Day /// @@ -86,56 +131,11 @@ public record Locations { return _locationMappings.TryGetValue(key, out var value) ? value : key; } - + private void HydrateDictionary() { var classProps = typeof(Locations).GetProperties().Where(p => p.PropertyType == typeof(Eft.Common.Location) && p.Name != "Item"); _locationDictionaryCache = classProps .ToDictionary(propertyInfo => propertyInfo.Name, propertyInfo => propertyInfo.GetValue(this, null) as Eft.Common.Location); } - - // sometimes we get the key or value given so save changing logic in each place - // have it key both - private Dictionary _locationMappings = new() - { - // EFT - { "factory4_day", "Factory4Day" }, - { "bigmap", "Bigmap" }, - { "develop", "Develop" }, - { "factory4_night", "Factory4Night" }, - { "hideout", "Hideout" }, - { "interchange", "Interchange" }, - { "laboratory", "Laboratory" }, - { "lighthouse", "Lighthouse" }, - { "privatearea", "PrivateArea" }, - { "rezervbase", "RezervBase" }, - { "shoreline", "Shoreline" }, - { "suburbs", "Suburbs" }, - { "tarkovstreets", "TarkovStreets" }, - { "terminal", "Terminal" }, - { "town", "Town" }, - { "woods", "Woods" }, - { "sandbox", "Sandbox" }, - { "sandbox_high", "SandboxHigh" }, - - // SPT - { "Factory4Day", "Factory4Day" }, - { "Bigmap", "Bigmap" }, - { "Develop", "Develop" }, - { "Factory4Night", "Factory4Night" }, - { "Hideout", "Hideout" }, - { "Interchange", "Interchange" }, - { "Laboratory", "Laboratory" }, - { "Lighthouse", "Lighthouse" }, - { "PrivateArea", "PrivateArea" }, - { "RezervBase", "RezervBase" }, - { "Shoreline", "Shoreline" }, - { "Suburbs", "Suburbs" }, - { "TarkovStreets", "TarkovStreets" }, - { "Terminal", "Terminal" }, - { "Town", "Town" }, - { "Woods", "Woods" }, - { "Sandbox", "Sandbox" }, - { "SandboxHigh", "SandboxHigh" } - }; } diff --git a/Libraries/Core/Routers/Dynamic/BotDynamicRouter.cs b/Libraries/Core/Routers/Dynamic/BotDynamicRouter.cs index 0e2f2233..a89484dd 100644 --- a/Libraries/Core/Routers/Dynamic/BotDynamicRouter.cs +++ b/Libraries/Core/Routers/Dynamic/BotDynamicRouter.cs @@ -10,53 +10,58 @@ namespace Core.Routers.Dynamic; public class BotDynamicRouter : DynamicRouter { protected static BotCallbacks _botCallbacks; - + public BotDynamicRouter( JsonUtil jsonUtil, BotCallbacks botCallbacks ) : base( jsonUtil, [ - new RouteAction( - "/singleplayer/settings/bot/limit/", - ( - url, - info, - sessionID, - output - ) => _botCallbacks.GetBotLimit(url, info as EmptyRequestData, sessionID)), - new RouteAction( - "/singleplayer/settings/bot/difficulty/", - ( - url, - info, - sessionID, - output - ) => _botCallbacks.GetBotDifficulty(url, info as EmptyRequestData, sessionID)), - new RouteAction( - "/singleplayer/settings/bot/difficulties", - ( - url, - info, - sessionID, - output - ) => _botCallbacks.GetAllBotDifficulties(url, info as EmptyRequestData, sessionID)), - new RouteAction( - "/singleplayer/settings/bot/maxCap", - ( - url, - info, - sessionID, - output - ) => _botCallbacks.GetBotCap(url, info as EmptyRequestData, sessionID)), - new RouteAction( - "/singleplayer/settings/bot/getBotBehaviours/", - ( - url, - info, - sessionID, - output - ) => _botCallbacks.GetBotBehaviours()) + new RouteAction( + "/singleplayer/settings/bot/limit/", + ( + url, + info, + sessionID, + output + ) => _botCallbacks.GetBotLimit(url, info as EmptyRequestData, sessionID) + ), + new RouteAction( + "/singleplayer/settings/bot/difficulty/", + ( + url, + info, + sessionID, + output + ) => _botCallbacks.GetBotDifficulty(url, info as EmptyRequestData, sessionID) + ), + new RouteAction( + "/singleplayer/settings/bot/difficulties", + ( + url, + info, + sessionID, + output + ) => _botCallbacks.GetAllBotDifficulties(url, info as EmptyRequestData, sessionID) + ), + new RouteAction( + "/singleplayer/settings/bot/maxCap", + ( + url, + info, + sessionID, + output + ) => _botCallbacks.GetBotCap(url, info as EmptyRequestData, sessionID) + ), + new RouteAction( + "/singleplayer/settings/bot/getBotBehaviours/", + ( + url, + info, + sessionID, + output + ) => _botCallbacks.GetBotBehaviours() + ) ] ) { diff --git a/Libraries/Core/Routers/Dynamic/BundleDynamicRouter.cs b/Libraries/Core/Routers/Dynamic/BundleDynamicRouter.cs index 973e8fa4..5acf6720 100644 --- a/Libraries/Core/Routers/Dynamic/BundleDynamicRouter.cs +++ b/Libraries/Core/Routers/Dynamic/BundleDynamicRouter.cs @@ -24,7 +24,8 @@ public class BundleDynamicRouter : DynamicRouter info, sessionID, output - ) => _bundleCallbacks.GetBundle(url, info as EmptyRequestData, sessionID)) + ) => _bundleCallbacks.GetBundle(url, info as EmptyRequestData, sessionID) + ) ] ) { diff --git a/Libraries/Core/Routers/Dynamic/CustomizationDynamicRouter.cs b/Libraries/Core/Routers/Dynamic/CustomizationDynamicRouter.cs index 2c142d3c..71717608 100644 --- a/Libraries/Core/Routers/Dynamic/CustomizationDynamicRouter.cs +++ b/Libraries/Core/Routers/Dynamic/CustomizationDynamicRouter.cs @@ -24,7 +24,8 @@ public class CustomizationDynamicRouter : DynamicRouter info, sessionID, output - ) => _customizationCallbacks.GetTraderSuits(url, info as EmptyRequestData, sessionID)) + ) => _customizationCallbacks.GetTraderSuits(url, info as EmptyRequestData, sessionID) + ) ] ) { diff --git a/Libraries/Core/Routers/Dynamic/DataDynamicRouter.cs b/Libraries/Core/Routers/Dynamic/DataDynamicRouter.cs index 66c02d46..ffd807f8 100644 --- a/Libraries/Core/Routers/Dynamic/DataDynamicRouter.cs +++ b/Libraries/Core/Routers/Dynamic/DataDynamicRouter.cs @@ -10,37 +10,40 @@ namespace Core.Routers.Dynamic; public class DataDynamicRouter : DynamicRouter { protected static DataCallbacks _dataCallbacks; - + public DataDynamicRouter( JsonUtil jsonUtil, DataCallbacks dataCallbacks ) : base( jsonUtil, [ - new RouteAction( - "/client/menu/locale/", - ( - url, - info, - sessionID, - output - ) => _dataCallbacks.GetLocalesMenu(url, info as EmptyRequestData, sessionID)), - new RouteAction( - "/client/locale/", - ( - url, - info, - sessionID, - output - ) => _dataCallbacks.GetLocalesGlobal(url, info as EmptyRequestData, sessionID)), - new RouteAction( - "/client/items/prices/", - ( - url, - info, - sessionID, - output - ) => _dataCallbacks.GetItemPrices(url, info as EmptyRequestData, sessionID)), + new RouteAction( + "/client/menu/locale/", + ( + url, + info, + sessionID, + output + ) => _dataCallbacks.GetLocalesMenu(url, info as EmptyRequestData, sessionID) + ), + new RouteAction( + "/client/locale/", + ( + url, + info, + sessionID, + output + ) => _dataCallbacks.GetLocalesGlobal(url, info as EmptyRequestData, sessionID) + ), + new RouteAction( + "/client/items/prices/", + ( + url, + info, + sessionID, + output + ) => _dataCallbacks.GetItemPrices(url, info as EmptyRequestData, sessionID) + ) ] ) { diff --git a/Libraries/Core/Routers/Dynamic/HttpDynamicRouter.cs b/Libraries/Core/Routers/Dynamic/HttpDynamicRouter.cs index 3dac2684..6a7169d8 100644 --- a/Libraries/Core/Routers/Dynamic/HttpDynamicRouter.cs +++ b/Libraries/Core/Routers/Dynamic/HttpDynamicRouter.cs @@ -10,9 +10,9 @@ public class HttpDynamicRouter : DynamicRouter public HttpDynamicRouter(ImageRouter imageRouter, JsonUtil jsonUtil) : base( jsonUtil, [ - new(".jpg", (_, _, _, _) => imageRouter.GetImage()), - new(".png", (_, _, _, _) => imageRouter.GetImage()), - new(".ico", (_, _, _, _) => imageRouter.GetImage()) + new RouteAction(".jpg", (_, _, _, _) => imageRouter.GetImage()), + new RouteAction(".png", (_, _, _, _) => imageRouter.GetImage()), + new RouteAction(".ico", (_, _, _, _) => imageRouter.GetImage()) ] ) { diff --git a/Libraries/Core/Routers/Dynamic/InraidDynamicRouter.cs b/Libraries/Core/Routers/Dynamic/InraidDynamicRouter.cs index 5442b675..4740f356 100644 --- a/Libraries/Core/Routers/Dynamic/InraidDynamicRouter.cs +++ b/Libraries/Core/Routers/Dynamic/InraidDynamicRouter.cs @@ -24,8 +24,9 @@ public class InraidDynamicRouter : DynamicRouter info, sessionID, output - ) => _inraidCallbacks.RegisterPlayer(url, info as RegisterPlayerRequestData, sessionID), - typeof(RegisterPlayerRequestData)) + ) => _inraidCallbacks.RegisterPlayer(url, info as RegisterPlayerRequestData, sessionID), + typeof(RegisterPlayerRequestData) + ) ] ) { diff --git a/Libraries/Core/Routers/Dynamic/LocationDynamicRouter.cs b/Libraries/Core/Routers/Dynamic/LocationDynamicRouter.cs index 57b4de66..f2556a78 100644 --- a/Libraries/Core/Routers/Dynamic/LocationDynamicRouter.cs +++ b/Libraries/Core/Routers/Dynamic/LocationDynamicRouter.cs @@ -7,7 +7,6 @@ namespace Core.Routers.Dynamic; [Injectable(InjectableTypeOverride = typeof(DynamicRouter))] public class LocationDynamicRouter : DynamicRouter { - public LocationDynamicRouter( JsonUtil jsonUtil ) : base( diff --git a/Libraries/Core/Routers/Dynamic/TraderDynamicRouter.cs b/Libraries/Core/Routers/Dynamic/TraderDynamicRouter.cs index dcd4511f..bfc6341a 100644 --- a/Libraries/Core/Routers/Dynamic/TraderDynamicRouter.cs +++ b/Libraries/Core/Routers/Dynamic/TraderDynamicRouter.cs @@ -24,7 +24,8 @@ public class TraderDynamicRouter : DynamicRouter info, sessionID, output - ) => _traderCallbacks.GetTrader(url, info as EmptyRequestData, sessionID)), + ) => _traderCallbacks.GetTrader(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/trading/api/getTraderAssort/", ( @@ -32,7 +33,8 @@ public class TraderDynamicRouter : DynamicRouter info, sessionID, output - ) => _traderCallbacks.GetAssort(url, info as EmptyRequestData, sessionID)), + ) => _traderCallbacks.GetAssort(url, info as EmptyRequestData, sessionID) + ) ] ) { diff --git a/Libraries/Core/Routers/EventOutputHolder.cs b/Libraries/Core/Routers/EventOutputHolder.cs index 3344f232..338ce63f 100644 --- a/Libraries/Core/Routers/EventOutputHolder.cs +++ b/Libraries/Core/Routers/EventOutputHolder.cs @@ -12,13 +12,13 @@ namespace Core.Routers; [Injectable] public class EventOutputHolder { - protected ISptLogger _logger; - protected ProfileHelper _profileHelper; - protected TimeUtil _timeUtil; + protected Dictionary> _clientActiveSessionStorage = new(); protected ICloner _cloner; + protected ISptLogger _logger; protected Dictionary _outputStore = new(); - protected Dictionary> _clientActiveSessionStorage = new(); + protected ProfileHelper _profileHelper; + protected TimeUtil _timeUtil; public EventOutputHolder( ISptLogger logger, @@ -35,11 +35,8 @@ public class EventOutputHolder public ItemEventRouterResponse GetOutput(string sessionId) { - var resultFound = _outputStore.TryGetValue(sessionId, out ItemEventRouterResponse? result); - if (resultFound) - { - return result; - } + var resultFound = _outputStore.TryGetValue(sessionId, out var result); + if (resultFound) return result; // Nothing found, reset to default ResetOutput(sessionId); @@ -52,11 +49,8 @@ public class EventOutputHolder { var pmcProfile = _profileHelper.GetPmcProfile(sessionId); - if (_outputStore.ContainsKey(sessionId)) - { - _outputStore.Remove(sessionId); - } - + if (_outputStore.ContainsKey(sessionId)) _outputStore.Remove(sessionId); + _outputStore.Add( sessionId, new ItemEventRouterResponse @@ -90,8 +84,8 @@ public class EventOutputHolder public void UpdateOutputProperties(string sessionId) { - PmcData pmcData = _profileHelper.GetPmcProfile(sessionId); - ProfileChange profileChanges = _outputStore[sessionId].ProfileChanges[sessionId]; + var pmcData = _profileHelper.GetPmcProfile(sessionId); + var profileChanges = _outputStore[sessionId].ProfileChanges[sessionId]; profileChanges.Experience = pmcData.Info.Experience; profileChanges.Health = _cloner.Clone(pmcData.Health); @@ -116,7 +110,6 @@ public class EventOutputHolder private void CleanUpCompleteCraftsInProfile(Dictionary? productions) { foreach (var production in productions) - { if ((production.Value.SptIsComplete ?? false) && (production.Value.SptIsContinuous ?? false)) { // Water collector / Bitcoin etc @@ -129,7 +122,6 @@ public class EventOutputHolder // Normal completed craft, delete productions.Remove(production.Key); } - } } private Dictionary? GetImprovementsFromProfileAndFlagComplete(PmcData pmcData) @@ -139,15 +131,9 @@ public class EventOutputHolder var improvement = pmcData.Hideout.Improvements[improvementKey.Key]; // Skip completed - if (improvement.Completed ?? false) - { - continue; - } + if (improvement.Completed ?? false) continue; - if (improvement.ImproveCompleteTimestamp < _timeUtil.GetTimeStamp()) - { - improvement.Completed = true; - } + if (improvement.ImproveCompleteTimestamp < _timeUtil.GetTimeStamp()) improvement.Completed = true; } return pmcData.Hideout.Improvements; @@ -158,22 +144,14 @@ public class EventOutputHolder foreach (var production in productions) { if (production.Value is null) - { // Could be cancelled production, skip item to save processing continue; - } // Complete and is Continuous e.g. water collector - if ((production.Value.SptIsComplete ?? false) && (production.Value.SptIsContinuous ?? false)) - { - continue; - } + if ((production.Value.SptIsComplete ?? false) && (production.Value.SptIsContinuous ?? false)) continue; // Skip completed - if (!production.Value.InProgress ?? false) - { - continue; - } + if (!production.Value.InProgress ?? false) continue; // Client informed of craft, remove from data returned Dictionary? storageForSessionId = null; @@ -192,10 +170,7 @@ public class EventOutputHolder } // Flag started craft as having been seen by client so it won't happen subsequent times - if (production.Value.Progress > 0 && !storageForSessionId.ContainsKey(production.Key)) - { - storageForSessionId.TryAdd(production.Key, true); - } + if (production.Value.Progress > 0 && !storageForSessionId.ContainsKey(production.Key)) storageForSessionId.TryAdd(production.Key, true); } // Return undefined if there's no crafts to send to client to match live behaviour @@ -204,7 +179,7 @@ public class EventOutputHolder private void ResetMoneyTransferLimit(MoneyTransferLimits limit) { - if (limit.NextResetTime < this._timeUtil.GetTimeStamp()) + if (limit.NextResetTime < _timeUtil.GetTimeStamp()) { limit.NextResetTime += limit.ResetInterval; limit.RemainingLimit = limit.TotalLimit; @@ -221,7 +196,7 @@ public class EventOutputHolder Disabled = trader.Value.Disabled, Loyalty = trader.Value.LoyaltyLevel, Standing = trader.Value.Standing, - Unlocked = trader.Value.Unlocked, + Unlocked = trader.Value.Unlocked } ); } diff --git a/Libraries/Core/Routers/HttpRouter.cs b/Libraries/Core/Routers/HttpRouter.cs index f7c809c0..e8ab8944 100644 --- a/Libraries/Core/Routers/HttpRouter.cs +++ b/Libraries/Core/Routers/HttpRouter.cs @@ -6,8 +6,8 @@ namespace Core.Routers; [Injectable] public class HttpRouter { - protected IEnumerable _staticRouters; protected IEnumerable _dynamicRoutes; + protected IEnumerable _staticRouters; public HttpRouter( IEnumerable staticRouters, @@ -39,14 +39,10 @@ public class HttpRouter var wrapper = new ResponseWrapper(""); var handled = HandleRoute(req, sessionID, wrapper, _staticRouters, false, body, out deserializedObject); - if (!handled) { - HandleRoute(req, sessionID, wrapper, _dynamicRoutes, true, body, out deserializedObject); - } + if (!handled) HandleRoute(req, sessionID, wrapper, _dynamicRoutes, true, body, out deserializedObject); // TODO: Temporary hack to change ItemEventRouter response sessionID binding to what client expects - if (wrapper.Output?.Contains("\"profileChanges\":{") ?? false) { - wrapper.Output = wrapper.Output.Replace(sessionID, sessionID); - } + if (wrapper.Output?.Contains("\"profileChanges\":{") ?? false) wrapper.Output = wrapper.Output.Replace(sessionID, sessionID); //var filepath = $"c:\\SharpServer\\{req.Path.ToString().Substring(1).Replace("/", ".")}.json"; //File.WriteAllText(filepath, wrapper.Output); @@ -66,28 +62,25 @@ public class HttpRouter { var url = request.Path.Value; deserializedObject = null; - + // remove retry from url - if (url?.Contains("?retry=") ?? false) { - url = url.Split("?retry=")[0]; - } + if (url?.Contains("?retry=") ?? false) url = url.Split("?retry=")[0]; var matched = false; foreach (var route in routers) - { - if (route.CanHandle(url, dynamic)) { - if (dynamic) { + if (route.CanHandle(url, dynamic)) + { + if (dynamic) wrapper.Output = (route as DynamicRouter).HandleDynamic(url, body, sessionID, wrapper.Output) as string; - } else { + else wrapper.Output = (route as StaticRouter).HandleStatic(url, body, sessionID, wrapper.Output) as string; - } matched = true; } - } + return matched; } + protected class ResponseWrapper(string? output) { public string? Output { get; set; } = output; } } - diff --git a/Libraries/Core/Routers/ImageRouter.cs b/Libraries/Core/Routers/ImageRouter.cs index 5506ed36..74fd0d84 100644 --- a/Libraries/Core/Routers/ImageRouter.cs +++ b/Libraries/Core/Routers/ImageRouter.cs @@ -8,8 +8,8 @@ namespace Core.Routers; public class ImageRouter { protected FileUtil _fileUtil; - protected ImageRouterService _imageRouterService; protected HttpFileUtil _httpFileUtil; + protected ImageRouterService _imageRouterService; public ImageRouter( FileUtil fileUtil, @@ -33,10 +33,7 @@ public class ImageRouter var url = _fileUtil.StripExtension(req.Path, true); // send image - if (_imageRouterService.ExistsByKey(url)) - { - _httpFileUtil.SendFile(resp, _imageRouterService.GetByKey(url)); - } + if (_imageRouterService.ExistsByKey(url)) _httpFileUtil.SendFile(resp, _imageRouterService.GetByKey(url)); } public string GetImage() diff --git a/Libraries/Core/Routers/ItemEventRouter.cs b/Libraries/Core/Routers/ItemEventRouter.cs index f3680094..5f11f963 100644 --- a/Libraries/Core/Routers/ItemEventRouter.cs +++ b/Libraries/Core/Routers/ItemEventRouter.cs @@ -8,74 +8,69 @@ using Core.Utils; using Core.Utils.Cloners; using LogLevel = Core.Models.Spt.Logging.LogLevel; -namespace Core.Routers +namespace Core.Routers; + +[Injectable] +public class ItemEventRouter { - [Injectable] - public class ItemEventRouter + protected ICloner _cloner; + protected EventOutputHolder _eventOutputHolder; + protected HttpResponseUtil _httpResponseUtil; + protected List _itemEventRouters; + protected JsonUtil _jsonUtil; + protected LocalisationService _localisationService; + protected ISptLogger _logger; + protected ProfileHelper _profileHelper; + + public ItemEventRouter( + ISptLogger logger, + HttpResponseUtil httpResponseUtil, + JsonUtil jsonUtil, + ProfileHelper profileHelper, + LocalisationService localisationService, + EventOutputHolder eventOutputHolder, + IEnumerable itemEventRouters, + ICloner cloner + ) { - protected ISptLogger _logger; - protected HttpResponseUtil _httpResponseUtil; - protected JsonUtil _jsonUtil; - protected ProfileHelper _profileHelper; - protected LocalisationService _localisationService; - protected EventOutputHolder _eventOutputHolder; - protected List _itemEventRouters; - protected ICloner _cloner; + _logger = logger; + _httpResponseUtil = httpResponseUtil; + _jsonUtil = jsonUtil; + _profileHelper = profileHelper; + _localisationService = localisationService; + _eventOutputHolder = eventOutputHolder; + _itemEventRouters = itemEventRouters.ToList(); + _cloner = cloner; + } - public ItemEventRouter( - ISptLogger logger, - HttpResponseUtil httpResponseUtil, - JsonUtil jsonUtil, - ProfileHelper profileHelper, - LocalisationService localisationService, - EventOutputHolder eventOutputHolder, - IEnumerable itemEventRouters, - ICloner cloner - ) + public ItemEventRouterResponse HandleEvents(ItemEventRouterRequest info, string sessionID) + { + var output = _eventOutputHolder.GetOutput(sessionID); + + foreach (var body in info.Data) { - _logger = logger; - _httpResponseUtil = httpResponseUtil; - _jsonUtil = jsonUtil; - _profileHelper = profileHelper; - _localisationService = localisationService; - _eventOutputHolder = eventOutputHolder; - _itemEventRouters = itemEventRouters.ToList(); - _cloner = cloner; - } + var pmcData = _profileHelper.GetPmcProfile(sessionID); - public ItemEventRouterResponse HandleEvents(ItemEventRouterRequest info, string sessionID) - { - var output = _eventOutputHolder.GetOutput(sessionID); + var eventRouter = _itemEventRouters.FirstOrDefault((r) => r.CanHandle(body.Action)); + if (eventRouter is null) + { + _logger.Error(_localisationService.GetText("event-unhandled_event", body.Action)); + _logger.WriteToLogFile(_jsonUtil.Serialize(info.Data)); - foreach (var body in info.Data) { - var pmcData = _profileHelper.GetPmcProfile(sessionID); - - var eventRouter = _itemEventRouters.FirstOrDefault((r) => r.CanHandle(body.Action)); - if (eventRouter is null) - { - _logger.Error(_localisationService.GetText("event-unhandled_event", body.Action)); - _logger.WriteToLogFile(_jsonUtil.Serialize(info.Data)); - - continue; - } - - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"event: { body.Action}"); - } - eventRouter.HandleItemEvent(body.Action, pmcData, body, sessionID, output); - if (output.Warnings?.Count > 0) { - break; - } + continue; } - _eventOutputHolder.UpdateOutputProperties(sessionID); - - // Clone output before resetting the output object ready for use next time - var outputClone = _cloner.Clone(output); - _eventOutputHolder.ResetOutput(sessionID); - - return outputClone; + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"event: {body.Action}"); + eventRouter.HandleItemEvent(body.Action, pmcData, body, sessionID, output); + if (output.Warnings?.Count > 0) break; } + + _eventOutputHolder.UpdateOutputProperties(sessionID); + + // Clone output before resetting the output object ready for use next time + var outputClone = _cloner.Clone(output); + _eventOutputHolder.ResetOutput(sessionID); + + return outputClone; } } diff --git a/Libraries/Core/Routers/ItemEvents/CustomizationItemEventRouter.cs b/Libraries/Core/Routers/ItemEvents/CustomizationItemEventRouter.cs index 10bc03c1..1b660530 100644 --- a/Libraries/Core/Routers/ItemEvents/CustomizationItemEventRouter.cs +++ b/Libraries/Core/Routers/ItemEvents/CustomizationItemEventRouter.cs @@ -12,8 +12,8 @@ namespace Core.Routers.ItemEvents; [Injectable(InjectableTypeOverride = typeof(ItemEventRouterDefinition))] public class CustomizationItemEventRouter : ItemEventRouterDefinition { - protected ISptLogger _logger; protected CustomizationCallbacks _customizationCallbacks; + protected ISptLogger _logger; public CustomizationItemEventRouter ( @@ -27,14 +27,15 @@ public class CustomizationItemEventRouter : ItemEventRouterDefinition protected override List GetHandledRoutes() { - return new() + return new List { - new HandledRoute("CustomizationBuy", false), - new HandledRoute("CustomizationSet", false) + new("CustomizationBuy", false), + new("CustomizationSet", false) }; } - public override ItemEventRouterResponse HandleItemEvent(string url, PmcData pmcData, BaseInteractionRequestData body, string sessionID, ItemEventRouterResponse output) + public override ItemEventRouterResponse HandleItemEvent(string url, PmcData pmcData, BaseInteractionRequestData body, string sessionID, + ItemEventRouterResponse output) { switch (url) { diff --git a/Libraries/Core/Routers/ItemEvents/HealthItemEventRouter.cs b/Libraries/Core/Routers/ItemEvents/HealthItemEventRouter.cs index d878eacd..c8698077 100644 --- a/Libraries/Core/Routers/ItemEvents/HealthItemEventRouter.cs +++ b/Libraries/Core/Routers/ItemEvents/HealthItemEventRouter.cs @@ -31,7 +31,8 @@ public class HealthItemEventRouter : ItemEventRouterDefinition ]; } - public override ItemEventRouterResponse HandleItemEvent(string url, PmcData pmcData, BaseInteractionRequestData body, string sessionID, ItemEventRouterResponse output) + public override ItemEventRouterResponse HandleItemEvent(string url, PmcData pmcData, BaseInteractionRequestData body, string sessionID, + ItemEventRouterResponse output) { switch (url) { diff --git a/Libraries/Core/Routers/ItemEvents/HideoutItemEventRouter.cs b/Libraries/Core/Routers/ItemEvents/HideoutItemEventRouter.cs index 4704272f..f6c77889 100644 --- a/Libraries/Core/Routers/ItemEvents/HideoutItemEventRouter.cs +++ b/Libraries/Core/Routers/ItemEvents/HideoutItemEventRouter.cs @@ -44,9 +44,11 @@ public class HideoutItemEventRouter : ItemEventRouterDefinition ]; } - public override ItemEventRouterResponse HandleItemEvent(string url, PmcData pmcData, BaseInteractionRequestData body, string sessionID, ItemEventRouterResponse output) + public override ItemEventRouterResponse HandleItemEvent(string url, PmcData pmcData, BaseInteractionRequestData body, string sessionID, + ItemEventRouterResponse output) { - switch (url) { + switch (url) + { case HideoutEventActions.HIDEOUT_UPGRADE: return _hideoutCallbacks.Upgrade(pmcData, body as HideoutUpgradeRequestData, sessionID, output); case HideoutEventActions.HIDEOUT_UPGRADE_COMPLETE: diff --git a/Libraries/Core/Routers/ItemEvents/InsuranceItemEventRouter.cs b/Libraries/Core/Routers/ItemEvents/InsuranceItemEventRouter.cs index 719189a4..6e54e642 100644 --- a/Libraries/Core/Routers/ItemEvents/InsuranceItemEventRouter.cs +++ b/Libraries/Core/Routers/ItemEvents/InsuranceItemEventRouter.cs @@ -23,13 +23,14 @@ public class InsuranceItemEventRouter : ItemEventRouterDefinition protected override List GetHandledRoutes() { - return new() + return new List { - new HandledRoute("Insure", false) + new("Insure", false) }; } - public override ItemEventRouterResponse HandleItemEvent(string url, PmcData pmcData, BaseInteractionRequestData body, string sessionID, ItemEventRouterResponse output) + public override ItemEventRouterResponse HandleItemEvent(string url, PmcData pmcData, BaseInteractionRequestData body, string sessionID, + ItemEventRouterResponse output) { switch (url) { diff --git a/Libraries/Core/Routers/ItemEvents/InventoryItemEventRouter.cs b/Libraries/Core/Routers/ItemEvents/InventoryItemEventRouter.cs index 2e4c82dd..9177495d 100644 --- a/Libraries/Core/Routers/ItemEvents/InventoryItemEventRouter.cs +++ b/Libraries/Core/Routers/ItemEvents/InventoryItemEventRouter.cs @@ -14,8 +14,8 @@ namespace Core.Routers.ItemEvents; [Injectable(InjectableTypeOverride = typeof(ItemEventRouterDefinition))] public class InventoryItemEventRouter : ItemEventRouterDefinition { - protected InventoryCallbacks _inventoryCallbacks; protected HideoutCallbacks _hideoutCallbacks; + protected InventoryCallbacks _inventoryCallbacks; public InventoryItemEventRouter ( @@ -29,37 +29,39 @@ public class InventoryItemEventRouter : ItemEventRouterDefinition protected override List GetHandledRoutes() { - return new() + return new List { - new HandledRoute(ItemEventActions.MOVE, false), - new HandledRoute(ItemEventActions.REMOVE, false), - new HandledRoute(ItemEventActions.SPLIT, false), - new HandledRoute(ItemEventActions.MERGE, false), - new HandledRoute(ItemEventActions.TRANSFER, false), - new HandledRoute(ItemEventActions.SWAP, false), - new HandledRoute(ItemEventActions.FOLD, false), - new HandledRoute(ItemEventActions.TOGGLE, false), - new HandledRoute(ItemEventActions.TAG, false), - new HandledRoute(ItemEventActions.BIND, false), - new HandledRoute(ItemEventActions.UNBIND, false), - new HandledRoute(ItemEventActions.EXAMINE, false), - new HandledRoute(ItemEventActions.READ_ENCYCLOPEDIA, false), - new HandledRoute(ItemEventActions.APPLY_INVENTORY_CHANGES, false), - new HandledRoute(ItemEventActions.CREATE_MAP_MARKER, false), - new HandledRoute(ItemEventActions.DELETE_MAP_MARKER, false), - new HandledRoute(ItemEventActions.EDIT_MAP_MARKER, false), - new HandledRoute(ItemEventActions.OPEN_RANDOM_LOOT_CONTAINER, false), - new HandledRoute(ItemEventActions.HIDEOUT_QTE_EVENT, false), - new HandledRoute(ItemEventActions.REDEEM_PROFILE_REWARD, false), - new HandledRoute(ItemEventActions.SET_FAVORITE_ITEMS, false), - new HandledRoute(ItemEventActions.QUEST_FAIL, false), - new HandledRoute(ItemEventActions.PIN_LOCK, false) + new(ItemEventActions.MOVE, false), + new(ItemEventActions.REMOVE, false), + new(ItemEventActions.SPLIT, false), + new(ItemEventActions.MERGE, false), + new(ItemEventActions.TRANSFER, false), + new(ItemEventActions.SWAP, false), + new(ItemEventActions.FOLD, false), + new(ItemEventActions.TOGGLE, false), + new(ItemEventActions.TAG, false), + new(ItemEventActions.BIND, false), + new(ItemEventActions.UNBIND, false), + new(ItemEventActions.EXAMINE, false), + new(ItemEventActions.READ_ENCYCLOPEDIA, false), + new(ItemEventActions.APPLY_INVENTORY_CHANGES, false), + new(ItemEventActions.CREATE_MAP_MARKER, false), + new(ItemEventActions.DELETE_MAP_MARKER, false), + new(ItemEventActions.EDIT_MAP_MARKER, false), + new(ItemEventActions.OPEN_RANDOM_LOOT_CONTAINER, false), + new(ItemEventActions.HIDEOUT_QTE_EVENT, false), + new(ItemEventActions.REDEEM_PROFILE_REWARD, false), + new(ItemEventActions.SET_FAVORITE_ITEMS, false), + new(ItemEventActions.QUEST_FAIL, false), + new(ItemEventActions.PIN_LOCK, false) }; } - public override ItemEventRouterResponse HandleItemEvent(string url, PmcData pmcData, BaseInteractionRequestData body, string sessionID, ItemEventRouterResponse output) + public override ItemEventRouterResponse HandleItemEvent(string url, PmcData pmcData, BaseInteractionRequestData body, string sessionID, + ItemEventRouterResponse output) { - switch (url) { + switch (url) + { case ItemEventActions.MOVE: return _inventoryCallbacks.MoveItem(pmcData, body as InventoryMoveRequestData, sessionID, output); case ItemEventActions.REMOVE: @@ -105,7 +107,7 @@ public class InventoryItemEventRouter : ItemEventRouterDefinition case ItemEventActions.QUEST_FAIL: return _inventoryCallbacks.FailQuest(pmcData, body as FailQuestRequestData, sessionID, output); case ItemEventActions.PIN_LOCK: - return _inventoryCallbacks.PinOrLock(pmcData, body as PinOrLockItemRequest, sessionID, output); + return _inventoryCallbacks.PinOrLock(pmcData, body as PinOrLockItemRequest, sessionID, output); default: throw new Exception($"InventoryItemEventRouter being used when it cant handle route {url}"); } diff --git a/Libraries/Core/Routers/ItemEvents/NoteItemEventRouter.cs b/Libraries/Core/Routers/ItemEvents/NoteItemEventRouter.cs index bf0b8cef..b1a2e6f8 100644 --- a/Libraries/Core/Routers/ItemEvents/NoteItemEventRouter.cs +++ b/Libraries/Core/Routers/ItemEvents/NoteItemEventRouter.cs @@ -23,15 +23,16 @@ public class NoteItemEventRouter : ItemEventRouterDefinition protected override List GetHandledRoutes() { - return new() + return new List { - new HandledRoute("AddNote", false), - new HandledRoute("EditNote", false), - new HandledRoute("DeleteNote", false) + new("AddNote", false), + new("EditNote", false), + new("DeleteNote", false) }; } - public override ItemEventRouterResponse HandleItemEvent(string url, PmcData pmcData, BaseInteractionRequestData body, string sessionID, ItemEventRouterResponse output) + public override ItemEventRouterResponse HandleItemEvent(string url, PmcData pmcData, BaseInteractionRequestData body, string sessionID, + ItemEventRouterResponse output) { switch (url) { diff --git a/Libraries/Core/Routers/ItemEvents/QuestItemEventRouter.cs b/Libraries/Core/Routers/ItemEvents/QuestItemEventRouter.cs index c0bb08ca..b1e00ca9 100644 --- a/Libraries/Core/Routers/ItemEvents/QuestItemEventRouter.cs +++ b/Libraries/Core/Routers/ItemEvents/QuestItemEventRouter.cs @@ -24,18 +24,20 @@ public class QuestItemEventRouter : ItemEventRouterDefinition protected override List GetHandledRoutes() { - return new() + return new List { - new HandledRoute("QuestAccept", false), - new HandledRoute("QuestComplete", false), - new HandledRoute("QuestHandover", false), - new HandledRoute("RepeatableQuestChange", false) + new("QuestAccept", false), + new("QuestComplete", false), + new("QuestHandover", false), + new("RepeatableQuestChange", false) }; } - public override ItemEventRouterResponse HandleItemEvent(string url, PmcData pmcData, BaseInteractionRequestData body, string sessionID, ItemEventRouterResponse output) + public override ItemEventRouterResponse HandleItemEvent(string url, PmcData pmcData, BaseInteractionRequestData body, string sessionID, + ItemEventRouterResponse output) { - switch (url) { + switch (url) + { case "QuestAccept": return _questCallbacks.AcceptQuest(pmcData, body as AcceptQuestRequestData, sessionID); case "QuestComplete": diff --git a/Libraries/Core/Routers/ItemEvents/RagfairItemEventRouter.cs b/Libraries/Core/Routers/ItemEvents/RagfairItemEventRouter.cs index c7ea6b42..197044e8 100644 --- a/Libraries/Core/Routers/ItemEvents/RagfairItemEventRouter.cs +++ b/Libraries/Core/Routers/ItemEvents/RagfairItemEventRouter.cs @@ -23,17 +23,19 @@ public class RagfairItemEventRouter : ItemEventRouterDefinition protected override List GetHandledRoutes() { - return new() + return new List { - new HandledRoute("RagFairAddOffer", false), - new HandledRoute("RagFairRemoveOffer", false), - new HandledRoute("RagFairRenewOffer", false), + new("RagFairAddOffer", false), + new("RagFairRemoveOffer", false), + new("RagFairRenewOffer", false) }; } - public override ItemEventRouterResponse HandleItemEvent(string url, PmcData pmcData, BaseInteractionRequestData body, string sessionID, ItemEventRouterResponse output) + public override ItemEventRouterResponse HandleItemEvent(string url, PmcData pmcData, BaseInteractionRequestData body, string sessionID, + ItemEventRouterResponse output) { - switch (url) { + switch (url) + { case "RagFairAddOffer": return _ragfairCallbacks.AddOffer(pmcData, body as AddOfferRequestData, sessionID); case "RagFairRemoveOffer": diff --git a/Libraries/Core/Routers/ItemEvents/RepairItemEventRouter.cs b/Libraries/Core/Routers/ItemEvents/RepairItemEventRouter.cs index e30f23cd..1c729ab6 100644 --- a/Libraries/Core/Routers/ItemEvents/RepairItemEventRouter.cs +++ b/Libraries/Core/Routers/ItemEvents/RepairItemEventRouter.cs @@ -23,16 +23,18 @@ public class RepairItemEventRouter : ItemEventRouterDefinition protected override List GetHandledRoutes() { - return new() + return new List { - new HandledRoute("Repair", false), - new HandledRoute("TraderRepair", false) + new("Repair", false), + new("TraderRepair", false) }; } - public override ItemEventRouterResponse HandleItemEvent(string url, PmcData pmcData, BaseInteractionRequestData body, string sessionID, ItemEventRouterResponse output) + public override ItemEventRouterResponse HandleItemEvent(string url, PmcData pmcData, BaseInteractionRequestData body, string sessionID, + ItemEventRouterResponse output) { - switch (url) { + switch (url) + { case "Repair": return _repairCallbacks.Repair(pmcData, body as RepairActionDataRequest, sessionID); case "TraderRepair": diff --git a/Libraries/Core/Routers/ItemEvents/TradeItemEventRouter.cs b/Libraries/Core/Routers/ItemEvents/TradeItemEventRouter.cs index f846b91d..cbc471a9 100644 --- a/Libraries/Core/Routers/ItemEvents/TradeItemEventRouter.cs +++ b/Libraries/Core/Routers/ItemEvents/TradeItemEventRouter.cs @@ -23,17 +23,19 @@ public class TradeItemEventRouter : ItemEventRouterDefinition protected override List GetHandledRoutes() { - return new() + return new List { - new HandledRoute("TradingConfirm", false), - new HandledRoute("RagFairBuyOffer", false), - new HandledRoute("SellAllFromSavage", false) + new("TradingConfirm", false), + new("RagFairBuyOffer", false), + new("SellAllFromSavage", false) }; } - public override ItemEventRouterResponse HandleItemEvent(string url, PmcData pmcData, BaseInteractionRequestData body, string sessionID, ItemEventRouterResponse output) + public override ItemEventRouterResponse HandleItemEvent(string url, PmcData pmcData, BaseInteractionRequestData body, string sessionID, + ItemEventRouterResponse output) { - switch (url) { + switch (url) + { case "TradingConfirm": return _tradeCallbacks.ProcessTrade(pmcData, body as ProcessBaseTradeRequestData, sessionID); case "RagFairBuyOffer": diff --git a/Libraries/Core/Routers/ItemEvents/WishlistItemEventRouter.cs b/Libraries/Core/Routers/ItemEvents/WishlistItemEventRouter.cs index ad2c9b41..882331e7 100644 --- a/Libraries/Core/Routers/ItemEvents/WishlistItemEventRouter.cs +++ b/Libraries/Core/Routers/ItemEvents/WishlistItemEventRouter.cs @@ -23,15 +23,16 @@ public class WishlistItemEventRouter : ItemEventRouterDefinition protected override List GetHandledRoutes() { - return new() + return new List { - new HandledRoute("AddToWishList", false), - new HandledRoute("RemoveFromWishList", false), - new HandledRoute("ChangeWishlistItemCategory", false) + new("AddToWishList", false), + new("RemoveFromWishList", false), + new("ChangeWishlistItemCategory", false) }; } - public override ItemEventRouterResponse HandleItemEvent(string url, PmcData pmcData, BaseInteractionRequestData body, string sessionID, ItemEventRouterResponse output) + public override ItemEventRouterResponse HandleItemEvent(string url, PmcData pmcData, BaseInteractionRequestData body, string sessionID, + ItemEventRouterResponse output) { switch (url) { diff --git a/Libraries/Core/Routers/SaveLoad/HealthSaveLoadRouter.cs b/Libraries/Core/Routers/SaveLoad/HealthSaveLoadRouter.cs index 43626bca..82dfa789 100644 --- a/Libraries/Core/Routers/SaveLoad/HealthSaveLoadRouter.cs +++ b/Libraries/Core/Routers/SaveLoad/HealthSaveLoadRouter.cs @@ -11,7 +11,7 @@ public class HealthSaveLoadRouter() : SaveLoadRouter { protected override List GetHandledRoutes() { - return [new("spt-health", false)]; + return [new HandledRoute("spt-health", false)]; } public override SptProfile HandleLoad(SptProfile profile) @@ -20,11 +20,11 @@ public class HealthSaveLoadRouter() : SaveLoadRouter return profile; } - + public void DefaultVitality(Vitality? vitality) { vitality ??= new Vitality { Health = null, Energy = 0, Temperature = 0, Hydration = 0 }; - + vitality.Health = new Dictionary { { @@ -32,7 +32,7 @@ public class HealthSaveLoadRouter() : SaveLoadRouter { Health = new CurrentMinMax { - Current = 0, + Current = 0 }, Effects = new Dictionary() } @@ -42,7 +42,7 @@ public class HealthSaveLoadRouter() : SaveLoadRouter { Health = new CurrentMinMax { - Current = 0, + Current = 0 }, Effects = new Dictionary() } @@ -52,7 +52,7 @@ public class HealthSaveLoadRouter() : SaveLoadRouter { Health = new CurrentMinMax { - Current = 0, + Current = 0 }, Effects = new Dictionary() } @@ -62,7 +62,7 @@ public class HealthSaveLoadRouter() : SaveLoadRouter { Health = new CurrentMinMax { - Current = 0, + Current = 0 }, Effects = new Dictionary() } @@ -72,7 +72,7 @@ public class HealthSaveLoadRouter() : SaveLoadRouter { Health = new CurrentMinMax { - Current = 0, + Current = 0 }, Effects = new Dictionary() } @@ -82,7 +82,7 @@ public class HealthSaveLoadRouter() : SaveLoadRouter { Health = new CurrentMinMax { - Current = 0, + Current = 0 }, Effects = new Dictionary() } @@ -92,7 +92,7 @@ public class HealthSaveLoadRouter() : SaveLoadRouter { Health = new CurrentMinMax { - Current = 0, + Current = 0 }, Effects = new Dictionary() } diff --git a/Libraries/Core/Routers/SaveLoad/InraidSaveLoadRouter.cs b/Libraries/Core/Routers/SaveLoad/InraidSaveLoadRouter.cs index 3bbef904..6c030d8f 100644 --- a/Libraries/Core/Routers/SaveLoad/InraidSaveLoadRouter.cs +++ b/Libraries/Core/Routers/SaveLoad/InraidSaveLoadRouter.cs @@ -9,7 +9,7 @@ public class InraidSaveLoadRouter : SaveLoadRouter { protected override List GetHandledRoutes() { - return [new("spt-inraid", false)]; + return [new HandledRoute("spt-inraid", false)]; } public override SptProfile HandleLoad(SptProfile profile) diff --git a/Libraries/Core/Routers/SaveLoad/InsuranceSaveLoadRouter.cs b/Libraries/Core/Routers/SaveLoad/InsuranceSaveLoadRouter.cs index acaa8559..1d13c56d 100644 --- a/Libraries/Core/Routers/SaveLoad/InsuranceSaveLoadRouter.cs +++ b/Libraries/Core/Routers/SaveLoad/InsuranceSaveLoadRouter.cs @@ -9,7 +9,7 @@ public class InsuranceSaveLoadRouter : SaveLoadRouter { protected override List GetHandledRoutes() { - return [new ("spt-insurance", false)]; + return [new HandledRoute("spt-insurance", false)]; } public override SptProfile HandleLoad(SptProfile profile) diff --git a/Libraries/Core/Routers/SaveLoad/ProfileSaveLoadRouter.cs b/Libraries/Core/Routers/SaveLoad/ProfileSaveLoadRouter.cs index 90ae39a7..ef7b257b 100644 --- a/Libraries/Core/Routers/SaveLoad/ProfileSaveLoadRouter.cs +++ b/Libraries/Core/Routers/SaveLoad/ProfileSaveLoadRouter.cs @@ -1,5 +1,6 @@ using SptCommon.Annotations; using Core.DI; +using Core.Models.Eft.Common; using Core.Models.Eft.Profile; namespace Core.Routers.SaveLoad; @@ -9,13 +10,13 @@ public class ProfileSaveLoadRouter : SaveLoadRouter { protected override List GetHandledRoutes() { - return [new ("spt-profile", false)]; + return [new HandledRoute("spt-profile", false)]; } public override SptProfile HandleLoad(SptProfile profile) { if (profile.CharacterData == null) - profile.CharacterData = new Characters { PmcData = new(), ScavData = new() }; + profile.CharacterData = new Characters { PmcData = new PmcData(), ScavData = new PmcData() }; return profile; } diff --git a/Libraries/Core/Routers/Serializers/BundleSerializer.cs b/Libraries/Core/Routers/Serializers/BundleSerializer.cs index 36e24e61..e7ea2b03 100644 --- a/Libraries/Core/Routers/Serializers/BundleSerializer.cs +++ b/Libraries/Core/Routers/Serializers/BundleSerializer.cs @@ -2,5 +2,4 @@ public class BundleSerializer { - } diff --git a/Libraries/Core/Routers/Serializers/NotifySerializer.cs b/Libraries/Core/Routers/Serializers/NotifySerializer.cs index b8b565da..9b0f23dd 100644 --- a/Libraries/Core/Routers/Serializers/NotifySerializer.cs +++ b/Libraries/Core/Routers/Serializers/NotifySerializer.cs @@ -2,5 +2,4 @@ public class NotifySerializer { - } diff --git a/Libraries/Core/Routers/Static/AchievementStaticRouter.cs b/Libraries/Core/Routers/Static/AchievementStaticRouter.cs index f22a2f65..d97ab9a5 100644 --- a/Libraries/Core/Routers/Static/AchievementStaticRouter.cs +++ b/Libraries/Core/Routers/Static/AchievementStaticRouter.cs @@ -24,7 +24,8 @@ public class AchievementStaticRouter : StaticRouter info, sessionID, output - ) => _achievementCallbacks?.GetAchievements(url, info as EmptyRequestData, sessionID)), + ) => _achievementCallbacks?.GetAchievements(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/achievement/statistic", ( @@ -32,7 +33,8 @@ public class AchievementStaticRouter : StaticRouter info, sessionID, output - ) => _achievementCallbacks?.Statistic(url, info as EmptyRequestData, sessionID)), + ) => _achievementCallbacks?.Statistic(url, info as EmptyRequestData, sessionID) + ) ] ) { diff --git a/Libraries/Core/Routers/Static/BotStaticRouter.cs b/Libraries/Core/Routers/Static/BotStaticRouter.cs index 9225ac8d..180d7536 100644 --- a/Libraries/Core/Routers/Static/BotStaticRouter.cs +++ b/Libraries/Core/Routers/Static/BotStaticRouter.cs @@ -18,14 +18,15 @@ public class BotStaticRouter : StaticRouter jsonUtil, [ new RouteAction( - "/client/game/bot/generate", + "/client/game/bot/generate", ( - url, - info, - sessionID, + url, + info, + sessionID, outout - ) => _botCallbacks.GenerateBots(url, info as GenerateBotsRequestData, sessionID), - typeof(GenerateBotsRequestData)) + ) => _botCallbacks.GenerateBots(url, info as GenerateBotsRequestData, sessionID), + typeof(GenerateBotsRequestData) + ) ] ) { diff --git a/Libraries/Core/Routers/Static/BuildStaticRouter.cs b/Libraries/Core/Routers/Static/BuildStaticRouter.cs index cf4efef0..7173d095 100644 --- a/Libraries/Core/Routers/Static/BuildStaticRouter.cs +++ b/Libraries/Core/Routers/Static/BuildStaticRouter.cs @@ -12,56 +12,62 @@ namespace Core.Routers.Static; public class BuildStaticRouter : StaticRouter { protected static BuildsCallbacks _buildsCallbacks; + public BuildStaticRouter( JsonUtil jsonUtil, BuildsCallbacks buildsCallbacks ) : base( jsonUtil, [ - new RouteAction( - "/client/builds/list", - ( - url, - info, - sessionID, - output - ) => _buildsCallbacks.GetBuilds(url, info as EmptyRequestData, sessionID)), - new RouteAction( - "/client/builds/magazine/save", - ( - url, - info, - sessionID, - output - ) => _buildsCallbacks.CreateMagazineTemplate(url, info as SetMagazineRequest, sessionID), - typeof(SetMagazineRequest)), - new RouteAction( - "/client/builds/weapon/save", - ( - url, - info, - sessionID, - output - ) => _buildsCallbacks.SetWeapon(url, info as PresetBuildActionRequestData, sessionID), - typeof(PresetBuildActionRequestData)), - new RouteAction( - "/client/builds/equipment/save", - ( - url, - info, - sessionID, - output - ) => _buildsCallbacks.SetEquipment(url, info as PresetBuildActionRequestData, sessionID), - typeof(PresetBuildActionRequestData)), - new RouteAction( - "/client/builds/delete", - ( - url, - info, - sessionID, - output - ) => _buildsCallbacks.DeleteBuild(url, info as RemoveBuildRequestData, sessionID), - typeof(RemoveBuildRequestData)), + new RouteAction( + "/client/builds/list", + ( + url, + info, + sessionID, + output + ) => _buildsCallbacks.GetBuilds(url, info as EmptyRequestData, sessionID) + ), + new RouteAction( + "/client/builds/magazine/save", + ( + url, + info, + sessionID, + output + ) => _buildsCallbacks.CreateMagazineTemplate(url, info as SetMagazineRequest, sessionID), + typeof(SetMagazineRequest) + ), + new RouteAction( + "/client/builds/weapon/save", + ( + url, + info, + sessionID, + output + ) => _buildsCallbacks.SetWeapon(url, info as PresetBuildActionRequestData, sessionID), + typeof(PresetBuildActionRequestData) + ), + new RouteAction( + "/client/builds/equipment/save", + ( + url, + info, + sessionID, + output + ) => _buildsCallbacks.SetEquipment(url, info as PresetBuildActionRequestData, sessionID), + typeof(PresetBuildActionRequestData) + ), + new RouteAction( + "/client/builds/delete", + ( + url, + info, + sessionID, + output + ) => _buildsCallbacks.DeleteBuild(url, info as RemoveBuildRequestData, sessionID), + typeof(RemoveBuildRequestData) + ) ] ) { diff --git a/Libraries/Core/Routers/Static/BundleStaticRouter.cs b/Libraries/Core/Routers/Static/BundleStaticRouter.cs index e9e16496..af6f3635 100644 --- a/Libraries/Core/Routers/Static/BundleStaticRouter.cs +++ b/Libraries/Core/Routers/Static/BundleStaticRouter.cs @@ -24,7 +24,8 @@ public class BundleStaticRouter : StaticRouter info, sessionID, output - ) => _bundleCallbacks.GetBundles(url, info as EmptyRequestData, sessionID)) + ) => _bundleCallbacks.GetBundles(url, info as EmptyRequestData, sessionID) + ) ] ) { diff --git a/Libraries/Core/Routers/Static/ClientLogStaticRouter.cs b/Libraries/Core/Routers/Static/ClientLogStaticRouter.cs index d6fcd473..f7abbd8e 100644 --- a/Libraries/Core/Routers/Static/ClientLogStaticRouter.cs +++ b/Libraries/Core/Routers/Static/ClientLogStaticRouter.cs @@ -25,7 +25,8 @@ public class ClientLogStaticRouter : StaticRouter sessionID, output ) => _clientLogCallbacks.ClientLog(url, info as ClientLogRequest, sessionID), - typeof(ClientLogRequest)), + typeof(ClientLogRequest) + ), new RouteAction( "/singleplayer/release", ( @@ -33,7 +34,8 @@ public class ClientLogStaticRouter : StaticRouter info, sessionID, output - ) => _clientLogCallbacks.ReleaseNotes()), + ) => _clientLogCallbacks.ReleaseNotes() + ), new RouteAction( "/singleplayer/enableBSGlogging", ( @@ -41,7 +43,8 @@ public class ClientLogStaticRouter : StaticRouter info, sessionID, output - ) => _clientLogCallbacks.BsgLogging()) + ) => _clientLogCallbacks.BsgLogging() + ) ] ) { diff --git a/Libraries/Core/Routers/Static/CustomizationStaticRouter.cs b/Libraries/Core/Routers/Static/CustomizationStaticRouter.cs index 3df9aac8..28ee1fc6 100644 --- a/Libraries/Core/Routers/Static/CustomizationStaticRouter.cs +++ b/Libraries/Core/Routers/Static/CustomizationStaticRouter.cs @@ -24,7 +24,8 @@ public class CustomizationStaticRouter : StaticRouter info, sessionID, output - ) => _customizationCallbacks.GetCustomisationUnlocks(url, info as EmptyRequestData, sessionID)), + ) => _customizationCallbacks.GetCustomisationUnlocks(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/hideout/customization/offer/list", ( @@ -32,7 +33,8 @@ public class CustomizationStaticRouter : StaticRouter info, sessionID, output - ) => _customizationCallbacks.GetHideoutCustomisation(url, info as EmptyRequestData, sessionID)), + ) => _customizationCallbacks.GetHideoutCustomisation(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/customization/storage", ( @@ -40,7 +42,8 @@ public class CustomizationStaticRouter : StaticRouter info, sessionID, output - ) => _customizationCallbacks.GetStorage(url, info as EmptyRequestData, sessionID)), + ) => _customizationCallbacks.GetStorage(url, info as EmptyRequestData, sessionID) + ) ] ) { diff --git a/Libraries/Core/Routers/Static/DataStaticRouter.cs b/Libraries/Core/Routers/Static/DataStaticRouter.cs index 3098f9b2..452ae8b7 100644 --- a/Libraries/Core/Routers/Static/DataStaticRouter.cs +++ b/Libraries/Core/Routers/Static/DataStaticRouter.cs @@ -10,7 +10,7 @@ namespace Core.Routers.Static; public class DataStaticRouter : StaticRouter { protected static DataCallbacks _dataCallbacks; - + public DataStaticRouter( JsonUtil jsonUtil, DataCallbacks dataCallbacks @@ -20,91 +20,103 @@ public class DataStaticRouter : StaticRouter new RouteAction( "/client/settings", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _dataCallbacks.GetSettings(url, info as EmptyRequestData, sessionID)), + ) => _dataCallbacks.GetSettings(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/globals", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _dataCallbacks.GetGlobals(url, info as EmptyRequestData, sessionID)), + ) => _dataCallbacks.GetGlobals(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/items", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _dataCallbacks.GetTemplateItems(url, info as EmptyRequestData, sessionID)), + ) => _dataCallbacks.GetTemplateItems(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/handbook/templates", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _dataCallbacks.GetTemplateHandbook(url, info as EmptyRequestData, sessionID)), + ) => _dataCallbacks.GetTemplateHandbook(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/customization", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _dataCallbacks.GetTemplateSuits(url, info as EmptyRequestData, sessionID)), + ) => _dataCallbacks.GetTemplateSuits(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/account/customization", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _dataCallbacks.GetTemplateCharacter(url, info as EmptyRequestData, sessionID)), + ) => _dataCallbacks.GetTemplateCharacter(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/hideout/production/recipes", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _dataCallbacks.GetHideoutProduction(url, info as EmptyRequestData, sessionID)), + ) => _dataCallbacks.GetHideoutProduction(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/hideout/settings", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _dataCallbacks.GetHideoutSettings(url, info as EmptyRequestData, sessionID)), + ) => _dataCallbacks.GetHideoutSettings(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/hideout/areas", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _dataCallbacks.GetHideoutAreas(url, info as EmptyRequestData, sessionID)), + ) => _dataCallbacks.GetHideoutAreas(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/languages", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _dataCallbacks.GetLocalesLanguages(url, info as EmptyRequestData, sessionID)), + ) => _dataCallbacks.GetLocalesLanguages(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/hideout/qte/list", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _dataCallbacks.GetQteList(url, info as EmptyRequestData, sessionID)),] + ) => _dataCallbacks.GetQteList(url, info as EmptyRequestData, sessionID) + ) + ] ) { _dataCallbacks = dataCallbacks; diff --git a/Libraries/Core/Routers/Static/DialogStaticRouter.cs b/Libraries/Core/Routers/Static/DialogStaticRouter.cs index c27c369b..b45bcb69 100644 --- a/Libraries/Core/Routers/Static/DialogStaticRouter.cs +++ b/Libraries/Core/Routers/Static/DialogStaticRouter.cs @@ -12,7 +12,7 @@ namespace Core.Routers.Static; public class DialogStaticRouter : StaticRouter { protected static DialogueCallbacks _dialogueCallbacks; - + public DialogStaticRouter( JsonUtil jsonUtil, DialogueCallbacks dialogueCallbacks @@ -22,233 +22,259 @@ public class DialogStaticRouter : StaticRouter new RouteAction( "/client/chatServer/list", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _dialogueCallbacks.GetChatServerList(url, info as GetChatServerListRequestData, sessionID), - typeof(GetChatServerListRequestData)), + typeof(GetChatServerListRequestData) + ), new RouteAction( "/client/mail/dialog/list", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _dialogueCallbacks.GetMailDialogList(url, info as GetMailDialogListRequestData, sessionID), - typeof(GetMailDialogListRequestData)), + typeof(GetMailDialogListRequestData) + ), new RouteAction( "/client/mail/dialog/view", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _dialogueCallbacks.GetMailDialogView(url, info as GetMailDialogViewRequestData, sessionID), - typeof(GetMailDialogViewRequestData)), + typeof(GetMailDialogViewRequestData) + ), new RouteAction( "/client/mail/dialog/info", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _dialogueCallbacks.GetMailDialogInfo(url, info as GetMailDialogInfoRequestData, sessionID), - typeof(GetMailDialogInfoRequestData)), + typeof(GetMailDialogInfoRequestData) + ), new RouteAction( "/client/mail/dialog/remove", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _dialogueCallbacks.RemoveDialog(url, info as RemoveDialogRequestData, sessionID), - typeof(RemoveDialogRequestData)), + typeof(RemoveDialogRequestData) + ), new RouteAction( "/client/mail/dialog/pin", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _dialogueCallbacks.PinDialog(url, info as PinDialogRequestData, sessionID), - typeof(PinDialogRequestData)), + typeof(PinDialogRequestData) + ), new RouteAction( "/client/mail/dialog/unpin", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _dialogueCallbacks.UnpinDialog(url, info as PinDialogRequestData, sessionID), - typeof(PinDialogRequestData)), + typeof(PinDialogRequestData) + ), new RouteAction( "/client/mail/dialog/read", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _dialogueCallbacks.SetRead(url, info as SetDialogReadRequestData, sessionID), - typeof(SetDialogReadRequestData)), + typeof(SetDialogReadRequestData) + ), new RouteAction( "/client/mail/dialog/getAllAttachments", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _dialogueCallbacks.GetAllAttachments(url, info as GetAllAttachmentsRequestData, sessionID), - typeof(GetAllAttachmentsRequestData)), + typeof(GetAllAttachmentsRequestData) + ), new RouteAction( "/client/mail/msg/send", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _dialogueCallbacks.SendMessage(url, info as SendMessageRequest, sessionID), - typeof(SendMessageRequest)), + typeof(SendMessageRequest) + ), new RouteAction( "client/mail/dialog/clear", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _dialogueCallbacks.ClearMail(url, info as ClearMailMessageRequest, sessionID), - typeof(ClearMailMessageRequest)), + typeof(ClearMailMessageRequest) + ), new RouteAction( "/client/mail/dialog/group/create", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _dialogueCallbacks.CreateGroupMail(url, info as CreateGroupMailRequest, sessionID), - typeof(CreateGroupMailRequest)), + typeof(CreateGroupMailRequest) + ), new RouteAction( "/client/mail/dialog/group/owner/change", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _dialogueCallbacks.ChangeMailGroupOwner(url, info as ChangeGroupMailOwnerRequest, sessionID), - typeof(ChangeGroupMailOwnerRequest)), + typeof(ChangeGroupMailOwnerRequest) + ), new RouteAction( "/client/mail/dialog/group/users/add", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _dialogueCallbacks.AddUserToMail(url, info as AddUserGroupMailRequest, sessionID), - typeof(AddUserGroupMailRequest)), + ) => _dialogueCallbacks.AddUserToMail(url, info as AddUserGroupMailRequest, sessionID), + typeof(AddUserGroupMailRequest) + ), new RouteAction( "/client/mail/dialog/group/users/remove", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _dialogueCallbacks.RemoveUserFromMail(url, info as RemoveUserGroupMailRequest, sessionID), - typeof(RemoveUserGroupMailRequest)), + typeof(RemoveUserGroupMailRequest) + ), new RouteAction( "/client/friend/list", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _dialogueCallbacks.GetFriendList(url, info as EmptyRequestData, sessionID)), + ) => _dialogueCallbacks.GetFriendList(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/friend/request/list/outbox", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _dialogueCallbacks.ListOutbox(url, info as EmptyRequestData, sessionID)), + ) => _dialogueCallbacks.ListOutbox(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/friend/request/list/inbox", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _dialogueCallbacks.ListInbox(url, info as EmptyRequestData, sessionID)), + ) => _dialogueCallbacks.ListInbox(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/friend/request/send", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _dialogueCallbacks.SendFriendRequest(url, info as FriendRequestData, sessionID), - typeof(FriendRequestData)), + typeof(FriendRequestData) + ), new RouteAction( "/client/friend/request/accept-all", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _dialogueCallbacks.AcceptAllFriendRequests(url, info as EmptyRequestData, sessionID)), + ) => _dialogueCallbacks.AcceptAllFriendRequests(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/friend/request/accept", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _dialogueCallbacks.AcceptFriendRequest(url, info as AcceptFriendRequestData, sessionID), - typeof(AcceptFriendRequestData)), + typeof(AcceptFriendRequestData) + ), new RouteAction( "/client/friend/request/decline", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _dialogueCallbacks.DeclineFriendRequest(url, info as DeclineFriendRequestData, sessionID), - typeof(DeclineFriendRequestData)), + typeof(DeclineFriendRequestData) + ), new RouteAction( "/client/friend/request/cancel", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _dialogueCallbacks.CancelFriendRequest(url, info as CancelFriendRequestData, sessionID), - typeof(CancelFriendRequestData)), + typeof(CancelFriendRequestData) + ), new RouteAction( "/client/friend/delete", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _dialogueCallbacks.DeleteFriend(url, info as DeleteFriendRequest, sessionID), - typeof(DeleteFriendRequest)), + typeof(DeleteFriendRequest) + ), new RouteAction( "/client/friend/ignore/set", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _dialogueCallbacks.IgnoreFriend(url, info as UIDRequestData, sessionID), - typeof(UIDRequestData)), + typeof(UIDRequestData) + ), new RouteAction( "/client/friend/ignore/remove", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _dialogueCallbacks.UnIgnoreFriend(url, info as UIDRequestData, sessionID), - typeof(UIDRequestData)), + typeof(UIDRequestData) + ) ] ) { diff --git a/Libraries/Core/Routers/Static/GameStaticRouter.cs b/Libraries/Core/Routers/Static/GameStaticRouter.cs index 458ad8aa..913199bd 100644 --- a/Libraries/Core/Routers/Static/GameStaticRouter.cs +++ b/Libraries/Core/Routers/Static/GameStaticRouter.cs @@ -16,8 +16,7 @@ public class GameStaticRouter : StaticRouter public GameStaticRouter( JsonUtil jsonUtil, GameCallbacks gameCallbacks - ) : base - ( + ) : base( jsonUtil, [ new RouteAction( @@ -28,7 +27,8 @@ public class GameStaticRouter : StaticRouter sessionID, output ) => _gameCallbacks.GetGameConfig(url, info as GameEmptyCrcRequestData, sessionID), - typeof(GameEmptyCrcRequestData)), + typeof(GameEmptyCrcRequestData) + ), new RouteAction( "/client/game/mode", ( @@ -37,7 +37,8 @@ public class GameStaticRouter : StaticRouter sessionID, output ) => _gameCallbacks.GetGameMode(url, info as GameModeRequestData, sessionID), - typeof(GameModeRequestData)), + typeof(GameModeRequestData) + ), new RouteAction( "/client/server/list", ( @@ -45,7 +46,8 @@ public class GameStaticRouter : StaticRouter info, sessionID, output - ) => _gameCallbacks.GetServer(url, info as EmptyRequestData, sessionID)), + ) => _gameCallbacks.GetServer(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/match/group/current", ( @@ -54,7 +56,8 @@ public class GameStaticRouter : StaticRouter sessionID, output ) => _gameCallbacks.GetCurrentGroup(url, info as EmptyRequestData, sessionID), - typeof(GameModeRequestData)), + typeof(GameModeRequestData) + ), new RouteAction( "/client/game/version/validate", ( @@ -63,7 +66,8 @@ public class GameStaticRouter : StaticRouter sessionID, output ) => _gameCallbacks.VersionValidate(url, info as VersionValidateRequestData, sessionID), - typeof(VersionValidateRequestData)), + typeof(VersionValidateRequestData) + ), new RouteAction( "/client/game/start", ( @@ -71,7 +75,8 @@ public class GameStaticRouter : StaticRouter info, sessionID, output - ) => _gameCallbacks.GameStart(url, info as EmptyRequestData, sessionID)), + ) => _gameCallbacks.GameStart(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/game/logout", ( @@ -79,7 +84,8 @@ public class GameStaticRouter : StaticRouter info, sessionID, output - ) => _gameCallbacks.GameLogout(url, info as EmptyRequestData, sessionID)), + ) => _gameCallbacks.GameLogout(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/checkVersion", ( @@ -87,7 +93,8 @@ public class GameStaticRouter : StaticRouter info, sessionID, output - ) => _gameCallbacks.ValidateGameVersion(url, info as EmptyRequestData, sessionID)), + ) => _gameCallbacks.ValidateGameVersion(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/game/keepalive", ( @@ -95,7 +102,8 @@ public class GameStaticRouter : StaticRouter info, sessionID, output - ) => _gameCallbacks.GameKeepalive(url, info as EmptyRequestData, sessionID)), + ) => _gameCallbacks.GameKeepalive(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/singleplayer/settings/version", ( @@ -103,7 +111,8 @@ public class GameStaticRouter : StaticRouter info, sessionID, output - ) => _gameCallbacks.GetVersion(url, info as EmptyRequestData, sessionID)), + ) => _gameCallbacks.GetVersion(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/reports/lobby/send", ( @@ -112,7 +121,8 @@ public class GameStaticRouter : StaticRouter sessionID, output ) => _gameCallbacks.ReportNickname(url, info as UIDRequestData, sessionID), - typeof(UIDRequestData)), + typeof(UIDRequestData) + ), new RouteAction( "/client/report/send", ( @@ -121,7 +131,8 @@ public class GameStaticRouter : StaticRouter sessionID, output ) => _gameCallbacks.ReportNickname(url, info as UIDRequestData, sessionID), - typeof(GameModeRequestData)), + typeof(GameModeRequestData) + ), new RouteAction( "/singleplayer/settings/getRaidTime", ( @@ -130,7 +141,8 @@ public class GameStaticRouter : StaticRouter sessionID, output ) => _gameCallbacks.GetRaidTime(url, info as GetRaidTimeRequest, sessionID), - typeof(GetRaidTimeRequest)), + typeof(GetRaidTimeRequest) + ), new RouteAction( "/client/survey", ( @@ -138,7 +150,8 @@ public class GameStaticRouter : StaticRouter info, sessionID, output - ) => _gameCallbacks.GetSurvey(url, info as EmptyRequestData, sessionID)), + ) => _gameCallbacks.GetSurvey(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/survey/view", ( @@ -147,7 +160,8 @@ public class GameStaticRouter : StaticRouter sessionID, output ) => _gameCallbacks.GetSurveyView(url, info as SendSurveyOpinionRequest, sessionID), - typeof(SendSurveyOpinionRequest)), + typeof(SendSurveyOpinionRequest) + ), new RouteAction( "/client/survey/opinion", ( @@ -156,7 +170,8 @@ public class GameStaticRouter : StaticRouter sessionID, output ) => _gameCallbacks.SendSurveyOpinion(url, info as SendSurveyOpinionRequest, sessionID), - typeof(SendSurveyOpinionRequest)), + typeof(SendSurveyOpinionRequest) + ) ] ) { diff --git a/Libraries/Core/Routers/Static/HealthStaticRouter.cs b/Libraries/Core/Routers/Static/HealthStaticRouter.cs index f881f818..7c6a53b1 100644 --- a/Libraries/Core/Routers/Static/HealthStaticRouter.cs +++ b/Libraries/Core/Routers/Static/HealthStaticRouter.cs @@ -25,7 +25,8 @@ public class HealthStaticRouter : StaticRouter sessionID, output ) => _healthCallbacks.HandleWorkoutEffects(url, info as WorkoutData, sessionID), - typeof(WorkoutData)), + typeof(WorkoutData) + ) ] ) { diff --git a/Libraries/Core/Routers/Static/InraidStaticRouter.cs b/Libraries/Core/Routers/Static/InraidStaticRouter.cs index cf80d131..8bf87022 100644 --- a/Libraries/Core/Routers/Static/InraidStaticRouter.cs +++ b/Libraries/Core/Routers/Static/InraidStaticRouter.cs @@ -21,7 +21,8 @@ public class InraidStaticRouter : StaticRouter sessionID, output ) => inraidCallbacks.SaveProgress(url, info as ScavSaveRequestData, sessionID), - typeof(ScavSaveRequestData)), + typeof(ScavSaveRequestData) + ), new RouteAction( "/singleplayer/settings/raid/menu", ( @@ -29,7 +30,8 @@ public class InraidStaticRouter : StaticRouter info, sessionID, output - ) => inraidCallbacks.GetRaidMenuSettings()), + ) => inraidCallbacks.GetRaidMenuSettings() + ), new RouteAction( "/singleplayer/scav/traitorscavhostile", ( @@ -37,7 +39,8 @@ public class InraidStaticRouter : StaticRouter info, sessionID, output - ) => inraidCallbacks.GetTraitorScavHostileChance(url, info as EmptyRequestData, sessionID)), + ) => inraidCallbacks.GetTraitorScavHostileChance(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/singleplayer/bossconvert", ( @@ -45,8 +48,10 @@ public class InraidStaticRouter : StaticRouter info, sessionID, output - ) => inraidCallbacks.GetBossConvertSettings(url, info as EmptyRequestData, sessionID)), - ]) + ) => inraidCallbacks.GetBossConvertSettings(url, info as EmptyRequestData, sessionID) + ) + ] + ) { } } diff --git a/Libraries/Core/Routers/Static/InsuranceStaticRouter.cs b/Libraries/Core/Routers/Static/InsuranceStaticRouter.cs index e54cdda4..76c35de1 100644 --- a/Libraries/Core/Routers/Static/InsuranceStaticRouter.cs +++ b/Libraries/Core/Routers/Static/InsuranceStaticRouter.cs @@ -25,7 +25,8 @@ public class InsuranceStaticRouter : StaticRouter sessionID, output ) => _insuranceCallbacks.GetInsuranceCost(url, info as GetInsuranceCostRequestData, sessionID), - typeof(GetInsuranceCostRequestData)) + typeof(GetInsuranceCostRequestData) + ) ] ) { diff --git a/Libraries/Core/Routers/Static/ItemEventStaticRouter.cs b/Libraries/Core/Routers/Static/ItemEventStaticRouter.cs index e80b104b..cf24434d 100644 --- a/Libraries/Core/Routers/Static/ItemEventStaticRouter.cs +++ b/Libraries/Core/Routers/Static/ItemEventStaticRouter.cs @@ -25,7 +25,8 @@ public class ItemEventStaticRouter : StaticRouter sessionID, output ) => _itemEventCallbacks.HandleEvents(url, info as ItemEventRouterRequest, sessionID), - typeof(ItemEventRouterRequest)) + typeof(ItemEventRouterRequest) + ) ] ) { diff --git a/Libraries/Core/Routers/Static/LauncherStaticRouter.cs b/Libraries/Core/Routers/Static/LauncherStaticRouter.cs index e8c746fc..a6e1dd1a 100644 --- a/Libraries/Core/Routers/Static/LauncherStaticRouter.cs +++ b/Libraries/Core/Routers/Static/LauncherStaticRouter.cs @@ -15,55 +15,69 @@ public class LauncherStaticRouter : StaticRouter [ new RouteAction( "/launcher/ping", - (url, _, sessionID, _) => launcherCallbacks.Ping(url, null, sessionID)), + (url, _, sessionID, _) => launcherCallbacks.Ping(url, null, sessionID) + ), new RouteAction( "/launcher/server/connect", - (_, _, _, _) => launcherCallbacks.Connect()), + (_, _, _, _) => launcherCallbacks.Connect() + ), new RouteAction( "/launcher/profile/login", (url, info, sessionID, _) => launcherCallbacks.Login(url, info as LoginRequestData, sessionID), - typeof(LoginRequestData)), + typeof(LoginRequestData) + ), new RouteAction( "/launcher/profile/register", (url, info, sessionID, _) => launcherCallbacks.Register(url, info as RegisterData, sessionID), - typeof(RegisterData)), + typeof(RegisterData) + ), new RouteAction( "/launcher/profile/get", (url, info, sessionID, _) => launcherCallbacks.Get(url, info as LoginRequestData, sessionID), - typeof(LoginRequestData)), + typeof(LoginRequestData) + ), new RouteAction( "/launcher/profile/change/username", (url, info, sessionID, _) => launcherCallbacks.ChangeUsername(url, info as ChangeRequestData, sessionID), - typeof(ChangeRequestData)), + typeof(ChangeRequestData) + ), new RouteAction( "/launcher/profile/change/password", (url, info, sessionID, _) => launcherCallbacks.ChangePassword(url, info as ChangeRequestData, sessionID), - typeof(ChangeRequestData)), + typeof(ChangeRequestData) + ), new RouteAction( "/launcher/profile/change/wipe", (url, info, sessionID, _) => launcherCallbacks.Wipe(url, info as RegisterData, sessionID), - typeof(RegisterData)), + typeof(RegisterData) + ), new RouteAction( "/launcher/profile/remove", (url, info, sessionID, _) => launcherCallbacks.RemoveProfile(url, info as RemoveProfileData, sessionID), - typeof(RemoveProfileData)), + typeof(RemoveProfileData) + ), new RouteAction( "/launcher/profile/compatibleTarkovVersion", - (_, _, _, _) => launcherCallbacks.GetCompatibleTarkovVersion()), + (_, _, _, _) => launcherCallbacks.GetCompatibleTarkovVersion() + ), new RouteAction( "/launcher/server/version", - (_, _, _, _) => launcherCallbacks.GetServerVersion()), + (_, _, _, _) => launcherCallbacks.GetServerVersion() + ), new RouteAction( "/launcher/server/loadedServerMods", - (_, _, _, _) => launcherCallbacks.GetLoadedServerMods()), + (_, _, _, _) => launcherCallbacks.GetLoadedServerMods() + ), new RouteAction( "/launcher/server/serverModsUsedByProfile", (url, info, sessionID, _) => launcherCallbacks.GetServerModsProfileUsed(url, info as EmptyRequestData, sessionID), - typeof(EmptyRequestData)) - ]) + typeof(EmptyRequestData) + ) + ] + ) { } } diff --git a/Libraries/Core/Routers/Static/LocationStaticRouter.cs b/Libraries/Core/Routers/Static/LocationStaticRouter.cs index 1f5ad5f4..bfa76abb 100644 --- a/Libraries/Core/Routers/Static/LocationStaticRouter.cs +++ b/Libraries/Core/Routers/Static/LocationStaticRouter.cs @@ -11,7 +11,7 @@ namespace Core.Routers.Static; public class LocationStaticRouter : StaticRouter { protected static LocationCallbacks _locationCallbacks; - + public LocationStaticRouter( JsonUtil jsonUtil, LocationCallbacks locationCallbacks @@ -21,20 +21,22 @@ public class LocationStaticRouter : StaticRouter new RouteAction( "/client/locations", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _locationCallbacks.GetLocationData(url, info as EmptyRequestData, sessionID)), + ) => _locationCallbacks.GetLocationData(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/airdrop/loot", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _locationCallbacks.GetAirdropLoot(url, info as GetAirdropLootRequest, sessionID), - typeof(GetAirdropLootRequest)) + typeof(GetAirdropLootRequest) + ) ] ) { diff --git a/Libraries/Core/Routers/Static/MatchStaticRouter.cs b/Libraries/Core/Routers/Static/MatchStaticRouter.cs index 2fd8250f..f3fbc7f2 100644 --- a/Libraries/Core/Routers/Static/MatchStaticRouter.cs +++ b/Libraries/Core/Routers/Static/MatchStaticRouter.cs @@ -12,7 +12,7 @@ namespace Core.Routers.Static; public class MatchStaticRouter : StaticRouter { protected static MatchCallbacks _matchCallbacks; - + public MatchStaticRouter( JsonUtil jsonUtil, MatchCallbacks matchCallbacks @@ -22,243 +22,271 @@ public class MatchStaticRouter : StaticRouter new RouteAction( "/client/match/available", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _matchCallbacks.ServerAvailable(url, info as EmptyRequestData, sessionID)), + ) => _matchCallbacks.ServerAvailable(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/match/updatePing", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _matchCallbacks.UpdatePing(url, info as UpdatePingRequestData, sessionID), - typeof(UpdatePingRequestData)), + typeof(UpdatePingRequestData) + ), new RouteAction( "/client/match/join", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _matchCallbacks.JoinMatch(url, info as MatchGroupStartGameRequest, sessionID), - typeof(MatchGroupStartGameRequest)), + typeof(MatchGroupStartGameRequest) + ), new RouteAction( "/client/match/exit", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _matchCallbacks.ExitMatch(url, info as EmptyRequestData, sessionID)), + ) => _matchCallbacks.ExitMatch(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/match/group/delete", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _matchCallbacks.DeleteGroup(url, info as DeleteGroupRequest, sessionID)), + ) => _matchCallbacks.DeleteGroup(url, info as DeleteGroupRequest, sessionID) + ), new RouteAction( "/client/match/group/leave", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _matchCallbacks.LeaveGroup(url, info as EmptyRequestData, sessionID)), + ) => _matchCallbacks.LeaveGroup(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/match/group/status", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _matchCallbacks.GetGroupStatus(url, info as MatchGroupStatusRequest, sessionID), - typeof(MatchGroupStatusRequest)), + typeof(MatchGroupStatusRequest) + ), new RouteAction( "/client/match/group/start_game", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _matchCallbacks.JoinMatch(url, info as MatchGroupStartGameRequest, sessionID), - typeof(MatchGroupStartGameRequest)), + typeof(MatchGroupStartGameRequest) + ), new RouteAction( "/client/match/group/exit_from_menu", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _matchCallbacks.ExitFromMenu(url, info as EmptyRequestData, sessionID)), + ) => _matchCallbacks.ExitFromMenu(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/match/group/current", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _matchCallbacks.GroupCurrent(url, info as EmptyRequestData, sessionID)), + ) => _matchCallbacks.GroupCurrent(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/match/group/looking/start", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _matchCallbacks.StartGroupSearch(url, info as EmptyRequestData, sessionID)), + ) => _matchCallbacks.StartGroupSearch(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/match/group/looking/stop", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _matchCallbacks.StopGroupSearch(url, info as EmptyRequestData, sessionID)), + ) => _matchCallbacks.StopGroupSearch(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/match/group/invite/send", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _matchCallbacks.SendGroupInvite(url, info as MatchGroupInviteSendRequest, sessionID), - typeof(MatchGroupInviteSendRequest)), + typeof(MatchGroupInviteSendRequest) + ), new RouteAction( "/client/match/group/invite/accept", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _matchCallbacks.AcceptGroupInvite(url, info as RequestIdRequest, sessionID), - typeof(RequestIdRequest)), + typeof(RequestIdRequest) + ), new RouteAction( "/client/match/group/invite/decline", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _matchCallbacks.DeclineGroupInvite(url, info as RequestIdRequest, sessionID), - typeof(RequestIdRequest)), + typeof(RequestIdRequest) + ), new RouteAction( "/client/match/group/invite/cancel", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _matchCallbacks.CancelGroupInvite(url, info as RequestIdRequest, sessionID), - typeof(RequestIdRequest)), + typeof(RequestIdRequest) + ), new RouteAction( "/client/match/group/invite/cancel-all", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _matchCallbacks.CancelAllGroupInvite(url, info as EmptyRequestData, sessionID)), + ) => _matchCallbacks.CancelAllGroupInvite(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/match/group/transfer", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _matchCallbacks.TransferGroup(url, info as MatchGroupTransferRequest, sessionID), - typeof(MatchGroupTransferRequest)), + typeof(MatchGroupTransferRequest) + ), new RouteAction( "/client/match/group/raid/ready", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _matchCallbacks.RaidReady(url, info as EmptyRequestData, sessionID)), + ) => _matchCallbacks.RaidReady(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/match/group/raid/not-ready", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _matchCallbacks.NotRaidReady(url, info as EmptyRequestData, sessionID)), + ) => _matchCallbacks.NotRaidReady(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/putMetrics", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _matchCallbacks.PutMetrics(url, info as PutMetricsRequestData, sessionID), - typeof(PutMetricsRequestData)), + typeof(PutMetricsRequestData) + ), new RouteAction( "/client/analytics/event-disconnect", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _matchCallbacks.EventDisconnect(url, info as PutMetricsRequestData, sessionID), - typeof(PutMetricsRequestData)), + typeof(PutMetricsRequestData) + ), new RouteAction( "/client/getMetricsConfig", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _matchCallbacks.GetMetrics(url, info as EmptyRequestData, sessionID)), + ) => _matchCallbacks.GetMetrics(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/raid/configuration", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _matchCallbacks.GetRaidConfiguration(url, info as GetRaidConfigurationRequestData, sessionID), - typeof(GetRaidConfigurationRequestData)), + typeof(GetRaidConfigurationRequestData) + ), new RouteAction( "/client/raid/configuration-by-profile", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _matchCallbacks.GetConfigurationByProfile(url, info as GetRaidConfigurationRequestData, sessionID), - typeof(GetRaidConfigurationRequestData)), + typeof(GetRaidConfigurationRequestData) + ), new RouteAction( "/client/match/group/player/remove", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _matchCallbacks.RemovePlayerFromGroup(url, info as MatchGroupPlayerRemoveRequest, sessionID), - typeof(MatchGroupPlayerRemoveRequest)), + typeof(MatchGroupPlayerRemoveRequest) + ), new RouteAction( "/client/match/local/start", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _matchCallbacks.StartLocalRaid(url, info as StartLocalRaidRequestData, sessionID), - typeof(StartLocalRaidRequestData)), + typeof(StartLocalRaidRequestData) + ), new RouteAction( "/client/match/local/end", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _matchCallbacks.EndLocalRaid(url, info as EndLocalRaidRequestData, sessionID), - typeof(EndLocalRaidRequestData)) + typeof(EndLocalRaidRequestData) + ) ] ) { diff --git a/Libraries/Core/Routers/Static/NotifierStaticRouter.cs b/Libraries/Core/Routers/Static/NotifierStaticRouter.cs index 845fb5a6..21416a5d 100644 --- a/Libraries/Core/Routers/Static/NotifierStaticRouter.cs +++ b/Libraries/Core/Routers/Static/NotifierStaticRouter.cs @@ -11,7 +11,7 @@ namespace Core.Routers.Static; public class NotifierStaticRouter : StaticRouter { protected static NotifierCallbacks _notifierCallbacks; - + public NotifierStaticRouter( JsonUtil jsonUtil, NotifierCallbacks notifierCallbacks @@ -21,20 +21,22 @@ public class NotifierStaticRouter : StaticRouter new RouteAction( "/client/notifier/channel/create", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _notifierCallbacks.CreateNotifierChannel(url, info as EmptyRequestData, sessionID)), + ) => _notifierCallbacks.CreateNotifierChannel(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/game/profile/select", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _notifierCallbacks.SelectProfile(url, info as UIDRequestData, sessionID), - typeof(UIDRequestData)), + typeof(UIDRequestData) + ) ] ) { diff --git a/Libraries/Core/Routers/Static/PrestigeStaticRouter.cs b/Libraries/Core/Routers/Static/PrestigeStaticRouter.cs index aebdba68..ba868915 100644 --- a/Libraries/Core/Routers/Static/PrestigeStaticRouter.cs +++ b/Libraries/Core/Routers/Static/PrestigeStaticRouter.cs @@ -25,7 +25,8 @@ public class PrestigeStaticRouter : StaticRouter info, sessionID, output - ) => _presetCallbacks.GetPrestige(url, info as EmptyRequestData, sessionID)), + ) => _presetCallbacks.GetPrestige(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/prestige/obtain", ( @@ -33,8 +34,9 @@ public class PrestigeStaticRouter : StaticRouter info, sessionID, output - ) => _presetCallbacks.ObtainPrestige(url, info as ObtainPrestigeRequestList, sessionID) - , typeof(ObtainPrestigeRequestList)) + ) => _presetCallbacks.ObtainPrestige(url, info as ObtainPrestigeRequestList, sessionID), + typeof(ObtainPrestigeRequestList) + ) ] ) { diff --git a/Libraries/Core/Routers/Static/ProfileStaticRouter.cs b/Libraries/Core/Routers/Static/ProfileStaticRouter.cs index 9b7a693b..a56eb6f6 100644 --- a/Libraries/Core/Routers/Static/ProfileStaticRouter.cs +++ b/Libraries/Core/Routers/Static/ProfileStaticRouter.cs @@ -22,7 +22,8 @@ public class ProfileStaticRouter : StaticRouter sessionID, output ) => profileCallbacks.CreateProfile(url, info as ProfileCreateRequestData, sessionID), - typeof(ProfileCreateRequestData)), + typeof(ProfileCreateRequestData) + ), new RouteAction( "/client/game/profile/list", ( @@ -30,7 +31,8 @@ public class ProfileStaticRouter : StaticRouter info, sessionID, output - ) => profileCallbacks.GetProfileData(url, info as EmptyRequestData, sessionID)), + ) => profileCallbacks.GetProfileData(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/game/profile/savage/regenerate", ( @@ -38,12 +40,14 @@ public class ProfileStaticRouter : StaticRouter info, sessionID, output - ) => profileCallbacks.RegenerateScav(url, info as EmptyRequestData, sessionID)), + ) => profileCallbacks.RegenerateScav(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/game/profile/voice/change", (url, info, sessionID, output) => profileCallbacks.ChangeVoice(url, info as ProfileChangeVoiceRequestData, sessionID), - typeof(ProfileChangeVoiceRequestData)), + typeof(ProfileChangeVoiceRequestData) + ), new RouteAction( "/client/game/profile/nickname/change", ( @@ -52,7 +56,8 @@ public class ProfileStaticRouter : StaticRouter sessionID, output ) => profileCallbacks.ChangeNickname(url, info as ProfileChangeNicknameRequestData, sessionID), - typeof(ProfileChangeNicknameRequestData)), + typeof(ProfileChangeNicknameRequestData) + ), new RouteAction( "/client/game/profile/nickname/validate", ( @@ -61,7 +66,8 @@ public class ProfileStaticRouter : StaticRouter sessionID, output ) => profileCallbacks.ValidateNickname(url, info as ValidateNicknameRequestData, sessionID), - typeof(ValidateNicknameRequestData)), + typeof(ValidateNicknameRequestData) + ), new RouteAction( "/client/game/profile/nickname/reserved", ( @@ -69,7 +75,8 @@ public class ProfileStaticRouter : StaticRouter info, sessionID, output - ) => profileCallbacks.GetReservedNickname(url, info as EmptyRequestData, sessionID)), + ) => profileCallbacks.GetReservedNickname(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/profile/status", ( @@ -77,7 +84,8 @@ public class ProfileStaticRouter : StaticRouter info, sessionID, output - ) => profileCallbacks.GetProfileStatus(url, info as EmptyRequestData, sessionID)), + ) => profileCallbacks.GetProfileStatus(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/profile/view", ( @@ -86,7 +94,8 @@ public class ProfileStaticRouter : StaticRouter sessionID, output ) => profileCallbacks.GetOtherProfile(url, info as GetOtherProfileRequest, sessionID), - typeof(GetOtherProfileRequest)), + typeof(GetOtherProfileRequest) + ), new RouteAction( "/client/profile/settings", ( @@ -95,7 +104,8 @@ public class ProfileStaticRouter : StaticRouter sessionID, output ) => profileCallbacks.GetProfileSettings(url, info as GetProfileSettingsRequest, sessionID), - typeof(GetProfileSettingsRequest)), + typeof(GetProfileSettingsRequest) + ), new RouteAction( "/client/game/profile/search", ( @@ -104,17 +114,21 @@ public class ProfileStaticRouter : StaticRouter sessionID, output ) => profileCallbacks.SearchProfiles(url, info as SearchProfilesRequestData, sessionID), - typeof(SearchProfilesRequestData)), + typeof(SearchProfilesRequestData) + ), new RouteAction( "/launcher/profile/info", (url, info, sessionID, output) => profileCallbacks.GetMiniProfile(url, info as GetMiniProfileRequestData, sessionID), - typeof(GetMiniProfileRequestData)), + typeof(GetMiniProfileRequestData) + ), new RouteAction( "/launcher/profiles", (url, info, sessionID, output) => - profileCallbacks.GetAllMiniProfiles(url, info as EmptyRequestData, sessionID)), - ]) + profileCallbacks.GetAllMiniProfiles(url, info as EmptyRequestData, sessionID) + ) + ] + ) { } } diff --git a/Libraries/Core/Routers/Static/QuestStaticRouter.cs b/Libraries/Core/Routers/Static/QuestStaticRouter.cs index cc58f4a3..fc9b1500 100644 --- a/Libraries/Core/Routers/Static/QuestStaticRouter.cs +++ b/Libraries/Core/Routers/Static/QuestStaticRouter.cs @@ -11,7 +11,7 @@ namespace Core.Routers.Static; public class QuestStaticRouter : StaticRouter { protected static QuestCallbacks _questCallbacks; - + public QuestStaticRouter( JsonUtil jsonUtil, QuestCallbacks questCallbacks @@ -21,20 +21,23 @@ public class QuestStaticRouter : StaticRouter new RouteAction( "/client/quest/list", ( - url, - info, - sessionID, + url, + info, + sessionID, output ) => _questCallbacks.ListQuests(url, info as ListQuestsRequestData, sessionID), - typeof(ListQuestsRequestData)), + typeof(ListQuestsRequestData) + ), new RouteAction( "/client/repeatalbeQuests/activityPeriods", ( - url, - info, - sessionID, + url, + info, + sessionID, output - ) => _questCallbacks.ActivityPeriods(url, info as EmptyRequestData, sessionID)),] + ) => _questCallbacks.ActivityPeriods(url, info as EmptyRequestData, sessionID) + ) + ] ) { _questCallbacks = questCallbacks; diff --git a/Libraries/Core/Routers/Static/RagfairStaticRouter.cs b/Libraries/Core/Routers/Static/RagfairStaticRouter.cs index 528383e8..9d3704b1 100644 --- a/Libraries/Core/Routers/Static/RagfairStaticRouter.cs +++ b/Libraries/Core/Routers/Static/RagfairStaticRouter.cs @@ -26,7 +26,8 @@ public class RagfairStaticRouter : StaticRouter sessionID, output ) => _ragfairCallbacks.Search(url, info as SearchRequestData, sessionID), - typeof(SearchRequestData)), + typeof(SearchRequestData) + ), new RouteAction( "/client/ragfair/find", ( @@ -35,7 +36,8 @@ public class RagfairStaticRouter : StaticRouter sessionID, output ) => _ragfairCallbacks.Search(url, info as SearchRequestData, sessionID), - typeof(SearchRequestData)), + typeof(SearchRequestData) + ), new RouteAction( "/client/ragfair/itemMarketPrice", ( @@ -44,7 +46,8 @@ public class RagfairStaticRouter : StaticRouter sessionID, output ) => _ragfairCallbacks.GetMarketPrice(url, info as GetMarketPriceRequestData, sessionID), - typeof(GetMarketPriceRequestData)), + typeof(GetMarketPriceRequestData) + ), new RouteAction( "/client/ragfair/offerfees", ( @@ -53,7 +56,8 @@ public class RagfairStaticRouter : StaticRouter sessionID, output ) => _ragfairCallbacks.StorePlayerOfferTaxAmount(url, info as StorePlayerOfferTaxAmountRequestData, sessionID), - typeof(StorePlayerOfferTaxAmountRequestData)), + typeof(StorePlayerOfferTaxAmountRequestData) + ), new RouteAction( "/client/reports/ragfair/send", ( @@ -62,7 +66,8 @@ public class RagfairStaticRouter : StaticRouter sessionID, output ) => _ragfairCallbacks.SendReport(url, info as SendRagfairReportRequestData, sessionID), - typeof(SendRagfairReportRequestData)), + typeof(SendRagfairReportRequestData) + ), new RouteAction( "/client/items/prices", ( @@ -70,7 +75,8 @@ public class RagfairStaticRouter : StaticRouter info, sessionID, output - ) => _ragfairCallbacks.GetFleaPrices(url, info as EmptyRequestData, sessionID)), + ) => _ragfairCallbacks.GetFleaPrices(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/ragfair/offer/findbyid", ( @@ -79,7 +85,8 @@ public class RagfairStaticRouter : StaticRouter sessionID, output ) => _ragfairCallbacks.GetFleaOfferById(url, info as GetRagfairOfferByIdRequest, sessionID), - typeof(GetRagfairOfferByIdRequest)) + typeof(GetRagfairOfferByIdRequest) + ) ] ) { diff --git a/Libraries/Core/Routers/Static/TraderStaticRouter.cs b/Libraries/Core/Routers/Static/TraderStaticRouter.cs index d1c7547b..2fac1924 100644 --- a/Libraries/Core/Routers/Static/TraderStaticRouter.cs +++ b/Libraries/Core/Routers/Static/TraderStaticRouter.cs @@ -14,8 +14,7 @@ public class TraderStaticRouter : StaticRouter public TraderStaticRouter( JsonUtil jsonUtil, TraderCallbacks traderCallbacks - ) : base - ( + ) : base( jsonUtil, [ new RouteAction( @@ -25,7 +24,8 @@ public class TraderStaticRouter : StaticRouter info, sessionID, output - ) => _traderCallbacks.GetTraderSettings(url, info as EmptyRequestData, sessionID)), + ) => _traderCallbacks.GetTraderSettings(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/singleplayer/moddedTraders", ( @@ -33,7 +33,8 @@ public class TraderStaticRouter : StaticRouter info, sessionID, output - ) => _traderCallbacks.GetModdedTraderData(url, info as EmptyRequestData, sessionID)) + ) => _traderCallbacks.GetModdedTraderData(url, info as EmptyRequestData, sessionID) + ) ] ) { diff --git a/Libraries/Core/Routers/Static/WeatherStaticRouter.cs b/Libraries/Core/Routers/Static/WeatherStaticRouter.cs index a7733b4d..116ed217 100644 --- a/Libraries/Core/Routers/Static/WeatherStaticRouter.cs +++ b/Libraries/Core/Routers/Static/WeatherStaticRouter.cs @@ -24,7 +24,8 @@ public class WeatherStaticRouter : StaticRouter info, sessionID, output - ) => _weatherCallbacks.GetWeather(url, info as EmptyRequestData, sessionID)), + ) => _weatherCallbacks.GetWeather(url, info as EmptyRequestData, sessionID) + ), new RouteAction( "/client/localGame/weather", ( @@ -32,7 +33,8 @@ public class WeatherStaticRouter : StaticRouter info, sessionID, output - ) => _weatherCallbacks.GetLocalWeather(url, info as EmptyRequestData, sessionID)), + ) => _weatherCallbacks.GetLocalWeather(url, info as EmptyRequestData, sessionID) + ) ] ) { diff --git a/Libraries/Core/Servers/ConfigServer.cs b/Libraries/Core/Servers/ConfigServer.cs index 813bd221..5befbf21 100644 --- a/Libraries/Core/Servers/ConfigServer.cs +++ b/Libraries/Core/Servers/ConfigServer.cs @@ -10,11 +10,11 @@ namespace Core.Servers; [Injectable(InjectionType.Singleton)] public class ConfigServer { - protected ISptLogger _logger; - protected JsonUtil _jsonUtil; - protected FileUtil _fileUtil; - protected Dictionary configs = new(); protected readonly string[] acceptableFileExtensions = ["json", "jsonc"]; + protected FileUtil _fileUtil; + protected JsonUtil _jsonUtil; + protected ISptLogger _logger; + protected Dictionary configs = new(); public ConfigServer( ISptLogger logger, @@ -51,10 +51,7 @@ public class ConfigServer public void Initialize() { - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug("Importing configs..."); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug("Importing configs..."); // Get all filepaths var filepath = "./assets/configs/"; diff --git a/Libraries/Core/Servers/Http/RequestLogger.cs b/Libraries/Core/Servers/Http/RequestLogger.cs index bf455a0b..d4361d3f 100644 --- a/Libraries/Core/Servers/Http/RequestLogger.cs +++ b/Libraries/Core/Servers/Http/RequestLogger.cs @@ -3,5 +3,4 @@ namespace Core.Servers.Http; // This is a dummy class to use for SourceContext in Serilog, do not remove! public class RequestLogger { - } diff --git a/Libraries/Core/Servers/Http/SptHttpListener.cs b/Libraries/Core/Servers/Http/SptHttpListener.cs index a18397d6..64783a3e 100644 --- a/Libraries/Core/Servers/Http/SptHttpListener.cs +++ b/Libraries/Core/Servers/Http/SptHttpListener.cs @@ -21,14 +21,16 @@ public class SptHttpListener : IHttpListener // We want to read 1KB at a time, for most request this is already big enough private const int BodyReadBufferSize = 1024 * 1; + private static readonly ImmutableHashSet SupportedMethods = ["GET", "PUT", "POST"]; + protected readonly HttpResponseUtil _httpResponseUtil; + protected readonly JsonUtil _jsonUtil; + protected readonly LocalisationService _localisationService; + protected readonly ISptLogger _logger; + protected readonly ISptLogger _requestLogger; + protected readonly HttpRouter _router; protected readonly IEnumerable _serializers; - protected readonly ISptLogger _logger; - protected readonly ISptLogger _requestLogger; - protected readonly HttpResponseUtil _httpResponseUtil; - protected readonly LocalisationService _localisationService; - protected readonly JsonUtil _jsonUtil; public SptHttpListener( HttpRouter httpRouter, @@ -49,8 +51,6 @@ public class SptHttpListener : IHttpListener _jsonUtil = jsonUtil; } - private static readonly ImmutableHashSet SupportedMethods = ["GET", "PUT", "POST"]; - public bool CanHandle(string _, HttpRequest req) { return SupportedMethods.Contains(req.Method); @@ -109,12 +109,8 @@ public class SptHttpListener : IHttpListener } if (!requestIsCompressed) - { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug(value); - } - } var response = GetResponse(sessionId, req, value); SendResponse(sessionId, req, resp, value, response); @@ -145,20 +141,14 @@ public class SptHttpListener : IHttpListener string output ) { - if (body == null) - { - body = new object(); - } + if (body == null) body = new object(); var bodyInfo = _jsonUtil.Serialize(body); if (IsDebugRequest(req)) { // Send only raw response without transformation SendJson(resp, output, sessionID); - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Response: {output}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Response: {output}"); LogRequest(req, output); return; @@ -167,14 +157,10 @@ public class SptHttpListener : IHttpListener // Not debug, minority of requests need a serializer to do the job (IMAGE/BUNDLE/NOTIFY) var serialiser = _serializers.FirstOrDefault((x) => x.CanHandle(output)); if (serialiser != null) - { serialiser.Serialize(sessionID, req, resp, bodyInfo); - } else - { // No serializer can handle the request (majority of requests dont), zlib the output and send response back SendZlibJson(resp, output, sessionID); - } LogRequest(req, output); } @@ -231,10 +217,7 @@ public class SptHttpListener : IHttpListener resp.StatusCode = 200; resp.ContentType = "application/json"; resp.Headers.Append("Set-Cookie", $"PHPSESSID={sessionID}"); - if (!string.IsNullOrEmpty(output)) - { - resp.Body.WriteAsync(Encoding.UTF8.GetBytes(output)).AsTask().Wait(); - } + if (!string.IsNullOrEmpty(output)) resp.Body.WriteAsync(Encoding.UTF8.GetBytes(output)).AsTask().Wait(); resp.StartAsync().Wait(); resp.CompleteAsync().Wait(); } @@ -256,9 +239,9 @@ public class SptHttpListener : IHttpListener resp.CompleteAsync().Wait(); } - record Response(string Method, string jsonData); + private record Response(string Method, string jsonData); - record Request(string Method, object output); + private record Request(string Method, object output); - record RequestData(string Url, object Headers, object Data); + private record RequestData(string Url, object Headers, object Data); } diff --git a/Libraries/Core/Servers/HttpServer.cs b/Libraries/Core/Servers/HttpServer.cs index 9698beac..27a41dbd 100644 --- a/Libraries/Core/Servers/HttpServer.cs +++ b/Libraries/Core/Servers/HttpServer.cs @@ -34,10 +34,7 @@ public class HttpServer( app?.Use((HttpContext req, RequestDelegate _) => { return Task.Factory.StartNew(() => HandleFallback(req)); }); started = true; - if (app is null) - { - throw new Exception($"Application context is null in HttpServer.Load()"); - } + if (app is null) throw new Exception($"Application context is null in HttpServer.Load()"); _applicationContext.AddValue(ContextVariableType.WEB_APPLICATION, app); } diff --git a/Libraries/Core/Servers/RagfairServer.cs b/Libraries/Core/Servers/RagfairServer.cs index 7d54b2b1..5044eb23 100644 --- a/Libraries/Core/Servers/RagfairServer.cs +++ b/Libraries/Core/Servers/RagfairServer.cs @@ -36,15 +36,9 @@ public class RagfairServer( foreach (var traderId in traders) { // Edge case - skip generating fence offers - if (traderId == Traders.FENCE) - { - continue; - } + if (traderId == Traders.FENCE) continue; - if (_ragfairOfferService.TraderOffersNeedRefreshing(traderId)) - { - _ragfairOfferGenerator.GenerateFleaOffersForTrader(traderId); - } + if (_ragfairOfferService.TraderOffersNeedRefreshing(traderId)) _ragfairOfferGenerator.GenerateFleaOffersForTrader(traderId); } // Regenerate expired offers when over threshold limit diff --git a/Libraries/Core/Servers/SaveServer.cs b/Libraries/Core/Servers/SaveServer.cs index add3b4d1..198a9379 100644 --- a/Libraries/Core/Servers/SaveServer.cs +++ b/Libraries/Core/Servers/SaveServer.cs @@ -1,6 +1,7 @@ using System.Diagnostics; using SptCommon.Annotations; using Core.DI; +using Core.Models.Eft.Common; using Core.Models.Eft.Profile; using Core.Models.Spt.Config; using Core.Models.Utils; @@ -21,13 +22,12 @@ public class SaveServer( ConfigServer _configServer ) { + // onLoad = require("../bindings/SaveLoad"); + protected readonly Dictionary> onBeforeSaveCallbacks = new(); + private Lock _lock = new(); protected string profileFilepath = "user/profiles/"; protected Dictionary profiles = new(); - private Lock _lock = new(); - - // onLoad = require("../bindings/SaveLoad"); - protected readonly Dictionary> onBeforeSaveCallbacks = new(); protected Dictionary saveMd5 = new(); /** @@ -56,25 +56,16 @@ public class SaveServer( public void Load() { // get files to load - if (!_fileUtil.DirectoryExists(profileFilepath)) - { - _fileUtil.CreateDirectory(profileFilepath); - } + if (!_fileUtil.DirectoryExists(profileFilepath)) _fileUtil.CreateDirectory(profileFilepath); var files = _fileUtil.GetFiles(profileFilepath).Where((item) => _fileUtil.GetFileExtension(item) == "json"); // load profiles var stopwatch = Stopwatch.StartNew(); - foreach (var file in files) - { - LoadProfile(_fileUtil.StripExtension(file)); - } + foreach (var file in files) LoadProfile(_fileUtil.StripExtension(file)); stopwatch.Stop(); - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"{files.Count()} Profiles took: {stopwatch.ElapsedMilliseconds}ms to load."); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"{files.Count()} Profiles took: {stopwatch.ElapsedMilliseconds}ms to load."); } /** @@ -86,15 +77,9 @@ public class SaveServer( { // Save every profile var totalTime = 0L; - foreach (var sessionID in profiles) - { - totalTime += SaveProfile(sessionID.Key); - } + foreach (var sessionID in profiles) totalTime += SaveProfile(sessionID.Key); - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Saved {profiles.Count} profiles, took: {totalTime}ms"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Saved {profiles.Count} profiles, took: {totalTime}ms"); } } @@ -107,15 +92,9 @@ public class SaveServer( { lock (_lock) { - if (string.IsNullOrEmpty(sessionId)) - { - throw new Exception("session id provided was empty, did you restart the server while the game was running?"); - } + if (string.IsNullOrEmpty(sessionId)) throw new Exception("session id provided was empty, did you restart the server while the game was running?"); - if (profiles == null || profiles.Count == 0) - { - throw new Exception($"no profiles found in saveServer with id: {sessionId}"); - } + if (profiles == null || profiles.Count == 0) throw new Exception($"no profiles found in saveServer with id: {sessionId}"); if (!profiles.TryGetValue(sessionId, out var sptProfile)) throw new Exception($"no profile found for sessionId: {sessionId}"); @@ -133,7 +112,10 @@ public class SaveServer( * Get all profiles from memory * @returns Dictionary of ISptProfile */ - public Dictionary GetProfiles() => profiles; + public Dictionary GetProfiles() + { + return profiles; + } /** * Delete a profile by id @@ -162,17 +144,14 @@ public class SaveServer( { lock (_lock) { - if (profiles.ContainsKey(profileInfo.ProfileId)) - { - throw new Exception($"profile already exists for sessionId: {profileInfo.ProfileId}"); - } + if (profiles.ContainsKey(profileInfo.ProfileId)) throw new Exception($"profile already exists for sessionId: {profileInfo.ProfileId}"); profiles.Add( profileInfo.ProfileId, new SptProfile() { ProfileInfo = profileInfo, - CharacterData = new Characters() { PmcData = new(), ScavData = new() } + CharacterData = new Characters() { PmcData = new PmcData(), ScavData = new PmcData() } } ); } @@ -202,17 +181,13 @@ public class SaveServer( var filename = $"{sessionID}.json"; var filePath = $"{profileFilepath}{filename}"; if (_fileUtil.FileExists(filePath)) - { // File found, store in profiles[] profiles[sessionID] = _jsonUtil.Deserialize(_fileUtil.ReadFile(filePath)); - } // Run callbacks foreach (var callback in _saveLoadRouters) // HealthSaveLoadRouter, InraidSaveLoadRouter, InsuranceSaveLoadRouter, ProfileSaveLoadRouter. THESE SHOULD EXIST IN HERE - { profiles[sessionID] = callback.HandleLoad(GetProfile(sessionID)); - } } } diff --git a/Libraries/Core/Servers/WebSocketServer.cs b/Libraries/Core/Servers/WebSocketServer.cs index 538fb08d..da89fa18 100644 --- a/Libraries/Core/Servers/WebSocketServer.cs +++ b/Libraries/Core/Servers/WebSocketServer.cs @@ -34,10 +34,7 @@ public class WebSocketServer( foreach (var wsh in socketHandlers) { wsh.OnConnection(webSocket, context).Wait(); - if (webSocket.State == WebSocketState.Open) - { - _logger.Info($"WebSocketHandler \"{wsh.GetSocketId()}\" connected"); - } + if (webSocket.State == WebSocketState.Open) _logger.Info($"WebSocketHandler \"{wsh.GetSocketId()}\" connected"); } return Task.CompletedTask; diff --git a/Libraries/Core/Servers/Ws/SptWebSocketConnectionHandler.cs b/Libraries/Core/Servers/Ws/SptWebSocketConnectionHandler.cs index 77c05715..6d64b0dc 100644 --- a/Libraries/Core/Servers/Ws/SptWebSocketConnectionHandler.cs +++ b/Libraries/Core/Servers/Ws/SptWebSocketConnectionHandler.cs @@ -22,17 +22,23 @@ public class SptWebSocketConnectionHandler( IEnumerable _messageHandlers ) : IWebSocketConnectionHandler { + protected WsPing _defaultNotification = new(); protected HttpConfig _httpConfig = _configServer.GetConfig(); + protected Lock _lockObject = new(); + protected Dictionary _receiveTasks = new(); + protected Dictionary _socketAliveTimers = new(); protected Dictionary _sockets = new(); - protected Dictionary _socketAliveTimers = new(); - protected Dictionary _receiveTasks = new(); - protected Lock _lockObject = new(); - protected WsPing _defaultNotification = new(); + public string GetHookUrl() + { + return "/notifierServer/getwebsocket/"; + } - public string GetHookUrl() => "/notifierServer/getwebsocket/"; - public string GetSocketId() => "SPT WebSocket Handler"; + public string GetSocketId() + { + return "SPT WebSocket Handler"; + } public Task OnConnection(WebSocket ws, HttpContext context) { @@ -50,15 +56,12 @@ public class SptWebSocketConnectionHandler( lock (_lockObject) { - _receiveTasks.Add(sessionID, new()); + _receiveTasks.Add(sessionID, new CancellationTokenSource()); var cancelToken = _receiveTasks[sessionID].Token; Task.Factory.StartNew(_ => ReceiveTask(sessionID, ws, cancelToken), null, cancelToken); } - while (ws.State == WebSocketState.Open) - { - Thread.Sleep(1000); - } + while (ws.State == WebSocketState.Open) Thread.Sleep(1000); // Once the websocket dies, we dispose of it //_logger.Debug(_localisationService.GetText("websocket-socket_lost_deleting_handle")); @@ -70,6 +73,7 @@ public class SptWebSocketConnectionHandler( timer.Change(Timeout.Infinite, Timeout.Infinite); _socketAliveTimers.Remove(sessionID); } + if (_sockets.ContainsKey(sessionID)) _sockets.Remove(sessionID); if (_receiveTasks.TryGetValue(sessionID, out var receiveTask)) @@ -79,25 +83,6 @@ public class SptWebSocketConnectionHandler( ); } - private void TimedTask(WebSocket ws, string sessionID) - { - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug(_localisationService.GetText("websocket-pinging_player", sessionID)); - } - - if (ws.State == WebSocketState.Open) - { - var sendTask = ws.SendAsync( - Encoding.UTF8.GetBytes(_jsonUtil.Serialize(_defaultNotification)), - WebSocketMessageType.Text, - true, - CancellationToken.None - ); - sendTask.Wait(); - } - } - public void SendMessage(string sessionID, WsNotificationEvent output) { try @@ -113,17 +98,11 @@ public class SptWebSocketConnectionHandler( CancellationToken.None ); sendTask.Wait(); - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug(_localisationService.GetText("websocket-message_sent")); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug(_localisationService.GetText("websocket-message_sent")); } else { - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug(_localisationService.GetText("websocket-not_ready_message_not_sent", sessionID)); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug(_localisationService.GetText("websocket-not_ready_message_not_sent", sessionID)); } } catch (Exception err) @@ -132,11 +111,31 @@ public class SptWebSocketConnectionHandler( } } + public bool IsWebSocketConnected(string sessionID) + { + return _sockets.TryGetValue(sessionID, out var socket) && socket.State == WebSocketState.Open; + } + + private void TimedTask(WebSocket ws, string sessionID) + { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug(_localisationService.GetText("websocket-pinging_player", sessionID)); + + if (ws.State == WebSocketState.Open) + { + var sendTask = ws.SendAsync( + Encoding.UTF8.GetBytes(_jsonUtil.Serialize(_defaultNotification)), + WebSocketMessageType.Text, + true, + CancellationToken.None + ); + sendTask.Wait(); + } + } + private void ReceiveTask(string sessionID, WebSocket ws, CancellationToken cancelToken) { List readBytes = new(); while (ws.State == WebSocketState.Open) - { try { if (cancelToken.IsCancellationRequested) @@ -151,16 +150,13 @@ public class SptWebSocketConnectionHandler( isEndOfMessage = readTask.Result.EndOfMessage; } - foreach (var sptWebSocketMessageHandler in _messageHandlers) - { - sptWebSocketMessageHandler.OnSptMessage(sessionID, ws, readBytes.ToArray()).Wait(); - } + foreach (var sptWebSocketMessageHandler in _messageHandlers) sptWebSocketMessageHandler.OnSptMessage(sessionID, ws, readBytes.ToArray()).Wait(); } catch (OperationCanceledException _) { _logger.Info("WebSocket disconnecting, receive task finalized..."); } - catch(Exception _) + catch (Exception _) { lock (_lockObject) { @@ -171,19 +167,13 @@ public class SptWebSocketConnectionHandler( var playerInfoText = $"{playerProfile.ProfileInfo.Username} ({sessionID})"; _logger.Info($"[ws] player: {playerInfoText} has disconnected"); } - + ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "Client closed connection", CancellationToken.None); } finally { readBytes.Clear(); } - } - } - - public bool IsWebSocketConnected(string sessionID) - { - return _sockets.TryGetValue(sessionID, out var socket) && socket.State == WebSocketState.Open; } public WebSocket GetSessionWebSocket(string sessionID) diff --git a/Libraries/Core/Services/AirdropService.cs b/Libraries/Core/Services/AirdropService.cs index bc083ae3..1917a8cb 100644 --- a/Libraries/Core/Services/AirdropService.cs +++ b/Libraries/Core/Services/AirdropService.cs @@ -15,8 +15,8 @@ namespace Core.Services; [Injectable] public class AirdropService( - ConfigServer configServer, - ISptLogger _logger, + ConfigServer configServer, + ISptLogger _logger, LootGenerator _lootGenerator, HashUtil _hashUtil, WeightedRandomHelper _weightedRandomHelper, @@ -28,7 +28,8 @@ public class AirdropService( public GetAirdropLootResponse GenerateCustomAirdropLoot(GetAirdropLootRequest request) { - if (!_airdropConfig.CustomAirdropMapping.TryGetValue(request.ContainerId, out var customAirdropInformation)) { + if (!_airdropConfig.CustomAirdropMapping.TryGetValue(request.ContainerId, out var customAirdropInformation)) + { _logger.Warning( $"Unable to find data for custom airdrop {request.ContainerId}, returning random airdrop instead" ); @@ -49,10 +50,7 @@ public class AirdropService( public GetAirdropLootResponse GenerateAirdropLoot(SptAirdropTypeEnum? forcedAirdropType = null) { var airdropType = forcedAirdropType != null ? forcedAirdropType : ChooseAirdropType(); - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Chose: {airdropType} for airdrop loot"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Chose: {airdropType} for airdrop loot"); // Common/weapon/etc var airdropConfig = GetAirdropLootConfigByType(airdropType); @@ -69,14 +67,15 @@ public class AirdropService( crateLoot.Insert(0, airdropCrateItem); // Reparent loot items to crate we added above - foreach (var item in crateLoot) { - if (item.Id == airdropCrateItem.Id) { + foreach (var item in crateLoot) + { + if (item.Id == airdropCrateItem.Id) // Crate itself, don't alter continue; - } // no parentId = root item, make item have create as parent - if (item.ParentId is null) { + if (item.ParentId is null) + { item.ParentId = airdropCrateItem.Id; item.SlotId = "main"; } @@ -92,17 +91,19 @@ public class AirdropService( /// Item protected Item GetAirdropCrateItem(SptAirdropTypeEnum airdropType) { - var airdropContainer = new Item { + var airdropContainer = new Item + { Id = _hashUtil.Generate(), Template = "", // picked later Upd = new Upd() - { + { SpawnedInSession = true, - StackObjectsCount = 1, - }, + StackObjectsCount = 1 + } }; - switch (airdropType) { + switch (airdropType) + { case SptAirdropTypeEnum.foodMedical: airdropContainer.Template = ItemTpl.LOOTCONTAINER_AIRDROP_MEDICAL_CRATE; break; @@ -145,7 +146,8 @@ public class AirdropService( protected AirdropLootRequest GetAirdropLootConfigByType(SptAirdropTypeEnum? airdropType) { var lootSettingsByType = _airdropConfig.Loot[airdropType.ToString()]; - if (lootSettingsByType is null) { + if (lootSettingsByType is null) + { _logger.Error( _localisationService.GetText("location-unable_to_find_airdrop_drop_config_of_type", airdropType) ); @@ -167,7 +169,8 @@ public class AirdropService( itemBlacklist.UnionWith(_itemFilterService.GetBossItems()); itemBlacklist.UnionWith(itemsMatchingTypeBlacklist); - return new AirdropLootRequest { + return new AirdropLootRequest + { Icon = lootSettingsByType.Icon, WeaponPresetCount = lootSettingsByType.WeaponPresetCount, ArmorPresetCount = lootSettingsByType.ArmorPresetCount, @@ -180,7 +183,7 @@ public class AirdropService( ArmorLevelWhitelist = lootSettingsByType.ArmorLevelWhitelist, AllowBossItems = lootSettingsByType.AllowBossItems, UseForcedLoot = lootSettingsByType.UseForcedLoot, - ForcedLoot = lootSettingsByType.ForcedLoot, + ForcedLoot = lootSettingsByType.ForcedLoot }; } } diff --git a/Libraries/Core/Services/BackupService.cs b/Libraries/Core/Services/BackupService.cs index 53e1c3f7..7270879e 100644 --- a/Libraries/Core/Services/BackupService.cs +++ b/Libraries/Core/Services/BackupService.cs @@ -10,17 +10,17 @@ namespace Core.Services; [Injectable(InjectionType.Singleton)] public class BackupService { - protected ISptLogger _logger; - protected JsonUtil _jsonUtil; - protected TimeUtil _timeUtil; - protected FileUtil _fileUtil; - protected BackupConfig _backupConfig; + protected const string _profileDir = "./user/profiles"; protected readonly List _activeServerMods; - protected const string _profileDir = "./user/profiles"; + protected BackupConfig _backupConfig; // Runs Init() every x minutes protected Timer _backupIntervalTimer; + protected FileUtil _fileUtil; + protected JsonUtil _jsonUtil; + protected ISptLogger _logger; + protected TimeUtil _timeUtil; public BackupService( ISptLogger _logger, @@ -71,18 +71,15 @@ public class BackupService /** * Initializes the backup process. - * + * * This method orchestrates the profile backup service. Handles copying profiles to a backup directory and cleaning * up old backups if the number exceeds the configured maximum. - * + * * @returns A promise that resolves when the backup process is complete. */ public void Init() { - if (!IsEnabled()) - { - return; - } + if (!IsEnabled()) return; var targetDir = GenerateBackupTargetDir(); @@ -100,10 +97,7 @@ public class BackupService if (currentProfilePaths.Count == 0) { - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug("No profiles to backup"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug("No profiles to backup"); return; } @@ -126,10 +120,7 @@ public class BackupService // Write a copy of active mods. _fileUtil.WriteFile(Path.Combine(targetDir, "activeMods.json"), _jsonUtil.Serialize(_activeServerMods)); - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Profile backup created in: {targetDir}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Profile backup created in: {targetDir}"); } catch (Exception ex) { @@ -142,20 +133,14 @@ public class BackupService /** * Check to see if the backup service is enabled via the config. - * + * * @returns True if enabled, false otherwise. */ protected bool IsEnabled() { - if (_backupConfig.Enabled) - { - return true; - } + if (_backupConfig.Enabled) return true; - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug("Profile backups disabled"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug("Profile backups disabled"); return false; } @@ -163,7 +148,7 @@ public class BackupService /** * Generates the target directory path for the backup. The directory path is constructed using the `directory` from * the configuration and the current backup date. - * + * * @returns The target directory path for the backup. */ protected string GenerateBackupTargetDir() @@ -174,7 +159,7 @@ public class BackupService /** * Generates a formatted backup date string in the format `YYYY-MM-DD_hh-mm-ss`. - * + * * @returns The formatted backup date string. */ protected string GenerateBackupDate() @@ -186,10 +171,10 @@ public class BackupService /** * Cleans up old backups in the backup directory. - * + * * This method reads the backup directory, and sorts backups by modification time. If the number of backups exceeds * the configured maximum, it deletes the oldest backups. - * + * * @returns A promise that resolves when the cleanup is complete. */ protected void CleanBackups() @@ -213,10 +198,7 @@ public class BackupService foreach (var backupPath in backupPaths) { var date = ExtractDateFromFolderName(backupPath); - if (!date.HasValue) - { - continue; - } + if (!date.HasValue) continue; result.Add(date.Value.ToFileTimeUtc(), backupPath); } @@ -226,7 +208,7 @@ public class BackupService /** * Retrieves and sorts the backup file paths from the specified directory. - * + * * @param dir - The directory to search for backup files. * @returns A promise that resolves to a List of sorted backup file paths. */ @@ -240,7 +222,7 @@ public class BackupService /** * Compares two backup folder names based on their extracted dates. - * + * * @param a - The name of the first backup folder. * @param b - The name of the second backup folder. * @returns The difference in time between the two dates in milliseconds, or `null` if either date is invalid. @@ -250,17 +232,14 @@ public class BackupService var dateA = ExtractDateFromFolderName(a); var dateB = ExtractDateFromFolderName(b); - if (!dateA.HasValue || !dateB.HasValue) - { - return 0; // Skip comparison if either date is invalid. - } + if (!dateA.HasValue || !dateB.HasValue) return 0; // Skip comparison if either date is invalid. return (int)(dateA.Value.ToFileTimeUtc() - dateB.Value.ToFileTimeUtc()); } /** * Extracts a date from a folder name string formatted as `YYYY-MM-DD_hh-mm-ss`. - * + * * @param folderName - The name of the folder from which to extract the date. * @returns A DateTime object if the folder name is in the correct format, otherwise null. */ @@ -286,7 +265,7 @@ public class BackupService /** * Removes excess backups from the backup directory. - * + * * @param backups - A List of backup file names to be removed. * @returns A promise that resolves when all specified backups have been removed. */ @@ -297,16 +276,13 @@ public class BackupService { _fileUtil.DeleteDirectory(Path.Combine(pathToDelete), true); - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Deleted old backup: {pathToDelete}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Deleted old backup: {pathToDelete}"); } } /** * Get a List of active server mod details. - * + * * @returns A List of mod names. */ protected List GetActiveServerMods() diff --git a/Libraries/Core/Services/BotEquipmentFilterService.cs b/Libraries/Core/Services/BotEquipmentFilterService.cs index eb30fb0f..7a386af8 100644 --- a/Libraries/Core/Services/BotEquipmentFilterService.cs +++ b/Libraries/Core/Services/BotEquipmentFilterService.cs @@ -14,12 +14,11 @@ namespace Core.Services; [Injectable(InjectionType.Singleton)] public class BotEquipmentFilterService { - protected ISptLogger _logger; - protected ProfileHelper _profileHelper; - protected BotHelper _botHelper; - protected BotConfig _botConfig; protected Dictionary _botEquipmentConfig; + protected BotHelper _botHelper; + protected ISptLogger _logger; + protected ProfileHelper _profileHelper; public BotEquipmentFilterService( ISptLogger logger, @@ -96,15 +95,9 @@ public class BotEquipmentFilterService Dictionary equipmentChanges, Dictionary baseValues) { - if (equipmentChanges is null) - { - return; - } + if (equipmentChanges is null) return; - foreach (var itemKey in equipmentChanges) - { - baseValues[itemKey.Key] = equipmentChanges[itemKey.Key]; - } + foreach (var itemKey in equipmentChanges) baseValues[itemKey.Key] = equipmentChanges[itemKey.Key]; } /// @@ -116,10 +109,7 @@ public class BotEquipmentFilterService Dictionary generationChanges, Generation baseBotGeneration) { - if (generationChanges is null) - { - return; - } + if (generationChanges is null) return; foreach (var itemKey in generationChanges) { @@ -147,10 +137,7 @@ public class BotEquipmentFilterService { var botEquipmentSettings = _botConfig.Equipment[botEquipmentRole]; - if (botEquipmentSettings is null) - { - return null; - } + if (botEquipmentSettings is null) return null; return botEquipmentSettings.WeaponSightWhitelist; } @@ -195,7 +182,7 @@ public class BotEquipmentFilterService { var weightingDetailsForBot = _botEquipmentConfig.GetValueOrDefault(botRole, null); - return (weightingDetailsForBot?.WeightingAdjustmentsByBotLevel ?? [] ).FirstOrDefault( + return (weightingDetailsForBot?.WeightingAdjustmentsByBotLevel ?? []).FirstOrDefault( x => botLevel >= x.LevelRange.Min && botLevel <= x.LevelRange.Max ); } @@ -232,48 +219,32 @@ public class BotEquipmentFilterService // Skip equipment slot if whitelist doesn't exist / is empty var whitelistEquipmentForSlot = whitelist.Equipment[equipmentSlotKey.Key.ToString()]; - if (whitelistEquipmentForSlot is null || whitelistEquipmentForSlot.Count == 0) - { - continue; - } + if (whitelistEquipmentForSlot is null || whitelistEquipmentForSlot.Count == 0) continue; // Filter equipment slot items to just items in whitelist baseBotNode.BotInventory.Equipment[equipmentSlotKey.Key] = new Dictionary(); foreach (var dict in botEquipment) - { if (whitelistEquipmentForSlot.Contains(dict.Key)) - { baseBotNode.BotInventory.Equipment[equipmentSlotKey.Key][dict.Key] = botEquipment[dict.Key]; - } - } } return; } if (blacklist is not null) - { foreach (var equipmentSlotKvP in baseBotNode.BotInventory.Equipment) { var botEquipment = baseBotNode.BotInventory.Equipment[equipmentSlotKvP.Key]; // Skip equipment slot if blacklist doesn't exist / is empty - if (!blacklist.Equipment.TryGetValue(equipmentSlotKvP.Key.ToString(), out var equipmentSlotBlacklist)) - { - continue; - } + if (!blacklist.Equipment.TryGetValue(equipmentSlotKvP.Key.ToString(), out var equipmentSlotBlacklist)) continue; // Filter equipment slot items to just items not in blacklist equipmentSlotKvP.Value.Clear(); foreach (var dict in botEquipment) - { if (!equipmentSlotBlacklist.Contains(dict.Key)) - { equipmentSlotKvP.Value[dict.Key] = botEquipment[dict.Key]; - } - } } - } } /// @@ -292,50 +263,38 @@ public class BotEquipmentFilterService if (whitelist is not null) { // Loop over each caliber + cartridges of that type - foreach ( var (caliber, cartridges) in baseBotNode.BotInventory.Ammo) { - - if(!whitelist.Cartridge.TryGetValue(caliber, out var matchingWhitelist)) - { + foreach (var (caliber, cartridges) in baseBotNode.BotInventory.Ammo) + { + if (!whitelist.Cartridge.TryGetValue(caliber, out var matchingWhitelist)) // No cartridge whitelist, move to next cartridge continue; - } // Loop over each cartridge + weight // Clear all cartridges ready for whitelist to be added foreach (var ammoKvP in cartridges) - { // Cartridge not on whitelist if (!matchingWhitelist.Contains(ammoKvP.Key)) - { // Remove cartridges.Remove(ammoKvP.Key); - } - } } return; } if (blacklist is not null) - { - foreach ( var ammoCaliberKvP in baseBotNode.BotInventory.Ammo) { - var botAmmo = baseBotNode.BotInventory.Ammo[ammoCaliberKvP.Key]; + foreach (var ammoCaliberKvP in baseBotNode.BotInventory.Ammo) + { + var botAmmo = baseBotNode.BotInventory.Ammo[ammoCaliberKvP.Key]; // Skip cartridge slot if blacklist doesn't exist / is empty blacklist.Cartridge.TryGetValue(ammoCaliberKvP.Key, out List cartridgeCaliberBlacklist); - if (cartridgeCaliberBlacklist is null || cartridgeCaliberBlacklist.Count == 0) - { - continue; - } + if (cartridgeCaliberBlacklist is null || cartridgeCaliberBlacklist.Count == 0) continue; // Filter cartridge slot items to just items not in blacklist foreach (var blacklistedTpl in cartridgeCaliberBlacklist .Where(blacklistedTpl => ammoCaliberKvP.Value.ContainsKey(blacklistedTpl))) - { ammoCaliberKvP.Value.Remove(blacklistedTpl); - } } - } } /// @@ -349,30 +308,20 @@ public class BotEquipmentFilterService bool showEditWarnings = true) { //TODO, bad typing by key with method below due to, EquipmentSlots - if (weightingAdjustments is null) - { - return; - } + if (weightingAdjustments is null) return; if (weightingAdjustments.Add?.Count > 0) - { foreach (var poolAdjustmentKvP in weightingAdjustments.Add) { var locationToUpdate = botItemPool[Enum.Parse(poolAdjustmentKvP.Key)]; - foreach (var itemToAddKvP in poolAdjustmentKvP.Value) - { - locationToUpdate[itemToAddKvP.Key] = itemToAddKvP.Value; - } + foreach (var itemToAddKvP in poolAdjustmentKvP.Value) locationToUpdate[itemToAddKvP.Key] = itemToAddKvP.Value; } - } if (weightingAdjustments.Edit?.Count > 0) - { foreach (var poolAdjustmentKvP in weightingAdjustments.Edit) { var locationToUpdate = botItemPool[Enum.Parse(poolAdjustmentKvP.Key)]; foreach (var itemToEditKvP in poolAdjustmentKvP.Value) - { // Only make change if item exists as we're editing, not adding if (locationToUpdate[itemToEditKvP.Key] != null || locationToUpdate[itemToEditKvP.Key] == 0) { @@ -381,16 +330,10 @@ public class BotEquipmentFilterService else { if (showEditWarnings) - { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug($"Tried to edit a non - existent item for slot: {poolAdjustmentKvP} {itemToEditKvP}"); - } - } } - } } - } } /// @@ -404,30 +347,20 @@ public class BotEquipmentFilterService Dictionary> botItemPool, bool showEditWarnings = true) { - if (weightingAdjustments is null) - { - return; - } + if (weightingAdjustments is null) return; if (weightingAdjustments.Add?.Count > 0) - { foreach (var poolAdjustmentKvP in weightingAdjustments.Add) { var locationToUpdate = botItemPool[poolAdjustmentKvP.Key]; - foreach (var itemToAddKvP in poolAdjustmentKvP.Value) - { - locationToUpdate[itemToAddKvP.Key] = itemToAddKvP.Value; - } + foreach (var itemToAddKvP in poolAdjustmentKvP.Value) locationToUpdate[itemToAddKvP.Key] = itemToAddKvP.Value; } - } if (weightingAdjustments.Edit?.Count > 0) - { foreach (var poolAdjustmentKvP in weightingAdjustments.Edit) { var locationToUpdate = botItemPool[poolAdjustmentKvP.Key]; foreach (var itemToEditKvP in poolAdjustmentKvP.Value) - { // Only make change if item exists as we're editing, not adding if (locationToUpdate.GetValueOrDefault(itemToEditKvP.Key) != null || locationToUpdate[itemToEditKvP.Key] == 0) { @@ -436,16 +369,10 @@ public class BotEquipmentFilterService else { if (showEditWarnings) - { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug($"Tried to edit a non - existent item for slot: {poolAdjustmentKvP} {itemToEditKvP}"); - } - } } - } } - } } /// @@ -458,30 +385,20 @@ public class BotEquipmentFilterService Appearance botItemPool, bool showEditWarnings = true) { - if (weightingAdjustments is null) - { - return; - } + if (weightingAdjustments is null) return; if (weightingAdjustments.Add?.Count > 0) - { foreach (var poolAdjustmentKvP in weightingAdjustments.Add) { var locationToUpdate = botItemPool.GetByJsonProp>(poolAdjustmentKvP.Key); - foreach (var itemToAddKvP in poolAdjustmentKvP.Value) - { - locationToUpdate[itemToAddKvP.Key] = itemToAddKvP.Value; - } + foreach (var itemToAddKvP in poolAdjustmentKvP.Value) locationToUpdate[itemToAddKvP.Key] = itemToAddKvP.Value; } - } if (weightingAdjustments.Edit?.Count > 0) - { foreach (var poolAdjustmentKvP in weightingAdjustments.Edit) { var locationToUpdate = botItemPool.GetByJsonProp>(poolAdjustmentKvP.Key); foreach (var itemToEditKvP in poolAdjustmentKvP.Value) - { // Only make change if item exists as we're editing, not adding if (locationToUpdate.GetValueOrDefault(itemToEditKvP.Key) != null || locationToUpdate.GetValueOrDefault(itemToEditKvP.Key) == 0) { @@ -490,15 +407,9 @@ public class BotEquipmentFilterService else { if (showEditWarnings) - { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug($"Tried to edit a non - existent item for slot: {poolAdjustmentKvP} {itemToEditKvP}"); - } - } } - } } - } } } diff --git a/Libraries/Core/Services/BotEquipmentModPoolService.cs b/Libraries/Core/Services/BotEquipmentModPoolService.cs index 3575dcad..b2a25fbf 100644 --- a/Libraries/Core/Services/BotEquipmentModPoolService.cs +++ b/Libraries/Core/Services/BotEquipmentModPoolService.cs @@ -12,27 +12,26 @@ namespace Core.Services; [Injectable(InjectionType.Singleton)] public class BotEquipmentModPoolService { - protected ISptLogger _logger; - protected ItemHelper _itemHelper; - protected DatabaseService _databaseService; - protected LocalisationService _localisationService; + private readonly Lock _lock = new(); + protected bool _armorPoolGenerated; + protected BotConfig _botConfig; protected ConfigServer _configServer; + protected DatabaseService _databaseService; + protected ConcurrentDictionary>> _gearModPool; + protected ItemHelper _itemHelper; + protected LocalisationService _localisationService; + protected ISptLogger _logger; + protected ConcurrentDictionary>> _weaponModPool; protected bool _weaponPoolGenerated; - protected bool _armorPoolGenerated; - protected ConcurrentDictionary>> _weaponModPool; - protected ConcurrentDictionary>> _gearModPool; - protected BotConfig _botConfig; - - private readonly Lock _lock = new(); public BotEquipmentModPoolService( ISptLogger logger, ItemHelper itemHelper, DatabaseService databaseService, LocalisationService localisationService, - ConfigServer configServer - ) + ConfigServer configServer + ) { _logger = logger; _itemHelper = itemHelper; @@ -60,28 +59,33 @@ public class BotEquipmentModPoolService // Get weapon or gear pool var pool = poolType == "weapon" ? _weaponModPool : _gearModPool; - foreach (var item in items) { + foreach (var item in items) + { if (item.Properties is null) { - _logger.Error(_localisationService.GetText("bot-item_missing_props_property", new { - itemTpl = item.Id, - name = item.Name, - })); + _logger.Error( + _localisationService.GetText( + "bot-item_missing_props_property", + new + { + itemTpl = item.Id, + name = item.Name + } + ) + ); continue; } // Skip item without slots - if (item.Properties.Slots is null || item.Properties.Slots.Count == 0) - { - continue; - } + if (item.Properties.Slots is null || item.Properties.Slots.Count == 0) continue; // Add base item (weapon/armor) to pool pool.TryAdd(item.Id, new ConcurrentDictionary>()); // iterate over each items mod slots e.g. mod_muzzle - foreach (var slot in item.Properties.Slots) { + foreach (var slot in item.Properties.Slots) + { // Get mods that fit into the current mod slot var itemsThatFit = slot.Props.Filters.FirstOrDefault().Filter; @@ -95,18 +99,14 @@ public class BotEquipmentModPoolService // Does tpl exist inside mod_slots hashset if (!SetContainsTpl(itemModPool[slot.Name], itemToAddTpl)) - { // Keyed by mod slot AddTplToSet(itemModPool[slot.Name], itemToAddTpl); - } var subItemDetails = _itemHelper.GetItem(itemToAddTpl).Value; var hasSubItemsToAdd = (subItemDetails?.Properties?.Slots?.Count ?? 0) > 0; if (hasSubItemsToAdd && !pool.ContainsKey(subItemDetails.Id)) - { // Recursive call GeneratePool([subItemDetails], poolType); - } } } } @@ -153,10 +153,8 @@ public class BotEquipmentModPoolService public HashSet GetCompatibleModsForWeaponSlot(string itemTpl, string slotName) { if (!_weaponPoolGenerated) - { // Get every weapon in db and generate mod pool GenerateWeaponPool(); - } return _weaponModPool[itemTpl][slotName]; } @@ -168,10 +166,7 @@ public class BotEquipmentModPoolService */ public ConcurrentDictionary> GetModsForGearSlot(string itemTpl) { - if (!_armorPoolGenerated) - { - GenerateGearPool(); - } + if (!_armorPoolGenerated) GenerateGearPool(); return _gearModPool.TryGetValue(itemTpl, out var value) ? value @@ -185,10 +180,7 @@ public class BotEquipmentModPoolService */ public ConcurrentDictionary> GetModsForWeaponSlot(string itemTpl) { - if (!_weaponPoolGenerated) - { - GenerateWeaponPool(); - } + if (!_weaponPoolGenerated) GenerateWeaponPool(); return _weaponModPool[itemTpl]; } @@ -200,7 +192,6 @@ public class BotEquipmentModPoolService // Get item from db var itemDb = _itemHelper.GetItem(itemTpl).Value; if (itemDb.Properties.Slots is not null) - { // Loop over slots flagged as 'required' foreach (var slot in itemDb.Properties.Slots.Where(slot => slot.Required.GetValueOrDefault(false))) { @@ -208,12 +199,8 @@ public class BotEquipmentModPoolService result.Add(slot.Name, []); // Add compatible tpls to dicts hashset - foreach (var compatibleItemTpl in slot.Props.Filters.FirstOrDefault().Filter) - { - result[slot.Name].Add(compatibleItemTpl); - } + foreach (var compatibleItemTpl in slot.Props.Filters.FirstOrDefault().Filter) result[slot.Name].Add(compatibleItemTpl); } - } return result; } @@ -223,8 +210,10 @@ public class BotEquipmentModPoolService */ protected void GenerateWeaponPool() { - var weapons = _databaseService.GetItems().Values.Where( - (item) => item.Type == "Item" && _itemHelper.IsOfBaseclass(item.Id, BaseClasses.WEAPON)); + var weapons = _databaseService.GetItems() + .Values.Where( + (item) => item.Type == "Item" && _itemHelper.IsOfBaseclass(item.Id, BaseClasses.WEAPON) + ); GeneratePool(weapons, "weapon"); // Flag pool as being complete @@ -236,14 +225,19 @@ public class BotEquipmentModPoolService */ protected void GenerateGearPool() { - var gear = _databaseService.GetItems().Values.Where( - (item) => item.Type == "Item" - && _itemHelper.IsOfBaseclasses(item.Id, [ - BaseClasses.ARMORED_EQUIPMENT, - BaseClasses.VEST, - BaseClasses.ARMOR, - BaseClasses.HEADWEAR, - ])); + var gear = _databaseService.GetItems() + .Values.Where( + (item) => item.Type == "Item" && + _itemHelper.IsOfBaseclasses( + item.Id, + [ + BaseClasses.ARMORED_EQUIPMENT, + BaseClasses.VEST, + BaseClasses.ARMOR, + BaseClasses.HEADWEAR + ] + ) + ); GeneratePool(gear, "gear"); // Flag pool as being complete diff --git a/Libraries/Core/Services/BotGenerationCacheService.cs b/Libraries/Core/Services/BotGenerationCacheService.cs index dc62c01d..90af6e8d 100644 --- a/Libraries/Core/Services/BotGenerationCacheService.cs +++ b/Libraries/Core/Services/BotGenerationCacheService.cs @@ -9,13 +9,13 @@ namespace Core.Services; public class BotGenerationCacheService( ISptLogger _logger, LocalisationService _localisationService - ) +) { - protected Dictionary> _storedBots = new(); protected Queue _activeBotsInRaid = []; protected object _lock = new(); - - + protected Dictionary> _storedBots = new(); + + /** * Store list of bots in cache, shuffle results before storage * @param botsToStore Bots we want to store in the cache @@ -25,12 +25,8 @@ public class BotGenerationCacheService( lock (_lock) { foreach (var bot in botsToStore) - { if (!_storedBots.TryAdd(key, [bot])) - { _storedBots[key].Add(bot); - } - } } } @@ -45,9 +41,7 @@ public class BotGenerationCacheService( lock (_lock) { if (_storedBots.TryGetValue(key, out var bots)) - { if (bots.Count > 0) - { try { return bots.PopLast(); @@ -56,8 +50,6 @@ public class BotGenerationCacheService( { _logger.Error(_localisationService.GetText("bot-cache_has_zero_bots_of_requested_type", key)); } - } - } } _logger.Error(_localisationService.GetText("bot-no_bot_type_in_cache", key)); diff --git a/Libraries/Core/Services/BotLootCacheService.cs b/Libraries/Core/Services/BotLootCacheService.cs index 472cf33c..503955d7 100644 --- a/Libraries/Core/Services/BotLootCacheService.cs +++ b/Libraries/Core/Services/BotLootCacheService.cs @@ -21,8 +21,8 @@ public class BotLootCacheService( ICloner _cloner ) { - protected Dictionary _lootCache = new(); protected object _lock = new(); + protected Dictionary _lootCache = new(); /// /// Remove cached bot loot data @@ -65,6 +65,7 @@ public class BotLootCacheService( { botRoleCache = _lootCache[botRole]; } + switch (lootType) { case LootCacheType.Special: @@ -128,19 +129,11 @@ public class BotLootCacheService( { var itemPrice = _itemHelper.GetItemPrice(i.Key); if (itemPriceMinMax?.Min is not null && itemPriceMinMax?.Max is not null) - { return itemPrice >= itemPriceMinMax?.Min && itemPrice <= itemPriceMinMax?.Max; - } - if (itemPriceMinMax?.Min is not null && itemPriceMinMax?.Max is null) - { - return itemPrice >= itemPriceMinMax?.Min; - } + if (itemPriceMinMax?.Min is not null && itemPriceMinMax?.Max is null) return itemPrice >= itemPriceMinMax?.Min; - if (itemPriceMinMax?.Min is null && itemPriceMinMax?.Max is not null) - { - return itemPrice <= itemPriceMinMax?.Max; - } + if (itemPriceMinMax?.Min is null && itemPriceMinMax?.Max is not null) return itemPrice <= itemPriceMinMax?.Max; return false; } @@ -194,10 +187,7 @@ public class BotLootCacheService( foreach (var kvp in poolsToProcess) { // No items to add, skip - if (kvp.Value.Count == 0) - { - continue; - } + if (kvp.Value.Count == 0) continue; // Sort loot pool into separate buckets switch (kvp.Key) @@ -223,10 +213,7 @@ public class BotLootCacheService( } // Add all items (if any) to combined pool (excluding secure) - if (kvp.Value.Count > 0 && kvp.Key.ToLower() != "securedcontainer") - { - AddItemsToPool(combinedLootPool, kvp.Value); - } + if (kvp.Value.Count > 0 && kvp.Key.ToLower() != "securedcontainer") AddItemsToPool(combinedLootPool, kvp.Value); } // Assign whitelisted special items to bot if any exist @@ -237,17 +224,12 @@ public class BotLootCacheService( // no whitelist, find and assign from combined item pool if (!specialLootItems.Any()) - { // key = tpl, value = weight foreach (var itemKvP in specialLootPool) { var itemTemplate = _itemHelper.GetItem(itemKvP.Key).Value; - if (!(IsBulletOrGrenade(itemTemplate.Properties) || IsMagazine(itemTemplate.Properties))) - { - specialLootItems[itemKvP.Key] = itemKvP.Value; - } + if (!(IsBulletOrGrenade(itemTemplate.Properties) || IsMagazine(itemTemplate.Properties))) specialLootItems[itemKvP.Key] = itemKvP.Value; } - } // Assign whitelisted healing items to bot if any exist var healingItems = @@ -257,7 +239,6 @@ public class BotLootCacheService( // No whitelist, find and assign from combined item pool if (!healingItems.Any()) - { // key = tpl, value = weight foreach (var itemKvP in combinedLootPool) { @@ -267,126 +248,88 @@ public class BotLootCacheService( itemTemplate.Parent != BaseClasses.STIMULATOR && itemTemplate.Parent != BaseClasses.DRUGS ) - { healingItems[itemKvP.Key] = itemKvP.Value; - } } - } // Assign whitelisted drugs to bot if any exist var drugItems = botJsonTemplate.BotGeneration?.Items?.Drugs?.Whitelist ?? new Dictionary(); // no drugs whitelist, find and assign from combined item pool if (!drugItems.Any()) - { - foreach (var itemKvP in (combinedLootPool)) + foreach (var itemKvP in combinedLootPool) { var itemTemplate = _itemHelper.GetItem(itemKvP.Key).Value; - if (IsMedicalItem(itemTemplate.Properties) && itemTemplate.Parent == BaseClasses.DRUGS) - { - drugItems[itemKvP.Key] = itemKvP.Value; - } + if (IsMedicalItem(itemTemplate.Properties) && itemTemplate.Parent == BaseClasses.DRUGS) drugItems[itemKvP.Key] = itemKvP.Value; } - } // Assign whitelisted food to bot if any exist var foodItems = botJsonTemplate.BotGeneration?.Items?.Food?.Whitelist ?? new Dictionary(); // No food whitelist, find and assign from combined item pool if (!foodItems.Any()) - { - foreach (var itemKvP in (combinedLootPool)) + foreach (var itemKvP in combinedLootPool) { var itemTemplate = _itemHelper.GetItem(itemKvP.Key).Value; - if (_itemHelper.IsOfBaseclass(itemTemplate.Id, BaseClasses.FOOD)) - { - foodItems[itemKvP.Key] = itemKvP.Value; - } + if (_itemHelper.IsOfBaseclass(itemTemplate.Id, BaseClasses.FOOD)) foodItems[itemKvP.Key] = itemKvP.Value; } - } // Assign whitelisted drink to bot if any exist var drinkItems = botJsonTemplate.BotGeneration?.Items?.Food?.Whitelist ?? new Dictionary(); // No drink whitelist, find and assign from combined item pool if (!drinkItems.Any()) - { foreach (var itemKvP in combinedLootPool) { var itemTemplate = _itemHelper.GetItem(itemKvP.Key).Value; - if (_itemHelper.IsOfBaseclass(itemTemplate.Id, BaseClasses.DRINK)) - { - drinkItems[itemKvP.Key] = itemKvP.Value; - } + if (_itemHelper.IsOfBaseclass(itemTemplate.Id, BaseClasses.DRINK)) drinkItems[itemKvP.Key] = itemKvP.Value; } - } // Assign whitelisted currency to bot if any exist var currencyItems = botJsonTemplate.BotGeneration?.Items?.Currency?.Whitelist ?? new Dictionary(); // No currency whitelist, find and assign from combined item pool if (!currencyItems.Any()) - { foreach (var itemKvP in combinedLootPool) { var itemTemplate = _itemHelper.GetItem(itemKvP.Key).Value; - if (_itemHelper.IsOfBaseclass(itemTemplate.Id, BaseClasses.MONEY)) - { - currencyItems[itemKvP.Key] = itemKvP.Value; - } + if (_itemHelper.IsOfBaseclass(itemTemplate.Id, BaseClasses.MONEY)) currencyItems[itemKvP.Key] = itemKvP.Value; } - } // Assign whitelisted stims to bot if any exist var stimItems = botJsonTemplate.BotGeneration?.Items?.Stims?.Whitelist ?? new Dictionary(); // No whitelist, find and assign from combined item pool if (!stimItems.Any()) - { foreach (var itemKvP in combinedLootPool) { var itemTemplate = _itemHelper.GetItem(itemKvP.Key).Value; - if (IsMedicalItem(itemTemplate.Properties) && itemTemplate.Parent == BaseClasses.STIMULATOR) - { - stimItems[itemKvP.Key] = itemKvP.Value; - } + if (IsMedicalItem(itemTemplate.Properties) && itemTemplate.Parent == BaseClasses.STIMULATOR) stimItems[itemKvP.Key] = itemKvP.Value; } - } // Assign whitelisted grenades to bot if any exist var grenadeItems = botJsonTemplate.BotGeneration?.Items?.Grenades?.Whitelist ?? new Dictionary(); // no whitelist, find and assign from combined item pool if (!grenadeItems.Any()) - { foreach (var itemKvP in combinedLootPool) { var itemTemplate = _itemHelper.GetItem(itemKvP.Key).Value; - if (IsGrenade(itemTemplate.Properties)) - { - grenadeItems[itemKvP.Key] = itemKvP.Value; - } + if (IsGrenade(itemTemplate.Properties)) grenadeItems[itemKvP.Key] = itemKvP.Value; } - } // Get backpack loot (excluding magazines, bullets, grenades, drink, food and healing/stim items) var filteredBackpackItems = new Dictionary(); foreach (var itemKvP in backpackLootPool) { var itemResult = _itemHelper.GetItem(itemKvP.Key); - if (itemResult.Value is null) - { - continue; - } + if (itemResult.Value is null) continue; var itemTemplate = itemResult.Value; if ( - IsBulletOrGrenade(itemTemplate.Properties) || - IsMagazine(itemTemplate.Properties) || - IsMedicalItem(itemTemplate.Properties) || - IsGrenade(itemTemplate.Properties) || - IsFood(itemTemplate.Id) || - IsDrink(itemTemplate.Id) || - IsCurrency(itemTemplate.Id) - ) - { + IsBulletOrGrenade(itemTemplate.Properties) || + IsMagazine(itemTemplate.Properties) || + IsMedicalItem(itemTemplate.Properties) || + IsGrenade(itemTemplate.Properties) || + IsFood(itemTemplate.Id) || + IsDrink(itemTemplate.Id) || + IsCurrency(itemTemplate.Id) + ) // Is type we don't want as backpack loot, skip continue; - } filteredBackpackItems[itemKvP.Key] = itemKvP.Value; } @@ -396,10 +339,7 @@ public class BotLootCacheService( foreach (var itemKvP in pocketLootPool) { var itemResult = _itemHelper.GetItem(itemKvP.Key); - if (itemResult.Value is null) - { - continue; - } + if (itemResult.Value is null) continue; var itemTemplate = itemResult.Value; if ( @@ -413,9 +353,7 @@ public class BotLootCacheService( itemTemplate.Properties.Height is null || // lacks height itemTemplate.Properties.Width is null // lacks width ) - { continue; - } filteredPocketItems[itemKvP.Key] = itemKvP.Value; } @@ -425,10 +363,7 @@ public class BotLootCacheService( foreach (var itemKvP in vestLootPool) { var itemResult = _itemHelper.GetItem(itemKvP.Key); - if (itemResult.Value is null) - { - continue; - } + if (itemResult.Value is null) continue; var itemTemplate = itemResult.Value; if ( @@ -440,9 +375,7 @@ public class BotLootCacheService( IsDrink(itemTemplate.Id) || IsCurrency(itemTemplate.Id) ) - { continue; - } filteredVestItems[itemKvP.Key] = itemKvP.Value; } @@ -490,10 +423,7 @@ public class BotLootCacheService( foreach (var tpl in poolOfItemsToAdd) { // Skip adding items that already exist - if (poolToAddTo.ContainsKey(tpl.Key)) - { - continue; - } + if (poolToAddTo.ContainsKey(tpl.Key)) continue; poolToAddTo[tpl.Key] = poolOfItemsToAdd[tpl.Key]; } @@ -562,7 +492,9 @@ public class BotLootCacheService( protected bool BotRoleExistsInCache(string botRole) { lock (_lock) + { return _lootCache.ContainsKey(botRole); + } } /// @@ -573,23 +505,26 @@ public class BotLootCacheService( { lock (_lock) { - _lootCache.Add(botRole, new() - { - BackpackLoot = new(), - PocketLoot = new(), - VestLoot = new(), - SecureLoot = new(), - CombinedPoolLoot = new(), + _lootCache.Add( + botRole, + new BotLootCache + { + BackpackLoot = new Dictionary(), + PocketLoot = new Dictionary(), + VestLoot = new Dictionary(), + SecureLoot = new Dictionary(), + CombinedPoolLoot = new Dictionary(), - SpecialItems = new(), - GrenadeItems = new(), - DrugItems = new(), - FoodItems = new(), - DrinkItems = new(), - CurrencyItems = new(), - HealingItems = new(), - StimItems = new(), - }); + SpecialItems = new Dictionary(), + GrenadeItems = new Dictionary(), + DrugItems = new Dictionary(), + FoodItems = new Dictionary(), + DrinkItems = new Dictionary(), + CurrencyItems = new Dictionary(), + HealingItems = new Dictionary(), + StimItems = new Dictionary() + } + ); } } @@ -602,25 +537,13 @@ public class BotLootCacheService( protected int CompareByValue(int itemAPrice, int itemBPrice) { // If item A has no price, it should be moved to the back when sorting - if (itemAPrice is 0) - { - return 1; - } + if (itemAPrice is 0) return 1; - if (itemBPrice is 0) - { - return -1; - } + if (itemBPrice is 0) return -1; - if (itemAPrice < itemBPrice) - { - return -1; - } + if (itemAPrice < itemBPrice) return -1; - if (itemAPrice > itemBPrice) - { - return 1; - } + if (itemAPrice > itemBPrice) return 1; return 0; } diff --git a/Libraries/Core/Services/BotNameService.cs b/Libraries/Core/Services/BotNameService.cs index 65da85ef..23574712 100644 --- a/Libraries/Core/Services/BotNameService.cs +++ b/Libraries/Core/Services/BotNameService.cs @@ -21,8 +21,8 @@ public class BotNameService( ) { protected BotConfig _botConfig = _configServer.GetConfig(); - protected HashSet _usedNameCache = new HashSet(); protected object _lock = new(); + protected HashSet _usedNameCache = new(); /// /// Clear out any entries in Name Set @@ -56,17 +56,14 @@ public class BotNameService( while (attempts <= 5) { // Get bot name with leading/trailing whitespace removed - var name = (isPmc.GetValueOrDefault(false)) // Explicit handling of PMCs, all other bots will get "first_name last_name" + var name = isPmc.GetValueOrDefault(false) // Explicit handling of PMCs, all other bots will get "first_name last_name" ? _botHelper.GetPmcNicknameOfMaxLength(_botConfig.BotNameLengthLimit, botGenerationDetails.Side) : $"{_randomUtil.GetArrayValue(botJsonTemplate.FirstNames)} {(botJsonTemplate.LastNames.Count > 0 ? _randomUtil.GetArrayValue(botJsonTemplate.LastNames) : "")}"; name = name.Trim(); // Config is set to add role to end of bot name - if (showTypeInNickname) - { - name += $" {botRole}"; - } + if (showTypeInNickname) name += $" {botRole}"; // Replace pmc bot names with player name + prefix if (botGenerationDetails.IsPmc.GetValueOrDefault(false) && botGenerationDetails.AllPmcsHaveSameNameAsPlayer.GetValueOrDefault(false)) @@ -77,7 +74,6 @@ public class BotNameService( // Is this a role that must be unique if (roleShouldBeUnique.GetValueOrDefault(false)) - { // Check name in cache if (CacheContainsName(name)) { @@ -87,9 +83,7 @@ public class BotNameService( // 5 attempts to generate a name, pool probably isn't big enough var genericName = $"{botGenerationDetails.Side} {_randomUtil.GetInt(100000, 999999)}"; if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug($"Failed to find unique name for: {botRole} {botGenerationDetails.Side} after 5 attempts, using: {genericName}"); - } return genericName; } @@ -99,7 +93,6 @@ public class BotNameService( // Try again continue; } - } // Add bot name to cache to prevent being used again AddNameToCache(name); diff --git a/Libraries/Core/Services/BotWeaponModLimitService.cs b/Libraries/Core/Services/BotWeaponModLimitService.cs index b4b53c23..c0f4ac70 100644 --- a/Libraries/Core/Services/BotWeaponModLimitService.cs +++ b/Libraries/Core/Services/BotWeaponModLimitService.cs @@ -26,9 +26,9 @@ public class BotWeaponModLimitService( /// BotModLimits object public BotModLimits GetWeaponModLimits(string botRole) { - return new() + return new BotModLimits { - Scope = new() { Count = 0 }, + Scope = new ItemCount { Count = 0 }, ScopeMax = _botConfig.Equipment[botRole]?.WeaponModLimits?.ScopeLimit, ScopeBaseTypes = [ @@ -38,13 +38,13 @@ public class BotWeaponModLimitService( BaseClasses.COMPACT_COLLIMATOR, BaseClasses.SPECIAL_SCOPE ], - FlashlightLaser = new() { Count = 0 }, + FlashlightLaser = new ItemCount { Count = 0 }, FlashlightLaserMax = _botConfig.Equipment[botRole]?.WeaponModLimits?.LightLaserLimit, FlashlightLaserBaseTypes = [ BaseClasses.TACTICAL_COMBO, BaseClasses.FLASHLIGHT, - BaseClasses.PORTABLE_RANGE_FINDER, + BaseClasses.PORTABLE_RANGE_FINDER ] }; } @@ -80,29 +80,21 @@ public class BotWeaponModLimitService( [ BaseClasses.ASSAULT_SCOPE, BaseClasses.OPTIC_SCOPE, - BaseClasses.SPECIAL_SCOPE, + BaseClasses.SPECIAL_SCOPE ] ) )) - { return false; - } return true; } // Mods parent is scope and mod is scope, allow it (adds those mini-sights to the tops of sights) var modIsScope = _itemHelper.IsOfBaseclasses(modTemplate.Id, modLimits.ScopeBaseTypes); - if (_itemHelper.IsOfBaseclasses(modsParent.Id, modLimits.ScopeBaseTypes) && modIsScope) - { - return false; - } + if (_itemHelper.IsOfBaseclasses(modsParent.Id, modLimits.ScopeBaseTypes) && modIsScope) return false; // If mod is a scope , Exit early - if (modIsScope) - { - return WeaponModLimitReached(modTemplate.Id, modLimits.Scope, modLimits.ScopeMax ?? 0, botRole); - } + if (modIsScope) return WeaponModLimitReached(modTemplate.Id, modLimits.Scope, modLimits.ScopeMax ?? 0, botRole); // Don't allow multple mounts on a weapon (except when mount is on another mount) // Fail when: @@ -115,21 +107,17 @@ public class BotWeaponModLimitService( !_itemHelper.IsOfBaseclass(modsParent.Id, BaseClasses.MOUNT) && modTemplate.Properties.Slots.Any((slot) => slot.Name == "mod_scope") ) - { return true; - } // If mod is a light/laser, return if limit reached var modIsLightOrLaser = _itemHelper.IsOfBaseclasses(modTemplate.Id, modLimits.FlashlightLaserBaseTypes); if (modIsLightOrLaser) - { return WeaponModLimitReached( modTemplate.Id, modLimits.FlashlightLaser, modLimits.FlashlightLaserMax ?? 0, botRole ); - } // Mod is a mount that can hold only flashlights ad limit is reached (dont want to add empty mounts if limit is reached) if (modLimits.Scope.Count >= modLimits.ScopeMax && @@ -137,9 +125,7 @@ public class BotWeaponModLimitService( _itemHelper.IsOfBaseclass(modTemplate.Id, BaseClasses.MOUNT) && modTemplate.Properties.Slots.Any((slot) => slot.Name == "mod_flashlight") ) - { return true; - } return false; } @@ -159,18 +145,13 @@ public class BotWeaponModLimitService( string botRole) { // No value or 0 - if (maxLimit is null || maxLimit is 0) - { - return false; - } + if (maxLimit is null || maxLimit is 0) return false; // Has mod limit for bot type been reached if (currentCount.Count >= maxLimit) { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug($"[{botRole}] scope limit reached! tried to add {modTpl} but scope count is {currentCount.Count}"); - } return true; } diff --git a/Libraries/Core/Services/Cache/BundleHashCacheService.cs b/Libraries/Core/Services/Cache/BundleHashCacheService.cs index ac740e55..27b5bae1 100644 --- a/Libraries/Core/Services/Cache/BundleHashCacheService.cs +++ b/Libraries/Core/Services/Cache/BundleHashCacheService.cs @@ -11,10 +11,10 @@ public class BundleHashCacheService( HashUtil _hashUtil, JsonUtil _jsonUtil, FileUtil _fileUtil - ) +) { - protected Dictionary _bundleHashes = new(); protected readonly string _bundleHashCachePath = "./user/cache/bundleHashCache.json"; + protected Dictionary _bundleHashes = new(); public string GetStoredValue(string key) { @@ -29,10 +29,7 @@ public class BundleHashCacheService( _fileUtil.WriteFile(_bundleHashCachePath, _jsonUtil.Serialize(_bundleHashes)); - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Bundle {key} hash stored in {_bundleHashCachePath}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Bundle {key} hash stored in {_bundleHashCachePath}"); } public bool MatchWithStoredHash(string bundlePath, string hash) diff --git a/Libraries/Core/Services/Cache/ModHashCacheService.cs b/Libraries/Core/Services/Cache/ModHashCacheService.cs index dc131634..d4e4c6b0 100644 --- a/Libraries/Core/Services/Cache/ModHashCacheService.cs +++ b/Libraries/Core/Services/Cache/ModHashCacheService.cs @@ -4,16 +4,17 @@ using SptCommon.Annotations; using LogLevel = Core.Models.Spt.Logging.LogLevel; namespace Core.Services.Cache; + [Injectable] public class ModHashCacheService( ISptLogger _logger, JsonUtil _jsonUtil, HashUtil _hashUtil, FileUtil _fileUtil - ) +) { - protected readonly Dictionary _modHashes = new(); protected readonly string _modCachePath = "./user/cache/modCache.json"; + protected readonly Dictionary _modHashes = new(); public string? GetStoredValue(string key) { @@ -28,10 +29,7 @@ public class ModHashCacheService( _fileUtil.WriteFile(_modCachePath, _jsonUtil.Serialize(_modHashes)); - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Mod {key} hash stored in: {_modCachePath}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Mod {key} hash stored in: {_modCachePath}"); } public bool MatchWithStoredHash(string modName, string hash) diff --git a/Libraries/Core/Services/CircleOfCultistService.cs b/Libraries/Core/Services/CircleOfCultistService.cs index 32841437..1548872a 100644 --- a/Libraries/Core/Services/CircleOfCultistService.cs +++ b/Libraries/Core/Services/CircleOfCultistService.cs @@ -39,8 +39,8 @@ public class CircleOfCultistService( ConfigServer _configServer ) { - protected HideoutConfig _hideoutConfig = _configServer.GetConfig(); protected const string CircleOfCultistSlotId = "CircleOfCultistsGrid1"; + protected HideoutConfig _hideoutConfig = _configServer.GetConfig(); /// /// Start a sacrifice event @@ -97,12 +97,8 @@ public class CircleOfCultistService( // Remove sacrificed items from circle inventory foreach (var item in sacrificedItems) - { if (item.SlotId == CircleOfCultistSlotId) - { _inventoryHelper.RemoveItem(pmcData, item.Id, sessionId, output); - } - } var rewards = hasDirectReward ? GetDirectRewards(sessionId, directRewardSettings, cultistCircleStashId) @@ -134,10 +130,8 @@ public class CircleOfCultistService( // Adjust value generated by the players hideout management skill var hideoutManagementSkill = _profileHelper.GetSkillFromProfile(pmcData, SkillTypes.HideoutManagement); if (hideoutManagementSkill is not null) - { rewardAmountMultiplier *= (float)(1 + hideoutManagementSkill.Progress / 10000); // 5100 becomes 0.51, add 1 to it, 1.51, multiply the bonus by it (e.g. 1.2 x 1.51) - } return rewardAmountMultiplier; } @@ -190,7 +184,7 @@ public class CircleOfCultistService( Time = -1, RewardType = CircleRewardType.RANDOM, RewardAmountRoubles = (int)rewardAmountRoubles, - RewardDetails = null, + RewardDetails = null }; // Direct reward edge case @@ -357,7 +351,7 @@ public class CircleOfCultistService( // Not a weapon/armor, standard single item List rewardItem = [ - new Item + new() { Id = _hashUtil.Generate(), Template = randomItemTplFromPool, @@ -365,9 +359,9 @@ public class CircleOfCultistService( SlotId = CircleOfCultistSlotId, Upd = new Upd { - StackObjectsCount = stackSize, - }, - }, + StackObjectsCount = stackSize + } + } ]; _itemHelper.SetFoundInRaid(rewardItem); @@ -409,9 +403,7 @@ public class CircleOfCultistService( // Handle special case of tagilla helmets - only one reward is allowed if (directReward.Reward.Contains(ItemTpl.FACECOVER_TAGILLAS_WELDING_MASK_GORILLA)) - { directReward.Reward = [_randomUtil.GetArrayValue(directReward.Reward)]; - } // Loop because these can include multiple rewards foreach (var rewardTpl in directReward.Reward) @@ -446,7 +438,7 @@ public class CircleOfCultistService( var stackSize = GetDirectRewardBaseTypeStackSize(rewardTpl); List rewardItem = [ - new Item + new() { Id = _hashUtil.Generate(), Template = rewardTpl, @@ -454,9 +446,9 @@ public class CircleOfCultistService( SlotId = CircleOfCultistSlotId, Upd = new Upd { - StackObjectsCount = stackSize, - }, - }, + StackObjectsCount = stackSize + } + } ]; _itemHelper.SetFoundInRaid(rewardItem); @@ -472,10 +464,7 @@ public class CircleOfCultistService( } // Direct reward is not repeatable, flag collected in profile - if (!directReward.Repeatable) - { - FlagDirectRewardAsAcceptedInProfile(sessionId, directReward); - } + if (!directReward.Repeatable) FlagDirectRewardAsAcceptedInProfile(sessionId, directReward); return rewards; } @@ -500,18 +489,14 @@ public class CircleOfCultistService( var matchingDirectReward = directRewardsCache.GetValueOrDefault(sacrificedItemsKey); if (matchingDirectReward is null) - { // No direct reward return null; - } var fullProfile = _profileHelper.GetFullProfile(sessionId); var directRewardHash = GetDirectRewardHashKey(matchingDirectReward); if (fullProfile.SptData.CultistRewards?.ContainsKey(directRewardHash) ?? false) - { // Player has already received this direct reward return null; - } return matchingDirectReward; } @@ -551,10 +536,7 @@ public class CircleOfCultistService( // Look for parent in dict var settings = _hideoutConfig.CultistCircle.DirectRewardStackSize.GetValueOrDefault(itemDetails.Value.Parent); - if (settings is null) - { - return 1; - } + if (settings is null) return 1; return _randomUtil.GetInt((int)settings.Min, (int)settings.Max); } @@ -567,11 +549,11 @@ public class CircleOfCultistService( protected void FlagDirectRewardAsAcceptedInProfile(string sessionId, DirectRewardSettings directReward) { var fullProfile = _profileHelper.GetFullProfile(sessionId); - AcceptedCultistReward dataToStoreInProfile = new AcceptedCultistReward + var dataToStoreInProfile = new AcceptedCultistReward { Timestamp = _timeUtil.GetTimeStamp(), SacrificeItems = directReward.RequiredItems, - RewardItems = directReward.Reward, + RewardItems = directReward.Reward }; fullProfile.SptData.CultistRewards[GetDirectRewardHashKey(directReward)] = dataToStoreInProfile; @@ -607,7 +589,7 @@ public class CircleOfCultistService( var currencyPriceAsRouble = _itemHelper.GetItemPrice(itemTpl); // How many items can we fit into chosen pool - var itemCountToReward = Math.Round((roubleAmountToFill / currencyPriceAsRouble) ?? 0); + var itemCountToReward = Math.Round(roubleAmountToFill / currencyPriceAsRouble ?? 0); return (int)itemCountToReward; } @@ -665,9 +647,7 @@ public class CircleOfCultistService( // If we have no tasks or hideout stuff left or need more loot to fill it out, default to high value if (rewardPool.Count < cultistCircleConfig.MaxRewardItemCount + 2) - { GenerateRandomisedItemsAndAddToRewardPool(rewardPool, itemRewardBlacklist, true); - } break; } @@ -675,18 +655,13 @@ public class CircleOfCultistService( // Add custom rewards from config if (cultistCircleConfig.AdditionalRewardItemPool.Count > 0) - { foreach (var additionalReward in cultistCircleConfig.AdditionalRewardItemPool) { - if (itemRewardBlacklist.Contains(additionalReward)) - { - continue; - } + if (itemRewardBlacklist.Contains(additionalReward)) continue; // Add tpl to reward pool rewardPool.Add(additionalReward); } - } return rewardPool.ToList(); } @@ -710,21 +685,13 @@ public class CircleOfCultistService( (condition) => condition.ConditionType == "HandoverItem" ); foreach (var condition in handoverConditions) + foreach (var neededItem in condition.Target.List) { - foreach (var neededItem in condition.Target.List) - { - if (itemRewardBlacklist.Contains(neededItem) || !_itemHelper.IsValidItem(neededItem)) - { - continue; - } + if (itemRewardBlacklist.Contains(neededItem) || !_itemHelper.IsValidItem(neededItem)) continue; - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Added Task Loot: {_itemHelper.GetItemName(neededItem)}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Added Task Loot: {_itemHelper.GetItemName(neededItem)}"); - rewardPool.Add(neededItem); - } + rewardPool.Add(neededItem); } } } @@ -758,18 +725,13 @@ public class CircleOfCultistService( foreach (var rewardToAdd in itemRequirements) { if ( - itemRewardBlacklist.Contains(rewardToAdd.TemplateId) || - !_itemHelper.IsValidItem(rewardToAdd.TemplateId) - ) - { + itemRewardBlacklist.Contains(rewardToAdd.TemplateId) || + !_itemHelper.IsValidItem(rewardToAdd.TemplateId) + ) // Dont reward items sacrificed continue; - } - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Added Hideout Loot: {_itemHelper.GetItemName(rewardToAdd.TemplateId)}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Added Hideout Loot: {_itemHelper.GetItemName(rewardToAdd.TemplateId)}"); rewardPool.Add(rewardToAdd.TemplateId); } @@ -788,10 +750,8 @@ public class CircleOfCultistService( (area) => { if (area.Type == HideoutAreas.CHRISTMAS_TREE && !_seasonalEventService.ChristmasEventEnabled()) - { // Christmas tree area and not Christmas, skip return false; - } return true; } @@ -822,25 +782,16 @@ public class CircleOfCultistService( { attempts++; var randomItem = _randomUtil.GetArrayValue(allItems); - if (itemRewardBlacklist.Contains(randomItem.Id) || !_itemHelper.IsValidItem(randomItem.Id)) - { - continue; - } + if (itemRewardBlacklist.Contains(randomItem.Id) || !_itemHelper.IsValidItem(randomItem.Id)) continue; // Valuable check if (itemsShouldBeHighValue) { var itemValue = _itemHelper.GetItemMaxPrice(randomItem.Id); - if (itemValue < _hideoutConfig.CultistCircle.HighValueThresholdRub) - { - continue; - } + if (itemValue < _hideoutConfig.CultistCircle.HighValueThresholdRub) continue; } - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Added: {_itemHelper.GetItemName(randomItem.Id)}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Added: {_itemHelper.GetItemName(randomItem.Id)}"); rewardPool.Add(randomItem.Id); currentItemCount++; @@ -916,10 +867,7 @@ public class CircleOfCultistService( ); // Doesn't fit, remove one item - if (!canAddToContainer) - { - rewards.PopLast(); - } + if (!canAddToContainer) rewards.PopLast(); } foreach (var itemToAdd in rewards) diff --git a/Libraries/Core/Services/CreateProfileService.cs b/Libraries/Core/Services/CreateProfileService.cs index 72912d8e..9f3fce9c 100644 --- a/Libraries/Core/Services/CreateProfileService.cs +++ b/Libraries/Core/Services/CreateProfileService.cs @@ -12,6 +12,7 @@ using Core.Servers; using Core.Utils; using Core.Utils.Cloners; using SptCommon.Extensions; +using Vitality = Core.Models.Eft.Profile.Vitality; namespace Core.Services; @@ -62,16 +63,13 @@ public class CreateProfileService( pmcData.Quests = []; pmcData.Hideout.Seed = _timeUtil.GetTimeStamp() + 8 * 60 * 60 * 24 * 365; // 8 years in future why? who knows, we saw it in live pmcData.RepeatableQuests = []; - pmcData.CarExtractCounts = new(); - pmcData.CoopExtractCounts = new(); - pmcData.Achievements = new(); + pmcData.CarExtractCounts = new Dictionary(); + pmcData.CoopExtractCounts = new Dictionary(); + pmcData.Achievements = new Dictionary(); UpdateInventoryEquipmentId(pmcData); - if (pmcData.UnlockedInfo == null) - { - pmcData.UnlockedInfo = new UnlockedInfo { UnlockedProductionRecipe = [] }; - } + if (pmcData.UnlockedInfo == null) pmcData.UnlockedInfo = new UnlockedInfo { UnlockedProductionRecipe = [] }; // Add required items to pmc stash AddMissingInternalContainersToProfile(pmcData); @@ -83,15 +81,15 @@ public class CreateProfileService( var profileDetails = new SptProfile { ProfileInfo = account, - CharacterData = new Characters { PmcData = pmcData, ScavData = new() }, + CharacterData = new Characters { PmcData = pmcData, ScavData = new PmcData() }, Suits = profileTemplate.Suits, UserBuildData = profileTemplate.UserBuilds, DialogueRecords = profileTemplate.Dialogues, SptData = _profileHelper.GetDefaultSptDataObject(), - VitalityData = new(), - InraidData = new(), + VitalityData = new Vitality(), + InraidData = new Inraid(), InsuranceList = [], - TraderPurchases = new(), + TraderPurchases = new Dictionary?>(), FriendProfileIds = [], CustomisationUnlocks = [] }; @@ -103,9 +101,7 @@ public class CreateProfileService( _saveServer.AddProfile(profileDetails); if (profileTemplate.Trader.SetQuestsAvailableForStart ?? false) - { _questHelper.AddAllQuestsToProfile(profileDetails.CharacterData.PmcData, [QuestStatusEnum.AvailableForStart]); - } // Profile is flagged as wanting quests set to ready to hand in and collect rewards if (profileTemplate.Trader.SetQuestsAvailableForFinish ?? false) @@ -115,12 +111,12 @@ public class CreateProfileService( [ QuestStatusEnum.AvailableForStart, QuestStatusEnum.Started, - QuestStatusEnum.AvailableForFinish, + QuestStatusEnum.AvailableForFinish ] ); // Make unused response so applyQuestReward works - ItemEventRouterResponse? response = _eventOutputHolder.GetOutput(sessionId); + var response = _eventOutputHolder.GetOutput(sessionId); // Add rewards for starting quests to profile GivePlayerStartingQuestRewards(profileDetails, sessionId, response); @@ -148,15 +144,11 @@ public class CreateProfileService( protected void DeleteProfileBySessionId(string sessionID) { if (_saveServer.GetProfiles().ContainsKey(sessionID)) - { _saveServer.DeleteProfileById(sessionID); - } else - { _logger.Warning( _localisationService.GetText("profile-unable_to_find_profile_by_id_cannot_delete", sessionID) ); - } } /** @@ -176,10 +168,7 @@ public class CreateProfileService( continue; } - if (item.Id == oldEquipmentId) - { - item.Id = pmcData.Inventory.Equipment; - } + if (item.Id == oldEquipmentId) item.Id = pmcData.Inventory.Equipment; } } @@ -189,10 +178,7 @@ public class CreateProfileService( */ protected void ResetAllTradersInProfile(string sessionId) { - foreach (var traderId in _databaseService.GetTraders().Keys) - { - _traderHelper.ResetTrader(sessionId, traderId); - } + foreach (var traderId in _databaseService.GetTraders().Keys) _traderHelper.ResetTrader(sessionId, traderId); } /** @@ -203,48 +189,40 @@ public class CreateProfileService( protected void AddMissingInternalContainersToProfile(PmcData pmcData) { if (!pmcData.Inventory.Items.Any((item) => item.Id == pmcData.Inventory.HideoutCustomizationStashId)) - { pmcData.Inventory.Items.Add( - new() + new Item { Id = pmcData.Inventory.HideoutCustomizationStashId, - Template = ItemTpl.HIDEOUTAREACONTAINER_CUSTOMIZATION, + Template = ItemTpl.HIDEOUTAREACONTAINER_CUSTOMIZATION } ); - } if (!pmcData.Inventory.Items.Any((item) => item.Id == pmcData.Inventory.SortingTable)) - { pmcData.Inventory.Items.Add( - new() + new Item { Id = pmcData.Inventory.SortingTable, - Template = ItemTpl.SORTINGTABLE_SORTING_TABLE, + Template = ItemTpl.SORTINGTABLE_SORTING_TABLE } ); - } if (!pmcData.Inventory.Items.Any((item) => item.Id == pmcData.Inventory.QuestStashItems)) - { pmcData.Inventory.Items.Add( - new() + new Item { Id = pmcData.Inventory.QuestStashItems, - Template = ItemTpl.STASH_QUESTOFFLINE, + Template = ItemTpl.STASH_QUESTOFFLINE } ); - } if (!pmcData.Inventory.Items.Any((item) => item.Id == pmcData.Inventory.QuestRaidItems)) - { pmcData.Inventory.Items.Add( - new() + new Item { Id = pmcData.Inventory.QuestRaidItems, - Template = ItemTpl.STASH_QUESTRAID, + Template = ItemTpl.STASH_QUESTRAID } ); - } } /// @@ -270,7 +248,7 @@ public class CreateProfileService( { Id = "6746fd09bafff85008048838", Source = CustomisationSource.DEFAULT, - Type = CustomisationType.DOG_TAG, + Type = CustomisationType.DOG_TAG } ); @@ -279,7 +257,7 @@ public class CreateProfileService( { Id = "67471938bafff850080488b7", Source = CustomisationSource.DEFAULT, - Type = CustomisationType.DOG_TAG, + Type = CustomisationType.DOG_TAG } ); @@ -291,7 +269,7 @@ public class CreateProfileService( { Id = "6746fd09bafff85008048838", Source = CustomisationSource.DEFAULT, - Type = CustomisationType.DOG_TAG, + Type = CustomisationType.DOG_TAG } ); @@ -300,7 +278,7 @@ public class CreateProfileService( { Id = "67471938bafff850080488b7", Source = CustomisationSource.DEFAULT, - Type = CustomisationType.DOG_TAG, + Type = CustomisationType.DOG_TAG } ); @@ -309,7 +287,7 @@ public class CreateProfileService( { Id = "67471928d17d6431550563b5", Source = CustomisationSource.DEFAULT, - Type = CustomisationType.DOG_TAG, + Type = CustomisationType.DOG_TAG } ); @@ -318,7 +296,7 @@ public class CreateProfileService( { Id = "6747193f170146228c0d2226", Source = CustomisationSource.DEFAULT, - Type = CustomisationType.DOG_TAG, + Type = CustomisationType.DOG_TAG } ); @@ -328,7 +306,7 @@ public class CreateProfileService( { Id = "666841a02537107dc508b704", Source = CustomisationSource.DEFAULT, - Type = CustomisationType.SUITE, + Type = CustomisationType.SUITE } ); @@ -338,7 +316,7 @@ public class CreateProfileService( { Id = "675850ba33627edb710b0592", Source = CustomisationSource.DEFAULT, - Type = CustomisationType.ENVIRONMENT, + Type = CustomisationType.ENVIRONMENT } ); @@ -349,43 +327,37 @@ public class CreateProfileService( if (pretigeLevel is not null) { if (pretigeLevel >= 1) - { fullProfile.CustomisationUnlocks.Add( new CustomisationStorage { Id = "674dbf593bee1152d407f005", Source = CustomisationSource.DEFAULT, - Type = CustomisationType.DOG_TAG, + Type = CustomisationType.DOG_TAG } ); - } if (pretigeLevel >= 2) - { fullProfile.CustomisationUnlocks.Add( new CustomisationStorage { Id = "675dcfea7ae1a8792107ca99", Source = CustomisationSource.DEFAULT, - Type = CustomisationType.DOG_TAG, + Type = CustomisationType.DOG_TAG } ); - } } // Dev profile additions if (fullProfile.ProfileInfo.Edition.ToLower().Contains("developer")) - { // CyberTark background fullProfile.CustomisationUnlocks.Add( new CustomisationStorage { Id = "67585108def253bd97084552", Source = CustomisationSource.DEFAULT, - Type = CustomisationType.ENVIRONMENT, + Type = CustomisationType.ENVIRONMENT } ); - } } /** @@ -394,10 +366,7 @@ public class CreateProfileService( private string? GetGameEdition(SptProfile profile) { var edition = profile.CharacterData?.PmcData?.Info?.GameVersion; - if (edition is not null) - { - return edition; - } + if (edition is not null) return edition; // Edge case - profile not created yet, fall back to what launcher has set var launcherEdition = profile.ProfileInfo.Edition; @@ -436,12 +405,13 @@ public class CreateProfileService( questFromDb.Description ); var itemRewards = _questRewardHelper.ApplyQuestReward( - profileDetails.CharacterData.PmcData, - quest.QId, - QuestStatusEnum.Started, - sessionID, - response - ).ToList(); + profileDetails.CharacterData.PmcData, + quest.QId, + QuestStatusEnum.Started, + sessionID, + response + ) + .ToList(); _mailSendService.SendLocalisedNpcMessageToPlayer( diff --git a/Libraries/Core/Services/CustomLocationWaveService.cs b/Libraries/Core/Services/CustomLocationWaveService.cs index ba820ebf..56048aed 100644 --- a/Libraries/Core/Services/CustomLocationWaveService.cs +++ b/Libraries/Core/Services/CustomLocationWaveService.cs @@ -74,18 +74,14 @@ public class CustomLocationWaveService( foreach (var bossWave in mapKvP.Value) { if (locationBase.BossLocationSpawn.Any(x => x.SptId == bossWave.SptId)) - { // Already exists, skip continue; - } locationBase.BossLocationSpawn.Add(bossWave); if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug( $"Added custom boss wave to {mapKvP.Key} of type {bossWave.BossName}, time: {bossWave.Time}, chance: {bossWave.BossChance}, zone: {(string.IsNullOrEmpty(bossWave.BossZone) ? "Global" : bossWave.BossZone)}" ); - } } } @@ -102,10 +98,8 @@ public class CustomLocationWaveService( foreach (var normalWave in mapKvP.Value) { if (locationBase.Waves.Any(x => x.SptId == normalWave.SptId)) - { // Already exists, skip continue; - } normalWave.Number = locationBase.Waves.Count; locationBase.Waves.Add(normalWave); diff --git a/Libraries/Core/Services/DatabaseService.cs b/Libraries/Core/Services/DatabaseService.cs index b686292f..3c31ed89 100644 --- a/Libraries/Core/Services/DatabaseService.cs +++ b/Libraries/Core/Services/DatabaseService.cs @@ -24,7 +24,7 @@ public class DatabaseService( ) { protected bool isDataValid = true; - + /** * @returns assets/database/ */ @@ -313,10 +313,7 @@ public class DatabaseService( if (!isDataValid) _logger.Error(_localisationService.GetText("database-invalid_data")); start.Stop(); - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"ID validation took: {start.ElapsedMilliseconds}ms"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"ID validation took: {start.ElapsedMilliseconds}ms"); } /** diff --git a/Libraries/Core/Services/FenceService.cs b/Libraries/Core/Services/FenceService.cs index 35efb603..032e7829 100644 --- a/Libraries/Core/Services/FenceService.cs +++ b/Libraries/Core/Services/FenceService.cs @@ -28,10 +28,8 @@ public class FenceService( ICloner _cloner ) { - protected TraderConfig traderConfig = configServer.GetConfig(); - - /** Time when some items in assort will be replaced */ - protected long nextPartialRefreshTimestamp; + /** Desired baseline counts - Hydrated on initial assort generation as part of generateFenceAssorts() */ + protected FenceAssortGenerationValues desiredAssortCounts; /** Main assorts you see at all rep levels */ protected TraderAssort? fenceAssort = null; @@ -39,9 +37,6 @@ public class FenceService( /** Assorts shown on a separate tab when you max out fence rep */ protected TraderAssort? fenceDiscountAssort = null; - /** Desired baseline counts - Hydrated on initial assort generation as part of generateFenceAssorts() */ - protected FenceAssortGenerationValues desiredAssortCounts; - protected HashSet fenceItemUpdCompareProperties = [ "Buff", @@ -52,9 +47,14 @@ public class FenceService( "MedKit", "FoodDrink", "Dogtag", - "RepairKit", + "RepairKit" ]; + /** Time when some items in assort will be replaced */ + protected long nextPartialRefreshTimestamp; + + protected TraderConfig traderConfig = configServer.GetConfig(); + /** * Replace main fence assort with new assort @@ -110,10 +110,8 @@ public class FenceService( public TraderAssort GetFenceAssorts(PmcData pmcProfile) { if (traderConfig.Fence.RegenerateAssortsOnRefresh) - { // Using base assorts made earlier, do some alterations and store in fenceAssort GenerateFenceAssorts(); - } // Clone assorts so we can adjust prices before sending to client var assort = _cloner.Clone(fenceAssort); @@ -153,17 +151,14 @@ public class FenceService( // Fix IDs clonedItems = itemHelper.ReparentItemAndChildren(root, clonedItems); root.ParentId = "hideout"; - if (root.Upd?.SpawnedInSession != null) - { - root.Upd.SpawnedInSession = false; - } + if (root.Upd?.SpawnedInSession != null) root.Upd.SpawnedInSession = false; // Clean up the items // We may need to find an alternative to nodes: delete root.location; root.Location = null; var createAssort = new CreateFenceAssortsResult() - { SptItems = [], BarterScheme = new(), LoyalLevelItems = new() }; + { SptItems = [], BarterScheme = new Dictionary>>(), LoyalLevelItems = new Dictionary() }; createAssort.BarterScheme[root.Id] = [[new BarterScheme() { Count = cost, Template = Money.ROUBLES }]]; createAssort.SptItems.Add(clonedItems); createAssort.LoyalLevelItems[root.Id] = 1; @@ -194,12 +189,8 @@ public class FenceService( { double? total = 0D; foreach (var item in items) - { if (itemHelper.IsOfBaseclass(item.Template, BaseClasses.AMMO)) - { total += handbookHelper.GetTemplatePrice(item.Template) * (item.Upd?.StackObjectsCount ?? 1); - } - } return total; } @@ -217,10 +208,7 @@ public class FenceService( ) { // Only get root items - foreach (var item in assort.Items.Where(x => x.SlotId is "hideout")) - { - AdjustItemPriceByModifier(item, assort, itemMultiplier, presetMultiplier); - } + foreach (var item in assort.Items.Where(x => x.SlotId is "hideout")) AdjustItemPriceByModifier(item, assort, itemMultiplier, presetMultiplier); } /** @@ -231,20 +219,11 @@ public class FenceService( */ protected TraderAssort MergeAssorts(TraderAssort firstAssort, TraderAssort secondAssort) { - foreach (var itemId in secondAssort.BarterScheme.Keys) - { - firstAssort.BarterScheme[itemId] = secondAssort.BarterScheme[itemId]; - } + foreach (var itemId in secondAssort.BarterScheme.Keys) firstAssort.BarterScheme[itemId] = secondAssort.BarterScheme[itemId]; - foreach (var item in secondAssort.Items) - { - firstAssort.Items.Add(item); - } + foreach (var item in secondAssort.Items) firstAssort.Items.Add(item); - foreach (var itemId in secondAssort.LoyalLevelItems.Keys) - { - firstAssort.LoyalLevelItems[itemId] = secondAssort.LoyalLevelItems[itemId]; - } + foreach (var itemId in secondAssort.LoyalLevelItems.Keys) firstAssort.LoyalLevelItems[itemId] = secondAssort.LoyalLevelItems[itemId]; return firstAssort; } @@ -273,23 +252,16 @@ public class FenceService( // Is preset if (item.Upd?.SptPresetId != null) { - if (assort.BarterScheme.TryGetValue(item.Id, out var barterSchemeForPreset)) - { - barterSchemeForPreset[0][0].Count *= presetModifier; - } + if (assort.BarterScheme.TryGetValue(item.Id, out var barterSchemeForPreset)) barterSchemeForPreset[0][0].Count *= presetModifier; return; } // Normal item if (assort.BarterScheme.TryGetValue(item.Id, out var barterScheme)) - { barterScheme[0][0].Count *= modifier; - } else - { logger.Warning($"adjustItemPriceByModifier() - no action taken for item: {item.Template}"); - } } /** @@ -343,28 +315,18 @@ public class FenceService( UpdateFenceAssorts(newDiscountItems, fenceDiscountAssort); // Add new barter items to fence barter scheme - foreach (var barterItemKey in newItems.BarterScheme.Keys) - { - fenceAssort.BarterScheme[barterItemKey] = newItems.BarterScheme[barterItemKey]; - } + foreach (var barterItemKey in newItems.BarterScheme.Keys) fenceAssort.BarterScheme[barterItemKey] = newItems.BarterScheme[barterItemKey]; // Add loyalty items to fence assorts loyalty object - foreach (var loyaltyItemKey in newItems.LoyalLevelItems.Keys) - { - fenceAssort.LoyalLevelItems[loyaltyItemKey] = newItems.LoyalLevelItems[loyaltyItemKey]; - } + foreach (var loyaltyItemKey in newItems.LoyalLevelItems.Keys) fenceAssort.LoyalLevelItems[loyaltyItemKey] = newItems.LoyalLevelItems[loyaltyItemKey]; // Add new barter items to fence assorts discounted barter scheme foreach (var barterItemKey in newDiscountItems.BarterScheme.Keys) - { fenceDiscountAssort.BarterScheme[barterItemKey] = newDiscountItems.BarterScheme[barterItemKey]; - } // Add loyalty items to fence discount assorts loyalty object foreach (var loyaltyItemKey in newDiscountItems.LoyalLevelItems.Keys) - { fenceDiscountAssort.LoyalLevelItems[loyaltyItemKey] = newDiscountItems.LoyalLevelItems[loyaltyItemKey]; - } // Reset the clock IncrementPartialRefreshTime(); @@ -408,10 +370,7 @@ public class FenceService( if (itemHelper.IsSameItems(itemWithChildren, existingFullItemTree, fenceItemUpdCompareProperties)) { // Guard against a missing stack count - if (existingRootItem.Upd?.StackObjectsCount == null) - { - existingRootItem.Upd.StackObjectsCount = 1; - } + if (existingRootItem.Upd?.StackObjectsCount == null) existingRootItem.Upd.StackObjectsCount = 1; // Merge new items count into existing, dont add new loyalty/barter data as it already exists existingRootItem.Upd.StackObjectsCount += newRootItem?.Upd?.StackObjectsCount ?? 1; @@ -421,10 +380,7 @@ public class FenceService( } // if the Upd doesnt exist just initialize it - if (newRootItem.Upd == null) - { - newRootItem.Upd = new(); - } + if (newRootItem.Upd == null) newRootItem.Upd = new Upd(); // New assort to be added to existing assorts existingFenceAssorts.Items.AddRange(itemWithChildren); @@ -496,10 +452,7 @@ public class FenceService( if (assort?.Items?.Count > 0) { var rootItems = assort.Items.Where((item) => item.SlotId == "hideout").ToList(); - for (var index = 0; index < itemCountToReplace; index++) - { - RemoveRandomItemFromAssorts(assort, rootItems); - } + for (var index = 0; index < itemCountToReplace; index++) RemoveRandomItemFromAssorts(assort, rootItems); } } @@ -528,7 +481,7 @@ public class FenceService( if (rootItemToAdjust.Upd == null) { logger.Warning($"Fence Item: {rootItemToAdjust.Template} lacks a Upd object, adding"); - rootItemToAdjust.Upd = new(); + rootItemToAdjust.Upd = new Upd(); } // Reduce stack to at smallest, 1 @@ -540,10 +493,8 @@ public class FenceService( // Remove item + child mods (if any) var itemWithChildren = itemHelper.FindAndReturnChildrenAsItems(assort.Items, rootItemToAdjust.Id); foreach (var itemToDelete in itemWithChildren) - { // Delete item from assort items array assort.Items.Remove(itemToDelete); - } // Need to remove item from all areas of trader assort // delete assort.barter_scheme[rootItemToAdjust._id]; @@ -568,10 +519,7 @@ public class FenceService( */ public int GetOfferCount() { - if ((fenceAssort?.Items?.Count ?? 0) == 0) - { - return 0; - } + if ((fenceAssort?.Items?.Count ?? 0) == 0) return 0; return fenceAssort.Items.Count; } @@ -609,10 +557,7 @@ public class FenceService( protected TraderAssort ConvertIntoFenceAssort(CreateFenceAssortsResult intermediaryAssorts) { var result = CreateFenceAssortSkeleton(); - foreach (var itemWithChilden in intermediaryAssorts.SptItems) - { - result.Items.AddRange(itemWithChilden); - } + foreach (var itemWithChilden in intermediaryAssorts.SptItems) result.Items.AddRange(itemWithChilden); result.BarterScheme = intermediaryAssorts.BarterScheme; result.LoyalLevelItems = intermediaryAssorts.LoyalLevelItems; @@ -668,9 +613,9 @@ public class FenceService( return new TraderAssort() { Items = [], - BarterScheme = new(), - LoyalLevelItems = new(), - NextResupply = GetNextFenceUpdateTimestamp(), + BarterScheme = new Dictionary>>(), + LoyalLevelItems = new Dictionary(), + NextResupply = GetNextFenceUpdateTimestamp() }; } @@ -681,18 +626,15 @@ public class FenceService( */ protected CreateFenceAssortsResult CreateAssorts(GenerationAssortValues itemCounts, int loyaltyLevel) { - var result = new CreateFenceAssortsResult() { SptItems = [], BarterScheme = new(), LoyalLevelItems = new() }; + var result = new CreateFenceAssortsResult() + { SptItems = [], BarterScheme = new Dictionary>>(), LoyalLevelItems = new Dictionary() }; var baseFenceAssortClone = _cloner.Clone(databaseService.GetTrader(Traders.FENCE).Assort); var itemTypeLimitCounts = InitItemLimitCounter(traderConfig.Fence.ItemTypeLimits); - if (itemCounts.Item > 0) - { - AddItemAssorts(itemCounts.Item, result, baseFenceAssortClone, itemTypeLimitCounts, loyaltyLevel); - } + if (itemCounts.Item > 0) AddItemAssorts(itemCounts.Item, result, baseFenceAssortClone, itemTypeLimitCounts, loyaltyLevel); if (itemCounts.WeaponPreset > 0 || itemCounts.EquipmentPreset > 0) - { // Add presets AddPresetsToAssort( itemCounts.WeaponPreset, @@ -701,7 +643,6 @@ public class FenceService( baseFenceAssortClone, loyaltyLevel ); - } return result; } @@ -789,10 +730,7 @@ public class FenceService( // Only randomise Upd values for single var isSingleStack = Math.Abs((rootItemBeingAdded.Upd?.StackObjectsCount ?? 0) - 1) < 0.1; - if (isSingleStack) - { - RandomiseItemUpdProperties(itemDbDetails, rootItemBeingAdded); - } + if (isSingleStack) RandomiseItemUpdProperties(itemDbDetails, rootItemBeingAdded); // Skip items already in the assort if it exists in the prevent duplicate list var existingItemThatMatches = GetMatchingItem(rootItemBeingAdded, itemDbDetails, assorts.SptItems); @@ -807,10 +745,7 @@ public class FenceService( } // Add mods to armors so they dont show as red in the trade screen - if (itemHelper.ItemRequiresSoftInserts(rootItemBeingAdded.Template)) - { - RandomiseArmorModDurability(desiredAssortItemAndChildrenClone, itemDbDetails); - } + if (itemHelper.ItemRequiresSoftInserts(rootItemBeingAdded.Template)) RandomiseArmorModDurability(desiredAssortItemAndChildrenClone, itemDbDetails); assorts.SptItems.Add(desiredAssortItemAndChildrenClone); @@ -818,10 +753,7 @@ public class FenceService( _cloner.Clone(baseFenceAssortClone.BarterScheme[chosenBaseAssortRoot.Id]); // Only adjust item price by quality for solo items, never multi-stack - if (isSingleStack) - { - AdjustItemPriceByQuality(assorts.BarterScheme, rootItemBeingAdded, itemDbDetails); - } + if (isSingleStack) AdjustItemPriceByQuality(assorts.BarterScheme, rootItemBeingAdded, itemDbDetails); assorts.LoyalLevelItems[rootItemBeingAdded.Id] = loyaltyLevel; } @@ -853,10 +785,8 @@ public class FenceService( .SelectMany(i => i) .ToList(); if (matchingItems.Count == 0) - { // Nothing matches by tpl and is root item, exit early return null; - } var isMedical = itemHelper.IsOfBaseclasses( rootItemBeingAdded.Template, @@ -876,20 +806,15 @@ public class FenceService( (itemDbDetails.Properties.Slots?.Count ?? 0) > 0; // Only one match and its not medical or armored gear - if (matchingItems.Count == 1 && !(isMedical || isGearAndHasSlots)) - { - return matchingItems[0]; - } + if (matchingItems.Count == 1 && !(isMedical || isGearAndHasSlots)) return matchingItems[0]; // Items have sub properties that need to be checked against foreach (var item in matchingItems) { if (isMedical && rootItemBeingAdded.Upd?.MedKit?.HpResource == item.Upd?.MedKit?.HpResource) - { // e.g. bandages with multiple use // Both undefined === both max resoruce left return item; - } // Armors/helmets etc if ( @@ -897,9 +822,7 @@ public class FenceService( rootItemBeingAdded.Upd.Repairable?.Durability == item.Upd.Repairable?.Durability && rootItemBeingAdded.Upd.Repairable?.MaxDurability == item.Upd.Repairable?.MaxDurability ) - { return item; - } } return null; @@ -914,16 +837,10 @@ public class FenceService( protected bool ItemShouldBeForceStacked(Item? existingItem, TemplateItem itemDbDetails) { // No existing item in assort - if (existingItem == null) - { - return false; - } + if (existingItem == null) return false; // Don't stack child items, only root items - if (existingItem.ParentId != "hideout") - { - return false; - } + if (existingItem.ParentId != "hideout") return false; return ItemInPreventDupeCategoryList(itemDbDetails.Id); } @@ -953,10 +870,7 @@ public class FenceService( var current = itemRoot.Upd.MedKit.HpResource; // Current and max match, no adjustment necessary - if (itemTotalMax == current) - { - return; - } + if (itemTotalMax == current) return; var multipler = current / itemTotalMax; @@ -982,12 +896,8 @@ public class FenceService( ) { foreach (var baseTypeKey in itemTypeLimits.Keys) - { if (itemHelper.IsOfBaseclass(itemTpl, baseTypeKey)) - { return itemTypeLimits[baseTypeKey]; - } - } return null; } @@ -1016,10 +926,7 @@ public class FenceService( while (weaponPresetsAddedCount < desiredWeaponPresetsCount) { var randomPresetRoot = randomUtil.GetArrayValue(weaponPresetRootItems); - if (traderConfig.Fence.Blacklist.Contains(randomPresetRoot.Template)) - { - continue; - } + if (traderConfig.Fence.Blacklist.Contains(randomPresetRoot.Template)) continue; var rootItemDb = itemHelper.GetItem(randomPresetRoot.Template).Value; @@ -1035,13 +942,9 @@ public class FenceService( var itemPrice = handbookHelper.GetTemplatePriceForItems(presetWithChildrenClone) * itemHelper.GetItemQualityModifierForItems(presetWithChildrenClone); if (traderConfig.Fence.ItemCategoryRoublePriceLimit.TryGetValue(rootItemDb.Parent, out var priceLimitRouble)) - { if (itemPrice > priceLimitRouble) - { // Too expensive, try again continue; - } - } // MUST randomise Ids as its possible to add the same base fence assort twice = duplicate IDs = dead client itemHelper.ReparentItemAndChildren(presetWithChildrenClone[0], presetWithChildrenClone); @@ -1060,7 +963,7 @@ public class FenceService( new BarterScheme() { Template = Money.ROUBLES, - Count = Math.Round(itemPrice), + Count = Math.Round(itemPrice) } ] ]; @@ -1071,10 +974,7 @@ public class FenceService( } var equipmentPresetsAddedCount = 0; - if (desiredEquipmentPresetsCount <= 0) - { - return; - } + if (desiredEquipmentPresetsCount <= 0) return; var equipmentPresetRootItems = baseFenceAssort.Items.Where( (item) => item.Upd?.SptPresetId != null && itemHelper.ArmorItemCanHoldMods(item.Template) @@ -1089,10 +989,7 @@ public class FenceService( ); // Need to add mods to armors so they dont show as red in the trade screen - if (itemHelper.ItemRequiresSoftInserts(randomPresetRoot.Template)) - { - RandomiseArmorModDurability(presetWithChildrenClone, rootItemDb); - } + if (itemHelper.ItemRequiresSoftInserts(randomPresetRoot.Template)) RandomiseArmorModDurability(presetWithChildrenClone, rootItemDb); RemoveRandomModsOfItem(presetWithChildrenClone); @@ -1102,13 +999,9 @@ public class FenceService( handbookHelper.GetTemplatePriceForItems(presetWithChildrenClone) * itemHelper.GetItemQualityModifierForItems(presetWithChildrenClone); if (priceLimitRouble != null) - { if (itemPrice > priceLimitRouble) - { // Too expensive, try again continue; - } - } // MUST randomise Ids as its possible to add the same base fence assort twice = duplicate IDs = dead client itemHelper.ReparentItemAndChildren(presetWithChildrenClone[0], presetWithChildrenClone); @@ -1127,7 +1020,7 @@ public class FenceService( new BarterScheme() { Template = Money.ROUBLES, - Count = Math.Round(itemPrice), + Count = Math.Round(itemPrice) } ] ]; @@ -1145,25 +1038,16 @@ public class FenceService( protected void RandomiseArmorModDurability(List armor, TemplateItem itemDbDetails) { // Armor has no mods, nothing to randomise - if (itemDbDetails.Properties.Slots == null) - { - return; - } + if (itemDbDetails.Properties.Slots == null) return; // Check for and adjust soft insert durability values var requiredSlots = itemDbDetails.Properties.Slots?.Where(slot => slot.Required ?? false).ToList(); - if ((requiredSlots?.Count ?? 0) > 1) - { - RandomiseArmorSoftInsertDurabilities(requiredSlots, armor); - } + if ((requiredSlots?.Count ?? 0) > 1) RandomiseArmorSoftInsertDurabilities(requiredSlots, armor); // Check for and adjust plate durability values var plateSlots = itemDbDetails.Properties.Slots?.Where(slot => itemHelper.IsRemovablePlateSlot(slot.Name)) .ToList(); - if ((plateSlots?.Count ?? 0) > 1) - { - RandomiseArmorInsertsDurabilities(plateSlots, armor); - } + if ((plateSlots?.Count ?? 0) > 1) RandomiseArmorInsertsDurabilities(plateSlots, armor); } /** @@ -1176,7 +1060,7 @@ public class FenceService( foreach (var requiredSlot in softInsertSlots) { var modItemDbDetails = itemHelper.GetItem(requiredSlot.Props.Filters[0].Plate).Value; - + var durabilityValues = GetRandomisedArmorDurabilityValues( modItemDbDetails, traderConfig.Fence.ArmorMaxDurabilityPercentMinMax @@ -1185,10 +1069,8 @@ public class FenceService( requiredSlot.Props.Filters[0].Plate ?? string.Empty; // "Plate" property appears to be the 'default' item for slot if (plateTpl == "") - { // Some bsg plate properties are empty, skip mod continue; - } // Find items mod to apply dura changes to var modItemToAdjust = @@ -1197,13 +1079,11 @@ public class FenceService( itemHelper.AddUpdObjectToItem(modItemToAdjust); if (modItemToAdjust.Upd.Repairable == null) - { modItemToAdjust.Upd.Repairable = new UpdRepairable() { Durability = modItemDbDetails.Properties.MaxDurability, MaxDurability = modItemDbDetails.Properties.MaxDurability }; - } modItemToAdjust.Upd.Repairable.Durability = durabilityValues.Durability; modItemToAdjust.Upd.Repairable.MaxDurability = durabilityValues.MaxDurability; @@ -1213,10 +1093,8 @@ public class FenceService( modItemToAdjust.ParentId == BaseClasses.ARMORED_EQUIPMENT && modItemToAdjust.SlotId == "mod_equipment_000" && modItemToAdjust.Upd.Repairable.Durability < modItemDbDetails.Properties.MaxDurability) - { // Is damaged modItemToAdjust.Upd.FaceShield = new UpdFaceShield() { Hits = randomUtil.GetInt(1, 3) }; - } } } @@ -1232,10 +1110,8 @@ public class FenceService( { var plateTpl = plateSlot.Props.Filters[0].Plate; if (string.IsNullOrEmpty(plateTpl)) - { // Bsg data lacks a default plate, skip randomisng for this mod continue; - } var armorWithMods = armorItemAndMods; @@ -1258,7 +1134,8 @@ public class FenceService( ); // Find items mod to apply durability changes to - var modItemToAdjust = armorWithMods.FirstOrDefault(mod => string.Equals( + var modItemToAdjust = armorWithMods.FirstOrDefault( + mod => string.Equals( mod.SlotId, plateSlot.Name, StringComparison.OrdinalIgnoreCase @@ -1276,13 +1153,11 @@ public class FenceService( itemHelper.AddUpdObjectToItem(modItemToAdjust); if (modItemToAdjust?.Upd?.Repairable == null) - { modItemToAdjust.Upd.Repairable = new UpdRepairable { Durability = modItemDbDetails.Properties.MaxDurability, MaxDurability = modItemDbDetails.Properties.MaxDurability }; - } modItemToAdjust.Upd.Repairable.Durability = durabilityValues.Durability; modItemToAdjust.Upd.Repairable.MaxDurability = durabilityValues.MaxDurability; @@ -1300,10 +1175,7 @@ public class FenceService( if (itemHelper.IsOfBaseclass(itemDbDetails.Id, BaseClasses.AMMO)) { overrideValues = traderConfig.Fence.ItemStackSizeOverrideMinMax[itemDbDetails.Parent]; - if (overrideValues != null) - { - return randomUtil.GetInt((int)overrideValues.Min, (int)overrideValues.Max); - } + if (overrideValues != null) return randomUtil.GetInt((int)overrideValues.Min, (int)overrideValues.Max); // No override, use stack max size from item db return itemDbDetails.Properties.StackMaxSize == 1 @@ -1316,15 +1188,11 @@ public class FenceService( // Check for override in config, use values if exists if (traderConfig.Fence.ItemStackSizeOverrideMinMax.TryGetValue(itemDbDetails.Id, out overrideValues)) - { return randomUtil.GetInt((int)overrideValues.Min, (int)overrideValues.Max); - } // Check for parent override if (traderConfig.Fence.ItemStackSizeOverrideMinMax.TryGetValue(itemDbDetails.Parent, out overrideValues)) - { return randomUtil.GetInt((int)overrideValues.Min, (int)overrideValues.Max); - } return 1; } @@ -1340,29 +1208,20 @@ public class FenceService( // Find mods to remove from item that could've been scavenged by other players in-raid foreach (var itemMod in itemAndMods) - { if (PresetModItemWillBeRemoved(itemMod, toDelete)) { // Skip if not an item var itemDbDetails = itemHelper.GetItem(itemMod.Template); - if (!itemDbDetails.Key) - { - continue; - } + if (!itemDbDetails.Key) continue; // Remove item and its sub-items to prevent orphans toDelete.AddRange(itemHelper.FindAndReturnChildrenByItems(itemAndMods, itemMod.Id)); } - } // Reverse loop and remove items for (var index = itemAndMods.Count - 1; index >= 0; --index) - { if (toDelete.Contains(itemAndMods[index].Id)) - { itemAndMods.Splice(index, 1); - } - } } /** @@ -1374,10 +1233,7 @@ public class FenceService( protected bool PresetModItemWillBeRemoved(Item weaponMod, List itemsBeingDeleted) { var slotIdsThatCanFail = traderConfig.Fence.PresetSlotsToRemoveChancePercent; - if (!slotIdsThatCanFail.TryGetValue(weaponMod.SlotId, out var removalChance) || removalChance == 0.0) - { - return false; - } + if (!slotIdsThatCanFail.TryGetValue(weaponMod.SlotId, out var removalChance) || removalChance == 0.0) return false; // Roll from 0 to 9999, then divide it by 100: 9999 = 99.99% var randomChance = randomUtil.GetInt(0, 9999) / 100; @@ -1402,10 +1258,8 @@ public class FenceService( // Randomise hp resource of med items if (itemDetails.Properties.MaxHpResource != null && (itemDetails.Properties.MaxHpResource ?? 0) > 0) - { itemToAdjust.Upd.MedKit = new UpdMedKit() { HpResource = randomUtil.GetInt(1, (int)itemDetails.Properties.MaxHpResource) }; - } // Randomise armor durability if ( @@ -1429,12 +1283,12 @@ public class FenceService( if (itemHelper.IsOfBaseclass(itemDetails.Id, BaseClasses.WEAPON)) { var weaponDurabilityLimits = traderConfig.Fence.WeaponDurabilityPercentMinMax; - var maxDuraMin = (weaponDurabilityLimits.Max.Min / 100) * itemDetails.Properties.MaxDurability; - var maxDuraMax = (weaponDurabilityLimits.Max.Max / 100) * itemDetails.Properties.MaxDurability; + var maxDuraMin = weaponDurabilityLimits.Max.Min / 100 * itemDetails.Properties.MaxDurability; + var maxDuraMax = weaponDurabilityLimits.Max.Max / 100 * itemDetails.Properties.MaxDurability; var chosenMaxDurability = randomUtil.GetInt((int)maxDuraMin, (int)maxDuraMax); - var currentDuraMin = (weaponDurabilityLimits.Current.Min / 100) * itemDetails.Properties.MaxDurability; - var currentDuraMax = (weaponDurabilityLimits.Current.Max / 100) * itemDetails.Properties.MaxDurability; + var currentDuraMin = weaponDurabilityLimits.Current.Min / 100 * itemDetails.Properties.MaxDurability; + var currentDuraMax = weaponDurabilityLimits.Current.Max / 100 * itemDetails.Properties.MaxDurability; var currentDurability = Math.Min( randomUtil.GetInt((int)currentDuraMin, (int)currentDuraMax), chosenMaxDurability @@ -1450,7 +1304,7 @@ public class FenceService( { itemToAdjust.Upd.RepairKit = new UpdRepairKit { - Resource = randomUtil.GetInt(1, (int)itemDetails.Properties.MaxRepairResource), + Resource = randomUtil.GetInt(1, (int)itemDetails.Properties.MaxRepairResource) }; return; @@ -1462,7 +1316,7 @@ public class FenceService( { itemToAdjust.Upd.Key = new UpdKey { - NumberOfUsages = randomUtil.GetInt(0, (int)itemDetails.Properties.MaximumNumberOfUsage - 1), + NumberOfUsages = randomUtil.GetInt(0, (int)itemDetails.Properties.MaximumNumberOfUsage - 1) }; return; @@ -1490,12 +1344,12 @@ public class FenceService( ItemDurabilityCurrentMax equipmentDurabilityLimits ) { - var maxDuraMin = (equipmentDurabilityLimits.Max.Min / 100) * itemDetails.Properties.MaxDurability; - var maxDuraMax = (equipmentDurabilityLimits.Max.Max / 100) * itemDetails.Properties.MaxDurability; + var maxDuraMin = equipmentDurabilityLimits.Max.Min / 100 * itemDetails.Properties.MaxDurability; + var maxDuraMax = equipmentDurabilityLimits.Max.Max / 100 * itemDetails.Properties.MaxDurability; var chosenMaxDurability = randomUtil.GetInt((int)maxDuraMin, (int)maxDuraMax); - var currentDuraMin = (equipmentDurabilityLimits.Current.Min / 100) * itemDetails.Properties.MaxDurability; - var currentDuraMax = (equipmentDurabilityLimits.Current.Max / 100) * itemDetails.Properties.MaxDurability; + var currentDuraMin = equipmentDurabilityLimits.Current.Min / 100 * itemDetails.Properties.MaxDurability; + var currentDuraMax = equipmentDurabilityLimits.Current.Max / 100 * itemDetails.Properties.MaxDurability; var chosenCurrentDurability = Math.Min( randomUtil.GetInt((int)currentDuraMin, (int)currentDuraMax), chosenMaxDurability @@ -1513,10 +1367,7 @@ public class FenceService( { var itemTypeCounts = new Dictionary(); - foreach (var x in limits.Keys) - { - itemTypeCounts[x] = new() { current = 0, max = limits[x] }; - } + foreach (var x in limits.Keys) itemTypeCounts[x] = new ValueTuple { current = 0, max = limits[x] }; return itemTypeCounts; } @@ -1553,25 +1404,16 @@ public class FenceService( var fenceSettings = databaseService.GetGlobals().Configuration.FenceSettings; var pmcFenceInfo = pmcData.TradersInfo[fenceSettings.FenceIdentifier]; - if (pmcFenceInfo == null) - { - return fenceSettings.Levels[0]; - } + if (pmcFenceInfo == null) return fenceSettings.Levels[0]; var fenceLevels = fenceSettings.Levels.Keys; var minLevel = fenceLevels.Min(); var maxLevel = fenceLevels.Max(); var pmcFenceLevel = Math.Floor((double)pmcFenceInfo.Standing); - if (pmcFenceLevel < minLevel) - { - return fenceSettings.Levels[minLevel]; - } + if (pmcFenceLevel < minLevel) return fenceSettings.Levels[minLevel]; - if (pmcFenceLevel > maxLevel) - { - return fenceSettings.Levels[maxLevel]; - } + if (pmcFenceLevel > maxLevel) return fenceSettings.Levels[maxLevel]; return fenceSettings.Levels[pmcFenceLevel]; } @@ -1625,11 +1467,9 @@ public class FenceService( fenceDiscountAssort.Items.Splice(indexToRemove, 1); if (indexToRemove == -1) - { logger.Warning( $"unable to remove fence assort item: {itemToRemove.Id} tpl: {itemToRemove.Template}" ); - } return; } diff --git a/Libraries/Core/Services/GiftService.cs b/Libraries/Core/Services/GiftService.cs index 8db1be50..c3ccf847 100644 --- a/Libraries/Core/Services/GiftService.cs +++ b/Libraries/Core/Services/GiftService.cs @@ -1,5 +1,6 @@ using SptCommon.Annotations; using Core.Helpers; +using Core.Models.Eft.Profile; using Core.Models.Enums; using Core.Models.Spt.Config; using Core.Models.Spt.Dialog; @@ -66,34 +67,25 @@ public class GiftService( public GiftSentResult SendGiftToPlayer(string playerId, string giftId) { var giftData = GetGiftById(giftId); - if (giftData is null) - { - return GiftSentResult.FAILED_GIFT_DOESNT_EXIST; - } + if (giftData is null) return GiftSentResult.FAILED_GIFT_DOESNT_EXIST; var maxGiftsToSendCount = giftData.MaxToSendPlayer ?? 1; if (_profileHelper.PlayerHasRecievedMaxNumberOfGift(playerId, giftId, maxGiftsToSendCount)) { - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Player already received gift: {giftId}"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Player already received gift: {giftId}"); return GiftSentResult.FAILED_GIFT_ALREADY_RECEIVED; } if (giftData.Items?.Count > 0 && giftData.CollectionTimeHours is not null) - { _logger.Warning($"Gift {giftId} has items but no collection time limit, defaulting to 48 hours"); - } // Handle system messsages if (giftData.Sender == GiftSenderType.System) { // Has a localisable text id to send to player if (giftData.LocaleTextId is not null) - { _mailSendService.SendLocalisedSystemMessageToPlayer( playerId, giftData.LocaleTextId, @@ -101,9 +93,7 @@ public class GiftService( giftData.ProfileChangeEvents, _timeUtil.GetHoursAsSeconds(giftData.CollectionTimeHours ?? 1) ); - } else - { _mailSendService.SendSystemMessageToPlayer( playerId, giftData.MessageText, @@ -111,7 +101,6 @@ public class GiftService( _timeUtil.GetHoursAsSeconds(giftData.CollectionTimeHours ?? 1), giftData.ProfileChangeEvents ); - } } // Handle user messages else if (giftData.Sender == GiftSenderType.User) @@ -127,7 +116,6 @@ public class GiftService( else if (giftData.Sender == GiftSenderType.Trader) { if (giftData.LocaleTextId is not null) - { _mailSendService.SendLocalisedNpcMessageToPlayer( playerId, giftData.Trader, @@ -138,9 +126,7 @@ public class GiftService( null, null ); - } else - { _mailSendService.SendLocalisedNpcMessageToPlayer( playerId, giftData.Trader, @@ -151,7 +137,6 @@ public class GiftService( null, null ); - } } else { @@ -161,21 +146,18 @@ public class GiftService( { RecipientId = playerId, Sender = GetMessageType(giftData), - SenderDetails = new() + SenderDetails = new UserDialogInfo { Id = GetSenderId(giftData), Aid = 1234567, // TODO - pass proper aid value - Info = null, + Info = null }, MessageText = giftData.MessageText, Items = giftData.Items, - ItemsMaxStorageLifetimeSeconds = _timeUtil.GetHoursAsSeconds(giftData.CollectionTimeHours ?? 0), + ItemsMaxStorageLifetimeSeconds = _timeUtil.GetHoursAsSeconds(giftData.CollectionTimeHours ?? 0) }; - if (giftData.Trader is not null) - { - details.Trader = giftData.Trader; - } + if (giftData.Trader is not null) details.Trader = giftData.Trader; _mailSendService.SendMessageToPlayer(details); } @@ -192,15 +174,9 @@ public class GiftService( */ private string? GetSenderId(Gift giftData) { - if (giftData.Sender == GiftSenderType.Trader) - { - return Enum.GetName(typeof(GiftSenderType), giftData.Sender); - } + if (giftData.Sender == GiftSenderType.Trader) return Enum.GetName(typeof(GiftSenderType), giftData.Sender); - if (giftData.Sender == GiftSenderType.User) - { - return giftData.Sender.ToString(); - } + if (giftData.Sender == GiftSenderType.User) return giftData.Sender.ToString(); return null; } @@ -241,12 +217,8 @@ public class GiftService( }; if (giftId is not null) - { if (!_profileHelper.PlayerHasRecievedMaxNumberOfGift(sessionId, giftId, 1)) - { SendGiftToPlayer(sessionId, giftId); - } - } } /** @@ -257,9 +229,6 @@ public class GiftService( */ public void SendGiftWithSilentReceivedCheck(string giftId, string? sessionId, int giftCount) { - if (!_profileHelper.PlayerHasRecievedMaxNumberOfGift(sessionId, giftId, giftCount)) - { - SendGiftToPlayer(sessionId, giftId); - } + if (!_profileHelper.PlayerHasRecievedMaxNumberOfGift(sessionId, giftId, giftCount)) SendGiftToPlayer(sessionId, giftId); } } diff --git a/Libraries/Core/Services/I18nService.cs b/Libraries/Core/Services/I18nService.cs index 4e58412d..044c07bc 100644 --- a/Libraries/Core/Services/I18nService.cs +++ b/Libraries/Core/Services/I18nService.cs @@ -6,15 +6,16 @@ namespace Core.Services; public class I18nService { - private List _locales; - private Dictionary _fallbacks; private string _defaultLocale; private string _directory; - private JsonUtil _jsonUtil; + private Dictionary _fallbacks; private FileUtil _fileUtil; - private string _setLocale; + private JsonUtil _jsonUtil; private Dictionary>> _loadedLocales = new(); + private List _locales; + private string _setLocale; + // TODO: try convert to primary ctor public I18nService( FileUtil fileUtil, @@ -41,11 +42,13 @@ public class I18nService if (files.Count == 0) throw new Exception($"Localisation files in directory {_directory} not found."); foreach (var file in files) - _loadedLocales.Add(_fileUtil.StripExtension(file), + _loadedLocales.Add( + _fileUtil.StripExtension(file), new LazyLoad>( () => _jsonUtil.Deserialize>(_fileUtil.ReadFile(file)) ?? new Dictionary() - )); + ) + ); if (!_loadedLocales.ContainsKey(_defaultLocale)) throw new Exception($"The default locale '{_defaultLocale}' does not exist on the loaded locales."); @@ -65,7 +68,8 @@ public class I18nService var foundFallbackLocale = fallback.First().Value; if (!_loadedLocales.ContainsKey(foundFallbackLocale)) throw new Exception( - $"Locale '{locale}' was not defined, and the found fallback locale did not match any of the loaded locales."); + $"Locale '{locale}' was not defined, and the found fallback locale did not match any of the loaded locales." + ); _setLocale = foundFallbackLocale; } @@ -95,11 +99,8 @@ public class I18nService public string GetLocalised(string key, object? args) { var rawLocalizedString = GetLocalised(key); - if (args == null) - { - return rawLocalizedString; - } - + if (args == null) return rawLocalizedString; + var typeToCheck = args.GetType(); var typeProps = typeToCheck.GetProperties(); @@ -107,10 +108,9 @@ public class I18nService { var localizedName = $"{{{{{propertyInfo.GetJsonName()}}}}}"; if (rawLocalizedString.Contains(localizedName)) - { rawLocalizedString = rawLocalizedString.Replace(localizedName, propertyInfo.GetValue(args)?.ToString() ?? string.Empty); - } } + return rawLocalizedString; } diff --git a/Libraries/Core/Services/InMemoryCacheService.cs b/Libraries/Core/Services/InMemoryCacheService.cs index ebee155c..57bb7200 100644 --- a/Libraries/Core/Services/InMemoryCacheService.cs +++ b/Libraries/Core/Services/InMemoryCacheService.cs @@ -23,10 +23,7 @@ public class InMemoryCacheService( // Stored data public T? GetDataByKey(string key) { - if (_cacheData.ContainsKey(key)) - { - return (T)_cacheData[key]; - } + if (_cacheData.ContainsKey(key)) return (T)_cacheData[key]; return default; } diff --git a/Libraries/Core/Services/InsuranceService.cs b/Libraries/Core/Services/InsuranceService.cs index eec13008..6e2dcab5 100644 --- a/Libraries/Core/Services/InsuranceService.cs +++ b/Libraries/Core/Services/InsuranceService.cs @@ -33,7 +33,7 @@ public class InsuranceService( ) { protected InsuranceConfig _insuranceConfig = _configServer.GetConfig(); - protected Dictionary>?> _insured = new Dictionary>?>(); + protected Dictionary>?> _insured = new(); /// /// Does player have insurance dictionary exists @@ -42,7 +42,7 @@ public class InsuranceService( /// True if exists public bool InsuranceDictionaryExists(string sessionId) { - return _insured.TryGetValue(sessionId, out var _); + return _insured.TryGetValue(sessionId, out _); } /// @@ -57,10 +57,7 @@ public class InsuranceService( public void ResetInsurance(string sessionId) { - if (!_insured.TryAdd(sessionId, new Dictionary>())) - { - _insured[sessionId] = new Dictionary>(); - } + if (!_insured.TryAdd(sessionId, new Dictionary>())) _insured[sessionId] = new Dictionary>(); } /// @@ -100,11 +97,11 @@ public class InsuranceService( continue; } - SystemData systemData = new SystemData + var systemData = new SystemData { Date = _timeUtil.GetDateMailFormat(), Time = _timeUtil.GetTimeMailFormat(), - Location = mapId, + Location = mapId }; // Send "i will go look for your stuff" message from trader to player @@ -130,7 +127,7 @@ public class InsuranceService( SystemData = systemData, MessageType = MessageType.INSURANCE_RETURN, MessageTemplateId = _randomUtil.GetArrayValue(dialogueTemplates["insuranceFound"]), - Items = GetInsurance(sessionID)[trader.Key], + Items = GetInsurance(sessionID)[trader.Key] } ); } @@ -151,9 +148,7 @@ public class InsuranceService( if (_insuranceConfig.ReturnTimeOverrideSeconds > 0) { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug($"Insurance override used: returning in {_insuranceConfig.ReturnTimeOverrideSeconds} seconds"); - } return _timeUtil.GetTimeStamp() + _insuranceConfig.ReturnTimeOverrideSeconds; } @@ -177,17 +172,12 @@ public class InsuranceService( "SpecialSlot" ); if (hasMarkOfUnheard) - { // Reduce return time by globals multipler value randomisedReturnTimeSeconds *= (int)globals.Configuration.Insurance.CoefOfHavingMarkOfUnknown; - } // EoD has 30% faster returns var editionModifier = globals.Configuration.Insurance.EditionSendingMessageTime[pmcData.Info.GameVersion]; - if (editionModifier is not null) - { - randomisedReturnTimeSeconds *= (int)editionModifier.Multiplier; - } + if (editionModifier is not null) randomisedReturnTimeSeconds *= (int)editionModifier.Multiplier; // Calculate the final return time based on our bonus percent var finalReturnTimeSeconds = randomisedReturnTimeSeconds * (1.0 - insuranceReturnTimeBonusPercent); @@ -197,10 +187,8 @@ public class InsuranceService( protected double GetMaxInsuranceStorageTime(TraderBase traderBase) { if (_insuranceConfig.StorageTimeOverrideSeconds > 0) - { // Override exists, use instead of traders value return _insuranceConfig.StorageTimeOverrideSeconds; - } return _timeUtil.GetHoursAsSeconds((int)traderBase.Insurance.MaxStorageTime); } @@ -212,10 +200,7 @@ public class InsuranceService( public void StoreGearLostInRaidToSendLater(string sessionID, List equipmentPkg) { // Process all insured items lost in-raid - foreach (var gear in equipmentPkg) - { - AddGearToSend(gear); - } + foreach (var gear in equipmentPkg) AddGearToSend(gear); } /// @@ -239,10 +224,7 @@ public class InsuranceService( continue; } - if (ItemCannotBeLostOnDeath(lostItem, pmcProfile.Inventory.Items)) - { - continue; - } + if (ItemCannotBeLostOnDeath(lostItem, pmcProfile.Inventory.Items)) continue; // Add insured item + details to return array result.Add( @@ -251,7 +233,7 @@ public class InsuranceService( SessionId = sessionId, ItemToReturnToPlayer = lostItem, PmcData = pmcProfile, - TraderId = insuranceDetails.TId, + TraderId = insuranceDetails.TId } ); } @@ -267,16 +249,10 @@ public class InsuranceService( /// True if item protected bool ItemCannotBeLostOnDeath(Item lostItem, List inventoryItems) { - if (lostItem.SlotId?.ToLower().StartsWith("specialslot") ?? false) - { - return true; - } + if (lostItem.SlotId?.ToLower().StartsWith("specialslot") ?? false) return true; // We check secure container items even tho they are omitted from lostInsuredItems, just in case - if (_itemHelper.ItemIsInsideContainer(lostItem, "SecuredContainer", inventoryItems)) - { - return true; - } + if (_itemHelper.ItemIsInsideContainer(lostItem, "SecuredContainer", inventoryItems)) return true; return false; } @@ -293,16 +269,10 @@ public class InsuranceService( var traderId = gear.TraderId; // Ensure insurance array is init - if (!InsuranceDictionaryExists(sessionId)) - { - ResetInsurance(sessionId); - } + if (!InsuranceDictionaryExists(sessionId)) ResetInsurance(sessionId); // init trader insurance array - if (!InsuranceTraderArrayExists(sessionId, traderId)) - { - ResetInsuranceTraderArray(sessionId, traderId); - } + if (!InsuranceTraderArrayExists(sessionId, traderId)) ResetInsuranceTraderArray(sessionId, traderId); AddInsuranceItemToArray(sessionId, traderId, itemToReturnToPlayer); @@ -318,7 +288,7 @@ public class InsuranceService( /// True if exists protected bool InsuranceTraderArrayExists(string sessionId, string traderId) { - return this._insured[sessionId][traderId] is not null; + return _insured[sessionId][traderId] is not null; } /// diff --git a/Libraries/Core/Services/ItemBaseClassService.cs b/Libraries/Core/Services/ItemBaseClassService.cs index 22817ef5..cc5b99dc 100644 --- a/Libraries/Core/Services/ItemBaseClassService.cs +++ b/Libraries/Core/Services/ItemBaseClassService.cs @@ -25,14 +25,11 @@ public class ItemBaseClassService( _itemBaseClassesCache = new Dictionary>(); var items = _databaseService.GetItems(); - var filteredDbItems = (items).Where((x) => x.Value.Type == "Item"); + var filteredDbItems = items.Where((x) => x.Value.Type == "Item"); foreach (var item in filteredDbItems) { var itemIdToUpdate = item.Value.Id; - if (!_itemBaseClassesCache.ContainsKey(item.Value.Id)) - { - _itemBaseClassesCache[item.Value.Id] = []; - } + if (!_itemBaseClassesCache.ContainsKey(item.Value.Id)) _itemBaseClassesCache[item.Value.Id] = []; AddBaseItems(itemIdToUpdate, item.Value); } @@ -50,10 +47,7 @@ public class ItemBaseClassService( _itemBaseClassesCache[itemIdToUpdate].Add(item.Parent); var parent = _databaseService.GetItems()[item.Parent]; - if (!string.IsNullOrEmpty(parent.Parent)) - { - AddBaseItems(itemIdToUpdate, parent); - } + if (!string.IsNullOrEmpty(parent.Parent)) AddBaseItems(itemIdToUpdate, parent); } /** @@ -64,10 +58,7 @@ public class ItemBaseClassService( */ public bool ItemHasBaseClass(string itemTpl, List baseClasses) { - if (!_cacheGenerated) - { - HydrateItemBaseClassCache(); - } + if (!_cacheGenerated) HydrateItemBaseClassCache(); if (string.IsNullOrEmpty(itemTpl)) { @@ -78,30 +69,18 @@ public class ItemBaseClassService( // The cache is only generated for item templates with `_type === "Item"`, so return false for any other type, // including item templates that simply don't exist. - if (!CachedItemIsOfItemType(itemTpl)) - { - return false; - } + if (!CachedItemIsOfItemType(itemTpl)) return false; // No item in cache - if (_itemBaseClassesCache.ContainsKey(itemTpl)) - { - return _itemBaseClassesCache[itemTpl].Any(baseClasses.Contains); - } + if (_itemBaseClassesCache.ContainsKey(itemTpl)) return _itemBaseClassesCache[itemTpl].Any(baseClasses.Contains); - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug(_localisationService.GetText("baseclass-item_not_found", itemTpl)); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug(_localisationService.GetText("baseclass-item_not_found", itemTpl)); // Not found in cache, Hydrate again - some mods add items late HydrateItemBaseClassCache(); // Check for item again, return false if item not found a second time - if (_itemBaseClassesCache.ContainsKey(itemTpl)) - { - return _itemBaseClassesCache[itemTpl].Any(baseClasses.Contains); - } + if (_itemBaseClassesCache.ContainsKey(itemTpl)) return _itemBaseClassesCache[itemTpl].Any(baseClasses.Contains); _logger.Warning(_localisationService.GetText("baseclass-item_not_found_failed", itemTpl)); @@ -125,15 +104,9 @@ public class ItemBaseClassService( */ public List GetItemBaseClasses(string itemTpl) { - if (!_cacheGenerated) - { - HydrateItemBaseClassCache(); - } + if (!_cacheGenerated) HydrateItemBaseClassCache(); - if (!_itemBaseClassesCache.ContainsKey(itemTpl)) - { - return []; - } + if (!_itemBaseClassesCache.ContainsKey(itemTpl)) return []; return _itemBaseClassesCache[itemTpl]; } diff --git a/Libraries/Core/Services/ItemFilterService.cs b/Libraries/Core/Services/ItemFilterService.cs index 7d8d9722..6ee0aed5 100644 --- a/Libraries/Core/Services/ItemFilterService.cs +++ b/Libraries/Core/Services/ItemFilterService.cs @@ -13,10 +13,10 @@ public class ItemFilterService( ConfigServer _configServer ) { + protected HashSet? _itemBlacklistCache = []; protected ItemConfig _itemConfig = _configServer.GetConfig(); protected HashSet? _lootableItemBlacklistCache = []; - protected HashSet? _itemBlacklistCache = []; /** * Check if the provided template id is blacklisted in config/item.json/blacklist @@ -26,11 +26,8 @@ public class ItemFilterService( public bool ItemBlacklisted(string tpl) { if (_itemBlacklistCache.Count == 0) - { - foreach (var item in _itemConfig.Blacklist) { + foreach (var item in _itemConfig.Blacklist) _itemBlacklistCache.Add(item); - } - } return _itemBlacklistCache.Contains(tpl); } @@ -97,7 +94,6 @@ public class ItemFilterService( */ public List GetBossItems() { - return _cloner.Clone(_itemConfig.BossItems).ToList(); } @@ -108,37 +104,26 @@ public class ItemFilterService( */ public bool IsLootableItemBlacklisted(string itemKey) { - if (!_lootableItemBlacklistCache.Any()) - { - HydrateLootableItemBlacklist(); - } + if (!_lootableItemBlacklistCache.Any()) HydrateLootableItemBlacklist(); return _lootableItemBlacklistCache.Contains(itemKey); } public bool IsItemBlacklisted(string tpl) { - if (!_itemBlacklistCache.Any()) - { - HydrateBlacklist(); - } + if (!_itemBlacklistCache.Any()) HydrateBlacklist(); return _itemBlacklistCache.Contains(tpl); } protected void HydrateLootableItemBlacklist() { - foreach (var item in _itemConfig.LootableItemBlacklist) - { - _lootableItemBlacklistCache.Add(item); - } + foreach (var item in _itemConfig.LootableItemBlacklist) _lootableItemBlacklistCache.Add(item); } protected void HydrateBlacklist() { - foreach (var item in _itemConfig.Blacklist) { - _itemBlacklistCache.Add(item); - } + foreach (var item in _itemConfig.Blacklist) _itemBlacklistCache.Add(item); } /** diff --git a/Libraries/Core/Services/LocalisationService.cs b/Libraries/Core/Services/LocalisationService.cs index cd06b04c..a193236a 100644 --- a/Libraries/Core/Services/LocalisationService.cs +++ b/Libraries/Core/Services/LocalisationService.cs @@ -8,11 +8,13 @@ namespace Core.Services; [Injectable(InjectionType.Singleton)] public class LocalisationService { + protected DatabaseServer _databaseServer; + + protected I18nService _i18nService; + protected LocaleService _localeService; protected ISptLogger _logger; protected RandomUtil _randomUtil; - protected DatabaseServer _databaseServer; - protected LocaleService _localeService; - protected I18nService _i18nService; + // TODO: turn into primary ctor public LocalisationService( ISptLogger logger, @@ -45,7 +47,7 @@ public class LocalisationService : _i18nService.GetLocalised(key, args); } - public string GetText(string key, T value) where T :IConvertible? + public string GetText(string key, T value) where T : IConvertible? { return _i18nService.GetLocalised(key, value); } diff --git a/Libraries/Core/Services/LocationLifecycleService.cs b/Libraries/Core/Services/LocationLifecycleService.cs index bc2d8717..97e04cb1 100644 --- a/Libraries/Core/Services/LocationLifecycleService.cs +++ b/Libraries/Core/Services/LocationLifecycleService.cs @@ -20,39 +20,39 @@ namespace Core.Services; [Injectable(InjectionType.Singleton)] public class LocationLifecycleService { - private readonly ISptLogger _logger; - private readonly RewardHelper _rewardHelper; - private readonly ConfigServer _configServer; - private readonly TimeUtil _timeUtil; - private readonly DatabaseService _databaseService; - private readonly ProfileHelper _profileHelper; - private readonly HashUtil _hashUtil; private readonly ApplicationContext _applicationContext; private readonly BotGenerationCacheService _botGenerationCacheService; - private readonly BotNameService _botNameService; - private readonly PmcConfig _pmcConfig; - private readonly ICloner _cloner; - private readonly LocationConfig _locationConfig; - private readonly RaidTimeAdjustmentService _raidTimeAdjustmentService; - private readonly LocationLootGenerator _locationLootGenerator; - private readonly LocalisationService _localisationService; private readonly BotLootCacheService _botLootCacheService; - private readonly RagfairConfig _ragfairConfig; + private readonly BotNameService _botNameService; + private readonly ICloner _cloner; + private readonly ConfigServer _configServer; + private readonly DatabaseService _databaseService; + private readonly HashUtil _hashUtil; + private readonly HealthHelper _healthHelper; private readonly HideoutConfig _hideoutConfig; - private readonly TraderConfig _traderConfig; - private readonly LootGenerator _lootGenerator; - private readonly MailSendService _mailSendService; - private readonly TraderHelper _traderHelper; - private readonly RandomUtil _randomUtil; private readonly InRaidConfig _inRaidConfig; private readonly InRaidHelper _inRaidHelper; - private readonly PlayerScavGenerator _playerScavGenerator; - private readonly SaveServer _saveServer; - private readonly HealthHelper _healthHelper; - private readonly PmcChatResponseService _pmcChatResponseService; - private readonly QuestHelper _questHelper; private readonly InsuranceService _insuranceService; + private readonly LocalisationService _localisationService; + private readonly LocationConfig _locationConfig; + private readonly LocationLootGenerator _locationLootGenerator; + private readonly ISptLogger _logger; + private readonly LootGenerator _lootGenerator; + private readonly MailSendService _mailSendService; private readonly MatchBotDetailsCacheService _matchBotDetailsCacheService; + private readonly PlayerScavGenerator _playerScavGenerator; + private readonly PmcChatResponseService _pmcChatResponseService; + private readonly PmcConfig _pmcConfig; + private readonly ProfileHelper _profileHelper; + private readonly QuestHelper _questHelper; + private readonly RagfairConfig _ragfairConfig; + private readonly RaidTimeAdjustmentService _raidTimeAdjustmentService; + private readonly RandomUtil _randomUtil; + private readonly RewardHelper _rewardHelper; + private readonly SaveServer _saveServer; + private readonly TimeUtil _timeUtil; + private readonly TraderConfig _traderConfig; + private readonly TraderHelper _traderHelper; public LocationLifecycleService( ISptLogger logger, @@ -82,7 +82,7 @@ public class LocationLifecycleService QuestHelper questHelper, InsuranceService insuranceService, MatchBotDetailsCacheService matchBotDetailsCacheService - ) + ) { _logger = logger; _rewardHelper = rewardHelper; @@ -111,7 +111,7 @@ public class LocationLifecycleService _questHelper = questHelper; _insuranceService = insuranceService; _matchBotDetailsCacheService = matchBotDetailsCacheService; - + _locationConfig = _configServer.GetConfig(); _inRaidConfig = _configServer.GetConfig(); _traderConfig = _configServer.GetConfig(); @@ -126,7 +126,7 @@ public class LocationLifecycleService _logger.Debug($"Starting: {request.Location}"); var playerProfile = _profileHelper.GetPmcProfile(sessionId); - + var result = new StartLocalRaidResponseData { ServerId = $"{request.Location}.{request.PlayerSide} {_timeUtil.GetTimeStamp()}", // TODO - does this need to be more verbose - investigate client? @@ -147,17 +147,17 @@ public class LocationLifecycleService }; // Only has value when transitioning into map from previous one - if (request.Transition is not null) { + if (request.Transition is not null) // TODO - why doesnt the raid after transit have any transit data? result.Transition = request.Transition; - } // Get data stored at end of previous raid (if any) var transitionData = _applicationContext .GetLatestValue(ContextVariableType.TRANSIT_INFO) ?.GetValue(); - - if (transitionData is not null) { + + if (transitionData is not null) + { _logger.Success($"Player: {sessionId} is in transit to {request.Location}"); result.Transition.TransitionType = TransitionType.COMMON; result.Transition.TransitionRaidId = transitionData.TransitionRaidId; @@ -195,10 +195,11 @@ public class LocationLifecycleService var playerIsScav = playerSide.ToLower() == "savage"; if (!playerIsScav) return; - + // Get relevant extract data for map var mapExtracts = _databaseService.GetLocation(location)?.AllExtracts; - if (mapExtracts is null) { + if (mapExtracts is null) + { _logger.Warning($"Unable to find map: {location} extract data, no adjustments made"); return; @@ -206,10 +207,9 @@ public class LocationLifecycleService // Find only scav extracts and overwrite existing exits with them var scavExtracts = mapExtracts.Where(extract => extract.Side.ToLower() == "scav").ToList(); - if (scavExtracts.Count() > 0) { + if (scavExtracts.Count() > 0) // Scav extracts found, use them locationData.Exits.AddRange(scavExtracts); - } } /** @@ -218,72 +218,66 @@ public class LocationLifecycleService */ protected void AdjustBotHostilitySettings(LocationBase location) { - foreach (var botId in _pmcConfig.HostilitySettings) { + foreach (var botId in _pmcConfig.HostilitySettings) + { var configHostilityChanges = _pmcConfig.HostilitySettings[botId.Key]; var locationBotHostilityDetails = location.BotLocationModifier.AdditionalHostilitySettings.FirstOrDefault( - botSettings => botSettings.BotRole.ToLower() == botId.Key); + botSettings => botSettings.BotRole.ToLower() == botId.Key + ); // No matching bot in config, skip - if (locationBotHostilityDetails is null) { + if (locationBotHostilityDetails is null) + { _logger.Warning($"No bot: {botId} hostility values found on: {location.Id}, can only edit existing. Skipping"); continue; } // Add new permanent enemies if they don't already exist - if (configHostilityChanges.AdditionalEnemyTypes is not null) { - foreach (var enemyTypeToAdd in configHostilityChanges.AdditionalEnemyTypes) { - if (!locationBotHostilityDetails.AlwaysEnemies.Contains(enemyTypeToAdd)) { + if (configHostilityChanges.AdditionalEnemyTypes is not null) + foreach (var enemyTypeToAdd in configHostilityChanges.AdditionalEnemyTypes) + if (!locationBotHostilityDetails.AlwaysEnemies.Contains(enemyTypeToAdd)) locationBotHostilityDetails.AlwaysEnemies.Add(enemyTypeToAdd); - } - } - } // Add/edit chance settings - if (configHostilityChanges.ChancedEnemies is not null) { + if (configHostilityChanges.ChancedEnemies is not null) + { locationBotHostilityDetails.ChancedEnemies = []; - foreach (var chanceDetailsToApply in configHostilityChanges.ChancedEnemies) { + foreach (var chanceDetailsToApply in configHostilityChanges.ChancedEnemies) + { var locationBotDetails = locationBotHostilityDetails.ChancedEnemies.FirstOrDefault( - botChance => botChance.Role == chanceDetailsToApply.Role); - if (locationBotDetails is not null) { + botChance => botChance.Role == chanceDetailsToApply.Role + ); + if (locationBotDetails is not null) // Existing locationBotDetails.EnemyChance = chanceDetailsToApply.EnemyChance; - } else { + else // Add new locationBotHostilityDetails.ChancedEnemies.Add(chanceDetailsToApply); - } } } // Add new permanent friends if they don't already exist - if (configHostilityChanges.AdditionalFriendlyTypes is not null) { + if (configHostilityChanges.AdditionalFriendlyTypes is not null) + { locationBotHostilityDetails.AlwaysFriends = []; - foreach (var friendlyTypeToAdd in configHostilityChanges.AdditionalFriendlyTypes) { - if (!locationBotHostilityDetails.AlwaysFriends.Contains(friendlyTypeToAdd)) { + foreach (var friendlyTypeToAdd in configHostilityChanges.AdditionalFriendlyTypes) + if (!locationBotHostilityDetails.AlwaysFriends.Contains(friendlyTypeToAdd)) locationBotHostilityDetails.AlwaysFriends.Add(friendlyTypeToAdd); - } - } } // Adjust vs bear hostility chance - if (configHostilityChanges.BearEnemyChance is not null) { - locationBotHostilityDetails.BearEnemyChance = configHostilityChanges.BearEnemyChance; - } + if (configHostilityChanges.BearEnemyChance is not null) locationBotHostilityDetails.BearEnemyChance = configHostilityChanges.BearEnemyChance; // Adjust vs usec hostility chance - if (configHostilityChanges.UsecEnemyChance is not null) { - locationBotHostilityDetails.UsecEnemyChance = configHostilityChanges.UsecEnemyChance; - } + if (configHostilityChanges.UsecEnemyChance is not null) locationBotHostilityDetails.UsecEnemyChance = configHostilityChanges.UsecEnemyChance; // Adjust vs savage hostility chance - if (configHostilityChanges.SavageEnemyChance is not null) { - locationBotHostilityDetails.SavageEnemyChance = configHostilityChanges.SavageEnemyChance; - } + if (configHostilityChanges.SavageEnemyChance is not null) locationBotHostilityDetails.SavageEnemyChance = configHostilityChanges.SavageEnemyChance; // Adjust vs scav hostility behaviour - if (configHostilityChanges.SavagePlayerBehaviour is not null) { + if (configHostilityChanges.SavagePlayerBehaviour is not null) locationBotHostilityDetails.SavagePlayerBehaviour = configHostilityChanges.SavagePlayerBehaviour; - } } } @@ -302,26 +296,21 @@ public class LocationLifecycleService locationBaseClone.UnixDateTime = _timeUtil.GetTimeStamp(); // Don't generate loot for hideout - if (name.ToLower() == "hideout") { - return locationBaseClone; - } + if (name.ToLower() == "hideout") return locationBaseClone; // If new spawn system is enabled, clear the spawn waves to prevent x2 spawns - if (locationBaseClone.NewSpawn is true) { - locationBaseClone.Waves = []; - } + if (locationBaseClone.NewSpawn is true) locationBaseClone.Waves = []; // Only requested base data, not loot - if (!generateLoot) { - return locationBaseClone; - } + if (!generateLoot) return locationBaseClone; // Check for a loot multipler adjustment in app context and apply if one is found LocationConfig? locationConfigClone = null; var raidAdjustments = _applicationContext .GetLatestValue(ContextVariableType.RAID_ADJUSTMENTS) ?.GetValue(); - if (raidAdjustments is not null) { + if (raidAdjustments is not null) + { locationConfigClone = _cloner.Clone(_locationConfig); // Clone values so they can be used to reset originals later _raidTimeAdjustmentService.MakeAdjustmentsToMap(raidAdjustments, locationBaseClone); } @@ -341,17 +330,17 @@ public class LocationLifecycleService ); // Push chosen spawn points into returned object - foreach (var spawnPoint in dynamicSpawnPoints) { - locationBaseClone.Loot.Add(spawnPoint); - } + foreach (var spawnPoint in dynamicSpawnPoints) locationBaseClone.Loot.Add(spawnPoint); // Done generating, log results _logger.Success( - _localisationService.GetText("location-dynamic_items_spawned_success", dynamicSpawnPoints.Count)); + _localisationService.GetText("location-dynamic_items_spawned_success", dynamicSpawnPoints.Count) + ); _logger.Success(_localisationService.GetText("location-generated_success", name)); // Reset loot multipliers back to original values - if (raidAdjustments is not null) { + if (raidAdjustments is not null) + { _logger.Debug("Resetting loot multipliers back to their original values"); _locationConfig.StaticLootMultiplier = locationConfigClone.StaticLootMultiplier; _locationConfig.LooseLootMultiplier = locationConfigClone.LooseLootMultiplier; @@ -396,7 +385,8 @@ public class LocationLifecycleService HandleItemTransferEvent(sessionId, request); // Player is moving between maps - if (isTransfer && request.LocationTransit is not null) { + if (isTransfer && request.LocationTransit is not null) + { // Manually store the map player just left request.LocationTransit.SptLastVisitedLocation = locationName; // TODO - Persist each players last visited location history over multiple transits, e.g using InMemoryCacheService, need to take care to not let data get stored forever @@ -405,7 +395,8 @@ public class LocationLifecycleService _applicationContext.AddValue(ContextVariableType.TRANSIT_INFO, request.LocationTransit); } - if (!isPmc) { + if (!isPmc) + { HandlePostRaidPlayerScav(sessionId, pmcProfile, scavProfile, isDead, isTransfer, request); return; @@ -423,16 +414,15 @@ public class LocationLifecycleService ); // Handle car extracts - if (ExtractWasViaCar(request.Results.ExitName)) { - HandleCarExtract(request.Results.ExitName, pmcProfile, sessionId); - } + if (ExtractWasViaCar(request.Results.ExitName)) HandleCarExtract(request.Results.ExitName, pmcProfile, sessionId); // Handle coop exit if ( request.Results.ExitName is not null && ExtractTakenWasCoop(request.Results.ExitName) && _traderConfig.Fence.CoopExtractGift.SendGift - ) { + ) + { HandleCoopExtract(sessionId, pmcProfile, request.Results.ExitName); SendCoopTakenFenceMessage(sessionId); } @@ -445,7 +435,8 @@ public class LocationLifecycleService var mailableLoot = new List(); var parentId = _hashUtil.Generate(); - foreach (var item in loot) { + foreach (var item in loot) + { item.ParentId = parentId; mailableLoot.Add(item); } @@ -457,7 +448,8 @@ public class LocationLifecycleService MessageType.MESSAGE_WITH_ITEMS, _randomUtil.GetArrayValue(_traderConfig.Fence.CoopExtractGift.MessageLocaleIds), mailableLoot, - _timeUtil.GetHoursAsSeconds(_traderConfig.Fence.CoopExtractGift.GiftExpiryHours)); + _timeUtil.GetHoursAsSeconds(_traderConfig.Fence.CoopExtractGift.GiftExpiryHours) + ); } /** @@ -468,13 +460,9 @@ public class LocationLifecycleService protected bool ExtractWasViaCar(string extractName) { // exit name is undefined on death - if (extractName is null) { - return false; - } + if (extractName is null) return false; - if (extractName.ToLower().Contains("v-ex")) { - return true; - } + if (extractName.ToLower().Contains("v-ex")) return true; return _inRaidConfig.CarExtracts.Contains(extractName.Trim()); } @@ -488,15 +476,16 @@ public class LocationLifecycleService protected void HandleCarExtract(string extractName, PmcData pmcData, string sessionId) { pmcData.CarExtractCounts?.TryAdd(extractName, 0); - + // Increment extract count value pmcData.CarExtractCounts[extractName] += 1; - + var newFenceStanding = GetFenceStandingAfterExtract( pmcData, _inRaidConfig.CarExtractBaseStandingGain, - pmcData.CarExtractCounts[extractName]); - + pmcData.CarExtractCounts[extractName] + ); + var fenceId = Traders.FENCE; pmcData.TradersInfo[fenceId].Standing = newFenceStanding; @@ -521,14 +510,15 @@ public class LocationLifecycleService protected void HandleCoopExtract(string sessionId, PmcData pmcData, string extractName) { pmcData.CoopExtractCounts?.TryAdd(extractName, 0); - + pmcData.CoopExtractCounts[extractName] += 1; - + var newFenceStanding = GetFenceStandingAfterExtract( pmcData, _inRaidConfig.CoopExtractBaseStandingGain, - pmcData.CoopExtractCounts[extractName]); - + pmcData.CoopExtractCounts[extractName] + ); + var fenceId = Traders.FENCE; pmcData.TradersInfo[fenceId].Standing = newFenceStanding; @@ -572,9 +562,7 @@ public class LocationLifecycleService protected bool ExtractTakenWasCoop(string extractName) { // No extract name, not a coop extract - if (extractName is null) { - return false; - } + if (extractName is null) return false; return _inRaidConfig.CoopExtracts.Contains(extractName.Trim()); } @@ -589,10 +577,9 @@ public class LocationLifecycleService { var postRaidProfile = request.Results.Profile; - if (isTransfer) { + if (isTransfer) // We want scav inventory to persist into next raid when pscav is moving between maps _inRaidHelper.SetInventory(sessionId, scavProfile, postRaidProfile, true, isTransfer); - } scavProfile.Info.Level = request.Results.Profile.Info.Level; scavProfile.Skills = request.Results.Profile.Skills; @@ -618,17 +605,15 @@ public class LocationLifecycleService scavProfile.TradersInfo[Traders.FENCE].Standing = Math.Min(Math.Max((double)currentFenceStanding, fenceMin), fenceMax); // Successful extract as scav, give some rep - if (IsPlayerSurvived(request.Results) && scavProfile.TradersInfo[Traders.FENCE].Standing < fenceMax) { + if (IsPlayerSurvived(request.Results) && scavProfile.TradersInfo[Traders.FENCE].Standing < fenceMax) scavProfile.TradersInfo[Traders.FENCE].Standing += _inRaidConfig.ScavExtractStandingGain; - } // Copy scav fence values to PMC profile pmcProfile.TradersInfo[Traders.FENCE] = scavProfile.TradersInfo[Traders.FENCE]; - if (ProfileHasConditionCounters(scavProfile)) { + if (ProfileHasConditionCounters(scavProfile)) // Scav quest progress needs to be moved to pmc so player can see it in menu / hand them in MigrateScavQuestProgressToPmcProfile(scavProfile, pmcProfile); - } // Must occur after encyclopedia updated MergePmcAndScavEncyclopedias(scavProfile, pmcProfile); @@ -637,9 +622,7 @@ public class LocationLifecycleService ResetSkillPointsEarnedDuringRaid(scavProfile.Skills.Common); // Scav died, regen scav loadout and reset timer - if (isDead) { - _playerScavGenerator.Generate(sessionId); - } + if (isDead) _playerScavGenerator.Generate(sessionId); // Update last played property pmcProfile.Info.LastTimePlayedAsSavage = _timeUtil.GetTimeStamp(); @@ -647,7 +630,7 @@ public class LocationLifecycleService // Force a profile save _saveServer.SaveProfile(sessionId); } - + /** * Scav quest progress isnt transferred automatically from scav to pmc, we do this manually * @param scavProfile Scav profile with quest progress post-raid @@ -655,26 +638,29 @@ public class LocationLifecycleService */ private void MigrateScavQuestProgressToPmcProfile(PmcData scavProfile, PmcData pmcProfile) { - foreach (var scavQuest in scavProfile.Quests) { + foreach (var scavQuest in scavProfile.Quests) + { var pmcQuest = pmcProfile.Quests.FirstOrDefault(quest => quest.QId == scavQuest.QId); - if (pmcQuest is null) { - _logger.Warning(_localisationService.GetText("inraid-unable_to_migrate_pmc_quest_not_found_in_profile", - scavQuest.QId)); + if (pmcQuest is null) + { + _logger.Warning( + _localisationService.GetText( + "inraid-unable_to_migrate_pmc_quest_not_found_in_profile", + scavQuest.QId + ) + ); continue; } // Get counters related to scav quest var matchingCounters = scavProfile.TaskConditionCounters.Where( - counter => counter.Value.SourceId == scavQuest.QId); + counter => counter.Value.SourceId == scavQuest.QId + ); - if (matchingCounters is null) { - continue; - } + if (matchingCounters is null) continue; // insert scav quest counters into pmc profile - foreach (var counter in matchingCounters) { - pmcProfile.TaskConditionCounters[counter.Value.Id] = counter.Value; - } + foreach (var counter in matchingCounters) pmcProfile.TaskConditionCounters[counter.Value.Id] = counter.Value; // Find Matching PMC Quest // Update Status and StatusTimer properties @@ -690,9 +676,7 @@ public class LocationLifecycleService */ protected bool ProfileHasConditionCounters(PmcData profile) { - if (profile.TaskConditionCounters is null) { - return false; - } + if (profile.TaskConditionCounters is null) return false; return profile.TaskConditionCounters.Count > 0; } @@ -738,7 +722,7 @@ public class LocationLifecycleService // MUST occur prior to profile achievements being overwritten by post-raid achievements ProcessAchievementRewards(fullProfile, postRaidProfile.Achievements); - pmcProfile.Achievements = postRaidProfile.Achievements; + pmcProfile.Achievements = postRaidProfile.Achievements; pmcProfile.Quests = ProcessPostRaidQuests(postRaidProfile.Quests); // Handle edge case - must occur AFTER processPostRaidQuests() @@ -753,10 +737,10 @@ public class LocationLifecycleService // Must occur AFTER experience is set and stats copied over pmcProfile.Stats.Eft.TotalSessionExperience = 0; - var fenceId = Traders.FENCE; + var fenceId = Traders.FENCE; // Clamp fence standing - var currentFenceStanding = postRaidProfile.TradersInfo[fenceId].Standing; + var currentFenceStanding = postRaidProfile.TradersInfo[fenceId].Standing; pmcProfile.TradersInfo[fenceId].Standing = Math.Min(Math.Max((double)currentFenceStanding, -7), 15); // Ensure it stays between -7 and 15 @@ -775,37 +759,34 @@ public class LocationLifecycleService if (isDead) { if (lostQuestItems.Count > 0) - { // MUST occur AFTER quests have post raid quest data has been merged "processPostRaidQuests()" // Player is dead + had quest items, check and fix any broken find item quests CheckForAndFixPickupQuestsAfterDeath(sessionId, lostQuestItems, pmcProfile.Quests); - } if (postRaidProfile.Stats.Eft.Aggressor is not null) - { _pmcChatResponseService.SendKillerResponse(sessionId, pmcProfile, postRaidProfile.Stats.Eft.Aggressor); - } _inRaidHelper.DeleteInventory(pmcProfile, sessionId); _inRaidHelper.RemoveFiRStatusFromItemsInContainer(sessionId, pmcProfile, "SecuredContainer"); } - + // Must occur AFTER killer messages have been sent _matchBotDetailsCacheService.ClearCache(); - var roles = new List + var roles = new List { "pmcbear", "pmcusec" }; var victims = postRaidProfile.Stats.Eft.Victims.Where( - victim => roles.Contains(victim.Role.ToLower())).ToList(); - if (victims?.Count > 0) { + victim => roles.Contains(victim.Role.ToLower()) + ) + .ToList(); + if (victims?.Count > 0) // Player killed PMCs, send some mail responses to them _pmcChatResponseService.SendVictimResponse(sessionId, victims, pmcProfile); - } HandleInsuredItemLostEvent(sessionId, pmcProfile, request, locationName); } @@ -822,32 +803,39 @@ public class LocationLifecycleService .Select(status => status.QId); // Get db details of quests we found above - var questDb = _databaseService.GetQuests().Values.Where(quest => - activeQuestIdsInProfile.Contains(quest.Id)); + var questDb = _databaseService.GetQuests() + .Values.Where( + quest => + activeQuestIdsInProfile.Contains(quest.Id) + ); foreach (var lostItem in lostQuestItems) { - string matchingConditionId = string.Empty; + var matchingConditionId = string.Empty; // Find a quest that has a FindItem condition that has the list items tpl as a target - var matchingQuests = questDb.Where(quest => { - var matchingCondition = quest.Conditions.AvailableForFinish.FirstOrDefault( - questCondition => questCondition.ConditionType == "FindItem" && - (questCondition.Target.IsList - ? questCondition.Target.List - : [questCondition.Target.Item]).Contains(lostItem.Template) - ); - if (matchingCondition is null) { - // Quest doesnt have a matching condition - return false; - } + var matchingQuests = questDb.Where( + quest => + { + var matchingCondition = quest.Conditions.AvailableForFinish.FirstOrDefault( + questCondition => questCondition.ConditionType == "FindItem" && + (questCondition.Target.IsList + ? questCondition.Target.List + : [questCondition.Target.Item]).Contains(lostItem.Template) + ); + if (matchingCondition is null) + // Quest doesnt have a matching condition + return false; - // We found a condition, save id for later - matchingConditionId = matchingCondition.Id; - return true; - }).ToList(); + // We found a condition, save id for later + matchingConditionId = matchingCondition.Id; + return true; + } + ) + .ToList(); // Fail if multiple were found - if (matchingQuests.Count != 1) { + if (matchingQuests.Count != 1) + { _logger.Error($"Unable to fix quest item: {lostItem}, {matchingQuests.Count()} matching quests found, expected 1"); continue; @@ -856,14 +844,15 @@ public class LocationLifecycleService var matchingQuest = matchingQuests[0]; // We have a match, remove the condition id from profile to reset progress and let player pick item up again var profileQuestToUpdate = profileQuests.FirstOrDefault(questStatus => questStatus.QId == matchingQuest.Id); - if (profileQuestToUpdate is null) { + if (profileQuestToUpdate is null) // Profile doesnt have a matching quest continue; - } // Filter out the matching condition we found profileQuestToUpdate.CompletedConditions = profileQuestToUpdate.CompletedConditions.Where( - conditionId => conditionId != matchingConditionId).ToList(); + conditionId => conditionId != matchingConditionId + ) + .ToList(); } } @@ -881,18 +870,22 @@ public class LocationLifecycleService { // LK quests that were not completed before raid but now are var newlyCompletedLightkeeperQuests = postRaidQuests - .Where(postRaidQuest => - postRaidQuest.Status == QuestStatusEnum.Success && // Quest is complete - preRaidQuests.Any(preRaidQuest => - preRaidQuest.QId == postRaidQuest.QId && // Get matching pre-raid quest - preRaidQuest.Status != QuestStatusEnum.Success) && // Completed quest was not completed before raid started - _databaseService.GetQuests().TryGetValue(postRaidQuest.QId, out var quest) && quest?.TraderId == Traders.LIGHTHOUSEKEEPER) // Quest is from LK + .Where( + postRaidQuest => + postRaidQuest.Status == QuestStatusEnum.Success && // Quest is complete + preRaidQuests.Any( + preRaidQuest => + preRaidQuest.QId == postRaidQuest.QId && // Get matching pre-raid quest + preRaidQuest.Status != QuestStatusEnum.Success + ) && // Completed quest was not completed before raid started + _databaseService.GetQuests().TryGetValue(postRaidQuest.QId, out var quest) && + quest?.TraderId == Traders.LIGHTHOUSEKEEPER + ) // Quest is from LK .ToList(); // Run server complete quest process to ensure player gets rewards foreach (var questToComplete in newlyCompletedLightkeeperQuests) - { _questHelper.CompleteQuest( pmcProfile, new CompleteQuestRequestData @@ -903,7 +896,6 @@ public class LocationLifecycleService }, sessionId ); - } } /* @@ -913,15 +905,12 @@ public class LocationLifecycleService protected List ProcessPostRaidQuests(List questsToProcess) { var failedQuests = questsToProcess.Where(quest => quest.Status == QuestStatusEnum.MarkedAsFailed); - foreach (var failedQuest in failedQuests) { + foreach (var failedQuest in failedQuests) + { var dbQuest = _databaseService.GetQuests()[failedQuest.QId]; - if (dbQuest is null) { - continue; - } + if (dbQuest is null) continue; - if (dbQuest.Restartable is not null) { - failedQuest.Status = QuestStatusEnum.Fail; - } + if (dbQuest.Restartable is not null) failedQuest.Status = QuestStatusEnum.Fail; } return questsToProcess; @@ -935,17 +924,15 @@ public class LocationLifecycleService Dictionary? tradersClientProfile ) { - foreach (var traderId in tradersClientProfile) { + foreach (var traderId in tradersClientProfile) + { var serverProfileTrader = tradersServerProfile.FirstOrDefault(x => x.Key == traderId.Key).Value; var clientProfileTrader = tradersClientProfile.FirstOrDefault(x => x.Key == traderId.Key).Value; - if (serverProfileTrader is null || clientProfileTrader is null) { - continue; - } + if (serverProfileTrader is null || clientProfileTrader is null) continue; - if (clientProfileTrader.Standing != serverProfileTrader.Standing) { + if (clientProfileTrader.Standing != serverProfileTrader.Standing) // Difference found, update server profile with values from client profile tradersServerProfile[traderId.Key].Standing = clientProfileTrader.Standing; - } } } @@ -960,21 +947,17 @@ public class LocationLifecycleService "transit" }; - foreach (var trasferType in transferTypes) { + foreach (var trasferType in transferTypes) + { var rootId = $"{Traders.BTR}_{trasferType}"; List? itemsToSend = null; // if rootId doesnt exist in TransferItems, skip - if (!request?.TransferItems?.TryGetValue(rootId, out itemsToSend) ?? false) - { - continue; - } - + if (!request?.TransferItems?.TryGetValue(rootId, out itemsToSend) ?? false) continue; + // Filter out the btr container item from transferred items before delivering itemsToSend = itemsToSend?.Where(item => item.Id != Traders.BTR).ToList(); - if (itemsToSend?.Count == 0) { - continue; - } + if (itemsToSend?.Count == 0) continue; TransferItemDelivery(sessionId, Traders.BTR, itemsToSend); } @@ -986,7 +969,8 @@ public class LocationLifecycleService var pmcData = serverProfile.CharacterData.PmcData; var dialogueTemplates = _databaseService.GetTrader(traderId).Dialogue; - if (dialogueTemplates is null) { + if (dialogueTemplates is null) + { _logger.Error(_localisationService.GetText("inraid-unable_to_deliver_item_no_trader_found", traderId)); return; @@ -997,6 +981,7 @@ public class LocationLifecycleService _logger.Error("dialogueTemplates doesn't contain itemsDelivered"); return; } + var messageId = _randomUtil.GetArrayValue(itemsDelivered); var messageStoreTime = _timeUtil.GetHoursAsSeconds(_traderConfig.Fence.BtrDeliveryExpireHours); @@ -1004,7 +989,9 @@ public class LocationLifecycleService // This is to stop items being duplicated by being returned from both item delivery and insurance var deliveredItemIds = items.Select(item => item.Id); pmcData.InsuredItems = pmcData.InsuredItems.Where( - insuredItem => !deliveredItemIds.Contains(insuredItem.ItemId)).ToList(); + insuredItem => !deliveredItemIds.Contains(insuredItem.ItemId) + ) + .ToList(); // Send the items to the player _mailSendService.SendLocalisedNpcMessageToPlayer( @@ -1013,7 +1000,8 @@ public class LocationLifecycleService MessageType.BTR_ITEMS_DELIVERY, messageId, items, - (int)messageStoreTime); + (int)messageStoreTime + ); } protected void HandleInsuredItemLostEvent( @@ -1032,10 +1020,7 @@ public class LocationLifecycleService ); // Is possible to have items in lostInsuredItems but removed before reaching mappedItems - if (mappedItems.Count == 0) - { - return; - } + if (mappedItems.Count == 0) return; _insuranceService.StoreGearLostInRaidToSendLater(sessionId, mappedItems); @@ -1075,25 +1060,21 @@ public class LocationLifecycleService var inventoryItems = new List(); // Get an array of root player items - foreach (var item in items) { - if (inventorySlots.Contains(item.SlotId)) { + foreach (var item in items) + if (inventorySlots.Contains(item.SlotId)) inventoryItems.Add(item); - } - } // Loop through these items and get all of their children var newItems = inventoryItems; - while (newItems.Count > 0) { + while (newItems.Count > 0) + { var foundItems = new List(); - foreach (var item in newItems) { + foreach (var item in newItems) // Find children of this item - foreach (var newItem in items) { - if (newItem.ParentId == item.Id) { - foundItems.Add(newItem); - } - } - } + foreach (var newItem in items) + if (newItem.ParentId == item.Id) + foundItems.Add(newItem); // Add these new found items to our list of inventory items inventoryItems.AddRange(inventoryItems); @@ -1124,7 +1105,6 @@ public class LocationLifecycleService ExitStatus.KILLED, ExitStatus.MISSINGINACTION, ExitStatus.LEFT - }; return deathEnums.Contains(results.Result.Value); } @@ -1142,9 +1122,7 @@ public class LocationLifecycleService */ protected void ResetSkillPointsEarnedDuringRaid(List commonSkills) { - foreach (var skill in commonSkills) { - skill.PointsEarnedDuringSession = 0; - } + foreach (var skill in commonSkills) skill.PointsEarnedDuringSession = 0; } /* @@ -1183,10 +1161,8 @@ public class LocationLifecycleService achievementsDb.FirstOrDefault((achievementDb) => achievementDb.Id == achievementId.Key) ); if (achievements is null) - { // No achievements found return; - } foreach (var achievement in achievements) { @@ -1199,7 +1175,6 @@ public class LocationLifecycleService ); if (rewardItems?.Count > 0) - { _mailSendService.SendLocalisedSystemMessageToPlayer( sessionId, "670547bb5fa0b1a7c30d5836 0", @@ -1207,7 +1182,6 @@ public class LocationLifecycleService [], _timeUtil.GetHoursAsSeconds(24 * 7) ); - } } } } diff --git a/Libraries/Core/Services/MailSendService.cs b/Libraries/Core/Services/MailSendService.cs index d79ac44f..5e446815 100644 --- a/Libraries/Core/Services/MailSendService.cs +++ b/Libraries/Core/Services/MailSendService.cs @@ -59,7 +59,7 @@ public class MailSendService( new { messageType = messageType, - sessionId = sessionId, + sessionId = sessionId } ) ); @@ -81,7 +81,7 @@ public class MailSendService( if (items?.Count > 0) { details.Items.AddRange(items); - details.ItemsMaxStorageLifetimeSeconds = (long?)(maxStorageTimeSeconds); + details.ItemsMaxStorageLifetimeSeconds = (long?)maxStorageTimeSeconds; } if (systemData is not null) @@ -121,7 +121,7 @@ public class MailSendService( new { messageType = messageType, - sessionId = sessionId, + sessionId = sessionId } ) ); @@ -136,7 +136,7 @@ public class MailSendService( DialogType = MessageType.NPC_TRADER, Trader = trader, TemplateId = messageLocaleId, - Items = new() + Items = new List() }; // add items to message @@ -145,13 +145,9 @@ public class MailSendService( { details.Items.AddRange(items); if (maxStorageTimeSeconds is not null && maxStorageTimeSeconds > 0) - { details.ItemsMaxStorageLifetimeSeconds = maxStorageTimeSeconds; - } else - { details.ItemsMaxStorageLifetimeSeconds = 172800; - } } if (systemData is not null) @@ -182,7 +178,7 @@ public class MailSendService( RecipientId = sessionId, Sender = MessageType.SYSTEM_MESSAGE, MessageText = message, - Items = new() + Items = new List() }; // add items to message @@ -213,7 +209,7 @@ public class MailSendService( RecipientId = sessionId, Sender = MessageType.SYSTEM_MESSAGE, TemplateId = messageLocaleId, - Items = new() + Items = new List() }; // add items to message @@ -251,7 +247,7 @@ public class MailSendService( Sender = MessageType.USER_MESSAGE, SenderDetails = senderDetails, MessageText = message, - Items = new() + Items = new List() }; // add items to message @@ -285,10 +281,7 @@ public class MailSendService( var itemsToSendToPlayer = ProcessItemsBeforeAddingToMail(senderDialog.Type, messageDetails); // If there's items to send to player, flag dialog as containing attachments - if ((itemsToSendToPlayer.Data?.Count ?? 0) > 0) - { - senderDialog.AttachmentsNew += 1; - } + if ((itemsToSendToPlayer.Data?.Count ?? 0) > 0) senderDialog.AttachmentsNew += 1; // Store reward items inside message and set appropriate flags inside message AddRewardItemsToMessage(message, itemsToSendToPlayer, messageDetails.ItemsMaxStorageLifetimeSeconds); @@ -303,7 +296,7 @@ public class MailSendService( // Offer Sold notifications are now separate from the main notification if (_messageTypes.Contains(senderDialog.Type ?? MessageType.SYSTEM_MESSAGE) && messageDetails?.RagfairDetails is not null - ) + ) { var offerSoldMessage = _notifierHelper.CreateRagfairOfferSoldNotification( message, @@ -329,7 +322,7 @@ public class MailSendService( } dialogWithNpc.Messages.Add( - new() + new Message { Id = _hashUtil.Generate(), DateTime = _timeUtil.GetTimeStamp(), @@ -350,22 +343,19 @@ public class MailSendService( UserId = dialogId, MessageType = messageDetails.DialogType, DateTime = _timeUtil.GetTimeStamp(), - Text = (messageDetails.TemplateId is not null) ? "" : messageDetails.MessageText, + Text = messageDetails.TemplateId is not null ? "" : messageDetails.MessageText, TemplateId = messageDetails.TemplateId, HasRewards = false, RewardCollected = false, SystemData = messageDetails.SystemData is not null ? messageDetails.SystemData : null, - ProfileChangeEvents = (messageDetails.ProfileChangeEvents?.Count == 0) ? messageDetails.ProfileChangeEvents : null + ProfileChangeEvents = messageDetails.ProfileChangeEvents?.Count == 0 ? messageDetails.ProfileChangeEvents : null }; // Handle replyTo if (messageDetails.ReplyTo is not null) { var replyMessage = GetMessageToReplyTo(messageDetails.RecipientId, messageDetails.ReplyTo, dialogId); - if (replyMessage is not null) - { - message.ReplyTo = replyMessage; - } + if (replyMessage is not null) message.ReplyTo = replyMessage; } return message; @@ -388,10 +378,7 @@ public class MailSendService( } var messageToReplyTo = currentDialogue.Messages?.FirstOrDefault(message => message.Id == replyToId); - if (messageToReplyTo is null) - { - return null; - } + if (messageToReplyTo is null) return null; return new ReplyTo { @@ -436,7 +423,7 @@ public class MailSendService( new { traderId = messageDetails.Trader, - sender = messageDetails.Sender, + sender = messageDetails.Sender } ); @@ -448,9 +435,9 @@ public class MailSendService( parentItem.ParentId = _hashUtil.Generate(); // Prep return object - itemsToSendToPlayer = new() + itemsToSendToPlayer = new MessageItems { - Stash = parentItem.ParentId, Data = new() + Stash = parentItem.ParentId, Data = new List() }; // Ensure Ids are unique and cont collide with items in player inventory later @@ -468,7 +455,7 @@ public class MailSendService( new { tpl = reward.Template, - type = dialogType, + type = dialogType } ) ); @@ -557,16 +544,12 @@ public class MailSendService( private Dialogue GetDialog(SendMessageDetails messageDetails) { var senderId = GetMessageSenderIdByType(messageDetails); - if (senderId is null) - { - throw new Exception(_localisationService.GetText("mail-unable_to_find_message_sender_by_id", messageDetails.Sender)); - } + if (senderId is null) throw new Exception(_localisationService.GetText("mail-unable_to_find_message_sender_by_id", messageDetails.Sender)); var dialogsInProfile = _dialogueHelper.GetDialogsForProfile(messageDetails.RecipientId); // Does dialog exist if (!dialogsInProfile.ContainsKey(senderId)) - { // Doesn't exist, create dialogsInProfile[senderId] = new Dialogue { @@ -577,7 +560,6 @@ public class MailSendService( New = 0, AttachmentsNew = 0 }; - } return dialogsInProfile[senderId]; } @@ -593,7 +575,7 @@ public class MailSendService( return _systemSenderId; if (messageDetails.Sender == MessageType.NPC_TRADER || messageDetails.DialogType == MessageType.NPC_TRADER) - return (messageDetails.Trader is not null) ? _traderHelper.GetValidTraderIdByEnumValue(messageDetails.Trader) : null; + return messageDetails.Trader is not null ? _traderHelper.GetValidTraderIdByEnumValue(messageDetails.Trader) : null; if (messageDetails.Sender == MessageType.USER_MESSAGE) return messageDetails.SenderDetails?.Id; diff --git a/Libraries/Core/Services/MapMarkerService.cs b/Libraries/Core/Services/MapMarkerService.cs index 6eb1eb9b..10ccc85b 100644 --- a/Libraries/Core/Services/MapMarkerService.cs +++ b/Libraries/Core/Services/MapMarkerService.cs @@ -24,7 +24,7 @@ public class MapMarkerService( var mapItem = pmcData?.Inventory?.Items?.FirstOrDefault((i) => i?.Id == request?.Item); // add marker to map item - mapItem.Upd.Map = mapItem?.Upd?.Map ?? new() { Markers = new() }; + mapItem.Upd.Map = mapItem?.Upd?.Map ?? new UpdMap { Markers = new List() }; // Update request note with text, then add to maps upd request.MapMarker.Note = SanitiseMapMarkerText(request.MapMarker.Note); @@ -72,7 +72,7 @@ public class MapMarkerService( _logger.Warning($"No marker found for item {request.Item}"); return null; } - + request.MapMarker.Note = SanitiseMapMarkerText(request.MapMarker.Note); mapItem.Upd.Map.Markers.Remove(markerToRemove); mapItem.Upd.Map.Markers.Add(request.MapMarker); diff --git a/Libraries/Core/Services/Mod/CustomItemService.cs b/Libraries/Core/Services/Mod/CustomItemService.cs index e96d7ca6..5c4e2627 100644 --- a/Libraries/Core/Services/Mod/CustomItemService.cs +++ b/Libraries/Core/Services/Mod/CustomItemService.cs @@ -67,10 +67,7 @@ public class CustomItemService( _itemBaseClassService.HydrateItemBaseClassCache(); - if (_itemHelper.IsOfBaseclass(itemClone.Id, BaseClasses.WEAPON)) - { - AddToWeaponShelf(newItemId); - } + if (_itemHelper.IsOfBaseclass(itemClone.Id, BaseClasses.WEAPON)) AddToWeaponShelf(newItemId); result.Success = true; result.ItemId = newItemId; @@ -111,10 +108,7 @@ public class CustomItemService( _itemBaseClassService.HydrateItemBaseClassCache(); - if (_itemHelper.IsOfBaseclass(newItem.Id, BaseClasses.WEAPON)) - { - AddToWeaponShelf(newItem.Id); - } + if (_itemHelper.IsOfBaseclass(newItem.Id, BaseClasses.WEAPON)) AddToWeaponShelf(newItem.Id); result.ItemId = newItemDetails.NewItem.Id; result.Success = true; @@ -140,9 +134,8 @@ public class CustomItemService( */ protected void UpdateBaseItemPropertiesWithOverrides(Props? overrideProperties, TemplateItem itemClone) { - foreach (var propKey in overrideProperties.GetAllPropsAsDict()) { + foreach (var propKey in overrideProperties.GetAllPropsAsDict()) itemClone.Properties.GetAllPropsAsDict()[propKey.Key] = overrideProperties.GetAllPropsAsDict()[propKey.Key]; - } } /** @@ -152,10 +145,7 @@ public class CustomItemService( */ protected void AddToItemsDb(string newItemId, TemplateItem itemToAdd) { - if (!_databaseService.GetItems().TryAdd(newItemId, itemToAdd)) - { - _logger.Warning($"Unable to add: {newItemId} To Database"); - } + if (!_databaseService.GetItems().TryAdd(newItemId, itemToAdd)) _logger.Warning($"Unable to add: {newItemId} To Database"); } /** @@ -191,10 +181,7 @@ public class CustomItemService( // Get locale details passed in, if not provided by caller use first record in newItemDetails.locales localeDetails.TryGetValue(shortNameKey.Key, out var newLocaleDetails); - if (newLocaleDetails is null) - { - newLocaleDetails = localeDetails[localeDetails.Keys.FirstOrDefault()]; - } + if (newLocaleDetails is null) newLocaleDetails = localeDetails[localeDetails.Keys.FirstOrDefault()]; // Create new record in locale file var globals = _databaseService.GetLocales(); @@ -230,10 +217,7 @@ public class CustomItemService( foreach (var wallId in wallStashIds) { var wall = _itemHelper.GetItem(wallId); - if (wall.Key) - { - wall.Value.Properties.Grids[0].Props.Filters[0].Filter.Add(newItemId); - } + if (wall.Key) wall.Value.Properties.Grids[0].Props.Filters[0].Filter.Add(newItemId); } } @@ -257,10 +241,7 @@ public class CustomItemService( // Get all slots weapon has and create a dictionary of them with possible mods that slot into each var weaponSlots = weapon.Value.Properties.Slots; - foreach (var slot in weaponSlots) - { - baseWeaponModObject[slot.Name] = new HashSet(slot.Props.Filters[0].Filter); - } + foreach (var slot in weaponSlots) baseWeaponModObject[slot.Name] = new HashSet(slot.Props.Filters[0].Filter); // Get PMCs var botTypes = _databaseService.GetBots().Types; diff --git a/Libraries/Core/Services/NotificationService.cs b/Libraries/Core/Services/NotificationService.cs index b1c91755..6e2fe5c9 100644 --- a/Libraries/Core/Services/NotificationService.cs +++ b/Libraries/Core/Services/NotificationService.cs @@ -20,10 +20,7 @@ public class NotificationService public void UpdateMessageOnQueue(string sessionId, List value) { - if (_messageQueue.ContainsKey(sessionId)) - { - _messageQueue[sessionId] = value; - } + if (_messageQueue.ContainsKey(sessionId)) _messageQueue[sessionId] = value; } public bool Has(string sessionID) @@ -55,15 +52,9 @@ public class NotificationService /// public List Get(string sessionID) { - if (sessionID is null) - { - throw new Exception("sessionID missing"); - } + if (sessionID is null) throw new Exception("sessionID missing"); - if (!_messageQueue.ContainsKey(sessionID)) - { - _messageQueue[sessionID] = []; - } + if (!_messageQueue.ContainsKey(sessionID)) _messageQueue[sessionID] = []; return _messageQueue[sessionID]; } diff --git a/Libraries/Core/Services/OpenZoneService.cs b/Libraries/Core/Services/OpenZoneService.cs index 38ecfe24..ac4349a8 100644 --- a/Libraries/Core/Services/OpenZoneService.cs +++ b/Libraries/Core/Services/OpenZoneService.cs @@ -24,10 +24,7 @@ public class OpenZoneService( { _locationConfig.OpenZones.TryAdd(locationId, []); - if (!_locationConfig.OpenZones[locationId].Contains(zoneToAdd)) - { - _locationConfig.OpenZones[locationId].Add(zoneToAdd); - } + if (!_locationConfig.OpenZones[locationId].Contains(zoneToAdd)) _locationConfig.OpenZones[locationId].Add(zoneToAdd); } /// diff --git a/Libraries/Core/Services/PaymentService.cs b/Libraries/Core/Services/PaymentService.cs index 700f9ceb..44e9bf4f 100644 --- a/Libraries/Core/Services/PaymentService.cs +++ b/Libraries/Core/Services/PaymentService.cs @@ -69,7 +69,7 @@ public class PaymentService( else { // If the item is money, add its count to the currencyAmounts object. - currencyAmounts.TryAdd(item.Template, (currencyAmounts.GetValueOrDefault(item.Template, 0)) + itemRequest.Count); + currencyAmounts.TryAdd(item.Template, currencyAmounts.GetValueOrDefault(item.Template, 0) + itemRequest.Count); } } else @@ -77,7 +77,7 @@ public class PaymentService( // Used by `SptInsure` // Handle differently, `id` is the money type tpl var currencyTpl = itemRequest.Id; - currencyAmounts.TryAdd(currencyTpl, (currencyAmounts.GetValueOrDefault(currencyTpl, 0)) + itemRequest.Count); + currencyAmounts.TryAdd(currencyTpl, currencyAmounts.GetValueOrDefault(currencyTpl, 0) + itemRequest.Count); } } @@ -87,10 +87,7 @@ public class PaymentService( // Loop through each type of currency involved in the trade. foreach (var currencyTpl in currencyAmounts) { - if (currencyTpl.Value <= 0) - { - continue; - } + if (currencyTpl.Value <= 0) continue; var currencyAmount = currencyTpl.Value; totalCurrencyAmount += (int)currencyAmount; @@ -99,10 +96,7 @@ public class PaymentService( AddPaymentToOutput(pmcData, currencyTpl.Key, (int)currencyAmount, sessionID, output); // If there are warnings, exit early. - if (output.Warnings?.Count > 0) - { - return; - } + if (output.Warnings?.Count > 0) return; if (payToTrader) { @@ -131,24 +125,15 @@ public class PaymentService( pmcData.TradersInfo[request.TransactionId].SalesSum += costOfPurchaseInCurrency; } - if (payToTrader) - { - _traderHelper.LevelUp(request.TransactionId, pmcData); - } + if (payToTrader) _traderHelper.LevelUp(request.TransactionId, pmcData); - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug("Item(s) taken. Status OK."); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug("Item(s) taken. Status OK."); } private double? GetTraderItemHandbookPriceRouble(string? traderAssortId, string traderId) { var purchasedAssortItem = _traderHelper.GetTraderAssortItemByAssortId(traderId, traderAssortId); - if (purchasedAssortItem is null) - { - return 1; - } + if (purchasedAssortItem is null) return 1; var assortItemPriceRouble = _handbookHelper.GetTemplatePrice(purchasedAssortItem.Template); if (assortItemPriceRouble == 0) @@ -187,16 +172,10 @@ public class PaymentService( foreach (var item in pmcData.Inventory.Items) { // Item is not currency - if (item.Template != currencyTpl) - { - continue; - } + if (item.Template != currencyTpl) continue; // Item is not in the stash - if (!_inventoryHelper.IsItemInStash(pmcData, item)) - { - continue; - } + if (!_inventoryHelper.IsItemInStash(pmcData, item)) continue; // Found currency item if (item.Upd.StackObjectsCount < currencyMaxStackSize) @@ -204,7 +183,7 @@ public class PaymentService( if (item.Upd.StackObjectsCount + calcAmount > currencyMaxStackSize) { // calculate difference - calcAmount -= (int)((currencyMaxStackSize - item.Upd.StackObjectsCount) ?? 0); + calcAmount -= (int)(currencyMaxStackSize - item.Upd.StackObjectsCount ?? 0); item.Upd.StackObjectsCount = currencyMaxStackSize; } else @@ -216,15 +195,12 @@ public class PaymentService( // Inform client of change to items StackObjectsCount output.ProfileChanges[sessionID].Items.ChangedItems.Add(item); - if (skipSendingMoneyToStash) - { - break; - } + if (skipSendingMoneyToStash) break; } } // Create single currency item with all currency on it - Item rootCurrencyReward = new Item + var rootCurrencyReward = new Item { Id = _hashUtil.Generate(), Template = currencyTpl, @@ -236,12 +212,12 @@ public class PaymentService( if (!skipSendingMoneyToStash) { - AddItemsDirectRequest addItemToStashRequest = new AddItemsDirectRequest + var addItemToStashRequest = new AddItemsDirectRequest { ItemsWithModsToAdd = rewards, FoundInRaid = false, Callback = null, - UseSortingTable = true, + UseSortingTable = true }; _inventoryHelper.AddItemsToStash(sessionID, addItemToStashRequest, pmcData, output); } @@ -276,10 +252,7 @@ public class PaymentService( ); //Ensure all money items found have a upd - foreach (var moneyStack in moneyItemsInInventory) - { - moneyStack.Upd ??= new Upd { StackObjectsCount = 1 }; - } + foreach (var moneyStack in moneyItemsInInventory) moneyStack.Upd ??= new Upd { StackObjectsCount = 1 }; var amountAvailable = moneyItemsInInventory.Aggregate( 0, @@ -295,7 +268,7 @@ public class PaymentService( new { amountToPay = amountToPay, - amountAvailable = amountAvailable, + amountAvailable = amountAvailable } ) ); @@ -324,10 +297,7 @@ public class PaymentService( output.ProfileChanges[sessionID].Items.ChangedItems.Add(profileMoneyItem); } - if (leftToPay == 0) - { - break; - } + if (leftToPay == 0) break; } } @@ -342,10 +312,7 @@ public class PaymentService( protected List GetSortedMoneyItemsInInventory(PmcData pmcData, string currencyTpl, string playerStashId) { var moneyItemsInInventory = _itemHelper.FindBarterItems("tpl", pmcData.Inventory.Items, currencyTpl); - if (moneyItemsInInventory.Count == 0) - { - _logger.Debug($"No {currencyTpl} money items found in inventory"); - } + if (moneyItemsInInventory.Count == 0) _logger.Debug($"No {currencyTpl} money items found in inventory"); // Prioritise items in stash to top of array moneyItemsInInventory.Sort((a, b) => PrioritiseStashSort(a, b, pmcData.Inventory.Items, playerStashId)); @@ -365,35 +332,23 @@ public class PaymentService( protected int PrioritiseStashSort(Item a, Item b, List inventoryItems, string playerStashId) { // a in root of stash, prioritise - if (a.ParentId == playerStashId && b.ParentId != playerStashId) - { - return -1; - } + if (a.ParentId == playerStashId && b.ParentId != playerStashId) return -1; // b in root stash, prioritise - if (a.ParentId != playerStashId && b.ParentId == playerStashId) - { - return 1; - } + if (a.ParentId != playerStashId && b.ParentId == playerStashId) return 1; // both in containers if (a.SlotId == "main" && b.SlotId == "main") { // Both items are in containers - var aInStash = this.IsInStash(a.ParentId, inventoryItems, playerStashId); - var bInStash = this.IsInStash(b.ParentId, inventoryItems, playerStashId); + var aInStash = IsInStash(a.ParentId, inventoryItems, playerStashId); + var bInStash = IsInStash(b.ParentId, inventoryItems, playerStashId); // a in stash in container, prioritise - if (aInStash && !bInStash) - { - return -1; - } + if (aInStash && !bInStash) return -1; // b in stash in container, prioritise - if (!aInStash && bInStash) - { - return 1; - } + if (!aInStash && bInStash) return 1; // Both in stash in containers if (aInStash && bInStash) @@ -408,18 +363,14 @@ public class PaymentService( !deprioritisedContainers.Contains(aImmediateParent.Template) && deprioritisedContainers.Contains(bImmediateParent.Template) ) - { return -1; - } // B is not a deprioritised container, A is if ( deprioritisedContainers.Contains(aImmediateParent.Template) && !deprioritisedContainers.Contains(bImmediateParent.Template) ) - { return 1; - } } } @@ -440,15 +391,9 @@ public class PaymentService( if (itemParent is not null) { - if (itemParent.SlotId == "hideout") - { - return true; - } + if (itemParent.SlotId == "hideout") return true; - if (itemParent.Id == playerStashId) - { - return true; - } + if (itemParent.Id == playerStashId) return true; return IsInStash(itemParent.ParentId, inventoryItems, playerStashId); } diff --git a/Libraries/Core/Services/PlayerService.cs b/Libraries/Core/Services/PlayerService.cs index 8a58a826..a6baae99 100644 --- a/Libraries/Core/Services/PlayerService.cs +++ b/Libraries/Core/Services/PlayerService.cs @@ -22,10 +22,7 @@ public class PlayerService( { accExp += expTable[i].Experience ?? 0; - if (pmcData.Info.Experience < accExp) - { - break; - } + if (pmcData.Info.Experience < accExp) break; pmcData.Info.Level = i + 1; } diff --git a/Libraries/Core/Services/PmcChatResponseService.cs b/Libraries/Core/Services/PmcChatResponseService.cs index bfcc9001..159059a4 100644 --- a/Libraries/Core/Services/PmcChatResponseService.cs +++ b/Libraries/Core/Services/PmcChatResponseService.cs @@ -26,8 +26,8 @@ public class PmcChatResponseService( MatchBotDetailsCacheService _matchBotDetailsCacheService, ConfigServer _configServer) { - protected PmcChatResponse _pmcResponsesConfig = _configServer.GetConfig(); protected GiftsConfig _giftConfig = _configServer.GetConfig(); + protected PmcChatResponse _pmcResponsesConfig = _configServer.GetConfig(); /** * For each PMC victim of the player, have a chance to send a message to the player, can be positive or negative @@ -37,15 +37,13 @@ public class PmcChatResponseService( */ public void SendVictimResponse(string sessionId, List pmcVictims, PmcData pmcData) { - foreach (var victim in pmcVictims) { - if (!_randomUtil.GetChance100(_pmcResponsesConfig.Victim.ResponseChancePercent)) - { - continue; - } + foreach (var victim in pmcVictims) + { + if (!_randomUtil.GetChance100(_pmcResponsesConfig.Victim.ResponseChancePercent)) continue; if (string.IsNullOrEmpty(victim.Name)) { - _logger.Warning($"Victim: { victim.ProfileId} does not have a nickname, skipping pmc response message send"); + _logger.Warning($"Victim: {victim.ProfileId} does not have a nickname, skipping pmc response message send"); continue; } @@ -53,13 +51,12 @@ public class PmcChatResponseService( var victimDetails = GetVictimDetails(victim); var message = ChooseMessage(true, pmcData, victim); if (message is not null) - { _notificationSendHelper.SendMessageToPlayer( sessionId, victimDetails, message, - MessageType.USER_MESSAGE); - } + MessageType.USER_MESSAGE + ); } } @@ -71,31 +68,20 @@ public class PmcChatResponseService( */ public void SendKillerResponse(string sessionId, PmcData pmcData, Aggressor killer) { - if (killer is null) - { - return; - } + if (killer is null) return; - if (!_randomUtil.GetChance100(_pmcResponsesConfig.Killer.ResponseChancePercent)) - { - return; - } + if (!_randomUtil.GetChance100(_pmcResponsesConfig.Killer.ResponseChancePercent)) return; // find bot by name in cache var killerDetailsInCache = _matchBotDetailsCacheService.GetBotByNameAndSide(killer.Name, killer.Side); - if (killerDetailsInCache is null) - { - return; - } + if (killerDetailsInCache is null) return; // If killer wasn't a PMC, skip var pmcTypes = new List { "pmcUSEC", "pmcBEAR" }; - if (!pmcTypes.Contains(killerDetailsInCache.Info.Settings.Role)) - { - return; - } + if (!pmcTypes.Contains(killerDetailsInCache.Info.Settings.Role)) return; - var killerDetails = new UserDialogInfo { + var killerDetails = new UserDialogInfo + { Id = killerDetailsInCache.Id, Aid = _hashUtil.GenerateAccountId(), // TODO: pass correct value Info = new UserDialogDetails @@ -104,15 +90,12 @@ public class PmcChatResponseService( Side = killerDetailsInCache.Info.Side, Level = killerDetailsInCache.Info.Level, MemberCategory = killerDetailsInCache.Info.MemberCategory, - SelectedMemberCategory = killerDetailsInCache.Info.SelectedMemberCategory, - }, + SelectedMemberCategory = killerDetailsInCache.Info.SelectedMemberCategory + } }; var message = ChooseMessage(false, pmcData); - if (message is null) - { - return; - } + if (message is null) return; _notificationSendHelper.SendMessageToPlayer(sessionId, killerDetails, message, MessageType.USER_MESSAGE); } @@ -139,12 +122,16 @@ public class PmcChatResponseService( } // Choose random response from above list and request it from localisation service - var responseText = _localisationService.GetText(_randomUtil.GetArrayValue(possibleResponseLocaleKeys), new { - playerName = pmcData.Info.Nickname, - playerLevel = pmcData.Info.Level, - playerSide = pmcData.Info.Side, - victimDeathLocation = victimData is not null ? GetLocationName(victimData.Location) : "", - }); + var responseText = _localisationService.GetText( + _randomUtil.GetArrayValue(possibleResponseLocaleKeys), + new + { + playerName = pmcData.Info.Nickname, + playerLevel = pmcData.Info.Level, + playerSide = pmcData.Info.Side, + victimDeathLocation = victimData is not null ? GetLocationName(victimData.Location) : "" + } + ); // Give the player a gift code if they were killed and response is 'pity'. if (responseType == "pity") @@ -161,15 +148,9 @@ public class PmcChatResponseService( responseText += $"{suffixText}"; } - if (StripCapitalisation(isVictim)) - { - responseText = responseText.ToLower(); - } + if (StripCapitalisation(isVictim)) responseText = responseText.ToLower(); - if (AllCaps(isVictim)) - { - responseText = responseText.ToUpper(); - } + if (AllCaps(isVictim)) responseText = responseText.ToUpper(); return responseText; } @@ -252,7 +233,7 @@ public class PmcChatResponseService( var keyBase = isVictim ? "pmcresponse-victim_" : "pmcresponse-killer_"; var keys = _localisationService.GetKeys(); - return keys.Where((x) => x.StartsWith($"{ keyBase}{ keyType}")).ToList(); + return keys.Where((x) => x.StartsWith($"{keyBase}{keyType}")).ToList(); } /** @@ -286,7 +267,8 @@ public class PmcChatResponseService( */ protected UserDialogInfo GetVictimDetails(Victim pmcVictim) { - var categories = new List{ + var categories = new List + { MemberCategory.UniqueId, MemberCategory.Default, MemberCategory.Default, @@ -300,16 +282,18 @@ public class PmcChatResponseService( var chosenCategory = _randomUtil.GetArrayValue(categories); - return new UserDialogInfo { + return new UserDialogInfo + { Id = pmcVictim.ProfileId, Aid = int.Parse(pmcVictim.AccountId), - Info = new UserDialogDetails{ + Info = new UserDialogDetails + { Nickname = pmcVictim.Name, Level = pmcVictim.Level, Side = pmcVictim.Side, MemberCategory = chosenCategory, SelectedMemberCategory = chosenCategory - }, + } }; } } diff --git a/Libraries/Core/Services/PostDbLoadService.cs b/Libraries/Core/Services/PostDbLoadService.cs index 45e3da97..c1d26bff 100644 --- a/Libraries/Core/Services/PostDbLoadService.cs +++ b/Libraries/Core/Services/PostDbLoadService.cs @@ -23,13 +23,13 @@ public class PostDbLoadService( ConfigServer _configServer, ICloner _cloner) { + protected BotConfig _botConfig = _configServer.GetConfig(); + protected CoreConfig _coreConfig = _configServer.GetConfig(); protected HideoutConfig _hideoutConfig = _configServer.GetConfig(); + protected ItemConfig _itemConfig = _configServer.GetConfig(); protected LocationConfig _locationConfig = _configServer.GetConfig(); protected LootConfig _lootConfig = _configServer.GetConfig(); - protected BotConfig _botConfig = _configServer.GetConfig(); - protected ItemConfig _itemConfig = _configServer.GetConfig(); protected RagfairConfig _ragfairConfig = _configServer.GetConfig(); - protected CoreConfig _coreConfig = _configServer.GetConfig(); public void PerformPostDbLoadActions() { @@ -42,43 +42,25 @@ public class PostDbLoadService( // Kill the startup if not. // TODO: We can probably remove this in a couple versions _databaseService.ValidateDatabase(); - if (!_databaseService.IsDatabaseValid()) - { - throw new Exception("Server start failure, database invalid"); - } + if (!_databaseService.IsDatabaseValid()) throw new Exception("Server start failure, database invalid"); AddCustomLooseLootPositions(); AdjustMinReserveRaiderSpawnChance(); - if (_coreConfig.Fixes.FixShotgunDispersion) - { - FixShotgunDispersions(); - } + if (_coreConfig.Fixes.FixShotgunDispersion) FixShotgunDispersions(); - if (_locationConfig.AddOpenZonesToAllMaps) - { - _openZoneService.ApplyZoneChangesToAllMaps(); - } + if (_locationConfig.AddOpenZonesToAllMaps) _openZoneService.ApplyZoneChangesToAllMaps(); - if (_locationConfig.AddCustomBotWavesToMaps) - { - _customLocationWaveService.ApplyWaveChangesToAllMaps(); - } + if (_locationConfig.AddCustomBotWavesToMaps) _customLocationWaveService.ApplyWaveChangesToAllMaps(); - if (_locationConfig.EnableBotTypeLimits) - { - AdjustMapBotLimits(); - } + if (_locationConfig.EnableBotTypeLimits) AdjustMapBotLimits(); AdjustLooseLootSpawnProbabilities(); AdjustLocationBotValues(); - if (_locationConfig.RogueLighthouseSpawnTimeSettings.Enabled) - { - FixRoguesSpawningInstantlyOnLighthouse(); - } + if (_locationConfig.RogueLighthouseSpawnTimeSettings.Enabled) FixRoguesSpawningInstantlyOnLighthouse(); AdjustLabsRaiderSpawnRate(); @@ -100,10 +82,7 @@ public class PostDbLoadService( } // Flea bsg blacklist is off - if (!_ragfairConfig.Dynamic.Blacklist.EnableBsgList) - { - SetAllDbItemsAsSellableOnFlea(); - } + if (!_ragfairConfig.Dynamic.Blacklist.EnableBsgList) SetAllDbItemsAsSellableOnFlea(); AddMissingTraderBuyRestrictionMaxValue(); @@ -119,9 +98,11 @@ public class PostDbLoadService( { var hideoutCraftDb = _databaseService.GetHideout().Production; var craftsToAdd = _hideoutConfig.HideoutCraftsToAdd; - foreach (var craftToAdd in craftsToAdd) { + foreach (var craftToAdd in craftsToAdd) + { var clonedCraft = _cloner.Clone( - hideoutCraftDb.Recipes.FirstOrDefault((x) => x.Id == craftToAdd.CraftIdToCopy)); + hideoutCraftDb.Recipes.FirstOrDefault((x) => x.Id == craftToAdd.CraftIdToCopy) + ); clonedCraft.Id = _hashUtil.Generate(); clonedCraft.Requirements = craftToAdd.Requirements; clonedCraft.EndProduct = craftToAdd.CraftOutputTpl; @@ -136,29 +117,26 @@ public class PostDbLoadService( var reserveBase = _databaseService.GetLocation(ELocationName.RezervBase.ToString()).Base; // Raiders are bosses, get only those from boss spawn array - foreach (var raiderSpawn in reserveBase.BossLocationSpawn.Where((boss) => boss.BossName == "pmcBot")) { + foreach (var raiderSpawn in reserveBase.BossLocationSpawn.Where((boss) => boss.BossName == "pmcBot")) + { var isTriggered = raiderSpawn.TriggerId.Length > 0; // Empty string if not triggered var newSpawnChance = isTriggered ? _locationConfig.ReserveRaiderSpawnChanceOverrides.Triggered : _locationConfig.ReserveRaiderSpawnChanceOverrides.NonTriggered; - if (newSpawnChance == -1) - { - continue; - } + if (newSpawnChance == -1) continue; if (raiderSpawn.BossChance < newSpawnChance) - { // Desired chance is bigger than existing, override it raiderSpawn.BossChance = newSpawnChance; - } } } protected void AddCustomLooseLootPositions() { var looseLootPositionsToAdd = _lootConfig.LooseLoot; - foreach (var (mapId, positionsToAdd) in looseLootPositionsToAdd) { + foreach (var (mapId, positionsToAdd) in looseLootPositionsToAdd) + { if (mapId is null) { _logger.Warning(_localisationService.GetText("location-unable_to_add_custom_loot_position", mapId)); @@ -174,10 +152,12 @@ public class PostDbLoadService( continue; } - foreach (var positionToAdd in positionsToAdd) { + foreach (var positionToAdd in positionsToAdd) + { // Exists already, add new items to existing positions pool var existingLootPosition = mapLooseLoot.Spawnpoints.FirstOrDefault( - (x) => x.Template.Id == positionToAdd.Template.Id); + (x) => x.Template.Id == positionToAdd.Template.Id + ); if (existingLootPosition is not null) { @@ -198,35 +178,31 @@ public class PostDbLoadService( { var itemDb = _databaseService.GetItems(); - var shotguns = new List { Weapons.SHOTGUN_12G_SAIGA_12K, Weapons.SHOTGUN_20G_TOZ_106, Weapons.SHOTGUN_12G_M870}; - foreach (var shotgunId in shotguns) { + var shotguns = new List { Weapons.SHOTGUN_12G_SAIGA_12K, Weapons.SHOTGUN_20G_TOZ_106, Weapons.SHOTGUN_12G_M870 }; + foreach (var shotgunId in shotguns) if (itemDb[shotgunId].Properties.ShotgunDispersion.HasValue) - { itemDb[shotgunId].Properties.shotgunDispersion = itemDb[shotgunId].Properties.ShotgunDispersion; - } - } } // Apply custom limits on bot types as defined in configs/location.json/botTypeLimits protected void AdjustMapBotLimits() { var mapsDb = _databaseService.GetLocations().GetDictionary(); - if (_locationConfig.BotTypeLimits is null) - { - return; - } + if (_locationConfig.BotTypeLimits is null) return; foreach (var (mapId, limits) in _locationConfig.BotTypeLimits) { if (!mapsDb.TryGetValue(mapId, out var map)) { _logger.Warning( - _localisationService.GetText("bot-unable_to_edit_limits_of_unknown_map", mapId)); + _localisationService.GetText("bot-unable_to_edit_limits_of_unknown_map", mapId) + ); continue; } - foreach (var botToLimit in limits) { + foreach (var botToLimit in limits) + { var index = map.Base.MinMaxBots.FindIndex(x => x.WildSpawnType == botToLimit.Type); if (index != -1) { @@ -238,12 +214,15 @@ public class PostDbLoadService( else { // Bot type not found, add new object - map.Base.MinMaxBots.Add( new MinMaxBot{ - // Bot type not found, add new object - WildSpawnType = botToLimit.Type, - Min = botToLimit.Min, - Max = botToLimit.Max, - }); + map.Base.MinMaxBots.Add( + new MinMaxBot + { + // Bot type not found, add new object + WildSpawnType = botToLimit.Type, + Min = botToLimit.Min, + Max = botToLimit.Max + } + ); } } } @@ -251,12 +230,10 @@ public class PostDbLoadService( protected void AdjustLooseLootSpawnProbabilities() { - if (_lootConfig.LooseLootSpawnPointAdjustments is null) - { - return; - } + if (_lootConfig.LooseLootSpawnPointAdjustments is null) return; - foreach (var (mapId, mapAdjustments) in _lootConfig.LooseLootSpawnPointAdjustments) { + foreach (var (mapId, mapAdjustments) in _lootConfig.LooseLootSpawnPointAdjustments) + { var mapLooseLootData = _databaseService.GetLocation(mapId).LooseLoot.Value; if (mapLooseLootData is null) { @@ -265,15 +242,23 @@ public class PostDbLoadService( continue; } - foreach (var (lootKey, newChanceValue) in mapAdjustments) { - var lootPostionToAdjust = mapLooseLootData.Spawnpoints.FirstOrDefault((spawnPoint) => spawnPoint.Template.Id == lootKey + foreach (var (lootKey, newChanceValue) in mapAdjustments) + { + var lootPostionToAdjust = mapLooseLootData.Spawnpoints.FirstOrDefault( + (spawnPoint) => spawnPoint.Template.Id == lootKey ); if (lootPostionToAdjust is null) { _logger.Warning( - _localisationService.GetText("location-unable_to_adjust_loot_position_on_map", new { - lootKey = lootKey, - mapId = mapId })); + _localisationService.GetText( + "location-unable_to_adjust_loot_position_on_map", + new + { + lootKey = lootKey, + mapId = mapId + } + ) + ); continue; } @@ -283,17 +268,15 @@ public class PostDbLoadService( } } - + protected void AdjustLocationBotValues() { var mapsDb = _databaseService.GetLocations(); var mapsDict = mapsDb.GetDictionary(); - foreach (var (key, cap) in _botConfig.MaxBotCap) { + foreach (var (key, cap) in _botConfig.MaxBotCap) + { // Keys given are like this: "factory4_night" use GetMappedKey to change to "Factory4Night" which the dictionary contains - if (!mapsDict.TryGetValue(mapsDb.GetMappedKey(key), out var map)) - { - continue; - } + if (!mapsDict.TryGetValue(mapsDb.GetMappedKey(key), out var map)) continue; map.Base.BotMaxPvE = cap; map.Base.BotMax = cap; @@ -309,17 +292,13 @@ public class PostDbLoadService( var rogueSpawnDelaySeconds = _locationConfig.RogueLighthouseSpawnTimeSettings.WaitTimeSeconds; var lighthouse = _databaseService.GetLocations().Lighthouse?.Base; if (lighthouse is null) - { // Just in case they remove this cursed map return; - } // Find Rogues that spawn instantly var instantRogueBossSpawns = lighthouse.BossLocationSpawn .Where((spawn) => spawn.BossName == "exUsec" && spawn.Time == -1); - foreach (var wave in instantRogueBossSpawns) { - wave.Time = rogueSpawnDelaySeconds; - } + foreach (var wave in instantRogueBossSpawns) wave.Time = rogueSpawnDelaySeconds; } // Make non-trigger-spawned raiders spawn earlier + always @@ -329,9 +308,11 @@ public class PostDbLoadService( // Find spawns with empty string for triggerId/TriggerName var nonTriggerLabsBossSpawns = labsBase.BossLocationSpawn.Where( - (bossSpawn) => bossSpawn.TriggerId is null && bossSpawn.TriggerName is null); + (bossSpawn) => bossSpawn.TriggerId is null && bossSpawn.TriggerName is null + ); - foreach (var boss in nonTriggerLabsBossSpawns) { + foreach (var boss in nonTriggerLabsBossSpawns) + { boss.BossChance = 100; boss.Time /= 10; } @@ -339,46 +320,37 @@ public class PostDbLoadService( protected void AdjustHideoutCraftTimes(int overrideSeconds) { - if (overrideSeconds == -1) - { - return; - } + if (overrideSeconds == -1) return; - foreach (var craft in _databaseService.GetHideout().Production.Recipes) { + foreach (var craft in _databaseService.GetHideout().Production.Recipes) // Only adjust crafts ABOVE the override craft.ProductionTime = Math.Min(craft.ProductionTime.Value, overrideSeconds); - } } // Adjust all hideout craft times to be no higher than the override protected void AdjustHideoutBuildTimes(int overrideSeconds) { - if (overrideSeconds == -1) - { - return; - } + if (overrideSeconds == -1) return; - foreach (var area in _databaseService.GetHideout().Areas) { - foreach (var (key, stage) in area.Stages) { - // Only adjust crafts ABOVE the override - stage.ConstructionTime = Math.Min(stage.ConstructionTime.Value, overrideSeconds); - } - } + foreach (var area in _databaseService.GetHideout().Areas) + foreach (var (key, stage) in area.Stages) + // Only adjust crafts ABOVE the override + stage.ConstructionTime = Math.Min(stage.ConstructionTime.Value, overrideSeconds); } protected void UnlockHideoutLootCrateCrafts() { - var hideoutLootBoxCraftIds = new List{ - "66582be04de4820934746cea", - "6745925da9c9adf0450d5bca", - "67449c79268737ef6908d636" }; + var hideoutLootBoxCraftIds = new List + { + "66582be04de4820934746cea", + "6745925da9c9adf0450d5bca", + "67449c79268737ef6908d636" + }; - foreach (var craftId in hideoutLootBoxCraftIds) { + foreach (var craftId in hideoutLootBoxCraftIds) + { var recipe = _databaseService.GetHideout().Production.Recipes.FirstOrDefault((craft) => craft.Id == craftId); - if (recipe is not null) - { - recipe.Locked = false; - } + if (recipe is not null) recipe.Locked = false; } } @@ -387,9 +359,7 @@ public class PostDbLoadService( { // Iterate over all languages (e.g. "en", "fr") var locales = _databaseService.GetLocales(); - foreach (var localeKvP in locales.Global) { - locales.Global[localeKvP.Key].Value["61687e2c3e526901fa76baf9"] = ""; - } + foreach (var localeKvP in locales.Global) locales.Global[localeKvP.Key].Value["61687e2c3e526901fa76baf9"] = ""; } // Check for any missing assorts inside each traders assort.json data, checking against traders questassort.json @@ -398,69 +368,69 @@ public class PostDbLoadService( var db = _databaseService.GetTables(); var traders = db.Traders; var quests = db.Templates.Quests; - foreach (var (traderId, traderData) in traders) { + foreach (var (traderId, traderData) in traders) + { var traderAssorts = traderData?.Assort; - if (traderAssorts is null) - { - continue; - } + if (traderAssorts is null) continue; // Merge started/success/fail quest assorts into one dictionary var mergedQuestAssorts = new Dictionary(); mergedQuestAssorts.Concat(traderData.QuestAssort["started"]) - .Concat(traderData.QuestAssort["success"]) - .Concat(traderData.QuestAssort["fail"]).ToDictionary(); + .Concat(traderData.QuestAssort["success"]) + .Concat(traderData.QuestAssort["fail"]) + .ToDictionary(); // Loop over all assorts for trader - foreach (var (assortKey, questKey) in (mergedQuestAssorts)) { + foreach (var (assortKey, questKey) in mergedQuestAssorts) // Does assort key exist in trader assort file if (!traderAssorts.LoyalLevelItems.ContainsKey(assortKey)) { // Reverse lookup of enum key by value - var messageValues = new { + var messageValues = new + { traderName = traderId, - questName = quests[questKey]?.QuestName ?? "UNKNOWN", + questName = quests[questKey]?.QuestName ?? "UNKNOWN" }; _logger.Warning( _localisationService.GetText("assort-missing_quest_assort_unlock", messageValues) ); } - } } } protected void SetAllDbItemsAsSellableOnFlea() { var dbItems = _databaseService.GetItems().Values.ToList(); - foreach (var item in dbItems.Where(item => item.Type == "Item" && - !item.Properties.CanSellOnRagfair.GetValueOrDefault(false) && - !_ragfairConfig.Dynamic.Blacklist.Custom.Contains(item.Id))) - { + foreach (var item in dbItems.Where( + item => item.Type == "Item" && + !item.Properties.CanSellOnRagfair.GetValueOrDefault(false) && + !_ragfairConfig.Dynamic.Blacklist.Custom.Contains(item.Id) + )) item.Properties.CanSellOnRagfair = true; - } } protected void AddMissingTraderBuyRestrictionMaxValue() { var restrictions = _databaseService.GetGlobals().Configuration.TradingSettings.BuyRestrictionMaxBonus; - restrictions["unheard_edition"] = new BuyRestrictionMaxBonus{ Multiplier = restrictions["edge_of_darkness"].Multiplier, + restrictions["unheard_edition"] = new BuyRestrictionMaxBonus + { + Multiplier = restrictions["edge_of_darkness"].Multiplier }; } protected void ApplyFleaPriceOverrides() { var fleaPrices = _databaseService.GetPrices(); - foreach (var (itemTpl, price) in _ragfairConfig.Dynamic.ItemPriceOverrideRouble) { - fleaPrices[itemTpl] = price; - } + foreach (var (itemTpl, price) in _ragfairConfig.Dynamic.ItemPriceOverrideRouble) fleaPrices[itemTpl] = price; } protected void AddCustomItemPresetsToGlobals() { - foreach (var presetToAdd in _itemConfig.CustomItemGlobalPresets) { + foreach (var presetToAdd in _itemConfig.CustomItemGlobalPresets) + { if (_databaseService.GetGlobals().ItemPresets.ContainsKey(presetToAdd.Id)) { - _logger.Warning($"Global ItemPreset with Id of: { presetToAdd.Id} already exists, unable to overwrite"); + _logger.Warning($"Global ItemPreset with Id of: {presetToAdd.Id} already exists, unable to overwrite"); continue; } diff --git a/Libraries/Core/Services/ProfileActivityService.cs b/Libraries/Core/Services/ProfileActivityService.cs index aee988bf..bd0f91a7 100644 --- a/Libraries/Core/Services/ProfileActivityService.cs +++ b/Libraries/Core/Services/ProfileActivityService.cs @@ -35,7 +35,7 @@ public class ProfileActivityService( var currentTimestamp = _timeUtil.GetTimeStamp(); var result = new List(); - foreach (var activity in profileActivityTimestamps ?? new()) + foreach (var activity in profileActivityTimestamps ?? new Dictionary()) { var lastActivityTimestamp = activity.Value; if (lastActivityTimestamp == null) diff --git a/Libraries/Core/Services/ProfileFixerService.cs b/Libraries/Core/Services/ProfileFixerService.cs index 993bbe51..20936bc9 100644 --- a/Libraries/Core/Services/ProfileFixerService.cs +++ b/Libraries/Core/Services/ProfileFixerService.cs @@ -28,6 +28,7 @@ public class ProfileFixerService( InventoryHelper _inventoryHelper ) { + protected List _areas = ["hideout", "main"]; protected CoreConfig _coreConfig = _configServer.GetConfig(); /// @@ -41,15 +42,9 @@ public class ProfileFixerService( RemoveOrphanedQuests(pmcProfile); VerifyQuestProductionUnlocks(pmcProfile); - if (pmcProfile.Hideout is not null) - { - AddHideoutEliteSlots(pmcProfile); - } + if (pmcProfile.Hideout is not null) AddHideoutEliteSlots(pmcProfile); - if (pmcProfile.Skills is not null) - { - CheckForSkillsOverMaxLevel(pmcProfile); - } + if (pmcProfile.Skills is not null) CheckForSkillsOverMaxLevel(pmcProfile); } /// @@ -61,35 +56,23 @@ public class ProfileFixerService( { foreach (var traderDialoguesKvP in fullProfile.DialogueRecords) { - if (traderDialoguesKvP.Value.Messages is null) - { - continue; - } + if (traderDialoguesKvP.Value.Messages is null) continue; var traderDialogues = traderDialoguesKvP.Value; foreach (var message in traderDialogues.Messages) { // Skip any messages without attached items - if (message.Items?.Data is null || message.Items?.Stash is null) - { - continue; - } + if (message.Items?.Data is null || message.Items?.Stash is null) continue; // Skip any messages that don't have a stashId collision with the player's equipment ID - if (message.Items?.Stash != fullProfile.CharacterData?.PmcData?.Inventory?.Equipment) - { - continue; - } + if (message.Items?.Stash != fullProfile.CharacterData?.PmcData?.Inventory?.Equipment) continue; // Otherwise we need to generate a new unique stash ID for this message's attachments message.Items.Stash = _hashUtil.Generate(); message.Items.Data = _itemHelper.AdoptOrphanedItems(message.Items.Stash, message.Items.Data); // Because `adoptOrphanedItems` sets the slotId to `hideout`, we need to re-set it to `main` to work with mail - foreach (var item in message.Items.Data.Where(item => item.SlotId == "hideout")) - { - item.SlotId = "main"; - } + foreach (var item in message.Items.Data.Where(item => item.SlotId == "hideout")) item.SlotId = "main"; } } } @@ -108,10 +91,7 @@ public class ProfileFixerService( foreach (var mappingKvP in itemMapping) { // Only one item for this id, not a dupe - if (mappingKvP.Value.Count == 1) - { - continue; - } + if (mappingKvP.Value.Count == 1) continue; _logger.Warning($"{mappingKvP.Value.Count - 1} duplicate(s) found for item: {mappingKvP.Key}"); var itemAJson = _jsonUtil.Serialize(mappingKvP.Value[0]); @@ -141,13 +121,11 @@ public class ProfileFixerService( foreach (var item in pmcProfile.Inventory.Items.Where((x) => x.SlotId is not null)) { if (item.Upd is null) - { // Ignore items without a upd object continue; - } // Check items with a tags for non-alphanumeric characters and remove - Regex regxp = new Regex("[^a-zA-Z0-9 -]"); + var regxp = new Regex("[^a-zA-Z0-9 -]"); if (item.Upd.Tag?.Name is not null && !regxp.IsMatch(item.Upd.Tag.Name)) { _logger.Warning($"Fixed item: {item.Id}s Tag value, removed invalid characters"); @@ -211,16 +189,11 @@ public class ProfileFixerService( /// profile to remove old counters from public void RemoveDanglingConditionCounters(PmcData pmcProfile) { - if (pmcProfile.TaskConditionCounters is null) - { - return; - } + if (pmcProfile.TaskConditionCounters is null) return; foreach (var counterKvP in pmcProfile.TaskConditionCounters .Where(counterKvP => counterKvP.Value.SourceId is null)) - { pmcProfile.TaskConditionCounters.Remove(counterKvP.Key); - } } /// @@ -229,10 +202,7 @@ public class ProfileFixerService( /// Player profile to check protected void RemoveDanglingTaskConditionCounters(PmcData pmcProfile) { - if (pmcProfile.TaskConditionCounters is null) - { - return; - } + if (pmcProfile.TaskConditionCounters is null) return; var taskConditionKeysToRemove = new List(); var activeRepeatableQuests = GetActiveRepeatableQuests(pmcProfile.RepeatableQuests); @@ -240,7 +210,6 @@ public class ProfileFixerService( // Loop over TaskConditionCounters objects and add once we want to remove to counterKeysToRemove foreach (var TaskConditionCounterKvP in pmcProfile.TaskConditionCounters) - { // Only check if profile has repeatable quests if (pmcProfile.RepeatableQuests is not null && activeRepeatableQuests.Count > 0) { @@ -255,19 +224,12 @@ public class ProfileFixerService( ); // If task conditions id is neither in activeQuests, quests or achievements - it's stale and should be cleaned up - if (!(existsInActiveRepeatableQuests || existsInQuests || isAchievementTracker)) - { - taskConditionKeysToRemove.Add(TaskConditionCounterKvP.Key); - } + if (!(existsInActiveRepeatableQuests || existsInQuests || isAchievementTracker)) taskConditionKeysToRemove.Add(TaskConditionCounterKvP.Key); } - } foreach (var counterKeyToRemove in taskConditionKeysToRemove) { - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Removed: {counterKeyToRemove} TaskConditionCounter object"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Removed: {counterKeyToRemove} TaskConditionCounter object"); pmcProfile.TaskConditionCounters.Remove(counterKeyToRemove); } } @@ -276,10 +238,8 @@ public class ProfileFixerService( { var activeQuests = new List(); foreach (var repeatableQuest in repeatableQuests.Where(questType => questType.ActiveQuests?.Count > 0)) - { // daily/weekly collection has active quests in them, add to array and return activeQuests.AddRange(repeatableQuest.ActiveQuests); - } return activeQuests; } @@ -296,13 +256,11 @@ public class ProfileFixerService( var activeRepeatableQuests = GetActiveRepeatableQuests(pmcProfile.RepeatableQuests); for (var i = profileQuests.Count - 1; i >= 0; i--) - { if (!quests.ContainsKey(profileQuests[i].QId) || activeRepeatableQuests.Any((x) => x.Id == profileQuests[i].QId)) { _logger.Info($"Successfully removed orphaned quest: {profileQuests[i].QId} that doesn't exist in quest data"); profileQuests.RemoveAt(i); } - } } /// @@ -317,10 +275,7 @@ public class ProfileFixerService( foreach (var profileQuest in profileQuests) { var quest = quests.GetValueOrDefault(profileQuest.QId, null); - if (quest is null) - { - continue; - } + if (quest is null) continue; // For started or successful quests, check for unlocks in the `Started` rewards if (profileQuest.Status is QuestStatusEnum.Started or QuestStatusEnum.Success) @@ -330,12 +285,8 @@ public class ProfileFixerService( ); if (productionRewards is not null) - { foreach (var reward in productionRewards) - { VerifyQuestProductionUnlock(pmcProfile, reward, quest); - } - } } // For successful quests, check for unlocks in the `Success` rewards @@ -346,12 +297,8 @@ public class ProfileFixerService( ); if (productionRewards is not null) - { foreach (var reward in productionRewards) - { VerifyQuestProductionUnlock(pmcProfile, reward, quest); - } - } } } } @@ -390,11 +337,9 @@ public class ProfileFixerService( if (!pmcProfile.UnlockedInfo.UnlockedProductionRecipe.Contains(matchingProductionId)) { pmcProfile.UnlockedInfo.UnlockedProductionRecipe.Add(matchingProductionId); - + if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug($"Added production: {matchingProductionId} to unlocked production recipes for: {questDetails.QuestName}"); - } } } @@ -415,10 +360,7 @@ public class ProfileFixerService( if (genSlots < 6 + extraGenSlots) { - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug("Updating generator area slots to a size of 6 + hideout management skill"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug("Updating generator area slots to a size of 6 + hideout management skill"); AddEmptyObjectsToHideoutAreaSlots(HideoutAreas.GENERATOR, (int)(6 + extraGenSlots ?? 0), pmcProfile); } } @@ -430,10 +372,7 @@ public class ProfileFixerService( if (waterCollSlots < 1 + extraWaterCollSlots) { - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug("Updating water collector area slots to a size of 1 + hideout management skill"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug("Updating water collector area slots to a size of 1 + hideout management skill"); AddEmptyObjectsToHideoutAreaSlots(HideoutAreas.WATER_COLLECTOR, (int)(1 + extraWaterCollSlots ?? 0), pmcProfile); } @@ -442,10 +381,7 @@ public class ProfileFixerService( if (filterSlots < 3 + extraFilterSlots) { - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug("Updating air filter area slots to a size of 3 + hideout management skill"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug("Updating air filter area slots to a size of 3 + hideout management skill"); AddEmptyObjectsToHideoutAreaSlots(HideoutAreas.AIR_FILTERING, (int)(3 + extraFilterSlots ?? 0), pmcProfile); } @@ -455,10 +391,7 @@ public class ProfileFixerService( // BTC Farm doesnt have extra slots for hideout management, but we still check for modded stuff!! if (btcFarmSlots < 50 + extraBtcSlots) { - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug("Updating bitcoin farm area slots to a size of 50 + hideout management skill"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug("Updating bitcoin farm area slots to a size of 50 + hideout management skill"); AddEmptyObjectsToHideoutAreaSlots(HideoutAreas.BITCOIN_FARM, (int)(50 + extraBtcSlots ?? 0), pmcProfile); } @@ -467,10 +400,7 @@ public class ProfileFixerService( .Count; if (cultistAreaSlots < 1) { - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug("Updating cultist area slots to a size of 1"); - } + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug("Updating cultist area slots to a size of 1"); AddEmptyObjectsToHideoutAreaSlots(HideoutAreas.CIRCLE_OF_CULTISTS, 1, pmcProfile); } } @@ -490,12 +420,8 @@ public class ProfileFixerService( protected List AddObjectsToList(int count, List slots) { for (var i = 0; i < count; i++) - { if (!slots.Any((x) => x.LocationIndex == i)) - { slots.Add(new HideoutSlot { LocationIndex = i }); - } - } return slots; } @@ -508,14 +434,9 @@ public class ProfileFixerService( { var skills = pmcProfile.Skills.Common; - foreach (var skill in skills.Where(skill => skill.Progress > 5100)) - { - skill.Progress = 5100; - } + foreach (var skill in skills.Where(skill => skill.Progress > 5100)) skill.Progress = 5100; } - protected List _areas = ["hideout", "main"]; - /** * Checks profile inventory for items that do not exist inside the items db * @param sessionId Session id @@ -530,10 +451,8 @@ public class ProfileFixerService( // TODO: extend to other areas / sub items var inventoryItemsToCheck = pmcProfile.Inventory.Items.Where(item => _areas.Contains(item.SlotId ?? "")); if (inventoryItemsToCheck is not null) - { // Check each item in inventory to ensure item exists in itemdb foreach (var item in inventoryItemsToCheck) - { if (!itemsDb.ContainsKey(item.Template)) { _logger.Error(_localisationService.GetText("fixer-mod_item_found", item.Template)); @@ -546,8 +465,6 @@ public class ProfileFixerService( _inventoryHelper.RemoveItem(pmcProfile, item.Id, sessionId); } } - } - } if (fullProfile.UserBuildData is not null) { @@ -576,7 +493,7 @@ public class ProfileFixerService( continue; // skip messages with no items // Fix message with no items but have the flags to indicate items to collect - if (message.Items.Data.Count == 0 && (message.HasRewards.GetValueOrDefault(false))) + if (message.Items.Data.Count == 0 && message.HasRewards.GetValueOrDefault(false)) { message.HasRewards = false; message.RewardCollected = true; @@ -587,10 +504,7 @@ public class ProfileFixerService( foreach (var item in message.Items.Data) { // Check item exists in itemsDb - if (!itemsDb.ContainsKey(item.Template)) - { - _logger.Error(_localisationService.GetText("fixer-mod_item_found", item.Template)); - } + if (!itemsDb.ContainsKey(item.Template)) _logger.Error(_localisationService.GetText("fixer-mod_item_found", item.Template)); if (_coreConfig.Fixes.RemoveModItemsFromProfile) { @@ -605,7 +519,6 @@ public class ProfileFixerService( var clothing = _databaseService.GetTemplates().Customization; foreach (var suit in fullProfile.Suits) - { if (suit is null) { _logger.Error(_localisationService.GetText("fixer-clothing_item_found", suit)); @@ -615,14 +528,10 @@ public class ProfileFixerService( _logger.Warning($"Non-default suit purchase: {suit} removed from profile"); } } - } - foreach (var repeatable in fullProfile.CharacterData.PmcData.RepeatableQuests ?? new()) + foreach (var repeatable in fullProfile.CharacterData.PmcData.RepeatableQuests ?? new List()) { - if (repeatable.ActiveQuests is null) - { - continue; - } + if (repeatable.ActiveQuests is null) continue; foreach (var activeQuest in repeatable.ActiveQuests) { @@ -640,30 +549,22 @@ public class ProfileFixerService( continue; } - if (activeQuest.Rewards?.Success is null) - { - continue; - } + if (activeQuest.Rewards?.Success is null) continue; // Get Item rewards only foreach (var successReward in activeQuest.Rewards.Success.Where(reward => reward.Type == RewardType.Item)) - { - foreach (var item in successReward.Items) + foreach (var item in successReward.Items) + if (!itemsDb.ContainsKey(item.Template)) { - if (!itemsDb.ContainsKey(item.Template)) - { - _logger.Warning( - $"Non-default quest: {activeQuest.Id} from trader: {activeQuest.TraderId} removed from RepeatableQuests list in profile" - ); - repeatable.ActiveQuests.Remove(activeQuest); - } + _logger.Warning( + $"Non-default quest: {activeQuest.Id} from trader: {activeQuest.TraderId} removed from RepeatableQuests list in profile" + ); + repeatable.ActiveQuests.Remove(activeQuest); } - } } } foreach (var TraderPurchase in fullProfile.TraderPurchases) - { if (!_traderHelper.TraderEnumHasValue(TraderPurchase.Key)) { _logger.Error(_localisationService.GetText("fixer-trader_found", TraderPurchase.Key)); @@ -673,7 +574,6 @@ public class ProfileFixerService( fullProfile.TraderPurchases.Remove(TraderPurchase.Key); } } - } } /** @@ -688,7 +588,6 @@ public class ProfileFixerService( Dictionary itemsDb) { if (buildType == "weapon") - { // Get items not found in items db foreach (var item in (build as WeaponBuild).Items.Where(item => !itemsDb.ContainsKey(item.Template))) { @@ -703,12 +602,10 @@ public class ProfileFixerService( break; } - } // TODO: refactor to be generic if (buildType == "equipment") - { // Get items not found in items db foreach (var item in (build as EquipmentBuild).Items.Where(item => !itemsDb.ContainsKey(item.Template))) { @@ -724,7 +621,6 @@ public class ProfileFixerService( // Found a broken item break; } - } return false; } @@ -741,10 +637,7 @@ public class ProfileFixerService( foreach (var item in magazineBuild.Items) { // Magazine builds can have undefined items in them, skip those - if (item is null) - { - continue; - } + if (item is null) continue; // Check item exists in itemsDb if (!itemsDb.ContainsKey(item.TemplateId)) @@ -779,35 +672,24 @@ public class ProfileFixerService( var areaType = profileArea.Type; var level = profileArea.Level; - if (level.GetValueOrDefault(0) == 0) - { - continue; - } + if (level.GetValueOrDefault(0) == 0) continue; // Get array of hideout area upgrade levels to check for bonuses // Zero indexed var areaLevelsToCheck = new List(); for (var index = 0; index < level + 1; index++) - { // Stage key is saved as string in db areaLevelsToCheck.Add(index.ToString()); - } // Iterate over area levels, check for bonuses, add if needed var dbArea = dbHideoutAreas?.FirstOrDefault((area) => area.Type == areaType); - if (dbArea is null) - { - continue; - } + if (dbArea is null) continue; foreach (var areaLevel in areaLevelsToCheck) { // Get areas level bonuses from db var levelBonuses = dbArea.Stages?[areaLevel].Bonuses; - if (levelBonuses is null || levelBonuses.Count == 0) - { - continue; - } + if (levelBonuses is null || levelBonuses.Count == 0) continue; // Iterate over each bonus for the areas level foreach (var bonus in levelBonuses) @@ -833,10 +715,7 @@ public class ProfileFixerService( protected Bonus? GetBonusFromProfile(List? profileBonuses, Bonus bonus) { // match by id first, used by "TextBonus" bonuses - if (bonus.Id is null) - { - return profileBonuses?.FirstOrDefault((x) => x.Id == bonus.Id); - } + if (bonus.Id is null) return profileBonuses?.FirstOrDefault((x) => x.Id == bonus.Id); return bonus.Type switch { diff --git a/Libraries/Core/Services/RagfairCategoriesService.cs b/Libraries/Core/Services/RagfairCategoriesService.cs index 654bd845..2e9fcd7e 100644 --- a/Libraries/Core/Services/RagfairCategoriesService.cs +++ b/Libraries/Core/Services/RagfairCategoriesService.cs @@ -32,31 +32,20 @@ public class RagfairCategoriesService( var isTraderOffer = offer.User.MemberType == MemberCategory.Trader; // Not level 15 and offer is from player, skip - if (!fleaUnlocked && !isTraderOffer) - { - return false; - } + if (!fleaUnlocked && !isTraderOffer) return false; // Skip items not for currency when `removeBartering` is enabled if ( searchRequestData.RemoveBartering.GetValueOrDefault(false) && (offer.Requirements.Count > 1 || !_paymentHelper.IsMoneyTpl(offer.Requirements.FirstOrDefault().Template)) ) - { return false; - } // Remove when filter set to players only + offer is from trader - if (searchRequestData.OfferOwnerType == OfferOwnerType.PLAYEROWNERTYPE && isTraderOffer) - { - return false; - } + if (searchRequestData.OfferOwnerType == OfferOwnerType.PLAYEROWNERTYPE && isTraderOffer) return false; // Remove when filter set to traders only + offer is not from trader - if (searchRequestData.OfferOwnerType == OfferOwnerType.TRADEROWNERTYPE && !isTraderOffer) - { - return false; - } + if (searchRequestData.OfferOwnerType == OfferOwnerType.TRADEROWNERTYPE && !isTraderOffer) return false; // Passed checks, it's a valid offer to process return true; diff --git a/Libraries/Core/Services/RagfairLinkedItemService.cs b/Libraries/Core/Services/RagfairLinkedItemService.cs index 513265be..88e67e1d 100644 --- a/Libraries/Core/Services/RagfairLinkedItemService.cs +++ b/Libraries/Core/Services/RagfairLinkedItemService.cs @@ -15,8 +15,8 @@ public class RagfairLinkedItemService( ISptLogger logger ) { - protected Dictionary> linkedItemsCache = new(); - + protected Dictionary> linkedItemsCache = new(); + public HashSet GetLinkedItems(string linkedSearchId) { if (!linkedItemsCache.TryGetValue(linkedSearchId, out var set)) @@ -37,15 +37,18 @@ public class RagfairLinkedItemService( public List GetLinkedDbItems(string itemTpl) { var linkedItemsToWeaponTpls = GetLinkedItems(itemTpl); - return linkedItemsToWeaponTpls.Aggregate(new List(), (result, linkedTpl) => { - var itemDetails = itemHelper.GetItem(linkedTpl); - if (itemDetails.Key) { - result.Add(itemDetails.Value); - } else { - logger.Warning($"Item {itemTpl} has invalid linked item {linkedTpl}"); + return linkedItemsToWeaponTpls.Aggregate( + new List(), + (result, linkedTpl) => + { + var itemDetails = itemHelper.GetItem(linkedTpl); + if (itemDetails.Key) + result.Add(itemDetails.Value); + else + logger.Warning($"Item {itemTpl} has invalid linked item {linkedTpl}"); + return result; } - return result; - }); + ); } /** @@ -55,7 +58,8 @@ public class RagfairLinkedItemService( { var linkedItems = new Dictionary>(); - foreach (var item in databaseService.GetItems().Values) { + foreach (var item in databaseService.GetItems().Values) + { var itemLinkedSet = GetLinkedItems(linkedItems, item.Id); ApplyLinkedItems(GetSlotFilters(item), item, itemLinkedSet); @@ -63,10 +67,9 @@ public class RagfairLinkedItemService( ApplyLinkedItems(GetCartridgeFilters(item), item, itemLinkedSet); // Edge case, ensure ammo for revolves is included - if (item.Parent == BaseClasses.REVOLVER) { + if (item.Parent == BaseClasses.REVOLVER) // Find magazine for revolver AddRevolverCylinderAmmoToLinkedItems(item, itemLinkedSet); - } } linkedItemsCache = linkedItems; @@ -92,10 +95,12 @@ public class RagfairLinkedItemService( protected void AddRevolverCylinderAmmoToLinkedItems(TemplateItem cylinder, HashSet itemLinkedSet) { var cylinderMod = cylinder.Properties.Slots?.FirstOrDefault((x) => x.Name == "mod_magazine"); - if (cylinderMod != null) { + if (cylinderMod != null) + { // Get the first cylinder filter tpl var cylinderTpl = cylinderMod.Props?.Filters?[0].Filter?[0]; - if (!string.IsNullOrEmpty(cylinderTpl)) { + if (!string.IsNullOrEmpty(cylinderTpl)) + { // Get db data for cylinder tpl, add found slots info (camora_xxx) to linked items on revolver weapon var cylinderTemplate = itemHelper.GetItem(cylinderTpl).Value; ApplyLinkedItems(GetSlotFilters(cylinderTemplate), cylinder, itemLinkedSet); @@ -108,15 +113,9 @@ public class RagfairLinkedItemService( var result = new HashSet(); var slots = item.Properties?.Slots; - if (slots is null) - { - return result; - } + if (slots is null) return result; - foreach (var slot in slots) - { - result.UnionWith(slot.Props?.Filters?.FirstOrDefault()?.Filter); - } + foreach (var slot in slots) result.UnionWith(slot.Props?.Filters?.FirstOrDefault()?.Filter); return result; } @@ -126,15 +125,9 @@ public class RagfairLinkedItemService( var result = new HashSet(); var chambers = item.Properties?.Chambers; - if (chambers is null) - { - return result; - } + if (chambers is null) return result; - foreach (var chamber in chambers) - { - result.UnionWith(chamber.Props?.Filters?.FirstOrDefault()?.Filter); - } + foreach (var chamber in chambers) result.UnionWith(chamber.Props?.Filters?.FirstOrDefault()?.Filter); return result; } @@ -144,15 +137,9 @@ public class RagfairLinkedItemService( var result = new HashSet(); var cartridges = item.Properties?.Cartridges; - if (cartridges is null) - { - return result; - } + if (cartridges is null) return result; - foreach (var cartridge in cartridges) - { - result.UnionWith(cartridge.Props?.Filters?.FirstOrDefault()?.Filter); - } + foreach (var cartridge in cartridges) result.UnionWith(cartridge.Props?.Filters?.FirstOrDefault()?.Filter); return result; } diff --git a/Libraries/Core/Services/RagfairOfferService.cs b/Libraries/Core/Services/RagfairOfferService.cs index 4a8c6cad..3672b77e 100644 --- a/Libraries/Core/Services/RagfairOfferService.cs +++ b/Libraries/Core/Services/RagfairOfferService.cs @@ -27,11 +27,11 @@ public class RagfairOfferService( RagfairOfferHolder ragfairOfferHolder ) { - protected bool playerOffersLoaded; - /** Offer id + offer object */ protected Dictionary expiredOffers = new(); + protected bool playerOffersLoaded; + protected RagfairConfig ragfairConfig = configServer.GetConfig(); /** @@ -142,10 +142,7 @@ public class RagfairOfferService( if (offer != null) { offer.Items[0].Upd.StackObjectsCount -= amount; - if (offer.Items[0].Upd.StackObjectsCount <= 0) - { - ProcessStaleOffer(offer); - } + if (offer.Items[0].Upd.StackObjectsCount <= 0) ProcessStaleOffer(offer); } } @@ -183,10 +180,8 @@ public class RagfairOfferService( var pmcData = saveServer.GetProfile(sessionID)?.CharacterData?.PmcData; if (pmcData?.RagfairInfo == null || pmcData.RagfairInfo.Offers == null) - { // Profile is wiped continue; - } ragfairOfferHolder.AddOffers(pmcData.RagfairInfo.Offers); } @@ -198,10 +193,7 @@ public class RagfairOfferService( public void ExpireStaleOffers() { var time = timeUtil.GetTimeStamp(); - foreach (var staleOffer in ragfairOfferHolder.GetStaleOffers(time)) - { - ProcessStaleOffer(staleOffer); - } + foreach (var staleOffer in ragfairOfferHolder.GetStaleOffers(time)) ProcessStaleOffer(staleOffer); } /** @@ -215,17 +207,12 @@ public class RagfairOfferService( var isPlayer = profileHelper.IsPlayer(staleOfferUserId.RegexReplace("^pmc", "")); // Skip trader offers, managed by RagfairServer.update() - if (isTrader) - { - return; - } + if (isTrader) return; // Handle dynamic offer if (!(isTrader || isPlayer)) - { // Dynamic offer AddOfferToExpired(staleOffer); - } // Handle player offer - items need returning/XP adjusting. Checking if offer has actually expired or not. if (isPlayer && staleOffer.EndTime <= timeUtil.GetTimeStamp()) @@ -265,9 +252,7 @@ public class RagfairOfferService( var firstOfferItem = playerOffer.Items[0]; if (firstOfferItem.Upd.StackObjectsCount > firstOfferItem.Upd.OriginalStackObjectsCount) - { playerOffer.Items[0].Upd.StackObjectsCount = firstOfferItem.Upd.OriginalStackObjectsCount; - } playerOffer.Items[0].Upd.OriginalStackObjectsCount = null; // Remove player offer from flea @@ -279,13 +264,9 @@ public class RagfairOfferService( // Need to regenerate Ids to ensure returned item(s) have correct parent values var newParentId = hashUtil.Generate(); foreach (var item in unstackedItems) - { // Refresh root items' parentIds if (item.ParentId == "hideout") - { item.ParentId = newParentId; - } - } ragfairServerHelper.ReturnItems(profile.SessionId, unstackedItems); profile.RagfairInfo.Offers.Splice(offerinProfileIndex, 1); @@ -311,19 +292,13 @@ public class RagfairOfferService( if (totalItemCount <= itemMaxStackSize) { // Edge case - Ensure items stack count isnt < 1 - if (items[0]?.Upd?.StackObjectsCount < 1) - { - items[0].Upd.StackObjectsCount = 1; - } + if (items[0]?.Upd?.StackObjectsCount < 1) items[0].Upd.StackObjectsCount = 1; return items; } // Single item with no children e.g. ammo, use existing de-stacking code - if (items.Count == 1) - { - return itemHelper.SplitStack(rootItem); - } + if (items.Count == 1) return itemHelper.SplitStack(rootItem); // Item with children, needs special handling // Force new item to have stack size of 1 @@ -332,7 +307,7 @@ public class RagfairOfferService( var itemAndChildrenClone = cloner.Clone(items); // Ensure upd object exits - itemAndChildrenClone[0].Upd ??= new(); + itemAndChildrenClone[0].Upd ??= new Upd(); // Force item to be singular itemAndChildrenClone[0].Upd.StackObjectsCount = 1; diff --git a/Libraries/Core/Services/RagfairPriceService.cs b/Libraries/Core/Services/RagfairPriceService.cs index 25e439a1..df72095c 100644 --- a/Libraries/Core/Services/RagfairPriceService.cs +++ b/Libraries/Core/Services/RagfairPriceService.cs @@ -25,8 +25,8 @@ public class RagfairPriceService( ConfigServer _configServer ) { + private RagfairConfig _ragfairConfig = _configServer.GetConfig(); protected Dictionary? _staticPrices; - RagfairConfig _ragfairConfig = _configServer.GetConfig(); /// /// Generate static (handbook) and dynamic (prices.json) flea prices, store inside class as dictionaries @@ -48,9 +48,8 @@ public class RagfairPriceService( public void RefreshStaticPrices() { _staticPrices = new Dictionary(); - foreach (var item in _databaseService.GetItems().Values.Where(item => item.Type == "Item")) { + foreach (var item in _databaseService.GetItems().Values.Where(item => item.Type == "Item")) _staticPrices[item.Id] = _handbookHelper.GetTemplatePrice(item.Id); - } } /// @@ -75,16 +74,19 @@ public class RagfairPriceService( { var itemFromDb = _itemHelper.GetItem(tplId); _logger.Warning( - _localisationService.GetText("ragfair-unable_to_find_item_price_for_item_in_flea_handbook", new { - tpl = tplId, - name = itemFromDb.Value.Name ?? "" })); + _localisationService.GetText( + "ragfair-unable_to_find_item_price_for_item_in_flea_handbook", + new + { + tpl = tplId, + name = itemFromDb.Value.Name ?? "" + } + ) + ); } // If no price in dynamic/static, set to 1 - if (itemPrice == 0) - { - itemPrice = 1; - } + if (itemPrice == 0) itemPrice = 1; return itemPrice.Value; } @@ -96,10 +98,7 @@ public class RagfairPriceService( public double GetFleaPriceForOfferItems(List offerItems) { // Preset weapons take the direct prices.json value, otherwise they're massively inflated - if (_itemHelper.IsOfBaseclass(offerItems[0].Template, BaseClasses.WEAPON)) - { - return GetFleaPriceForItem(offerItems[0].Template); - } + if (_itemHelper.IsOfBaseclass(offerItems[0].Template, BaseClasses.WEAPON)) return GetFleaPriceForItem(offerItems[0].Template); return offerItems.Sum(item => GetFleaPriceForItem(item.Template)); } @@ -143,10 +142,7 @@ public class RagfairPriceService( public Dictionary GetAllStaticPrices() { // Refresh the cache so we include any newly added custom items - if (_staticPrices is null) - { - RefreshStaticPrices(); - } + if (_staticPrices is null) RefreshStaticPrices(); return _staticPrices; } @@ -159,7 +155,7 @@ public class RagfairPriceService( /// different in percent protected double GetPriceDifference(double a, double b) { - return (100 * a) / (a + b); + return 100 * a / (a + b); } /// @@ -171,9 +167,7 @@ public class RagfairPriceService( { var price = 0d; - foreach (var item in barterScheme) { - price += GetStaticPriceForItem(item.Template).Value * item.Count.Value; - } + foreach (var item in barterScheme) price += GetStaticPriceForItem(item.Template).Value * item.Count.Value; return Math.Round(price); } @@ -191,26 +185,22 @@ public class RagfairPriceService( var price = 0d; // Iterate over each item in the offer. - foreach (var item in offerItems) { + foreach (var item in offerItems) + { // Skip over armor inserts as those are not factored into item prices. - if (_itemHelper.IsOfBaseclass(item.Template, BaseClasses.BUILT_IN_INSERTS)) - { - continue; - } + if (_itemHelper.IsOfBaseclass(item.Template, BaseClasses.BUILT_IN_INSERTS)) continue; price += GetDynamicItemPrice(item.Template, desiredCurrency, item, offerItems, isPackOffer).Value; // Check if the item is a weapon preset. if ( - item?.Upd?.SptPresetId is not null && - _presetHelper.IsPresetBaseClass(item.Upd.SptPresetId, BaseClasses.WEAPON) - ) - { + item?.Upd?.SptPresetId is not null && + _presetHelper.IsPresetBaseClass(item.Upd.SptPresetId, BaseClasses.WEAPON) + ) // This is a weapon preset, which has it's own price calculation that takes into account the mods in the // preset. Since we've already calculated the price for the preset entire preset in // `getDynamicItemPrice`, we can skip the rest of the items in the offer. break; - } } return Math.Round(price); @@ -230,19 +220,13 @@ public class RagfairPriceService( var price = GetFleaPriceForItem(itemTemplateId); // Adjust price if below handbook price, based on config. - if (_ragfairConfig.Dynamic.OfferAdjustment.AdjustPriceWhenBelowHandbookPrice) - { - price = AdjustPriceIfBelowHandbook(price, itemTemplateId); - } + if (_ragfairConfig.Dynamic.OfferAdjustment.AdjustPriceWhenBelowHandbookPrice) price = AdjustPriceIfBelowHandbook(price, itemTemplateId); // Use trader price if higher, based on config. if (_ragfairConfig.Dynamic.UseTraderPriceForOffersIfHigher) { var traderPrice = _traderHelper.GetHighestSellToTraderPrice(itemTemplateId); - if (traderPrice > price) - { - price = traderPrice; - } + if (traderPrice > price) price = traderPrice; } // Prices for weapon presets are handled differently. @@ -257,10 +241,7 @@ public class RagfairPriceService( } // Check for existence of manual price adjustment multiplier - if (_ragfairConfig.Dynamic.ItemPriceMultiplier.TryGetValue(itemTemplateId, out var multiplier)) - { - price *= multiplier; - } + if (_ragfairConfig.Dynamic.ItemPriceMultiplier.TryGetValue(itemTemplateId, out var multiplier)) price *= multiplier; // The quality of the item affects the price + not on the ignore list if (item is not null && !_ragfairConfig.Dynamic.IgnoreQualityPriceVarianceBlacklist.Contains(itemTemplateId)) @@ -272,16 +253,14 @@ public class RagfairPriceService( // Make adjustments for unreasonably priced items. foreach (var (key, value) in _ragfairConfig.Dynamic.UnreasonableModPrices) { - if (!_itemHelper.IsOfBaseclass(itemTemplateId, key) || !value.Enabled) - { - continue; - } + if (!_itemHelper.IsOfBaseclass(itemTemplateId, key) || !value.Enabled) continue; price = AdjustUnreasonablePrice( _databaseService.GetHandbook().Items, value, itemTemplateId, - price); + price + ); } // Vary the price based on the type of offer. @@ -290,15 +269,9 @@ public class RagfairPriceService( // Convert to different currency if required. var roublesId = Money.ROUBLES; - if (desiredCurrency != roublesId) - { - price = _handbookHelper.FromRUB(price, desiredCurrency); - } + if (desiredCurrency != roublesId) price = _handbookHelper.FromRUB(price, desiredCurrency); - if (price < 1) - { - return 1; - } + if (price < 1) return 1; return price; } @@ -317,19 +290,13 @@ public class RagfairPriceService( double price) { var itemHandbookPrice = handbookPrices.FirstOrDefault((handbookItem) => handbookItem.Id == itemTpl); - if (itemHandbookPrice is not null) - { - return price; - } + if (itemHandbookPrice is not null) return price; // Flea price is over handbook price if (price > itemHandbookPrice.Price * unreasonableItemChange.HandbookPriceOverMultiplier) { // Skip extreme values - if (price <= 1) - { - return price; - } + if (price <= 1) return price; // Price is over limit, adjust return itemHandbookPrice.Price.Value * unreasonableItemChange.NewPriceHandbookMultiplier; @@ -348,15 +315,9 @@ public class RagfairPriceService( { // Use different min/max values if the item is a preset or pack var priceRanges = _ragfairConfig.Dynamic.PriceRanges; - if (isPreset) - { - return priceRanges.Preset; - } + if (isPreset) return priceRanges.Preset; - if (isPack) - { - return priceRanges.Pack; - } + if (isPack) return priceRanges.Pack; return priceRanges.Default; } @@ -375,15 +336,13 @@ public class RagfairPriceService( // Only adjust price if difference is > a percent AND item price passes threshold set in config if ( - priceDifferencePercent > - offerAdjustmentSettings.MaxPriceDifferenceBelowHandbookPercent && - itemPrice >= offerAdjustmentSettings.PriceThresholdRub - ) - { + priceDifferencePercent > + offerAdjustmentSettings.MaxPriceDifferenceBelowHandbookPercent && + itemPrice >= offerAdjustmentSettings.PriceThresholdRub + ) // var itemDetails = this.itemHelper.getItem(itemTpl); // this.logger.debug(`item below handbook price {itemDetails[1]._name} handbook: {itemHandbookPrice} flea: ${itemPrice} {priceDifferencePercent}%`); return Math.Round(itemHandbookPrice.Value * offerAdjustmentSettings.HandbookPriceMultiplier); - } return itemPrice; } @@ -414,33 +373,29 @@ public class RagfairPriceService( { // Get the default preset for this weapon var presetResult = GetWeaponPreset(weaponRootItem); - if (presetResult.IsDefault) - { - return GetFleaPriceForItem(weaponRootItem.Template); - } + if (presetResult.IsDefault) return GetFleaPriceForItem(weaponRootItem.Template); // Get mods on current gun not in default preset var newOrReplacedModsInPresetVsDefault = weaponWithChildren.Where(x => !presetResult.Preset.Items.Any(y => y.Template == x.Template)); // Add up extra mods price var extraModsPrice = 0d; - foreach (var mod in newOrReplacedModsInPresetVsDefault) { + foreach (var mod in newOrReplacedModsInPresetVsDefault) // Use handbook or trader price, whatever is higher (dont use dynamic flea price as purchased item cannot be relisted) extraModsPrice += GetHighestHandbookOrTraderPriceAsRouble(mod.Template).Value; - } // Only deduct cost of replaced mods if there's replaced/new mods if (newOrReplacedModsInPresetVsDefault.Any()) { // Add up cost of mods replaced - var modsReplacedByNewMods = newOrReplacedModsInPresetVsDefault.Where((x) => - presetResult.Preset.Items.Any((y) => y.SlotId == x.SlotId)); + var modsReplacedByNewMods = newOrReplacedModsInPresetVsDefault.Where( + (x) => + presetResult.Preset.Items.Any((y) => y.SlotId == x.SlotId) + ); // Add up replaced mods price var replacedModsPrice = 0d; - foreach (var replacedMod in modsReplacedByNewMods) { - replacedModsPrice += GetHighestHandbookOrTraderPriceAsRouble(replacedMod.Template).Value; - } + foreach (var replacedMod in modsReplacedByNewMods) replacedModsPrice += GetHighestHandbookOrTraderPriceAsRouble(replacedMod.Template).Value; // Subtract replaced mods total from extra mods total extraModsPrice -= replacedModsPrice; @@ -459,10 +414,7 @@ public class RagfairPriceService( { var price = GetStaticPriceForItem(itemTpl); var traderPrice = _traderHelper.GetHighestSellToTraderPrice(itemTpl); - if (traderPrice > price) - { - price = traderPrice; - } + if (traderPrice > price) price = traderPrice; return price; } @@ -476,20 +428,15 @@ public class RagfairPriceService( protected WeaponPreset GetWeaponPreset(Item weapon) { var defaultPreset = _presetHelper.GetDefaultPreset(weapon.Template); - if (defaultPreset is not null) - { - return new WeaponPreset { IsDefault = true, Preset = defaultPreset }; - } + if (defaultPreset is not null) return new WeaponPreset { IsDefault = true, Preset = defaultPreset }; var nonDefaultPresets = _presetHelper.GetPresets(weapon.Template); if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug( nonDefaultPresets.Count == 1 ? $"Item Id: {weapon.Template} has no default encyclopedia entry but only one preset: ({nonDefaultPresets[0].Name}), choosing preset: ({nonDefaultPresets[0].Name})" : $"Item Id: {weapon.Template} has no default encyclopedia entry, choosing first preset({nonDefaultPresets[0].Name}) of {nonDefaultPresets.Count}" ); - } return new WeaponPreset { IsDefault = false, Preset = nonDefaultPresets[0] }; } diff --git a/Libraries/Core/Services/RagfairRequiredItemsService.cs b/Libraries/Core/Services/RagfairRequiredItemsService.cs index d7077600..641ac725 100644 --- a/Libraries/Core/Services/RagfairRequiredItemsService.cs +++ b/Libraries/Core/Services/RagfairRequiredItemsService.cs @@ -10,7 +10,6 @@ public class RagfairRequiredItemsService( RagfairOfferService _ragfairOfferService, PaymentHelper _paymentHelper) { - protected ConcurrentDictionary> _requiredItemsCache; public List? GetRequiredItemsById(string searchId) @@ -22,20 +21,18 @@ public class RagfairRequiredItemsService( public void BuildRequiredItemTable() { _requiredItemsCache = new ConcurrentDictionary>(); - foreach (var offer in _ragfairOfferService.GetOffers()) { - foreach (var requirement in offer.Requirements) { - if (_paymentHelper.IsMoneyTpl(requirement.Template)) - { - // This would just be too noisy - continue; - } + foreach (var offer in _ragfairOfferService.GetOffers()) + foreach (var requirement in offer.Requirements) + { + if (_paymentHelper.IsMoneyTpl(requirement.Template)) + // This would just be too noisy + continue; - // Ensure key is init - _requiredItemsCache.TryAdd(requirement.Template, []); + // Ensure key is init + _requiredItemsCache.TryAdd(requirement.Template, []); - // Add matching offer - _requiredItemsCache.GetValueOrDefault(requirement.Template)?.Add(offer); - } + // Add matching offer + _requiredItemsCache.GetValueOrDefault(requirement.Template)?.Add(offer); } } } diff --git a/Libraries/Core/Services/RagfairTaxService.cs b/Libraries/Core/Services/RagfairTaxService.cs index e0157b70..0ee95d85 100644 --- a/Libraries/Core/Services/RagfairTaxService.cs +++ b/Libraries/Core/Services/RagfairTaxService.cs @@ -54,15 +54,9 @@ public class RagfairTaxService( int? offerItemCount, bool sellInOnePiece) { - if (requirementsValue is null) - { - return 0; - } + if (requirementsValue is null) return 0; - if (offerItemCount is null) - { - return 0; - } + if (offerItemCount is null) return 0; var globals = _databaseService.GetGlobals(); @@ -77,13 +71,9 @@ public class RagfairTaxService( var requirementPriceMult = Math.Log10(requirementsPrice.Value / itemWorth); if (requirementsPrice >= itemWorth) - { requirementPriceMult = Math.Pow(requirementPriceMult, 1.08); - } else - { itemPriceMult = Math.Pow(itemPriceMult, 1.08); - } itemPriceMult = Math.Pow(4.0, itemPriceMult); requirementPriceMult = Math.Pow(4.0, requirementPriceMult); @@ -118,11 +108,8 @@ public class RagfairTaxService( } var taxValue = Math.Round(discountedTax.Value * itemComissionMult); - - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Tax Calculated to be: {taxValue}"); - } + + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Tax Calculated to be: {taxValue}"); return taxValue; } @@ -163,10 +150,7 @@ public class RagfairTaxService( var upd = item.Upd ??= new Upd(); - if (upd.Dogtag is not null) - { - worth *= upd.Dogtag.Level.Value; - } + if (upd.Dogtag is not null) worth *= upd.Dogtag.Level.Value; if (itemTemplate.Properties is null) { @@ -176,34 +160,24 @@ public class RagfairTaxService( } if (upd.Key is not null && (itemTemplate.Properties.MaximumNumberOfUsage ?? 0) > 0) - { worth = worth / (itemTemplate.Properties.MaximumNumberOfUsage ?? 1) * ((itemTemplate.Properties.MaximumNumberOfUsage ?? 1) - upd.Key.NumberOfUsages.Value); - } if (upd.Resource is not null && (itemTemplate.Properties.MaxResource ?? 0) > 0) - { worth = (double)(worth * 0.1 + - (worth * 0.9 / (itemTemplate.Properties.MaxResource ?? 1) * upd.Resource.Value)); - } + worth * 0.9 / (itemTemplate.Properties.MaxResource ?? 1) * upd.Resource.Value); if (upd.SideEffect is not null && (itemTemplate.Properties.MaxResource ?? 0) > 0) - { worth = (double)(worth * 0.1 + worth * 0.9 / (itemTemplate.Properties.MaxResource ?? 1) * upd.SideEffect.Value); - } if (upd.MedKit is not null && (itemTemplate.Properties.MaxHpResource ?? 0) > 0) - { worth = worth / (itemTemplate.Properties.MaxHpResource ?? 1) * upd.MedKit.HpResource.Value; - } if (upd.FoodDrink is not null && (itemTemplate.Properties.MaxResource ?? 0) > 0) - { worth = worth / (itemTemplate.Properties.MaxResource ?? 1) * upd.FoodDrink.HpPercent.Value; - } if (upd.Repairable is not null && (itemTemplate.Properties.ArmorClass ?? 0) > 0) { diff --git a/Libraries/Core/Services/RaidTimeAdjustmentService.cs b/Libraries/Core/Services/RaidTimeAdjustmentService.cs index de0df755..a69f98ae 100644 --- a/Libraries/Core/Services/RaidTimeAdjustmentService.cs +++ b/Libraries/Core/Services/RaidTimeAdjustmentService.cs @@ -43,10 +43,8 @@ public class RaidTimeAdjustmentService( var mapSettings = GetMapSettings(mapBase.Id); if (mapSettings.AdjustWaves) - { // Make alterations to bot spawn waves now player is simulated spawning later AdjustWaves(mapBase, raidAdjustments); - } } /// @@ -57,9 +55,7 @@ public class RaidTimeAdjustmentService( protected void AdjustLootMultipliers(Dictionary mapLootMultiplers, double? loosePercent) { foreach (var location in mapLootMultiplers) - { mapLootMultiplers[location.Key] = _randomUtil.GetPercentOfValue(mapLootMultiplers[location.Key], loosePercent ?? 1); - } } /// @@ -96,33 +92,28 @@ public class RaidTimeAdjustmentService( public GetRaidTimeResponse GetRaidAdjustments(string sessionId, GetRaidTimeRequest request) { var globals = _databaseService.GetGlobals(); - LocationBase mapBase = _databaseService.GetLocation(request.Location.ToLower()).Base; + var mapBase = _databaseService.GetLocation(request.Location.ToLower()).Base; var baseEscapeTimeMinutes = mapBase.EscapeTimeLimit; // Prep result object to return - GetRaidTimeResponse result = new GetRaidTimeResponse + var result = new GetRaidTimeResponse { RaidTimeMinutes = baseEscapeTimeMinutes, ExitChanges = [], NewSurviveTimeSeconds = null, - OriginalSurvivalTimeSeconds = globals.Configuration.Exp.MatchEnd.SurvivedSecondsRequirement, + OriginalSurvivalTimeSeconds = globals.Configuration.Exp.MatchEnd.SurvivedSecondsRequirement }; // Pmc raid, send default - if (request.Side.ToLower() == "pmc") - { - return result; - } + if (request.Side.ToLower() == "pmc") return result; // We're scav adjust values var mapSettings = GetMapSettings(request.Location); // Chance of reducing raid time for scav, not guaranteed if (!_randomUtil.GetChance100(mapSettings.ReducedChancePercent)) - { // Send default return result; - } // Get the weighted percent to reduce the raid time by var chosenRaidReductionPercent = int.Parse( @@ -139,7 +130,6 @@ public class RaidTimeAdjustmentService( var simulatedRaidStartTimeMinutes = baseEscapeTimeMinutes - newRaidTimeMinutes; if (mapSettings.ReduceLootByPercent) - { // Store time reduction percent in app context so loot gen can pick it up later _applicationContext.AddValue( ContextVariableType.RAID_ADJUSTMENTS, @@ -147,10 +137,9 @@ public class RaidTimeAdjustmentService( { DynamicLootPercent = Math.Max(raidTimeRemainingPercent, mapSettings.MinDynamicLootPercent), StaticLootPercent = Math.Max(raidTimeRemainingPercent, mapSettings.MinStaticLootPercent), - SimulatedRaidStartSeconds = simulatedRaidStartTimeMinutes * 60, + SimulatedRaidStartSeconds = simulatedRaidStartTimeMinutes * 60 } ); - } // Update result object with new time result.RaidTimeMinutes = newRaidTimeMinutes; @@ -159,15 +148,12 @@ public class RaidTimeAdjustmentService( // Calculate how long player needs to be in raid to get a `survived` extract status result.NewSurviveTimeSeconds = Math.Max( - (result.OriginalSurvivalTimeSeconds - (baseEscapeTimeMinutes - newRaidTimeMinutes) * 60) ?? 0, + result.OriginalSurvivalTimeSeconds - (baseEscapeTimeMinutes - newRaidTimeMinutes) * 60 ?? 0, 0D ); var exitAdjustments = GetExitAdjustments(mapBase, newRaidTimeMinutes); - if (exitAdjustments is not null) - { - result.ExitChanges.AddRange(exitAdjustments); - } + if (exitAdjustments is not null) result.ExitChanges.AddRange(exitAdjustments); return result; } @@ -199,17 +185,17 @@ public class RaidTimeAdjustmentService( { List result = []; // Adjust train exits only - foreach (var exit in mapBase.Exits) { - if (exit.PassageRequirement != RequirementState.Train) { - continue; - } + foreach (var exit in mapBase.Exits) + { + if (exit.PassageRequirement != RequirementState.Train) continue; // Prepare train adjustment object - var exitChange = new ExtractChange { + var exitChange = new ExtractChange + { Name = exit.Name, MinTime = null, MaxTime = null, - Chance = null, + Chance = null }; // At what minute we simulate the player joining the raid @@ -241,10 +227,13 @@ public class RaidTimeAdjustmentService( // If raid is after last moment train can leave, assume train has already left, disable extract var mostPossibleTimeRemainingAfterDeparture = mapBase.EscapeTimeLimit - earliestPossibleDepartureMinutes; - if (newRaidTimeMinutes < mostPossibleTimeRemainingAfterDeparture) { + if (newRaidTimeMinutes < mostPossibleTimeRemainingAfterDeparture) + { exitChange.Chance = 0; - _logger.Debug($"Train Exit: {exit.Name} disabled as new raid time {newRaidTimeMinutes} minutes is below {mostPossibleTimeRemainingAfterDeparture} minutes"); + _logger.Debug( + $"Train Exit: {exit.Name} disabled as new raid time {newRaidTimeMinutes} minutes is below {mostPossibleTimeRemainingAfterDeparture} minutes" + ); result.Add(exitChange); @@ -252,8 +241,8 @@ public class RaidTimeAdjustmentService( } // Reduce extract arrival times. Negative values seem to make extract turn red in game. - exitChange.MinTime = Math.Max((exit.MinTime - reductionSeconds) ?? 0, 0); - exitChange.MaxTime = Math.Max((exit.MaxTime - reductionSeconds) ?? 0, 0); + exitChange.MinTime = Math.Max(exit.MinTime - reductionSeconds ?? 0, 0); + exitChange.MaxTime = Math.Max(exit.MaxTime - reductionSeconds ?? 0, 0); _logger.Debug($"Train appears between: {exitChange.MinTime} and {exitChange.MaxTime} seconds raid time"); diff --git a/Libraries/Core/Services/RaidWeatherService.cs b/Libraries/Core/Services/RaidWeatherService.cs index bde35e25..1339af42 100644 --- a/Libraries/Core/Services/RaidWeatherService.cs +++ b/Libraries/Core/Services/RaidWeatherService.cs @@ -95,9 +95,6 @@ public class RaidWeatherService( // Check data exists for current time var result = _weatherForecast.Where((weather) => weather.Timestamp >= _timeUtil.GetTimeStamp()); - if (!result.Any()) - { - GenerateWeather(currentSeason); - } + if (!result.Any()) GenerateWeather(currentSeason); } } diff --git a/Libraries/Core/Services/RepairService.cs b/Libraries/Core/Services/RepairService.cs index 6af667ca..4c7af55c 100644 --- a/Libraries/Core/Services/RepairService.cs +++ b/Libraries/Core/Services/RepairService.cs @@ -52,21 +52,16 @@ public class RepairService( { var itemToRepair = pmcData.Inventory.Items.FirstOrDefault(item => item.Id == repairItemDetails.Id); if (itemToRepair is null) - { _logger.Error( _localisationService.GetText( "repair-unable_to_find_item_in_inventory_cant_repair", repairItemDetails.Id ) ); - } var priceCoef = _traderHelper.GetLoyaltyLevel(traderId, pmcData).RepairPriceCoefficient; var traderRepairDetails = _traderHelper.GetTrader(traderId, sessionID)?.Repair; - if (traderRepairDetails is null) - { - _logger.Error(_localisationService.GetText("repair-unable_to_find_trader_details_by_id", traderId)); - } + if (traderRepairDetails is null) _logger.Error(_localisationService.GetText("repair-unable_to_find_trader_details_by_id", traderId)); var repairQualityMultiplier = traderRepairDetails.Quality; var repairRate = priceCoef <= 0 ? 1 : priceCoef / 100 + 1; @@ -88,11 +83,9 @@ public class RepairService( // get repair price var itemRepairCost = items[itemToRepair.Template].Properties.RepairCost; if (itemRepairCost is null) - { _logger.Error( _localisationService.GetText("repair-unable_to_find_item_repair_cost", itemToRepair.Template) ); - } var repairCost = Math.Round( itemRepairCost.Value * repairItemDetails.Count.Value * repairRate.Value * _repairConfig.PriceMultiplier @@ -198,14 +191,12 @@ public class RepairService( var isHeavyArmor = itemDetails.Value.Properties.ArmorType == "Heavy"; var vestSkillToLevel = isHeavyArmor ? SkillTypes.HeavyVests : SkillTypes.LightVests; if (repairDetails.RepairPoints is null) - { _logger.Error( _localisationService.GetText( "repair-item_has_no_repair_points", repairDetails.RepairedItem.Template ) ); - } var pointsToAddToVestSkill = repairDetails.RepairPoints * _repairConfig.ArmorKitSkillPointGainPerRepairPointMultiplier; @@ -234,14 +225,12 @@ public class RepairService( // Limit gain to a max value defined in config.maxIntellectGainPerRepair if (repairDetails.RepairPoints is null) - { _logger.Error( _localisationService.GetText( "repair-item_has_no_repair_points", repairDetails.RepairedItem.Template ) ); - } return Math.Min( repairDetails.RepairPoints.Value * intRepairMultiplier, @@ -276,16 +265,10 @@ public class RepairService( // You can both crit fail and succeed at the same time, for fun (Balances out to 0 with default settings) // Add a random chance to crit-fail - if (random.Next() <= _repairConfig.WeaponTreatment.CritFailureChance) - { - skillPoints -= _repairConfig.WeaponTreatment.CritFailureAmount; - } + if (random.Next() <= _repairConfig.WeaponTreatment.CritFailureChance) skillPoints -= _repairConfig.WeaponTreatment.CritFailureAmount; // Add a random chance to crit-succeed - if (random.Next() <= _repairConfig.WeaponTreatment.CritSuccessChance) - { - skillPoints += _repairConfig.WeaponTreatment.CritSuccessAmount; - } + if (random.Next() <= _repairConfig.WeaponTreatment.CritSuccessChance) skillPoints += _repairConfig.WeaponTreatment.CritSuccessAmount; return Math.Max(skillPoints, 0); } @@ -308,10 +291,7 @@ public class RepairService( { // Find item to repair in inventory var itemToRepair = pmcData.Inventory.Items.FirstOrDefault(x => x.Id == itemToRepairId); - if (itemToRepair is null) - { - _logger.Error(_localisationService.GetText("repair-item_not_found_unable_to_repair", itemToRepairId)); - } + if (itemToRepair is null) _logger.Error(_localisationService.GetText("repair-item_not_found_unable_to_repair", itemToRepairId)); var itemsDb = _databaseService.GetItems(); var itemToRepairDetails = itemsDb[itemToRepair.Template]; @@ -337,11 +317,9 @@ public class RepairService( { var repairKitInInventory = pmcData.Inventory.Items.FirstOrDefault(item => item.Id == repairKit.Id); if (repairKitInInventory is null) - { _logger.Error( _localisationService.GetText("repair-repair_kit_not_found_in_inventory", repairKit.Id) ); - } var repairKitDetails = itemsDb[repairKitInInventory.Template]; var repairKitReductionAmount = repairKit.Count; @@ -440,10 +418,8 @@ public class RepairService( // Random loss not disabled via config, perform charisma check var hasEliteCharisma = _profileHelper.HasEliteSkillLevel(SkillTypes.Charisma, pmcData); if (hasEliteCharisma) - { // 50/50 chance of loss being ignored at elite level shouldApplyDurabilityLoss = _randomUtil.GetChance100(50); - } } return shouldApplyDurabilityLoss; @@ -459,18 +435,12 @@ public class RepairService( var maxRepairAmount = repairKitDetails.Properties.MaxRepairResource; if (repairKitInInventory.Upd is null) { - if(_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"Repair kit: {repairKitInInventory.Id} in inventory lacks upd object, adding"); - } - + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"Repair kit: {repairKitInInventory.Id} in inventory lacks upd object, adding"); + repairKitInInventory.Upd = new Upd { RepairKit = new UpdRepairKit { Resource = maxRepairAmount } }; } - if (repairKitInInventory.Upd.RepairKit?.Resource is null) - { - repairKitInInventory.Upd.RepairKit = new UpdRepairKit { Resource = maxRepairAmount }; - } + if (repairKitInInventory.Upd.RepairKit?.Resource is null) repairKitInInventory.Upd.RepairKit = new UpdRepairKit { Resource = maxRepairAmount }; } /// @@ -481,10 +451,7 @@ public class RepairService( public void AddBuffToItem(RepairDetails repairDetails, PmcData pmcData) { // Buffs are repair kit only - if (!repairDetails.RepairedByKit.GetValueOrDefault(false)) - { - return; - } + if (!repairDetails.RepairedByKit.GetValueOrDefault(false)) return; if (ShouldBuffItem(repairDetails, pmcData)) { @@ -553,37 +520,27 @@ public class RepairService( var globals = _databaseService.GetGlobals(); var hasTemplate = _itemHelper.GetItem(repairDetails.RepairedItem.Template); - if (!hasTemplate.Key) - { - return false; - } + if (!hasTemplate.Key) return false; var template = hasTemplate.Value; // Returns SkillTypes.LIGHT_VESTS/HEAVY_VESTS/WEAPON_TREATMENT var itemSkillType = (SkillTypes)GetItemSkillType(template); - if (itemSkillType == null) - { - return false; - } + if (itemSkillType == null) return false; // Skill < level 10 + repairing weapon if ( itemSkillType == SkillTypes.WeaponTreatment && _profileHelper.GetSkillFromProfile(pmcData, SkillTypes.WeaponTreatment)?.Progress < 1000 ) - { return false; - } // Skill < level 10 + repairing armor if ( new List { SkillTypes.LightVests, SkillTypes.HeavyVests }.Contains(itemSkillType) && _profileHelper.GetSkillFromProfile(pmcData, itemSkillType)?.Progress < 1000 ) - { return false; - } var skillSettings = globals.Configuration.SkillsSettings.GetAllPropsAsDict(); BuffSettings buffSettings = null; @@ -609,11 +566,9 @@ public class RepairService( Math.Truncate((_profileHelper.GetSkillFromProfile(pmcData, itemSkillType)?.Progress ?? 0) / 100); if (repairDetails.RepairPoints is null) - { _logger.Error( _localisationService.GetText("repair-item_has_no_repair_points", repairDetails.RepairedItem.Template) ); - } var durabilityToRestorePercent = repairDetails.RepairPoints / template.Properties.MaxDurability; var durabilityMultiplier = GetDurabilityMultiplier( @@ -646,26 +601,14 @@ public class RepairService( if (isArmorRelated) { var armorType = itemTemplate.Properties.ArmorType; - if (armorType == "Light") - { - return SkillTypes.LightVests; - } + if (armorType == "Light") return SkillTypes.LightVests; - if (armorType == "Heavy") - { - return SkillTypes.HeavyVests; - } + if (armorType == "Heavy") return SkillTypes.HeavyVests; } - if (_itemHelper.IsOfBaseclass(itemTemplate.Id, BaseClasses.WEAPON)) - { - return SkillTypes.WeaponTreatment; - } + if (_itemHelper.IsOfBaseclass(itemTemplate.Id, BaseClasses.WEAPON)) return SkillTypes.WeaponTreatment; - if (_itemHelper.IsOfBaseclass(itemTemplate.Id, BaseClasses.KNIFE)) - { - return SkillTypes.Melee; - } + if (_itemHelper.IsOfBaseclass(itemTemplate.Id, BaseClasses.KNIFE)) return SkillTypes.Melee; return null; } diff --git a/Libraries/Core/Services/SeasonalEventService.cs b/Libraries/Core/Services/SeasonalEventService.cs index b7e44ad6..769467cb 100644 --- a/Libraries/Core/Services/SeasonalEventService.cs +++ b/Libraries/Core/Services/SeasonalEventService.cs @@ -24,15 +24,7 @@ public class SeasonalEventService( ConfigServer _configServer ) { - protected SeasonalEventConfig _seasonalEventConfig = _configServer.GetConfig(); - protected QuestConfig _questConfig = _configServer.GetConfig(); - protected HttpConfig _httpConfig = _configServer.GetConfig(); - protected WeatherConfig _weatherConfig = _configServer.GetConfig(); - protected LocationConfig _locationConfig = _configServer.GetConfig(); - - private List _currentlyActiveEvents = []; private bool _christmasEventActive = false; - private bool _halloweenEventActive = false; protected IReadOnlyList _christmasEventItems = [ @@ -61,6 +53,9 @@ public class SeasonalEventService( ItemTpl.FACECOVER_AYBOLIT_MASK ]; + private List _currentlyActiveEvents = []; + private bool _halloweenEventActive = false; + protected IReadOnlyList _halloweenEventItems = [ ItemTpl.FACECOVER_SPOOKY_SKULL_MASK, @@ -76,6 +71,12 @@ public class SeasonalEventService( ItemTpl.FACECOVER_HOCKEY_PLAYER_MASK_QUIET ]; + protected HttpConfig _httpConfig = _configServer.GetConfig(); + protected LocationConfig _locationConfig = _configServer.GetConfig(); + protected QuestConfig _questConfig = _configServer.GetConfig(); + protected SeasonalEventConfig _seasonalEventConfig = _configServer.GetConfig(); + protected WeatherConfig _weatherConfig = _configServer.GetConfig(); + /// /// Get an array of christmas items found in bots inventories as loot /// @@ -132,15 +133,9 @@ public class SeasonalEventService( public List GetInactiveSeasonalEventItems() { var items = new List(); - if (!ChristmasEventEnabled()) - { - items.AddRange(_christmasEventItems); - } + if (!ChristmasEventEnabled()) items.AddRange(_christmasEventItems); - if (!HalloweenEventEnabled()) - { - items.AddRange(_halloweenEventItems); - } + if (!HalloweenEventEnabled()) items.AddRange(_halloweenEventItems); return items; } @@ -219,10 +214,7 @@ public class SeasonalEventService( public bool IsQuestRelatedToEvent(string questId, SeasonalEventType eventType) { var eventQuestData = _questConfig.EventQuests.GetValueOrDefault(questId, null); - if (eventQuestData?.Season == eventType) - { - return true; - } + if (eventQuestData?.Season == eventType) return true; return false; } @@ -235,10 +227,7 @@ public class SeasonalEventService( if (_currentlyActiveEvents.Any()) { var globalConfig = _databaseService.GetGlobals().Configuration; - foreach (var activeEvent in _currentlyActiveEvents) - { - UpdateGlobalEvents(globalConfig, activeEvent); - } + foreach (var activeEvent in _currentlyActiveEvents) UpdateGlobalEvents(globalConfig, activeEvent); } } @@ -271,20 +260,14 @@ public class SeasonalEventService( var seasonalEvents = GetEventDetails(); // reset existing data - _currentlyActiveEvents = new(); + _currentlyActiveEvents = new List(); // Add active events to array foreach (var events in seasonalEvents) { - if (!events.Enabled) - { - continue; - } + if (!events.Enabled) continue; - if (DateIsBetweenTwoDates(currentDate, events.StartMonth, events.StartDay, events.EndMonth, events.EndDay)) - { - _currentlyActiveEvents.Add(events); - } + if (DateIsBetweenTwoDates(currentDate, events.StartMonth, events.StartDay, events.EndMonth, events.EndDay)) _currentlyActiveEvents.Add(events); } } @@ -294,14 +277,10 @@ public class SeasonalEventService( /// Season enum value public Season GetActiveWeatherSeason() { - if (_weatherConfig.OverrideSeason.HasValue) - { - return _weatherConfig.OverrideSeason.Value; - } + if (_weatherConfig.OverrideSeason.HasValue) return _weatherConfig.OverrideSeason.Value; var currentDate = _timeUtil.GetDateTimeNow(); foreach (var seasonRange in _weatherConfig.SeasonDates) - { if ( DateIsBetweenTwoDates( currentDate, @@ -311,10 +290,7 @@ public class SeasonalEventService( seasonRange.EndDay ?? 0 ) ) - { return seasonRange.SeasonType ?? Season.SUMMER; - } - } _logger.Warning(_localisationService.GetText("season-no_matching_season_found_for_date")); @@ -355,18 +331,16 @@ public class SeasonalEventService( foreach (var equipmentSlotKey in equipmentSlotsToFilter) { if (botInventory.Equipment[equipmentSlotKey] is null) - { _logger.Warning( _localisationService.GetText( "seasonal-missing_equipment_slot_on_bot", new { equipmentSlot = equipmentSlotKey, - botRole = botRole, + botRole = botRole } ) ); - } Dictionary equipment = botInventory.Equipment[equipmentSlotKey]; botInventory.Equipment[equipmentSlotKey] = equipment.Where(i => !_christmasEventItems.Contains(i.Key)).ToDictionary(); @@ -379,46 +353,31 @@ public class SeasonalEventService( var prop = (Dictionary?)props.FirstOrDefault(p => p.Name.ToLower() == lootContainerKey.ToLower()).GetValue(botInventory.Items); if (prop is null) - { _logger.Warning( _localisationService.GetText( "seasonal-missing_loot_container_slot_on_bot", new { lootContainer = lootContainerKey, - botRole = botRole, + botRole = botRole } ) ); - } List tplsToRemove = []; foreach (var tplKey in prop) - { if (christmasItems.Contains(tplKey.Key)) - { tplsToRemove.Add(tplKey.Key); - } - } - foreach (var tplToRemove in tplsToRemove) - { - prop.Remove(tplToRemove); - } + foreach (var tplToRemove in tplsToRemove) prop.Remove(tplToRemove); // Get non-christmas items var nonChristmasTpls = prop.Where(tpl => !christmasItems.Contains(tpl.Key)); - if (nonChristmasTpls.Count() == 0) - { - continue; - } + if (nonChristmasTpls.Count() == 0) continue; Dictionary intermediaryDict = new(); - foreach (var tpl in nonChristmasTpls) - { - intermediaryDict[tpl.Key] = prop[tpl.Key]; - } + foreach (var tpl in nonChristmasTpls) intermediaryDict[tpl.Key] = prop[tpl.Key]; // Replace the original containerItems with the updated one prop = intermediaryDict; @@ -483,25 +442,14 @@ public class SeasonalEventService( AddEventBossesToMaps("halloweensummon"); } - if (eventType.Settings?.ZombieSettings?.Enabled ?? false) - { - ConfigureZombies(eventType.Settings.ZombieSettings); - } + if (eventType.Settings?.ZombieSettings?.Enabled ?? false) ConfigureZombies(eventType.Settings.ZombieSettings); - if (eventType.Settings?.RemoveEntryRequirement is not null) - { - RemoveEntryRequirement(eventType.Settings.RemoveEntryRequirement); - } + if (eventType.Settings?.RemoveEntryRequirement is not null) RemoveEntryRequirement(eventType.Settings.RemoveEntryRequirement); if (eventType.Settings?.ReplaceBotHostility ?? false) - { ReplaceBotHostility(_seasonalEventConfig.HostilitySettingsForEvent.FirstOrDefault(x => x.Key == "zombies").Value); - } - if (eventType.Settings?.AdjustBotAppearances ?? false) - { - AdjustBotAppearanceValues(eventType.Type); - } + if (eventType.Settings?.AdjustBotAppearances ?? false) AdjustBotAppearanceValues(eventType.Type); AddPumpkinsToScavBackpacks(); AdjustTraderIcons(eventType.Type); @@ -527,10 +475,7 @@ public class SeasonalEventService( } EnableDancingTree(); - if (eventType.Settings?.AdjustBotAppearances ?? false) - { - AdjustBotAppearanceValues(eventType.Type); - } + if (eventType.Settings?.AdjustBotAppearances ?? false) AdjustBotAppearanceValues(eventType.Type); } private void ApplyNewYearsEvent(SeasonalEvent eventType, Config globalConfig) @@ -554,27 +499,18 @@ public class SeasonalEventService( EnableDancingTree(); - if (eventType.Settings?.AdjustBotAppearances ?? false) - { - AdjustBotAppearanceValues(SeasonalEventType.Christmas); - } + if (eventType.Settings?.AdjustBotAppearances ?? false) AdjustBotAppearanceValues(SeasonalEventType.Christmas); } private void AdjustBotAppearanceValues(SeasonalEventType season) { var adjustments = _seasonalEventConfig.BotAppearanceChanges[season]; - if (adjustments is null) - { - return; - } + if (adjustments is null) return; foreach (var botTypeKey in adjustments) { var botDb = _databaseService.GetBots().Types[botTypeKey.Key]; - if (botDb is null) - { - continue; - } + if (botDb is null) continue; var botAppearanceAdjustments = botTypeKey.Value; foreach (var appearanceKey in botAppearanceAdjustments) @@ -602,24 +538,15 @@ public class SeasonalEventService( foreach (var locationProp in props) { - if (ignoreList.Contains(locationProp.Name)) - { - continue; - } + if (ignoreList.Contains(locationProp.Name)) continue; var location = (Location)locationProp.GetValue(locations); - if (location?.Base?.BotLocationModifier?.AdditionalHostilitySettings is null) - { - continue; - } + if (location?.Base?.BotLocationModifier?.AdditionalHostilitySettings is null) continue; - var newHostilitySettings = useDefault ? new() : hostilitySettings[locationProp.Name]; - if (newHostilitySettings is null) - { - continue; - } + var newHostilitySettings = useDefault ? new List() : hostilitySettings[locationProp.Name]; + if (newHostilitySettings is null) continue; - location.Base.BotLocationModifier.AdditionalHostilitySettings = new(); + location.Base.BotLocationModifier.AdditionalHostilitySettings = new List(); } } @@ -635,13 +562,9 @@ public class SeasonalEventService( public void GivePlayerSeasonalGifts(string sessionId) { - if (_currentlyActiveEvents is null) - { - return; - } + if (_currentlyActiveEvents is null) return; foreach (var seasonEvent in _currentlyActiveEvents) - { switch (seasonEvent.Type) { case SeasonalEventType.Christmas: @@ -652,7 +575,6 @@ public class SeasonalEventService( GiveGift(sessionId, "NewYear2024"); break; } - } } /// @@ -693,26 +615,24 @@ public class SeasonalEventService( infectionHalloween.Enabled = true; var globalInfectionDict = globals.LocationInfection.GetAllPropsAsDict(); - foreach (var infectedLocationKvP in zombieSettings.MapInfectionAmount) { + foreach (var infectedLocationKvP in zombieSettings.MapInfectionAmount) + { var mappedLocations = GetLocationFromInfectedLocation(infectedLocationKvP.Key); - foreach (var locationKey in mappedLocations) { + foreach (var locationKey in mappedLocations) _databaseService.GetLocation( - locationKey.ToLower()).Base.Events.Halloween2024.InfectionPercentage = + locationKey.ToLower() + ) + .Base.Events.Halloween2024.InfectionPercentage = zombieSettings.MapInfectionAmount[infectedLocationKvP.Key]; - } globalInfectionDict[infectedLocationKvP.Key] = zombieSettings.MapInfectionAmount[infectedLocationKvP.Key]; } - foreach (var locationId in zombieSettings.DisableBosses) { - _databaseService.GetLocation(locationId).Base.BossLocationSpawn = []; - } + foreach (var locationId in zombieSettings.DisableBosses) _databaseService.GetLocation(locationId).Base.BossLocationSpawn = []; - foreach (var locationId in zombieSettings.DisableWaves) { - _databaseService.GetLocation(locationId).Base.Waves = []; - } + foreach (var locationId in zombieSettings.DisableWaves) _databaseService.GetLocation(locationId).Base.Waves = []; var locationsWithActiveInfection = GetLocationsWithZombies(zombieSettings.MapInfectionAmount); AddEventBossesToMaps("halloweenzombies", locationsWithActiveInfection); @@ -729,12 +649,11 @@ public class SeasonalEventService( // Get only the locations with an infection above 0 var infectionKeys = locationInfections.Where( - (location) => locationInfections[location.Key] > 0); + (location) => locationInfections[location.Key] > 0 + ); // Convert the infected location id into its generic location id - foreach (var location in infectionKeys) { - result.AddRange(GetLocationFromInfectedLocation(location.Key)); - } + foreach (var location in infectionKeys) result.AddRange(GetLocationFromInfectedLocation(location.Key)); return result; } @@ -760,12 +679,13 @@ public class SeasonalEventService( if (wavesToAddByMap is null) { - _logger.Warning($"Unable to add: { eventType} waves, eventWaves is missing"); + _logger.Warning($"Unable to add: {eventType} waves, eventWaves is missing"); return; } var locations = _databaseService.GetLocations().GetAllPropsAsDict(); - foreach (var map in wavesToAddByMap) { + foreach (var map in wavesToAddByMap) + { var wavesToAdd = wavesToAddByMap[map.Key]; if (wavesToAdd is null) { @@ -793,7 +713,8 @@ public class SeasonalEventService( var mapKeys = botsToAddPerMap; var locations = _databaseService.GetLocations().GetAllPropsAsDict(); - foreach (var (key, _) in mapKeys) { + foreach (var (key, _) in mapKeys) + { if (!botsToAddPerMap.TryGetValue(key, out var bossesToAdd)) { _logger.Warning($"Unable to add: {eventType} bosses to: {key}"); @@ -801,18 +722,13 @@ public class SeasonalEventService( continue; } - if (mapIdWhitelist is null || !mapIdWhitelist.Contains(key)) - { - continue; - } + if (mapIdWhitelist is null || !mapIdWhitelist.Contains(key)) continue; - foreach (var boss in bossesToAdd) { + foreach (var boss in bossesToAdd) + { var mapBosses = ((Location)locations[key]).Base.BossLocationSpawn; // If no bosses match by name - if (mapBosses.All(bossSpawn => bossSpawn.BossName != boss.BossName)) - { - ((Location)locations[key]).Base.BossLocationSpawn.AddRange(bossesToAdd); - } + if (mapBosses.All(bossSpawn => bossSpawn.BossName != boss.BossName)) ((Location)locations[key]).Base.BossLocationSpawn.AddRange(bossesToAdd); } } } @@ -885,7 +801,8 @@ public class SeasonalEventService( } // Iterate over bots with changes to apply - foreach (var botKvP in botGearChanges) { + foreach (var botKvP in botGearChanges) + { var botToUpdate = _databaseService.GetBots().Types[botKvP.Key.ToLower()]; if (botToUpdate is null) { @@ -895,11 +812,13 @@ public class SeasonalEventService( // Iterate over each equipment slot change var gearAmendmentsBySlot = botGearChanges[botKvP.Key]; - foreach (var equipmentKvP in gearAmendmentsBySlot) { + foreach (var equipmentKvP in gearAmendmentsBySlot) + { // Adjust slots spawn chance to be at least 75% botToUpdate.BotChances.EquipmentChances[equipmentKvP.Key] = Math.Max( botToUpdate.BotChances.EquipmentChances[equipmentKvP.Key], - 75); + 75 + ); // Grab gear to add and loop over it foreach (var itemToAddKvP in equipmentKvP.Value) @@ -927,7 +846,8 @@ public class SeasonalEventService( } // Iterate over bots with changes to apply - foreach (var botKvpP in botLootChanges) { + foreach (var botKvpP in botLootChanges) + { var botToUpdate = _databaseService.GetBots().Types[botKvpP.Key.ToLower()]; if (botToUpdate is null) { @@ -937,7 +857,8 @@ public class SeasonalEventService( // Iterate over each loot slot change var lootAmendmentsBySlot = botLootChanges[botKvpP.Key]; - foreach (var slotKvP in lootAmendmentsBySlot) { + foreach (var slotKvP in lootAmendmentsBySlot) + { // Grab loot to add and loop over it var itemTplsToAdd = slotKvP.Value; foreach (var itemKvP in itemTplsToAdd) @@ -978,12 +899,11 @@ public class SeasonalEventService( foreach (var mapKvP in maps.GetDictionary()) { // Skip maps that have no tree - if (mapsToCheck.Contains(mapKvP.Key)) { - continue; - } + if (mapsToCheck.Contains(mapKvP.Key)) continue; var mapData = mapKvP.Value; - if (mapData.Base?.Events?.Khorovod?.Chance is not null) { + if (mapData.Base?.Events?.Khorovod?.Chance is not null) + { mapData.Base.Events.Khorovod.Chance = 100; mapData.Base.BotLocationModifier.KhorovodChance = 100; } @@ -1004,65 +924,61 @@ public class SeasonalEventService( _logger.Warning($"AddGifterBotToMaps() Map not found {gifterMapSettings.Map}"); continue; } - // Dont add gifter to map twice - if (mapData.Base.BossLocationSpawn.Any((boss) => boss.BossName == "gifter")) { - continue; - } - mapData.Base.BossLocationSpawn.Add(new BossLocationSpawn { - BossName = "gifter", - BossChance = gifterMapSettings.SpawnChance, - BossZone = gifterMapSettings.Zones, - IsBossPlayer = false, - BossDifficulty = "normal", - BossEscortType = "gifter", - BossEscortDifficulty = "normal", - BossEscortAmount = "0", - ForceSpawn = true, - SpawnMode = ["regular", "pve"], - Time = -1, - TriggerId = "", - TriggerName = "", - Delay = 0, - IsRandomTimeSpawn = false, - }); + // Dont add gifter to map twice + if (mapData.Base.BossLocationSpawn.Any((boss) => boss.BossName == "gifter")) continue; + + mapData.Base.BossLocationSpawn.Add( + new BossLocationSpawn + { + BossName = "gifter", + BossChance = gifterMapSettings.SpawnChance, + BossZone = gifterMapSettings.Zones, + IsBossPlayer = false, + BossDifficulty = "normal", + BossEscortType = "gifter", + BossEscortDifficulty = "normal", + BossEscortAmount = "0", + ForceSpawn = true, + SpawnMode = ["regular", "pve"], + Time = -1, + TriggerId = "", + TriggerName = "", + Delay = 0, + IsRandomTimeSpawn = false + } + ); } } protected void HandleModEvent(SeasonalEvent seasonalEvent, Config globalConfig) { - if (seasonalEvent.Settings?.EnableChristmasHideout ?? false) { + if (seasonalEvent.Settings?.EnableChristmasHideout ?? false) + { globalConfig.EventType = globalConfig.EventType.Where((x) => x != EventType.None).ToList(); globalConfig.EventType.Add(EventType.Christmas); } - if (seasonalEvent.Settings?.EnableHalloweenHideout ?? false) { + if (seasonalEvent.Settings?.EnableHalloweenHideout ?? false) + { globalConfig.EventType = globalConfig.EventType.Where((x) => x != EventType.None).ToList(); globalConfig.EventType.Add(EventType.Halloween); globalConfig.EventType.Add(EventType.HalloweenIllumination); } - if (seasonalEvent.Settings?.AddEventGearToBots ?? false) { - AddEventGearToBots(seasonalEvent.Type); - } - if (seasonalEvent.Settings?.AddEventLootToBots ?? false) { - AddEventLootToBots(seasonalEvent.Type); - } + if (seasonalEvent.Settings?.AddEventGearToBots ?? false) AddEventGearToBots(seasonalEvent.Type); + if (seasonalEvent.Settings?.AddEventLootToBots ?? false) AddEventLootToBots(seasonalEvent.Type); - if (seasonalEvent.Settings?.EnableSummoning ?? false) { + if (seasonalEvent.Settings?.EnableSummoning ?? false) + { EnableHalloweenSummonEvent(); AddEventBossesToMaps("halloweensummon"); } - if (seasonalEvent.Settings?.ZombieSettings?.Enabled ?? false) { - ConfigureZombies(seasonalEvent.Settings.ZombieSettings); - } - if (seasonalEvent.Settings?.ForceSeason is not null) { - _weatherConfig.OverrideSeason = seasonalEvent.Settings.ForceSeason; - } - if (seasonalEvent.Settings?.AdjustBotAppearances ?? false) { - AdjustBotAppearanceValues(seasonalEvent.Type); - } + if (seasonalEvent.Settings?.ZombieSettings?.Enabled ?? false) ConfigureZombies(seasonalEvent.Settings.ZombieSettings); + if (seasonalEvent.Settings?.ForceSeason is not null) _weatherConfig.OverrideSeason = seasonalEvent.Settings.ForceSeason; + + if (seasonalEvent.Settings?.AdjustBotAppearances ?? false) AdjustBotAppearanceValues(seasonalEvent.Type); } /// @@ -1074,9 +990,7 @@ public class SeasonalEventService( { var giftData = _giftService.GetGiftById(giftKey); if (!_profileHelper.PlayerHasRecievedMaxNumberOfGift(playerId, giftKey, giftData.MaxToSendPlayer ?? 5)) - { _giftService.SendGiftToPlayer(playerId, giftKey); - } } /// diff --git a/Libraries/Core/Services/TraderAssortService.cs b/Libraries/Core/Services/TraderAssortService.cs index 1c941d32..028f9efb 100644 --- a/Libraries/Core/Services/TraderAssortService.cs +++ b/Libraries/Core/Services/TraderAssortService.cs @@ -9,12 +9,12 @@ public class TraderAssortService( TraderHelper _traderHelper) { protected readonly Dictionary _pristineTraderAssorts = new(); - + public TraderAssort? GetPristineTraderAssort(string traderId) { return _traderHelper.GetTraderAssortsByTraderId(traderId); _pristineTraderAssorts.TryGetValue(traderId, out var result); - + return result; } diff --git a/Libraries/Core/Services/TraderPurchasePersisterService.cs b/Libraries/Core/Services/TraderPurchasePersisterService.cs index f89641c3..17bce8f1 100644 --- a/Libraries/Core/Services/TraderPurchasePersisterService.cs +++ b/Libraries/Core/Services/TraderPurchasePersisterService.cs @@ -30,15 +30,9 @@ public class TraderPurchasePersisterService( { var profile = _profileHelper.GetFullProfile(sessionId); - if (profile.TraderPurchases is null) - { - return null; - } + if (profile.TraderPurchases is null) return null; - if (profile.TraderPurchases.ContainsKey(traderId)) - { - return profile.TraderPurchases[traderId]; - } + if (profile.TraderPurchases.ContainsKey(traderId)) return profile.TraderPurchases[traderId]; return null; } @@ -57,22 +51,13 @@ public class TraderPurchasePersisterService( { var profile = _profileHelper.GetFullProfile(sessionId); - if (profile.TraderPurchases is null) - { - return null; - } + if (profile.TraderPurchases is null) return null; - if (!profile.TraderPurchases.TryGetValue(traderId, out var _)) - { - profile.TraderPurchases.TryAdd(traderId, new Dictionary()); - } + if (!profile.TraderPurchases.TryGetValue(traderId, out _)) profile.TraderPurchases.TryAdd(traderId, new Dictionary()); var traderPurchases = profile.TraderPurchases[traderId]; - if (!traderPurchases.TryGetValue(assortId, out var _)) - { - traderPurchases.TryAdd(assortId, new TraderPurchaseData()); - } + if (!traderPurchases.TryGetValue(assortId, out _)) traderPurchases.TryAdd(assortId, new TraderPurchaseData()); return traderPurchases[assortId]; } @@ -88,19 +73,14 @@ public class TraderPurchasePersisterService( foreach (var profile in profiles) { // Skip if no purchases - if (profile.Value.TraderPurchases is null) - { - continue; - } + if (profile.Value.TraderPurchases is null) continue; // Skip if no trader-speicifc purchases - if (!profile.Value.TraderPurchases.TryGetValue(traderId, out var _)) - { - continue; - } + if (!profile.Value.TraderPurchases.TryGetValue(traderId, out _)) continue; profile.Value.TraderPurchases[traderId] = new Dictionary(); } + _logger.Debug($"Reset trader: {traderId} assort buy limits"); } @@ -117,10 +97,7 @@ public class TraderPurchasePersisterService( // Skip if no purchases or no trader-specific purchases var purchasesFromTrader = profile.TraderPurchases?.GetValueOrDefault(traderId, null); - if (purchasesFromTrader is null) - { - continue; - } + if (purchasesFromTrader is null) continue; foreach (var purchaseKvP in purchasesFromTrader) { @@ -133,7 +110,7 @@ public class TraderPurchasePersisterService( new { profileId = profile.ProfileInfo.ProfileId, - traderId = traderId, + traderId = traderId } ) ); diff --git a/Libraries/Core/Utils/App.cs b/Libraries/Core/Utils/App.cs index 199ba5da..88af96bb 100644 --- a/Libraries/Core/Utils/App.cs +++ b/Libraries/Core/Utils/App.cs @@ -12,20 +12,20 @@ namespace Core.Utils; [Injectable(InjectionType.Singleton)] public class App { - protected Dictionary _onUpdateLastRun = new Dictionary(); - protected Timer _timer; - protected CoreConfig _coreConfig; - - protected ISptLogger _logger; - protected TimeUtil _timeUtil; protected readonly RandomUtil _randomUtil; - protected LocalisationService _localisationService; protected ConfigServer _configServer; + protected CoreConfig _coreConfig; + protected DatabaseService _databaseService; protected EncodingUtil _encodingUtil; protected HttpServer _httpServer; - protected DatabaseService _databaseService; + protected LocalisationService _localisationService; + + protected ISptLogger _logger; protected IEnumerable _onLoad; protected IEnumerable _onUpdate; + protected Dictionary _onUpdateLastRun = new(); + protected Timer _timer; + protected TimeUtil _timeUtil; public App( ISptLogger logger, @@ -69,31 +69,22 @@ public class App // _logger.Debug($"RAM: {(os.totalmem() / 1024 / 1024 / 1024).toFixed(2)}GB"); - if (ProgramStatics.BUILD_TIME() is not null) - { - _logger.Debug($"Date: {ProgramStatics.BUILD_TIME()}"); - } + if (ProgramStatics.BUILD_TIME() is not null) _logger.Debug($"Date: {ProgramStatics.BUILD_TIME()}"); - if (ProgramStatics.COMMIT() is not null) - { - _logger.Debug($"Commit: {ProgramStatics.COMMIT()}"); - } + if (ProgramStatics.COMMIT() is not null) _logger.Debug($"Commit: {ProgramStatics.COMMIT()}"); } foreach (var onLoad in _onLoad) await onLoad.OnLoad(); _timer = new Timer(_ => Update(_onUpdate), null, TimeSpan.Zero, TimeSpan.FromMilliseconds(5000)); - + _logger.Success(GetRandomisedStartMessage()); } protected string GetRandomisedStartMessage() { - if (_randomUtil.GetInt(1, 1000) > 999) - { - return _localisationService.GetRandomTextThatMatchesPartialKey("server_start_meme_"); - } + if (_randomUtil.GetInt(1, 1000) > 999) return _localisationService.GetRandomTextThatMatchesPartialKey("server_start_meme_"); return _localisationService.GetText("server_start_success"); } @@ -131,12 +122,8 @@ public class App const int warnTime = 20 * 60; if (secondsSinceLastRun % warnTime == 0) - { if (_logger.IsLogEnabled(LogLevel.Debug)) - { _logger.Debug(_localisationService.GetText("route_onupdate_no_response", updateable.GetRoute())); - } - } } } } diff --git a/Libraries/Core/Utils/Callbacks/TimeoutCallback.cs b/Libraries/Core/Utils/Callbacks/TimeoutCallback.cs index 890a0842..60a9e13a 100644 --- a/Libraries/Core/Utils/Callbacks/TimeoutCallback.cs +++ b/Libraries/Core/Utils/Callbacks/TimeoutCallback.cs @@ -2,7 +2,6 @@ namespace Core.Utils.Callbacks; public static class TimeoutCallback { - public static Task RunInTimespan(Action action, TimeSpan timeSpan) { return Task.Factory.StartNew( diff --git a/Libraries/Core/Utils/Cloners/JsonCloner.cs b/Libraries/Core/Utils/Cloners/JsonCloner.cs index b3b19205..b571554c 100644 --- a/Libraries/Core/Utils/Cloners/JsonCloner.cs +++ b/Libraries/Core/Utils/Cloners/JsonCloner.cs @@ -6,10 +6,12 @@ namespace Core.Utils.Cloners; public class JsonCloner : ICloner { protected JsonUtil _jsonUtil; + public JsonCloner(JsonUtil jsonUtil) { _jsonUtil = jsonUtil; } + public T? Clone(T? obj) { return _jsonUtil.Deserialize(_jsonUtil.Serialize(obj)); diff --git a/Libraries/Core/Utils/Collections/ExhaustableArray.cs b/Libraries/Core/Utils/Collections/ExhaustableArray.cs index b897d057..7def7b34 100644 --- a/Libraries/Core/Utils/Collections/ExhaustableArray.cs +++ b/Libraries/Core/Utils/Collections/ExhaustableArray.cs @@ -4,16 +4,17 @@ namespace Core.Utils.Collections; public record ExhaustableArray : IExhaustableArray { - private LinkedList? pool; - private RandomUtil _randomUtil; private ICloner _cloner; + private RandomUtil _randomUtil; + private LinkedList? pool; public ExhaustableArray( T[]? itemPool, RandomUtil randomUtil, ICloner cloner ) : this(new LinkedList(itemPool ?? []), randomUtil, cloner) - {} + { + } public ExhaustableArray( LinkedList? itemPool, @@ -25,20 +26,18 @@ public record ExhaustableArray : IExhaustableArray _randomUtil = randomUtil; pool = cloner.Clone(itemPool ?? []); } - + public ExhaustableArray( ICollection? itemPool, RandomUtil randomUtil, ICloner cloner ) : this(new LinkedList(itemPool ?? []), randomUtil, cloner) - {} + { + } public T? GetRandomValue() { - if (pool?.Count == 0) - { - return default; - } + if (pool?.Count == 0) return default; var index = _randomUtil.GetInt(0, pool.Count - 1); var element = pool.ElementAt(index); @@ -46,11 +45,9 @@ public record ExhaustableArray : IExhaustableArray return _cloner.Clone(element); } - public T? GetFirstValue() { - if (pool?.Count == 0) - { - return default; - } + public T? GetFirstValue() + { + if (pool?.Count == 0) return default; var element = pool.ElementAt(0); pool.Remove(element); diff --git a/Libraries/Core/Utils/Collections/ProbabilityObjectArray.cs b/Libraries/Core/Utils/Collections/ProbabilityObjectArray.cs index 3848869d..ee07ee3c 100644 --- a/Libraries/Core/Utils/Collections/ProbabilityObjectArray.cs +++ b/Libraries/Core/Utils/Collections/ProbabilityObjectArray.cs @@ -23,8 +23,8 @@ namespace Core.Utils.Collections; /// public class ProbabilityObjectArray : List> { - private readonly MathUtil _mathUtil; private readonly ICloner _cloner; + private readonly MathUtil _mathUtil; public ProbabilityObjectArray( MathUtil mathUtil, @@ -60,9 +60,7 @@ public class ProbabilityObjectArray : List> var result = new ProbabilityObjectArray(_mathUtil, _cloner, new List>()); foreach (var probabilityObject in this) if (predicate.Invoke(probabilityObject)) - { result.Add(probabilityObject); - } return result; } @@ -157,10 +155,7 @@ public class ProbabilityObjectArray : List> public List Draw(int drawCount = 1, bool removeAfterDraw = true, List? neverRemoveWhitelist = null) { neverRemoveWhitelist ??= []; - if (Count == 0) - { - return []; - } + if (Count == 0) return []; var totals = this.Aggregate( new { probArray = new List(), keyArray = new List() }, @@ -195,10 +190,7 @@ public class ProbabilityObjectArray : List> drawnKeys.Add(key); probCumsum = CumulativeProbability(totals.probArray); // If we draw without replacement and the ProbabilityObjectArray is exhausted we need to break - if (totals.keyArray.Count < 1) - { - break; - } + if (totals.keyArray.Count < 1) break; } } diff --git a/Libraries/Core/Utils/CompareUtil.cs b/Libraries/Core/Utils/CompareUtil.cs index 7d95a7a7..861890e9 100644 --- a/Libraries/Core/Utils/CompareUtil.cs +++ b/Libraries/Core/Utils/CompareUtil.cs @@ -5,16 +5,17 @@ namespace Core.Utils; [Injectable] public class CompareUtil { - private readonly HashSet typesToCheckAgainst = [ - "string", - "number", - "boolean", - "bigint", - "symbol", - "undefined", - "null", + private readonly HashSet typesToCheckAgainst = + [ + "string", + "number", + "boolean", + "bigint", + "symbol", + "undefined", + "null" ]; - + /** * This function does an object comparison, equivalent to applying reflections * and scanning for all possible properties including arrays. @@ -54,7 +55,7 @@ public class CompareUtil // } // // return false; - + throw new NotImplementedException(); } } diff --git a/Libraries/Core/Utils/DatabaseImporter.cs b/Libraries/Core/Utils/DatabaseImporter.cs index fd61d1cf..dd3906ff 100644 --- a/Libraries/Core/Utils/DatabaseImporter.cs +++ b/Libraries/Core/Utils/DatabaseImporter.cs @@ -14,22 +14,22 @@ namespace Core.Utils; [Injectable(InjectionType.Singleton, InjectableTypeOverride = typeof(OnLoad), TypePriority = OnLoadOrder.Database)] public class DatabaseImporter : OnLoad { - private object hashedFile; - private ValidationResult valid = ValidationResult.UNDEFINED; - private string filepath; - private HttpConfig httpConfig; - - protected ISptLogger _logger; - protected LocalisationService _localisationService; + protected ConfigServer _configServer; protected DatabaseServer _databaseServer; + protected EncodingUtil _encodingUtil; + protected FileUtil _fileUtil; + protected HashUtil _hashUtil; protected ImageRouter _imageRouter; - protected EncodingUtil _encodingUtil; - protected HashUtil _hashUtil; protected ImporterUtil _importerUtil; - protected ConfigServer _configServer; - protected FileUtil _fileUtil; + protected LocalisationService _localisationService; + + protected ISptLogger _logger; + private string filepath; + private object hashedFile; + private HttpConfig httpConfig; + private ValidationResult valid = ValidationResult.UNDEFINED; public DatabaseImporter( ISptLogger logger, @@ -56,15 +56,6 @@ public class DatabaseImporter : OnLoad httpConfig = _configServer.GetConfig(); } - /** - * Get path to spt data - * @returns path to data - */ - public string GetSptDataPath() - { - return "./Assets/"; - } - public async Task OnLoad() { filepath = GetSptDataPath(); @@ -97,6 +88,20 @@ public class DatabaseImporter : OnLoad CreateRouteMapping(imageFilePath, "files"); } + public string GetRoute() + { + return "spt-database"; + } + + /** + * Get path to spt data + * @returns path to data + */ + public string GetSptDataPath() + { + return "./Assets/"; + } + private void CreateRouteMapping(string directory, string newBasePath) { var directoryContent = GetAllFilesInDirectory(directory); @@ -107,7 +112,7 @@ public class DatabaseImporter : OnLoad var filePathNoExtension = _fileUtil.StripExtension(fileNameWithNoSPTPath, true); if (filePathNoExtension.StartsWith("/") || fileNameWithPath.StartsWith("\\")) filePathNoExtension = $"{filePathNoExtension.Substring(1)}"; - + var bsgPath = $"/{newBasePath}/{filePathNoExtension}".Replace("\\", "/"); _imageRouter.AddRoute(bsgPath, fileNameWithPath); } @@ -118,10 +123,7 @@ public class DatabaseImporter : OnLoad List result = []; result.AddRange(Directory.GetFiles(directoryPath)); - foreach (var subdirectory in Directory.GetDirectories(directoryPath)) - { - result.AddRange(GetAllFilesInDirectory(subdirectory)); - } + foreach (var subdirectory in Directory.GetDirectories(directoryPath)) result.AddRange(GetAllFilesInDirectory(subdirectory)); return result; } @@ -138,11 +140,11 @@ public class DatabaseImporter : OnLoad $"{filePath}database/", OnReadValidate ); - + // TODO: Fix loading of traders, so their full path is not included as the key var tempTraders = new Dictionary(); - + // temp fix for trader keys foreach (var trader in dataToImport.Traders) { @@ -150,7 +152,7 @@ public class DatabaseImporter : OnLoad var tempKey = trader.Key.Split("/").Last(); tempTraders.Add(tempKey, trader.Value); } - + dataToImport.Traders = tempTraders; var validation = valid == ValidationResult.FAILED || valid == ValidationResult.NOT_FOUND ? "." : ""; @@ -166,11 +168,6 @@ public class DatabaseImporter : OnLoad //} } - public string GetRoute() - { - return "spt-database"; - } - protected bool ValidateFile(string filePathAndName, object fileData) { /* @@ -218,13 +215,11 @@ public class DatabaseImporter : OnLoad var filename = _fileUtil.StripExtension(file); var routeKey = $"{routes[i]}{filename}"; //var imagePath = $"{filepath}{directories[i]}/{file}"; - + var pathOverride = GetImagePathOverride(imagePath); - if (!string.IsNullOrEmpty(pathOverride)) { - if (_logger.IsLogEnabled(LogLevel.Debug)) - { - _logger.Debug($"overrode route: {routeKey} endpoint: {imagePath} with {pathOverride}"); - } + if (!string.IsNullOrEmpty(pathOverride)) + { + if (_logger.IsLogEnabled(LogLevel.Debug)) _logger.Debug($"overrode route: {routeKey} endpoint: {imagePath} with {pathOverride}"); imagePath = pathOverride; } diff --git a/Libraries/Core/Utils/FileUtil.cs b/Libraries/Core/Utils/FileUtil.cs index 181d0fd9..ef37323a 100644 --- a/Libraries/Core/Utils/FileUtil.cs +++ b/Libraries/Core/Utils/FileUtil.cs @@ -34,10 +34,7 @@ public class FileUtil( public string StripExtension(string path, bool keepPath = false) { - if (keepPath) - { - return path.StartsWith(".") ? path.Split('.')[1] : path.Split('.').First(); - } + if (keepPath) return path.StartsWith(".") ? path.Split('.')[1] : path.Split('.').First(); return Path.GetFileNameWithoutExtension(path); } @@ -97,12 +94,9 @@ public class FileUtil( public void CopyFile(string copyFromPath, string destinationFilePath, bool overwrite = false) { // Check it exists first - if (!FileExists(copyFromPath)) - { - _logger.Error($"Source file not found: {copyFromPath}. Cannot copy to: {destinationFilePath}"); - } + if (!FileExists(copyFromPath)) _logger.Error($"Source file not found: {copyFromPath}. Cannot copy to: {destinationFilePath}"); + - // Ensure dir exists Directory.CreateDirectory(Path.GetDirectoryName(destinationFilePath)); diff --git a/Libraries/Core/Utils/HashUtil.cs b/Libraries/Core/Utils/HashUtil.cs index bf377c45..35a02413 100644 --- a/Libraries/Core/Utils/HashUtil.cs +++ b/Libraries/Core/Utils/HashUtil.cs @@ -8,9 +8,8 @@ namespace Core.Utils; [Injectable(InjectionType.Singleton)] public class HashUtil { - protected Regex MongoIdRegex = new("^[a-fA-F0-9]{24}$"); - protected RandomUtil _randomUtil; + protected Regex MongoIdRegex = new("^[a-fA-F0-9]{24}$"); public HashUtil(RandomUtil randomUtil) { diff --git a/Libraries/Core/Utils/HttpFileUtil.cs b/Libraries/Core/Utils/HttpFileUtil.cs index 21f761a3..6b24c489 100644 --- a/Libraries/Core/Utils/HttpFileUtil.cs +++ b/Libraries/Core/Utils/HttpFileUtil.cs @@ -13,7 +13,8 @@ public class HttpFileUtil _httpServerHelper = httpServerHelper; } - public void SendFile(HttpResponse resp,string filePath) { + public void SendFile(HttpResponse resp, string filePath) + { var pathSlice = filePath.Split("/"); var mimePath = _httpServerHelper.GetMimeText(pathSlice[^1].Split(".")[^1]); var type = string.IsNullOrWhiteSpace(mimePath) ? _httpServerHelper.GetMimeText("txt") : mimePath; diff --git a/Libraries/Core/Utils/HttpResponseUtil.cs b/Libraries/Core/Utils/HttpResponseUtil.cs index afcc474a..22e02d86 100644 --- a/Libraries/Core/Utils/HttpResponseUtil.cs +++ b/Libraries/Core/Utils/HttpResponseUtil.cs @@ -11,17 +11,8 @@ namespace Core.Utils; [Injectable] public class HttpResponseUtil { - protected readonly LocalisationService _localisationService; protected readonly JsonUtil _jsonUtil; - - public HttpResponseUtil( - JsonUtil jsonUtil, - LocalisationService localisationService - ) - { - _localisationService = localisationService; - _jsonUtil = jsonUtil; - } + protected readonly LocalisationService _localisationService; protected ImmutableList _cleanupRegexList = [ @@ -32,13 +23,19 @@ public class HttpResponseUtil new("[\\t]") ]; + public HttpResponseUtil( + JsonUtil jsonUtil, + LocalisationService localisationService + ) + { + _localisationService = localisationService; + _jsonUtil = jsonUtil; + } + protected string ClearString(string? s) { var value = s ?? ""; - foreach (var regex in _cleanupRegexList) - { - value = regex.Replace(value, string.Empty); - } + foreach (var regex in _cleanupRegexList) value = regex.Replace(value, string.Empty); return value; } @@ -103,18 +100,16 @@ public class HttpResponseUtil if (string.IsNullOrEmpty(message)) message = _localisationService.GetText("http-unknown_error"); if (output.Warnings?.Count > 0) - { - output.Warnings.Add(new Warning - { - Index = output.Warnings?.Count - 1, - ErrorMessage = message, - Code = errorCode.ToString() - }); - } + output.Warnings.Add( + new Warning + { + Index = output.Warnings?.Count - 1, + ErrorMessage = message, + Code = errorCode.ToString() + } + ); else - { output.Warnings = [new Warning { Index = 0, ErrorMessage = message, Code = errorCode.ToString() }]; - } return output; } diff --git a/Libraries/Core/Utils/ImporterUtil.cs b/Libraries/Core/Utils/ImporterUtil.cs index d851a9e1..4ca0fa76 100644 --- a/Libraries/Core/Utils/ImporterUtil.cs +++ b/Libraries/Core/Utils/ImporterUtil.cs @@ -12,9 +12,9 @@ public class ImporterUtil protected FileUtil _fileUtil; protected JsonUtil _jsonUtil; protected ISptLogger _logger; + protected HashSet directoriesToIgnore = ["./Assets/database/locales/server"]; protected HashSet filesToIgnore = ["bearsuits.json", "usecsuits.json", "archivedquests.json"]; - protected HashSet directoriesToIgnore = ["./Assets/database/locales/server"]; public ImporterUtil(ISptLogger logger, FileUtil fileUtil, JsonUtil jsonUtil) { diff --git a/Libraries/Core/Utils/Json/Converters/ArrayToObjectFactoryConverter.cs b/Libraries/Core/Utils/Json/Converters/ArrayToObjectFactoryConverter.cs index 032e8b18..92d6d90b 100644 --- a/Libraries/Core/Utils/Json/Converters/ArrayToObjectFactoryConverter.cs +++ b/Libraries/Core/Utils/Json/Converters/ArrayToObjectFactoryConverter.cs @@ -18,6 +18,7 @@ public class ArrayToObjectFactoryConverter : JsonConverterFactory private class ArrayToObjectConverter : JsonConverter { public override bool HandleNull => true; + public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { switch (reader.TokenType) diff --git a/Libraries/Core/Utils/Json/Converters/BaseInteractionRequestDataConverter.cs b/Libraries/Core/Utils/Json/Converters/BaseInteractionRequestDataConverter.cs index 0aa3975b..8e4df39f 100644 --- a/Libraries/Core/Utils/Json/Converters/BaseInteractionRequestDataConverter.cs +++ b/Libraries/Core/Utils/Json/Converters/BaseInteractionRequestDataConverter.cs @@ -90,7 +90,9 @@ public class BaseInteractionRequestDataConverter : JsonConverter(jsonText); default: - throw new Exception($"Unhandled action type {value.Action}, make sure the BaseInteractionRequestDataConverter has the deserialization for this action handled."); + throw new Exception( + $"Unhandled action type {value.Action}, make sure the BaseInteractionRequestDataConverter has the deserialization for this action handled." + ); } } case ItemEventActions.RAGFAIR_BUY_OFFER: @@ -165,7 +167,9 @@ public class BaseInteractionRequestDataConverter : JsonConverter(jsonText); default: - throw new Exception($"Unhandled action type {value.Action}, make sure the BaseInteractionRequestDataConverter has the deserialization for this action handled."); + throw new Exception( + $"Unhandled action type {value.Action}, make sure the BaseInteractionRequestDataConverter has the deserialization for this action handled." + ); } } diff --git a/Libraries/Core/Utils/Json/Converters/DictionaryOfListOrTConverter.cs b/Libraries/Core/Utils/Json/Converters/DictionaryOfListOrTConverter.cs index aeb0c695..acc72541 100644 --- a/Libraries/Core/Utils/Json/Converters/DictionaryOfListOrTConverter.cs +++ b/Libraries/Core/Utils/Json/Converters/DictionaryOfListOrTConverter.cs @@ -7,13 +7,20 @@ public class DictionaryOfListOrTConverter : JsonConverterFactory { public override bool CanConvert(Type typeToConvert) { - return typeToConvert.IsGenericType && typeToConvert.GetGenericTypeDefinition() == typeof(Dictionary<,>) && - typeToConvert.GenericTypeArguments[1].IsGenericType && typeToConvert.GenericTypeArguments[1].GetGenericTypeDefinition() == typeof(ListOrT<>); + return typeToConvert.IsGenericType && + typeToConvert.GetGenericTypeDefinition() == typeof(Dictionary<,>) && + typeToConvert.GenericTypeArguments[1].IsGenericType && + typeToConvert.GenericTypeArguments[1].GetGenericTypeDefinition() == typeof(ListOrT<>); } public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options) { - return (JsonConverter)Activator.CreateInstance(typeof(DictionaryOfListOrTConverter<,>).MakeGenericType(typeToConvert.GenericTypeArguments[0], typeToConvert.GenericTypeArguments[1].GenericTypeArguments[0])); + return (JsonConverter)Activator.CreateInstance( + typeof(DictionaryOfListOrTConverter<,>).MakeGenericType( + typeToConvert.GenericTypeArguments[0], + typeToConvert.GenericTypeArguments[1].GenericTypeArguments[0] + ) + ); } } @@ -25,7 +32,7 @@ public class DictionaryOfListOrTConverter : JsonConverter).MakeGenericType(typeToConvert.GenericTypeArguments[0], typeToConvert.GenericTypeArguments[1])); + return (JsonConverter)Activator.CreateInstance( + typeof(DictionaryOrListConverter<,>).MakeGenericType(typeToConvert.GenericTypeArguments[0], typeToConvert.GenericTypeArguments[1]) + ); } } -public class DictionaryOrListConverter : JsonConverter?> +public class DictionaryOrListConverter : JsonConverter?> { - public override DictionaryOrList? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override DictionaryOrList? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { switch (reader.TokenType) { @@ -27,29 +29,25 @@ public class DictionaryOrListConverter : JsonConverter>(jsonText, options); - return new DictionaryOrList(null, list); + return new DictionaryOrList(null, list); } case JsonTokenType.StartObject: using (var jsonDocument = JsonDocument.ParseValue(ref reader)) { var jsonText = jsonDocument.RootElement.GetRawText(); - var dictionary = JsonSerializer.Deserialize>(jsonText, options); - return new DictionaryOrList(dictionary, null); + var dictionary = JsonSerializer.Deserialize>(jsonText, options); + return new DictionaryOrList(dictionary, null); } default: throw new Exception($"Unable to translate object type {reader.TokenType} to ListOrT."); } } - public override void Write(Utf8JsonWriter writer, DictionaryOrList value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, DictionaryOrList value, JsonSerializerOptions options) { if (value.IsList) - { JsonSerializer.Serialize(writer, value.List, options); - } else - { JsonSerializer.Serialize(writer, value.Dictionary, options); - } } } diff --git a/Libraries/Core/Utils/Json/Converters/EftEnumConverter.cs b/Libraries/Core/Utils/Json/Converters/EftEnumConverter.cs index 9e1016c8..9ebc1d14 100644 --- a/Libraries/Core/Utils/Json/Converters/EftEnumConverter.cs +++ b/Libraries/Core/Utils/Json/Converters/EftEnumConverter.cs @@ -6,7 +6,8 @@ namespace Core.Utils.Json.Converters; public class EftEnumConverter : JsonConverter { - private static readonly JsonSerializerOptions _options = new() {Converters = { new JsonStringEnumConverter() }}; + private static readonly JsonSerializerOptions _options = new() { Converters = { new JsonStringEnumConverter() } }; + public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.String || reader.TokenType == JsonTokenType.PropertyName) @@ -20,6 +21,7 @@ public class EftEnumConverter : JsonConverter var str = reader.GetInt32().ToString(); return (T)Enum.Parse(typeof(T), str, true); } + return default; } @@ -61,6 +63,7 @@ public class EftEnumConverter : JsonConverter else throw new Exception($"Could not convert enum {value.GetType()} with value {value}"); } + writer.WritePropertyName(propertyValue.ToString()); } } diff --git a/Libraries/Core/Utils/Json/Converters/ListOrTConverter.cs b/Libraries/Core/Utils/Json/Converters/ListOrTConverter.cs index 8cd96f1a..247b45a3 100644 --- a/Libraries/Core/Utils/Json/Converters/ListOrTConverter.cs +++ b/Libraries/Core/Utils/Json/Converters/ListOrTConverter.cs @@ -52,12 +52,8 @@ public class ListOrTConverter : JsonConverter?> public override void Write(Utf8JsonWriter writer, ListOrT value, JsonSerializerOptions options) { if (value.IsItem) - { JsonSerializer.Serialize(writer, value.Item, options); - } else - { JsonSerializer.Serialize(writer, value.List, options); - } } } diff --git a/Libraries/Core/Utils/Json/Converters/StringToNumberFactoryConverter.cs b/Libraries/Core/Utils/Json/Converters/StringToNumberFactoryConverter.cs index 52791e64..129666e0 100644 --- a/Libraries/Core/Utils/Json/Converters/StringToNumberFactoryConverter.cs +++ b/Libraries/Core/Utils/Json/Converters/StringToNumberFactoryConverter.cs @@ -31,12 +31,15 @@ public class StringToNumberFactoryConverter : JsonConverterFactory { if (typeToConvert.IsGenericType && typeToConvert.GetGenericTypeDefinition() == typeof(Nullable<>)) - { type = typeToConvert.GenericTypeArguments[0]; - } - return (T) type.GetMethods().First(m => - m.Name == "Parse" && m.GetParameters().Length == 1 && - m.GetParameters().First().ParameterType == typeof(string)).Invoke(null, [value]); + return (T)type.GetMethods() + .First( + m => + m.Name == "Parse" && + m.GetParameters().Length == 1 && + m.GetParameters().First().ParameterType == typeof(string) + ) + .Invoke(null, [value]); } catch (Exception ex) { diff --git a/Libraries/Core/Utils/Json/LazyLoad.cs b/Libraries/Core/Utils/Json/LazyLoad.cs index 468eca2b..09a2050e 100644 --- a/Libraries/Core/Utils/Json/LazyLoad.cs +++ b/Libraries/Core/Utils/Json/LazyLoad.cs @@ -2,12 +2,12 @@ public class LazyLoad(Func deserialize) { - private T? _result; - private bool _isLoaded; - - private Timer? autoCleanerTimeout; private static readonly TimeSpan _autoCleanerTimeout = TimeSpan.FromSeconds(30); - + private bool _isLoaded; + private T? _result; + + private Timer? autoCleanerTimeout; + public T? Value { get @@ -16,13 +16,17 @@ public class LazyLoad(Func deserialize) { _result = deserialize(); _isLoaded = true; - autoCleanerTimeout = new Timer(_ => + autoCleanerTimeout = new Timer( + _ => { _result = default; _isLoaded = false; autoCleanerTimeout?.Change(Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan); autoCleanerTimeout = null; - },null, _autoCleanerTimeout, Timeout.InfiniteTimeSpan + }, + null, + _autoCleanerTimeout, + Timeout.InfiniteTimeSpan ); } diff --git a/Libraries/Core/Utils/JsonUtil.cs b/Libraries/Core/Utils/JsonUtil.cs index 8b31657c..85121394 100644 --- a/Libraries/Core/Utils/JsonUtil.cs +++ b/Libraries/Core/Utils/JsonUtil.cs @@ -53,11 +53,12 @@ public class JsonUtil new BaseInteractionRequestDataConverter() } }; + private static readonly JsonSerializerOptions jsonSerializerOptionsIndented = new(jsonSerializerOptionsNoIndent) { WriteIndented = true }; - + public T? Deserialize(string? json) { diff --git a/Libraries/Core/Utils/ProgramStatics.cs b/Libraries/Core/Utils/ProgramStatics.cs index 028ea586..aa1c1da4 100644 --- a/Libraries/Core/Utils/ProgramStatics.cs +++ b/Libraries/Core/Utils/ProgramStatics.cs @@ -1,103 +1,108 @@ -namespace Server +namespace Server; + +public static class ProgramStatics { - public static class ProgramStatics + private static EntryType _entryType; + + private static bool _debug; + private static bool _compiled; + private static bool _mods; + + private static string? _sptVersion; + private static string? _commit; + private static double? _buildTime; + + private static BuildInfo buildInfo; // TODO get from buildinfo.json + + public static void Initialize() { - private static EntryType _entryType; + buildInfo = new BuildInfo(); + _entryType = buildInfo.entryType.GetValueOrDefault(EntryType.LOCAL); - private static bool _debug; - private static bool _compiled; - private static bool _mods; - - private static string? _sptVersion; - private static string? _commit; - private static double? _buildTime; - - private static BuildInfo buildInfo; // TODO get from buildinfo.json - - public static void Initialize() + switch (_entryType) { - buildInfo = new BuildInfo(); - ProgramStatics._entryType = buildInfo.entryType.GetValueOrDefault(EntryType.LOCAL); - - switch (ProgramStatics._entryType) - { - case EntryType.RELEASE: - _debug = false; - _compiled = true; - _mods = true; - break; - case EntryType.BLEEDING_EDGE: - _debug = true; - _compiled = true; - _mods = false; - break; - case EntryType.DEBUG: - case EntryType.BLEEDING_EDGE_MODS: - _debug = true; - _compiled = true; - _mods = true; - break; - case EntryType.LOCAL: - default: // EntryType.LOCAL - _debug = true; - _compiled = false; - _mods = true; - break; - } - } - - // Public Static Getters - public static EntryType ENTRY_TYPE() - { - return _entryType; - } - public static bool DEBUG() - { - return ProgramStatics._debug; - } - public static bool COMPILED() - { - return ProgramStatics._compiled; - } - public static bool MODS() - { - return ProgramStatics._mods; - } - public static string? SPT_VERSION() - { - return ProgramStatics._sptVersion; - } - public static string? COMMIT() - { - return ProgramStatics._commit; - } - public static double? BUILD_TIME() - { - return ProgramStatics._buildTime; + case EntryType.RELEASE: + _debug = false; + _compiled = true; + _mods = true; + break; + case EntryType.BLEEDING_EDGE: + _debug = true; + _compiled = true; + _mods = false; + break; + case EntryType.DEBUG: + case EntryType.BLEEDING_EDGE_MODS: + _debug = true; + _compiled = true; + _mods = true; + break; + case EntryType.LOCAL: + default: // EntryType.LOCAL + _debug = true; + _compiled = false; + _mods = true; + break; } } - public enum EntryType + // Public Static Getters + public static EntryType ENTRY_TYPE() { - LOCAL, - DEBUG, - RELEASE, - BLEEDING_EDGE, - BLEEDING_EDGE_MODS + return _entryType; } - public class BuildInfo + public static bool DEBUG() { - public BuildInfo() - { - sptVersion = ""; - commit = ""; - buildTime = 0; - } + return _debug; + } - public EntryType? entryType { get; set; } - public string? sptVersion { get; set; } - public string? commit { get; set; } - public double? buildTime { get; set; } + public static bool COMPILED() + { + return _compiled; + } + + public static bool MODS() + { + return _mods; + } + + public static string? SPT_VERSION() + { + return _sptVersion; + } + + public static string? COMMIT() + { + return _commit; + } + + public static double? BUILD_TIME() + { + return _buildTime; } } + +public enum EntryType +{ + LOCAL, + DEBUG, + RELEASE, + BLEEDING_EDGE, + BLEEDING_EDGE_MODS +} + +public class BuildInfo +{ + public BuildInfo() + { + sptVersion = ""; + commit = ""; + buildTime = 0; + } + + public EntryType? entryType { get; set; } + public string? sptVersion { get; set; } + public string? commit { get; set; } + public double? buildTime { get; set; } +} diff --git a/Libraries/Core/Utils/ProgressWriter.cs b/Libraries/Core/Utils/ProgressWriter.cs index d21b47da..9142b127 100644 --- a/Libraries/Core/Utils/ProgressWriter.cs +++ b/Libraries/Core/Utils/ProgressWriter.cs @@ -1,33 +1,30 @@ -namespace Core.Utils +namespace Core.Utils; + +public class ProgressWriter { - public class ProgressWriter + protected string? _barEmptyChar; + protected string? _barFillChar; + protected int? _maxBarLength; + protected int _total; + + public ProgressWriter(int total, int maxBarLength, string barFillChar, string barEmptyChar) { - protected int _total; - protected int? _maxBarLength; - protected string? _barFillChar; - protected string? _barEmptyChar; - - public ProgressWriter(int total, int maxBarLength, string barFillChar, string barEmptyChar) - { - _total = total; - _maxBarLength = maxBarLength; - _barFillChar = barFillChar; - _barEmptyChar = barEmptyChar; - } - - public ProgressWriter(int total) - { - _total = total; - _maxBarLength = 25; - _barFillChar = "\u2593"; - _barEmptyChar = "\u2591"; - } - - public void Increment() - { - // TODO - implement - } + _total = total; + _maxBarLength = maxBarLength; + _barFillChar = barFillChar; + _barEmptyChar = barEmptyChar; } + public ProgressWriter(int total) + { + _total = total; + _maxBarLength = 25; + _barFillChar = "\u2593"; + _barEmptyChar = "\u2591"; + } + public void Increment() + { + // TODO - implement + } } diff --git a/Libraries/Core/Utils/RagfairOfferHolder.cs b/Libraries/Core/Utils/RagfairOfferHolder.cs index 64b46469..69fc6247 100644 --- a/Libraries/Core/Utils/RagfairOfferHolder.cs +++ b/Libraries/Core/Utils/RagfairOfferHolder.cs @@ -13,15 +13,14 @@ public class RagfairOfferHolder( HashUtil hashUtil, ConfigServer configServer) { - + protected int _maxOffersPerTemplate = (int)configServer.GetConfig().Dynamic.OfferItemCount.Max; protected Dictionary _offersById = new(); protected object _offersByIdLock = new(); protected Dictionary> _offersByTemplate = new(); protected object _offersByTemplateLock = new(); protected Dictionary> _offersByTrader = new(); protected object _offersByTraderLock = new(); - protected int _maxOffersPerTemplate = (int) configServer.GetConfig().Dynamic.OfferItemCount.Max; - + public RagfairOffer? GetOfferById(string id) { lock (_offersByIdLock) @@ -42,10 +41,7 @@ public class RagfairOfferHolder( { lock (_offersByTraderLock) { - if (_offersByTrader.ContainsKey(traderId)) - { - return _offersByTrader[traderId].Values.ToList(); - } + if (_offersByTrader.ContainsKey(traderId)) return _offersByTrader[traderId].Values.ToList(); } return null; @@ -55,10 +51,7 @@ public class RagfairOfferHolder( { lock (_offersByIdLock) { - if (_offersById.Count > 0) - { - return _offersById.Values.ToList(); - } + if (_offersById.Count > 0) return _offersById.Values.ToList(); } return []; @@ -77,7 +70,7 @@ public class RagfairOfferHolder( // keep generating IDs until we get a new one while (_offersById.ContainsKey(offer.Id)) offer.Id = hashUtil.Generate(); - + var offerId = offer.Id; var itemTpl = offer.Items.FirstOrDefault().Template; // If its an NPC PMC offer AND we have already reached the maximum amount of possible offers @@ -85,10 +78,8 @@ public class RagfairOfferHolder( if (!(ragfairServerHelper.IsTrader(trader) || profileHelper.IsPlayer(trader)) && (GetOffersByTemplate(itemTpl)?.Count ?? 0) >= _maxOffersPerTemplate ) - { return; - } - + _offersById.Add(offerId, offer); AddOfferByTrader(trader, offer); AddOfferByTemplates(itemTpl, offer); @@ -115,19 +106,13 @@ public class RagfairOfferHolder( // the user ID from the cached offers after they dont have anything else // on the flea placed. We regenerate the ID for the NPC users, making it // continuously grow otherwise - if (_offersByTrader[offer.User.Id].Count == 0) - { - _offersByTrader.Remove(offer.User.Id); - } + if (_offersByTrader[offer.User.Id].Count == 0) _offersByTrader.Remove(offer.User.Id); } } lock (_offersByTemplateLock) { - if (_offersByTemplate.ContainsKey(offer.Items.FirstOrDefault().Template)) - { - _offersByTemplate[offer.Items[0].Template].Remove(offer.Id); - } + if (_offersByTemplate.ContainsKey(offer.Items.FirstOrDefault().Template)) _offersByTemplate[offer.Items[0].Template].Remove(offer.Id); } } } @@ -142,10 +127,7 @@ public class RagfairOfferHolder( { lock (_offersByTraderLock) { - if (_offersByTrader.ContainsKey(traderId)) - { - RemoveOffers(_offersByTrader[traderId].Values.ToList()); - } + if (_offersByTrader.ContainsKey(traderId)) RemoveOffers(_offersByTrader[traderId].Values.ToList()); } } @@ -193,10 +175,7 @@ public class RagfairOfferHolder( protected bool IsStale(RagfairOffer? offer, long time) { - if (offer is null) - { - return false; - } + if (offer is null) return false; return offer.EndTime < time || (offer.Items.FirstOrDefault().Upd?.StackObjectsCount ?? 0) < 1; } diff --git a/Libraries/Core/Utils/RandomUtil.cs b/Libraries/Core/Utils/RandomUtil.cs index 6255ec73..43c14182 100644 --- a/Libraries/Core/Utils/RandomUtil.cs +++ b/Libraries/Core/Utils/RandomUtil.cs @@ -10,9 +10,7 @@ namespace Core.Utils; [Injectable(InjectionType.Singleton)] public class RandomUtil(ISptLogger _logger, ICloner _cloner) { - public readonly Random Random = new(); private const int DecimalPointRandomPrecision = 6; - private static readonly int DecimalPointRandomPrecisionMultiplier = (int) Math.Pow(10, DecimalPointRandomPrecision); /// /// The IEEE-754 standard for double-precision floating-point numbers limits the number of digits (including both @@ -20,6 +18,9 @@ public class RandomUtil(ISptLogger _logger, ICloner _cloner) /// public const int MaxSignificantDigits = 15; + private static readonly int DecimalPointRandomPrecisionMultiplier = (int)Math.Pow(10, DecimalPointRandomPrecision); + public readonly Random Random = new(); + /// /// Generates a random integer between the specified minimum and maximum values, inclusive. /// @@ -30,14 +31,11 @@ public class RandomUtil(ISptLogger _logger, ICloner _cloner) public int GetInt(int min, int max = int.MaxValue, bool exclusive = false) { // Prevents a potential integer overflow. - if (exclusive && max == int.MaxValue) - { - max -= 1; - } + if (exclusive && max == int.MaxValue) max -= 1; return max > min ? Random.Next(min, exclusive ? max : max + 1) : min; } - + /// /// Generates a random floating-point number within the specified range ~15-17 digits (8 bytes). /// @@ -46,8 +44,8 @@ public class RandomUtil(ISptLogger _logger, ICloner _cloner) /// A random floating-point number between `min` (inclusive) and `max` (exclusive). public double GetDouble(double min, double max) { - var realMin = (long) (min * DecimalPointRandomPrecisionMultiplier); - var realMax = (long) (max * DecimalPointRandomPrecisionMultiplier); + var realMin = (long)(min * DecimalPointRandomPrecisionMultiplier); + var realMax = (long)(max * DecimalPointRandomPrecisionMultiplier); return Math.Round( Random.NextInt64(realMin, realMax) / (double)DecimalPointRandomPrecisionMultiplier, @@ -224,13 +222,13 @@ public class RandomUtil(ISptLogger _logger, ICloner _cloner) // Determine the range var min = Math.Min(val1, val2); var max = Math.Max(val1, val2); - - var realPrecision = (long) Math.Pow(10, precision); - - var minInt = (long) (min * realPrecision); - var maxInt = (long) (max * realPrecision); - - return Math.Round(Random.NextInt64(minInt, maxInt) / (double) realPrecision, precision); + + var realPrecision = (long)Math.Pow(10, precision); + + var minInt = (long)(min * realPrecision); + var maxInt = (long)(max * realPrecision); + + return Math.Round(Random.NextInt64(minInt, maxInt) / (double)realPrecision, precision); } /// @@ -250,10 +248,7 @@ public class RandomUtil(ISptLogger _logger, ICloner _cloner) { list = _cloner.Clone(originalList); // Adjust drawCount to avoid drawing more elements than available - if (drawCount > list.Count) - { - drawCount = list.Count; - } + if (drawCount > list.Count) drawCount = list.Count; } var results = new List(); @@ -261,13 +256,9 @@ public class RandomUtil(ISptLogger _logger, ICloner _cloner) { var randomIndex = RandInt(list.Count); if (replacement) - { results.Add(list[randomIndex]); - } else - { results.Add(list.Splice(randomIndex, 1)[0]); - } } return results; @@ -325,10 +316,7 @@ public class RandomUtil(ISptLogger _logger, ICloner _cloner) return -1; } - if (min == max) - { - return min; - } + if (min == max) return min; if (shift > max - min) { @@ -339,7 +327,8 @@ public class RandomUtil(ISptLogger _logger, ICloner _cloner) * Shifting even further drops the success chance very rapidly - so we want to warn against that **/ _logger.Warning( - "Bias shift for random number generation is greater than the range of available numbers. This will have a severe performance impact"); + "Bias shift for random number generation is greater than the range of available numbers. This will have a severe performance impact" + ); _logger.Warning($"min-> {min}; max-> {max}; shift-> {shift}"); } @@ -364,10 +353,7 @@ public class RandomUtil(ISptLogger _logger, ICloner _cloner) private double GetGaussianRandom(double n) { var rand = 0d; - for (var i = 0; i < n; i += 1) - { - rand += GetSecureRandomNumber(); - } + for (var i = 0; i < n; i += 1) rand += GetSecureRandomNumber(); return rand / n; } @@ -421,6 +407,7 @@ public class RandomUtil(ISptLogger _logger, ICloner _cloner) preciseNum *= 10M; factor++; } + return factor; } diff --git a/Libraries/Core/Utils/TimeUtil.cs b/Libraries/Core/Utils/TimeUtil.cs index a6c3c579..8967dd58 100644 --- a/Libraries/Core/Utils/TimeUtil.cs +++ b/Libraries/Core/Utils/TimeUtil.cs @@ -74,11 +74,11 @@ public class TimeUtil /// Unix epoch for the start of day of the calculated date public long GetStartOfDayTimeStamp(long? timestamp) { - DateTime now = timestamp.HasValue + var now = timestamp.HasValue ? DateTimeOffset.FromUnixTimeMilliseconds(timestamp.Value).DateTime : GetDateTimeNow(); - - DateTime startOfDay = new DateTime(now.Year, now.Month, now.Day, 0, 0, 0); + + var startOfDay = new DateTime(now.Year, now.Month, now.Day, 0, 0, 0); return ((DateTimeOffset)startOfDay).ToUnixTimeMilliseconds(); } @@ -137,11 +137,11 @@ public class TimeUtil /// Time stamp of the next hour in unix time seconds public long GetTimeStampOfNextHour() { - DateTime now = DateTime.UtcNow; - TimeSpan timeUntilNextHour = TimeSpan.FromMinutes(60 - now.Minute) + var now = DateTime.UtcNow; + var timeUntilNextHour = TimeSpan.FromMinutes(60 - now.Minute) .Subtract(TimeSpan.FromSeconds(now.Second)) .Subtract(TimeSpan.FromMilliseconds(now.Millisecond)); - + var time = ((DateTimeOffset)now.Add(timeUntilNextHour)).ToUnixTimeSeconds(); return time; @@ -154,19 +154,16 @@ public class TimeUtil /// Timestamp public long GetTodayMidnightTimeStamp() { - DateTime now = DateTime.UtcNow; - int hours = now.Hour; - int minutes = now.Minute; - + var now = DateTime.UtcNow; + var hours = now.Hour; + var minutes = now.Minute; + // If minutes greater than 0, subtract 1 hour - if (hours > 0 && minutes > 0) - { - hours--; - } - + if (hours > 0 && minutes > 0) hours--; + // Create a new DateTime with the last full hour, 0 minutes, and 0 seconds - DateTime lastFullHour = new DateTime(now.Year, now.Month, now.Day, hours, 0, 0); - + var lastFullHour = new DateTime(now.Year, now.Month, now.Day, hours, 0, 0); + return ((DateTimeOffset)lastFullHour).ToUnixTimeMilliseconds(); } @@ -189,7 +186,7 @@ public class TimeUtil { return DateTimeOffset.FromUnixTimeMilliseconds(timeStamp).DateTime; } - + /// /// Takes a date and gets difference between Epoch time and time provided resulting in a timestamp (date defaults to utcnow) /// This attempts to mimic gettime() in js diff --git a/Libraries/Core/Utils/TimerUtil.cs b/Libraries/Core/Utils/TimerUtil.cs index 86c23f39..cb72ab46 100644 --- a/Libraries/Core/Utils/TimerUtil.cs +++ b/Libraries/Core/Utils/TimerUtil.cs @@ -1,30 +1,29 @@ using System.Diagnostics; using SptCommon.Annotations; -namespace Core.Utils +namespace Core.Utils; + +[Injectable] +public class TimerUtil { - [Injectable] - public class TimerUtil + protected Stopwatch _stopwatch; + + public TimerUtil() { - protected Stopwatch _stopwatch; + _stopwatch = new Stopwatch(); + _stopwatch.Start(); + } - public TimerUtil() + public int Stop(string unit = "sec") + { + _stopwatch.Stop(); + var timePassed = _stopwatch.Elapsed; + + return unit switch { - _stopwatch = new Stopwatch(); - _stopwatch.Start(); - } - - public int Stop(string unit = "sec") - { - _stopwatch.Stop(); - var timePassed = _stopwatch.Elapsed; - - return unit switch - { - "ns" => timePassed.Nanoseconds, - "ms" => timePassed.Milliseconds, - _ => timePassed.Seconds - }; - } + "ns" => timePassed.Nanoseconds, + "ms" => timePassed.Milliseconds, + _ => timePassed.Seconds + }; } } diff --git a/Libraries/Core/Utils/Watermark.cs b/Libraries/Core/Utils/Watermark.cs index 30c1f1d4..84f07862 100644 --- a/Libraries/Core/Utils/Watermark.cs +++ b/Libraries/Core/Utils/Watermark.cs @@ -9,20 +9,24 @@ using Server; namespace Core.Utils; [Injectable] -public class WatermarkLocale { +public class WatermarkLocale +{ protected List description; - protected List warning; protected List modding; + protected List warning; - public WatermarkLocale(LocalisationService localisationService) { - description = [ + public WatermarkLocale(LocalisationService localisationService) + { + description = + [ localisationService.GetText("watermark-discord_url"), "", localisationService.GetText("watermark-free_of_charge"), localisationService.GetText("watermark-paid_scammed"), - localisationService.GetText("watermark-commercial_use_prohibited"), + localisationService.GetText("watermark-commercial_use_prohibited") ]; - warning = [ + warning = + [ "", localisationService.GetText("watermark-testing_build"), localisationService.GetText("watermark-no_support"), @@ -30,38 +34,53 @@ public class WatermarkLocale { $"{localisationService.GetText("watermark-report_issues_to")}:", localisationService.GetText("watermark-issue_tracker_url"), "", - localisationService.GetText("watermark-use_at_own_risk"), + localisationService.GetText("watermark-use_at_own_risk") ]; - modding = [ + modding = + [ "", localisationService.GetText("watermark-modding_disabled"), "", localisationService.GetText("watermark-not_an_issue"), - localisationService.GetText("watermark-do_not_report"), + localisationService.GetText("watermark-do_not_report") ]; } - public List GetDescription() => description; - public List GetWarning() => warning; - public List GetModding() => modding; + public List GetDescription() + { + return description; + } + + public List GetWarning() + { + return warning; + } + + public List GetModding() + { + return modding; + } } [Injectable] -public class Watermark { +public class Watermark +{ + protected ConfigServer _configServer; + protected LocalisationService _localisationService; + + protected ISptLogger _logger; + protected WatermarkLocale _watermarkLocale; protected CoreConfig sptConfig; protected List text = []; protected string versionLabel = ""; - protected ISptLogger _logger; - protected ConfigServer _configServer; - protected LocalisationService _localisationService; - protected WatermarkLocale _watermarkLocale; public Watermark( ISptLogger logger, ConfigServer configServer, LocalisationService localisationService, WatermarkLocale watermarkLocale - ) { + ) + { _logger = logger; _configServer = configServer; _localisationService = localisationService; @@ -81,20 +100,14 @@ public class Watermark { text = [versionLabel]; text = [..text, ..description]; - - if (ProgramStatics.DEBUG()) { - text.AddRange(warning); - } - if (!ProgramStatics.MODS()) { - text.AddRange(modding); - } - - if (sptConfig.CustomWatermarkLocaleKeys?.Count > 0) { - foreach (var key in sptConfig.CustomWatermarkLocaleKeys) { + if (ProgramStatics.DEBUG()) text.AddRange(warning); + if (!ProgramStatics.MODS()) text.AddRange(modding); + + + if (sptConfig.CustomWatermarkLocaleKeys?.Count > 0) + foreach (var key in sptConfig.CustomWatermarkLocaleKeys) text.AddRange(["", _localisationService.GetText(key)]); - } - } SetTitle(); ResetCursor(); @@ -106,11 +119,13 @@ public class Watermark { * @param withEftVersion Include the eft version this spt version was made for * @returns string */ - public string GetVersionTag(bool withEftVersion = false) { + public string GetVersionTag(bool withEftVersion = false) + { var sptVersion = ProgramStatics.SPT_VERSION() ?? sptConfig.SptVersion; var versionTag = /*ProgramStatics.DEBUG*/ $"{sptVersion} - {_localisationService.GetText("bleeding_edge_build")}"; - if (withEftVersion) { + if (withEftVersion) + { var tarkovVersion = sptConfig.CompatibleTarkovVersion.Split(".").Last(); return $"{versionTag} ({tarkovVersion})"; } @@ -128,7 +143,7 @@ public class Watermark { var sptVersion = /*ProgramStatics.SPT_VERSION ||*/ sptConfig.SptVersion; var versionTag = /*ProgramStatics.DEBUG ? */ $"{sptVersion} - BLEEDINGEDGE { /*ProgramStatics.COMMIT?.slice(0, 6) ?? */""}"; - //: `{sptVersion} - {ProgramStatics.COMMIT?.slice(0, 6) ?? ""}`; + //: `{sptVersion} - {ProgramStatics.COMMIT?.slice(0, 6) ?? ""}`; return $"{sptConfig.ProjectName} {versionTag}"; } @@ -159,21 +174,18 @@ public class Watermark { // Create line of - to add top/bottom of watermark var line = ""; - for (var i = 0; i < longestLength; ++i) { - line += "─"; - } + for (var i = 0; i < longestLength; ++i) line += "─"; // Opening line result.Add($"┌─{line}─┐"); // Add content of watermark to screen - foreach (var watermarkText in text) { + foreach (var watermarkText in text) + { var spacingSize = longestLength - watermarkText.Length; var textWithRightPadding = watermarkText; - for (var i = 0; i < spacingSize; ++i) { - textWithRightPadding += " "; - } + for (var i = 0; i < spacingSize; ++i) textWithRightPadding += " "; result.Add($"│ {textWithRightPadding} │"); } @@ -182,8 +194,6 @@ public class Watermark { result.Add($"└─{line}─┘"); // Log watermark to screen - foreach (var text in result) { - _logger.LogWithColor(text, textColor: LogTextColor.Yellow); - } + foreach (var text in result) _logger.LogWithColor(text, LogTextColor.Yellow); } } diff --git a/Libraries/SptAssets/SptAssets.csproj b/Libraries/SptAssets/SptAssets.csproj index ca2472ba..8200083d 100644 --- a/Libraries/SptAssets/SptAssets.csproj +++ b/Libraries/SptAssets/SptAssets.csproj @@ -13,5 +13,5 @@ PreserveNewest - + diff --git a/Libraries/SptDependencyInjection/DependencyInjectionRegistrator.cs b/Libraries/SptDependencyInjection/DependencyInjectionRegistrator.cs index 6b6dd7b4..a16f1385 100644 --- a/Libraries/SptDependencyInjection/DependencyInjectionRegistrator.cs +++ b/Libraries/SptDependencyInjection/DependencyInjectionRegistrator.cs @@ -6,6 +6,9 @@ namespace SptDependencyInjection; public static class DependencyInjectionRegistrator { + private static List? _allLoadedTypes; + private static List? _allConstructors; + public static void RegisterModOverrideComponents(IServiceCollection builderServices, List assemblies) { // We get all the services from this assembly first, since mods will override them later @@ -28,14 +31,9 @@ public static class DependencyInjectionRegistrator { // if we have a type override this takes priority if (attribute.InjectableTypeOverride != null) - { registerableType = attribute.InjectableTypeOverride; - } // if this class only has 1 interface we register it on that interface - else if (registerableType.GetInterfaces().Length == 1) - { - registerableType = registerableType.GetInterfaces()[0]; - } + else if (registerableType.GetInterfaces().Length == 1) registerableType = registerableType.GetInterfaces()[0]; registerableComponents.Add(new RegisterableType(registerableType, t, attribute)); } @@ -46,25 +44,18 @@ public static class DependencyInjectionRegistrator .GroupBy(t => t.RegisterableInterface.FullName); // We get all injectable services to register them on our services foreach (var groupedInjectables in groupedTypes) - { - foreach (var valueTuple in groupedInjectables.OrderBy(t => t.InjectableAttribute.TypePriority)) - { - if (valueTuple.TypeToRegister.IsGenericType) - RegisterGenericComponents(builderServices, valueTuple); - else - RegisterComponent( - builderServices, - valueTuple.InjectableAttribute.InjectionType, - valueTuple.RegisterableInterface, - valueTuple.TypeToRegister - ); - } - } + foreach (var valueTuple in groupedInjectables.OrderBy(t => t.InjectableAttribute.TypePriority)) + if (valueTuple.TypeToRegister.IsGenericType) + RegisterGenericComponents(builderServices, valueTuple); + else + RegisterComponent( + builderServices, + valueTuple.InjectableAttribute.InjectionType, + valueTuple.RegisterableInterface, + valueTuple.TypeToRegister + ); } - private static List? _allLoadedTypes; - private static List? _allConstructors; - private static void RegisterGenericComponents(IServiceCollection builderServices, RegisterableType valueTuple) { _allLoadedTypes ??= AppDomain.CurrentDomain.GetAssemblies().SelectMany(t => t.GetTypes()).ToList(); @@ -85,22 +76,20 @@ public static class DependencyInjectionRegistrator if (constructorInfos.Count == 0) return; foreach (var matchedConstructor in constructorInfos) + foreach (var parameterInfo in matchedConstructor.GetParameters() + .Where( + p => p.ParameterType.IsGenericType && + p.ParameterType.GetGenericTypeDefinition().FullName == typeName + )) { - foreach (var parameterInfo in matchedConstructor.GetParameters() - .Where( - p => p.ParameterType.IsGenericType && - p.ParameterType.GetGenericTypeDefinition().FullName == typeName - )) - { - var parameters = parameterInfo.ParameterType.GetGenericArguments(); - var typedGeneric = valueTuple.TypeToRegister.MakeGenericType(parameters); - RegisterComponent( - builderServices, - valueTuple.InjectableAttribute.InjectionType, - parameterInfo.ParameterType, - typedGeneric - ); - } + var parameters = parameterInfo.ParameterType.GetGenericArguments(); + var typedGeneric = valueTuple.TypeToRegister.MakeGenericType(parameters); + RegisterComponent( + builderServices, + valueTuple.InjectableAttribute.InjectionType, + parameterInfo.ParameterType, + typedGeneric + ); } } catch (Exception e) @@ -150,7 +139,7 @@ public static class DependencyInjectionRegistrator ); } - class RegisterableType(Type registerableInterface, Type typeToRegister, Injectable injectableAttribute) + private class RegisterableType(Type registerableInterface, Type typeToRegister, Injectable injectableAttribute) { public Type RegisterableInterface { get; } = registerableInterface; public Type TypeToRegister { get; } = typeToRegister; diff --git a/Server/Logger/AbstractFormatter.cs b/Server/Logger/AbstractFormatter.cs index 6020e908..e8a26864 100644 --- a/Server/Logger/AbstractFormatter.cs +++ b/Server/Logger/AbstractFormatter.cs @@ -5,13 +5,6 @@ namespace Server.Logger; public abstract class AbstractFormatter : ITextFormatter { - protected abstract string ProcessText(string text); - - protected virtual string GetFormattedText(string timestamp, string logLevel, string sourceContext, string message) - { - return $"[{timestamp} {logLevel}][{sourceContext}] {message}"; - } - public void Format(LogEvent logEvent, TextWriter output) { var newLine = Environment.NewLine; @@ -23,4 +16,11 @@ public abstract class AbstractFormatter : ITextFormatter var logMessage = ProcessText(GetFormattedText(timestamp, logLevel, sourceContext, $"{message}{exception}")); output.WriteLine(logMessage); } + + protected abstract string ProcessText(string text); + + protected virtual string GetFormattedText(string timestamp, string logLevel, string sourceContext, string message) + { + return $"[{timestamp} {logLevel}][{sourceContext}] {message}"; + } } diff --git a/Server/Logger/ConsoleFormatter.cs b/Server/Logger/ConsoleFormatter.cs index ceb9ecbe..10ea329f 100644 --- a/Server/Logger/ConsoleFormatter.cs +++ b/Server/Logger/ConsoleFormatter.cs @@ -2,6 +2,8 @@ namespace Server.Logger; public class ConsoleFormatter : AbstractFormatter { + public static ConsoleFormatter Default { get; } = new(); + protected override string ProcessText(string text) { return text; @@ -11,6 +13,4 @@ public class ConsoleFormatter : AbstractFormatter { return message; } - - public static ConsoleFormatter Default { get; } = new(); } diff --git a/Server/Logger/FileFormatter.cs b/Server/Logger/FileFormatter.cs index 7c079c57..bafe62bb 100644 --- a/Server/Logger/FileFormatter.cs +++ b/Server/Logger/FileFormatter.cs @@ -4,14 +4,11 @@ namespace Server.Logger; public class FileFormatter : AbstractFormatter { + public static FileFormatter Default { get; } = new(); + protected override string ProcessText(string message) { - foreach (Match match in Regex.Matches(message, @"\x1b\[[0-9]{1,2}(;[0-1]{1,2}){0,1}m")) - { - message = message.Replace(match.Value, ""); - } + foreach (Match match in Regex.Matches(message, @"\x1b\[[0-9]{1,2}(;[0-1]{1,2}){0,1}m")) message = message.Replace(match.Value, ""); return message.Replace("\"", ""); } - - public static FileFormatter Default { get; } = new FileFormatter(); } diff --git a/Server/Logger/WebApplicationLogger.cs b/Server/Logger/WebApplicationLogger.cs index 4d782663..800c303d 100644 --- a/Server/Logger/WebApplicationLogger.cs +++ b/Server/Logger/WebApplicationLogger.cs @@ -24,31 +24,11 @@ public class SptWebApplicationLogger : ISptLogger ) { if (textColor != null || backgroundColor != null) - { _logger.LogInformation(ex, GetColorizedText(data, textColor, backgroundColor)); - } else _logger.LogInformation(ex, data); } - private string GetColorizedText( - string data, - LogTextColor? textColor = null, - LogBackgroundColor? backgroundColor = null - ) - { - var colorString = string.Empty; - if (textColor != null) - colorString += ((int)textColor.Value).ToString(); - - if (backgroundColor != null) - colorString += string.IsNullOrEmpty(colorString) - ? ((int)backgroundColor.Value).ToString() - : $";{((int)backgroundColor.Value).ToString()}"; - - return $"\x1b[{colorString}m{data}\x1b[0m"; - } - public void Success(string data, Exception? ex = null) { _logger.LogInformation(ex, GetColorizedText(data, LogTextColor.Green)); @@ -90,6 +70,24 @@ public class SptWebApplicationLogger : ISptLogger return _logger.IsEnabled(ConvertLogLevel(level)); } + private string GetColorizedText( + string data, + LogTextColor? textColor = null, + LogBackgroundColor? backgroundColor = null + ) + { + var colorString = string.Empty; + if (textColor != null) + colorString += ((int)textColor.Value).ToString(); + + if (backgroundColor != null) + colorString += string.IsNullOrEmpty(colorString) + ? ((int)backgroundColor.Value).ToString() + : $";{((int)backgroundColor.Value).ToString()}"; + + return $"\x1b[{colorString}m{data}\x1b[0m"; + } + protected Microsoft.Extensions.Logging.LogLevel ConvertLogLevel(LogLevel level) { return level switch diff --git a/Server/ModDllLoader.cs b/Server/ModDllLoader.cs index f718e6a4..52874643 100644 --- a/Server/ModDllLoader.cs +++ b/Server/ModDllLoader.cs @@ -5,13 +5,13 @@ namespace Server; public class ModDllLoader { private const string ModPath = "./user/mods/"; + public static List LoadAllMods() { if (!Directory.Exists(ModPath)) Directory.CreateDirectory(ModPath); var mods = new List(); foreach (var file in Directory.GetFiles(ModPath, "*.dll", SearchOption.AllDirectories)) - { try { mods.Add(Assembly.LoadFile(Path.GetFullPath(file))); @@ -20,7 +20,7 @@ public class ModDllLoader { Console.WriteLine(e); } - } + return mods; } } diff --git a/Server/Program.cs b/Server/Program.cs index 5459b069..24fbf87e 100644 --- a/Server/Program.cs +++ b/Server/Program.cs @@ -23,14 +23,14 @@ public static class Program builder.Host.UseSerilog(); builder.Configuration.AddJsonFile("appsettings.json", true, true); - + CreateAndRegisterLogger(builder, out var registeredLogger); ProgramStatics.Initialize(); DependencyInjectionRegistrator.RegisterSptComponents(typeof(Program).Assembly, typeof(App).Assembly, builder.Services); DependencyInjectionRegistrator.RegisterModOverrideComponents(builder.Services, assemblies); - ILogger logger = new SerilogLoggerProvider(registeredLogger).CreateLogger("Server"); + var logger = new SerilogLoggerProvider(registeredLogger).CreateLogger("Server"); try { var serviceProvider = builder.Services.BuildServiceProvider(); @@ -40,16 +40,13 @@ public static class Program // Initialize PreSptMods var preSptLoadMods = serviceProvider.GetServices(); - foreach (var preSptLoadMod in preSptLoadMods) - { - preSptLoadMod.PreSptLoad(); - } + foreach (var preSptLoadMod in preSptLoadMods) preSptLoadMod.PreSptLoad(); var appContext = serviceProvider.GetService(); // Add the Loaded Mod Assemblies for later appContext?.AddValue(ContextVariableType.LOADED_MOD_ASSEMBLIES, assemblies); // This is the builder that will get use by the HttpServer to start up the web application appContext?.AddValue(ContextVariableType.APP_BUILDER, builder); - + // Get the Built app and run it var app = serviceProvider.GetService(); app?.Run().Wait(); @@ -68,15 +65,15 @@ public static class Program // throw ex; } } - + public static void CreateAndRegisterLogger(WebApplicationBuilder builder, out Serilog.Core.Logger logger) { builder.Logging.ClearProviders(); logger = new LoggerConfiguration() .ReadFrom.Configuration(builder.Configuration) - # if DEBUG +# if DEBUG .MinimumLevel.Debug() - # endif +# endif .MinimumLevel.Override("Microsoft.AspNetCore.Hosting.Diagnostics", LogEventLevel.Warning) .Enrich.FromLogContext() .Enrich.WithThreadId() diff --git a/SptCommon/Extensions/ListExtensions.cs b/SptCommon/Extensions/ListExtensions.cs index a3d34c27..e5ed52bd 100644 --- a/SptCommon/Extensions/ListExtensions.cs +++ b/SptCommon/Extensions/ListExtensions.cs @@ -5,20 +5,20 @@ public static class ListExtensions public static List Splice(this List source, int index, int count) { var items = source.GetRange(index, count); - source.RemoveRange(index,count); + source.RemoveRange(index, count); return items; } public static T PopFirst(this IList source) { - T r = source.First(); + var r = source.First(); source.Remove(source.First()); return r; } public static T PopLast(this IList source) { - T r = source.Last(); + var r = source.Last(); source.Remove(source.Last()); return r; } diff --git a/SptCommon/Extensions/MemberInfoExtensions.cs b/SptCommon/Extensions/MemberInfoExtensions.cs index ebd39d31..ed281c08 100644 --- a/SptCommon/Extensions/MemberInfoExtensions.cs +++ b/SptCommon/Extensions/MemberInfoExtensions.cs @@ -11,5 +11,4 @@ public static class MemberInfoExtensions ? (Attribute.GetCustomAttribute(memberInfo, typeof(JsonPropertyNameAttribute)) as JsonPropertyNameAttribute).Name : memberInfo.Name; } - } diff --git a/SptCommon/Extensions/ObjectExtensions.cs b/SptCommon/Extensions/ObjectExtensions.cs index c8347093..e95785d3 100644 --- a/SptCommon/Extensions/ObjectExtensions.cs +++ b/SptCommon/Extensions/ObjectExtensions.cs @@ -1,81 +1,74 @@ using System.Reflection; using System.Text.Json; -namespace SptCommon.Extensions +namespace SptCommon.Extensions; + +public static class ObjectExtensions { - public static class ObjectExtensions + private static readonly Dictionary> _indexedProperties = new(); + private static readonly object _indexedPropertiesLockObject = new(); + + private static bool TryGetCachedProperty(Type type, string key, out PropertyInfo cachedProperty) { - private static readonly Dictionary> _indexedProperties = new(); - private static readonly object _indexedPropertiesLockObject = new(); - - private static bool TryGetCachedProperty(Type type, string key, out PropertyInfo cachedProperty) + lock (_indexedPropertiesLockObject) { - lock (_indexedPropertiesLockObject) + if (!_indexedProperties.TryGetValue(type, out var properties)) { - if (!_indexedProperties.TryGetValue(type, out var properties)) - { - properties = type.GetProperties().ToDictionary(prop => prop.GetJsonName(), prop => prop); - _indexedProperties.Add(type, properties); - } - - return properties.TryGetValue(key, out cachedProperty); + properties = type.GetProperties().ToDictionary(prop => prop.GetJsonName(), prop => prop); + _indexedProperties.Add(type, properties); } - } - /// - /// CARE WHEN USING THIS, THIS IS TO GET PROP ON A TYPE - /// - /// - /// - /// - /// - /// - public static bool ContainsJsonProp(this object? obj, T key) - { - if (obj == null) - { - throw new ArgumentNullException(nameof(obj)); - } - - return TryGetCachedProperty(obj.GetType(), key.ToString(), out _); - } - - public static T? GetByJsonProp(this object? obj, string? toLower) - { - ArgumentNullException.ThrowIfNull(obj); - ArgumentNullException.ThrowIfNull(toLower); - - if (!TryGetCachedProperty(obj.GetType(), toLower, out var cachedProperty)) - return default; - return (T?)cachedProperty.GetValue(obj); - } - - public static List GetAllPropValuesAsList(this object? obj) - { - ArgumentNullException.ThrowIfNull(obj); - - var list = obj.GetType().GetProperties(); - var result = new List(); - - foreach (var prop in list) - { - result.Add(prop.GetValue(obj)); - } - - return result; - } - - public static Dictionary GetAllPropsAsDict(this object? obj) - { - var props = obj.GetType().GetProperties(); - - return props.ToDictionary(prop => prop.Name, prop => prop.GetValue(obj)); - } - - public static T ToObject(this JsonElement element) - { - var json = element.GetRawText(); - return JsonSerializer.Deserialize(json); + return properties.TryGetValue(key, out cachedProperty); } } + + /// + /// CARE WHEN USING THIS, THIS IS TO GET PROP ON A TYPE + /// + /// + /// + /// + /// + /// + public static bool ContainsJsonProp(this object? obj, T key) + { + if (obj == null) throw new ArgumentNullException(nameof(obj)); + + return TryGetCachedProperty(obj.GetType(), key.ToString(), out _); + } + + public static T? GetByJsonProp(this object? obj, string? toLower) + { + ArgumentNullException.ThrowIfNull(obj); + ArgumentNullException.ThrowIfNull(toLower); + + if (!TryGetCachedProperty(obj.GetType(), toLower, out var cachedProperty)) + return default; + return (T?)cachedProperty.GetValue(obj); + } + + public static List GetAllPropValuesAsList(this object? obj) + { + ArgumentNullException.ThrowIfNull(obj); + + var list = obj.GetType().GetProperties(); + var result = new List(); + + foreach (var prop in list) result.Add(prop.GetValue(obj)); + + return result; + } + + public static Dictionary GetAllPropsAsDict(this object? obj) + { + var props = obj.GetType().GetProperties(); + + return props.ToDictionary(prop => prop.Name, prop => prop.GetValue(obj)); + } + + public static T ToObject(this JsonElement element) + { + var json = element.GetRawText(); + return JsonSerializer.Deserialize(json); + } } diff --git a/SptCommon/Extensions/StringExtensions.cs b/SptCommon/Extensions/StringExtensions.cs index ce5bd992..44fcff51 100644 --- a/SptCommon/Extensions/StringExtensions.cs +++ b/SptCommon/Extensions/StringExtensions.cs @@ -19,9 +19,10 @@ public static class StringExtensions RegexCache[regexString] = regex; } } + return regex.Replace(source, newValue); } - + public static bool RegexMatch(this string source, [StringSyntax(StringSyntaxAttribute.Regex)] string regexString, out Match? matchedString) { Regex regex; diff --git a/Tools/ItemTplGenerator/ItemOverrides.cs b/Tools/ItemTplGenerator/ItemOverrides.cs index 3d89ce7d..c37b6470 100644 --- a/Tools/ItemTplGenerator/ItemOverrides.cs +++ b/Tools/ItemTplGenerator/ItemOverrides.cs @@ -124,7 +124,7 @@ public class ItemOverrides { "6764207f2fa5e32733055c4a", "Dogtag USEC Prestige 1" }, { "675dc9d37ae1a8792107ca96", "Dogtag BEAR Prestige 1" }, { "675dcb0545b1a2d108011b2b", "Dogtag BEAR Prestige 2" }, - { "6764202ae307804338014c1a", "Dogtag USEC Prestige 2" }, + { "6764202ae307804338014c1a", "Dogtag USEC Prestige 2" } } ); } diff --git a/Tools/ItemTplGenerator/ItemTplGenerator.cs b/Tools/ItemTplGenerator/ItemTplGenerator.cs index 648d5462..c9c4d877 100644 --- a/Tools/ItemTplGenerator/ItemTplGenerator.cs +++ b/Tools/ItemTplGenerator/ItemTplGenerator.cs @@ -22,10 +22,10 @@ public class ItemTplGenerator( IEnumerable _onLoadComponents ) { - private string enumDir; - private Dictionary items; - private IDictionary itemOverrides; private HashSet collidedEnumKeys = []; + private string enumDir; + private IDictionary itemOverrides; + private Dictionary items; public async Task Run() { @@ -82,17 +82,14 @@ public class ItemTplGenerator( var itemPrefix = GetItemPrefix(item); var itemName = GetItemName(item); var itemSuffix = GetItemSuffix(item); - + // Handle the case where the item starts with the parent category name. Avoids things like 'POCKETS_POCKETS' if (itemName.Length > itemParentName.Length && itemParentName == itemName.Substring(1, itemParentName.Length) && itemPrefix == "") { itemName = itemName.Substring(itemParentName.Length + 1); - if (itemName.Length > 0 && itemName[0] != '_') - { - itemName = $"_{itemName}"; - } + if (itemName.Length > 0 && itemName[0] != '_') itemName = $"_{itemName}"; } // Handle the case where the item ends with the parent category name. Avoids things like 'KEY_DORM_ROOM_103_KEY' @@ -101,10 +98,7 @@ public class ItemTplGenerator( { itemName = itemName.Substring(0, itemName.Length - itemParentName.Length); - if (itemName.Substring(itemName.Length - 1) == "_") - { - itemName = itemName.Substring(0, itemName.Length - 1); - } + if (itemName.Substring(itemName.Length - 1) == "_") itemName = itemName.Substring(0, itemName.Length - 1); } var itemKey = $"{itemParentName}{itemPrefix}{itemName}{itemSuffix}"; @@ -138,17 +132,13 @@ public class ItemTplGenerator( // If we still collide, log an error if (itemsObject.ContainsKey(itemKey)) - { _logger.Error( $"After rename, itemsObject already contains {itemKey} {itemsObject[itemKey]} => {item.Id}" ); - } } else { - var val = itemsObject.ContainsKey(itemKey) ? - itemsObject[itemKey] : - itemKey; + var val = itemsObject.ContainsKey(itemKey) ? itemsObject[itemKey] : itemKey; _logger.Error($"New itemOverride entry required: itemsObject already contains {itemKey} {val} => {item.Id}"); continue; } @@ -174,27 +164,19 @@ public class ItemTplGenerator( var weaponsObject = new Dictionary(); foreach (var kv /*[itemId, item]*/ in items) { - if (!_itemHelper.IsOfBaseclass(kv.Key, BaseClasses.WEAPON)) - { - continue; - } + if (!_itemHelper.IsOfBaseclass(kv.Key, BaseClasses.WEAPON)) continue; var caliber = CleanCaliber(kv.Value.Properties.AmmoCaliber.ToUpper()); var weaponShortName = _localeService.GetLocaleDb()[$"{kv.Key} ShortName"]?.ToUpper(); // Special case for the weird duplicated grenade launcher - if (kv.Key == "639c3fbbd0446708ee622ee9") - { - weaponShortName = "FN40GL_2"; - } + if (kv.Key == "639c3fbbd0446708ee622ee9") weaponShortName = "FN40GL_2"; // Include any bracketed suffixes that exist, handles the case of colored gun variants var weaponFullName = _localeService.GetLocaleDb()[$"{kv.Key} Name"]?.ToUpper(); if (weaponFullName.RegexMatch(@"\((.+?)\)$", out var itemNameBracketSuffix) && !weaponShortName.EndsWith(itemNameBracketSuffix.Groups[1].Value)) - { weaponShortName += $"_{itemNameBracketSuffix.Groups[1].Value}"; - } var parentName = GetParentName(kv.Value); @@ -235,62 +217,29 @@ public class ItemTplGenerator( private string GetParentName(TemplateItem item) { - if (item.Properties?.QuestItem is true) - { - return "QUEST"; - } + if (item.Properties?.QuestItem is true) return "QUEST"; - if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.BARTER_ITEM)) - { - return "BARTER"; - } + if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.BARTER_ITEM)) return "BARTER"; - if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.THROW_WEAPON)) - { - return "GRENADE"; - } + if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.THROW_WEAPON)) return "GRENADE"; - if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.STIMULATOR)) - { - return "STIM"; - } + if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.STIMULATOR)) return "STIM"; - if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.MAGAZINE)) - { - return "MAGAZINE"; - } + if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.MAGAZINE)) return "MAGAZINE"; - if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.KEY_MECHANICAL)) - { - return "KEY"; - } + if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.KEY_MECHANICAL)) return "KEY"; - if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.MOB_CONTAINER)) - { - return "SECURE"; - } + if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.MOB_CONTAINER)) return "SECURE"; - if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.SIMPLE_CONTAINER)) - { - return "CONTAINER"; - } + if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.SIMPLE_CONTAINER)) return "CONTAINER"; - if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.PORTABLE_RANGE_FINDER)) - { - return "RANGEFINDER"; - } + if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.PORTABLE_RANGE_FINDER)) return "RANGEFINDER"; // Why are flares grenade launcher...? - if (item.Name.StartsWith("weapon_rsp30")) - { - return "FLARE"; - } + if (item.Name.StartsWith("weapon_rsp30")) return "FLARE"; // This is a special case for the signal pistol, I'm not adding it as a Grenade Launcher - if (item.Id == "620109578d82e67e7911abf2") - { - return "SIGNALPISTOL"; - } + if (item.Id == "620109578d82e67e7911abf2") return "SIGNALPISTOL"; var parentId = item.Parent; return items[parentId].Name.ToUpper(); @@ -300,15 +249,9 @@ public class ItemTplGenerator( { var shrapnelId = "5943d9c186f7745a13413ac9"; - if (item.Type != "Item") - { - return false; - } + if (item.Type != "Item") return false; - if (item.Prototype == shrapnelId) - { - return false; - } + if (item.Prototype == shrapnelId) return false; return true; } @@ -324,25 +267,15 @@ public class ItemTplGenerator( // Prefix ammo with its caliber if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.AMMO)) - { prefix = GetAmmoPrefix(item); - } // Prefix ammo boxes with their caliber else if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.AMMO_BOX)) - { prefix = GetAmmoBoxPrefix(item); - } // Prefix magazines with their caliber - else if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.MAGAZINE)) - { - prefix = GetMagazinePrefix(item); - } + else if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.MAGAZINE)) prefix = GetMagazinePrefix(item); // Make sure there's an underscore separator - if (prefix.Length > 0 && prefix[0] != '_') - { - prefix = $"_{prefix}"; - } + if (prefix.Length > 0 && prefix[0] != '_') prefix = $"_{prefix}"; return prefix; } @@ -353,26 +286,15 @@ public class ItemTplGenerator( // Add mag size for magazines if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.MAGAZINE)) - { suffix = $"{item.Properties?.Cartridges?[0].MaxCount?.ToString()}RND"; - } // Add pack size for ammo boxes - else if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.AMMO_BOX)) - { - suffix = $"{item.Properties.StackSlots[0]?.MaxCount.ToString()}RND"; - } + else if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.AMMO_BOX)) suffix = $"{item.Properties.StackSlots[0]?.MaxCount.ToString()}RND"; // Add "DAMAGED" for damaged items - if (item.Name.ToLower().Contains("damaged")) - { - suffix += "_DAMAGED"; - } + if (item.Name.ToLower().Contains("damaged")) suffix += "_DAMAGED"; // Make sure there's an underscore separator - if (suffix.Length > 0 && suffix[0] != '_') - { - suffix = $"_{suffix}"; - } + if (suffix.Length > 0 && suffix[0] != '_') suffix = $"_{suffix}"; return suffix; } @@ -456,15 +378,10 @@ public class ItemTplGenerator( // Fall back in the event we couldn't find a name if (string.IsNullOrEmpty(itemName)) - { if (localeDb.TryGetValue($"{item.Id} Name", out itemName)) itemName = itemName.ToUpper(); - } - if (string.IsNullOrEmpty(itemName)) - { - itemName = item.Name?.ToUpper() ?? null; - } + if (string.IsNullOrEmpty(itemName)) itemName = item.Name?.ToUpper() ?? null; if (string.IsNullOrEmpty(itemName)) { @@ -485,9 +402,7 @@ public class ItemTplGenerator( // Add grid size for lootable containers if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.LOOT_CONTAINER)) - { return $"{item.Properties.Grids[0]?.Props.CellsH}X{item.Properties.Grids[0]?.Props.CellsV}"; - } // Add ammo caliber to conflicting weapons if (_itemHelper.IsOfBaseclass(item.Id, BaseClasses.WEAPON)) @@ -495,31 +410,19 @@ public class ItemTplGenerator( var caliber = CleanCaliber(item.Properties.AmmoCaliber.ToUpper()); // If the item has a bracketed section at the end of its name, include that - if (itemName?.RegexMatch(@"\((.+?)\)$", out var itemNameBracketSuffix) ?? false) - { - return $"{caliber}_{itemNameBracketSuffix.Groups[1].Value}"; - } + if (itemName?.RegexMatch(@"\((.+?)\)$", out var itemNameBracketSuffix) ?? false) return $"{caliber}_{itemNameBracketSuffix.Groups[1].Value}"; return caliber; } // Make sure we have a full name - if (string.IsNullOrEmpty(itemName)) - { - return ""; - } + if (string.IsNullOrEmpty(itemName)) return ""; // If the item has a bracketed section at the end of its name, use that - if (itemName.RegexMatch(@"\((.+?)\)$", out var itemNameBracker)) - { - return itemNameBracker.Groups[1].Value; - } + if (itemName.RegexMatch(@"\((.+?)\)$", out var itemNameBracker)) return itemNameBracker.Groups[1].Value; // If the item has a number at the end of its name, use that - if (itemName.RegexMatch("#([0-9]+)$", out var itemNameNumberSuffix)) - { - return itemNameNumberSuffix.Groups[1].Value; - } + if (itemName.RegexMatch("#([0-9]+)$", out var itemNameNumberSuffix)) return itemNameNumberSuffix.Groups[1].Value; return ""; } @@ -528,21 +431,14 @@ public class ItemTplGenerator( { // First generate a mapping of the original enum values to names var originalEnumValues = new Dictionary(); - foreach (var field in originalEnum.GetFields()) - { - originalEnumValues.Add(field.GetValue(null)!.ToString()!, field.Name); - } + foreach (var field in originalEnum.GetFields()) originalEnumValues.Add(field.GetValue(null)!.ToString()!, field.Name); // Loop through our new data, and find any where the given ID's name doesn't match the original enum foreach (var kv in data) - { if (originalEnumValues.ContainsKey(kv.Value) && originalEnumValues[kv.Value] != kv.Key) - { _logger.Warning( $"Enum {enumName} key has changed for {kv.Value}, {originalEnumValues[kv.Value]} => {kv.Key}" ); - } - } } private void WriteEnumsToFile(string outputPath, Dictionary> enumEntries) @@ -554,10 +450,7 @@ public class ItemTplGenerator( { enumFileData += $"\npublic static class {enumName}\n{{\n"; - foreach (var (key, value) in data) - { - enumFileData += $" {key} = \"{value}\";\n"; - } + foreach (var (key, value) in data) enumFileData += $" {key} = \"{value}\";\n"; enumFileData += "}\n"; } diff --git a/Tools/ItemTplGenerator/SptBasicLogger.cs b/Tools/ItemTplGenerator/SptBasicLogger.cs index 90301601..23c6c19f 100644 --- a/Tools/ItemTplGenerator/SptBasicLogger.cs +++ b/Tools/ItemTplGenerator/SptBasicLogger.cs @@ -9,11 +9,12 @@ namespace ItemTplGenerator; public class SptBasicLogger : ISptLogger { private readonly string categoryName; + public SptBasicLogger() { categoryName = typeof(T).Name; } - + public void LogWithColor(string data, LogTextColor? textColor = null, LogBackgroundColor? backgroundColor = null, Exception? ex = null) { diff --git a/UnitTests/MSTestSettings.cs b/UnitTests/MSTestSettings.cs index 8b7de71c..aaf278c8 100644 --- a/UnitTests/MSTestSettings.cs +++ b/UnitTests/MSTestSettings.cs @@ -1 +1 @@ -[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] \ No newline at end of file +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] diff --git a/UnitTests/Mock/MockLogger.cs b/UnitTests/Mock/MockLogger.cs index 57449f47..a15e9fba 100644 --- a/UnitTests/Mock/MockLogger.cs +++ b/UnitTests/Mock/MockLogger.cs @@ -6,16 +6,6 @@ namespace UnitTests.Mock; public class MockLogger : ISptLogger { - public void LogWithColor( - string data, - Exception? ex = null, - LogTextColor? textColor = null, - LogBackgroundColor? backgroundColor = null - ) - { - Console.WriteLine(data); - } - public void LogWithColor(string data, LogTextColor? textColor = null, LogBackgroundColor? backgroundColor = null, Exception? ex = null) { throw new NotImplementedException(); @@ -61,6 +51,16 @@ public class MockLogger : ISptLogger return true; } + public void LogWithColor( + string data, + Exception? ex = null, + LogTextColor? textColor = null, + LogBackgroundColor? backgroundColor = null + ) + { + Console.WriteLine(data); + } + public void WriteToLogFile(object body) { Console.WriteLine(body); diff --git a/UnitTests/Tests/Test.cs b/UnitTests/Tests/Test.cs index 0b88ab2a..f84fcd82 100644 --- a/UnitTests/Tests/Test.cs +++ b/UnitTests/Tests/Test.cs @@ -9,17 +9,16 @@ namespace UnitTests.Tests; public class Test { private Templates? _templates; - + [TestInitialize] public void Setup() { - var importer = new ImporterUtil(new MockLogger(), new FileUtil(new MockLogger()), new JsonUtil()); var loadTask = importer.LoadRecursiveAsync("./TestAssets/"); loadTask.Wait(); _templates = loadTask.Result; } - + [TestMethod] public void TestMethod1() { diff --git a/UnitTests/Tests/Utils/JsonUtilTests.cs b/UnitTests/Tests/Utils/JsonUtilTests.cs index f7f72745..4cc60549 100644 --- a/UnitTests/Tests/Utils/JsonUtilTests.cs +++ b/UnitTests/Tests/Utils/JsonUtilTests.cs @@ -7,6 +7,7 @@ namespace UnitTests.Tests.Utils; public class JsonUtilTests { protected JsonUtil _jsonUtil = new(); + [TestMethod] public void SerializeAndDeserialize_WithDictionaryOfETFEnum_ExpectCorrectParsing() { diff --git a/UnitTests/Tests/Utils/MathUtilTests.cs b/UnitTests/Tests/Utils/MathUtilTests.cs index e8bc1b4e..62f3de4a 100644 --- a/UnitTests/Tests/Utils/MathUtilTests.cs +++ b/UnitTests/Tests/Utils/MathUtilTests.cs @@ -5,79 +5,73 @@ namespace UnitTests.Tests.Utils; [TestClass] public class MathUtilTests { - protected MathUtil _mathUtil = new(); - - [TestMethod] - public void ListSumTest() - { - var test = new List { 1.1f, 2.1f, 3.3f }; - const double expected = 6.5f; - - var actual = _mathUtil.ListSum(test); - - Assert.AreEqual(expected, actual, - $"ListSum() Expected: {expected}, Actual: {actual}"); - } - - [TestMethod] - public void ListCumSumTest() - { - var test = new List { 1f, 2f, 3f, 4f }; - var expected = new List { 1f, 3f, 6f, 10f }; - - var actual = _mathUtil.ListCumSum(test); + protected MathUtil _mathUtil = new(); - for (var i = 0; i < actual.Count; i++) - { - if (Math.Abs(expected[i] - actual[i]) > 0.00001f) - { - Assert.Fail($"ListCumSum() Expected: {string.Join(", ", expected)}, Actual: {string.Join(", ", actual)}"); - } - } - } - - [TestMethod] - public void ListProductTest() - { - var test = new List { 1f, 2f, 3f, 4f }; - var expected = new List { 2f, 4f, 6f, 8f }; - - var actual = _mathUtil.ListProduct(test, 2); + [TestMethod] + public void ListSumTest() + { + var test = new List { 1.1f, 2.1f, 3.3f }; + const double expected = 6.5f; - for (var i = 0; i < actual.Count; i++) - { - if (Math.Abs(expected[i] - actual[i]) > 0.00001f) - { - Assert.Fail($"ListProduct() Expected: {string.Join(", ", expected)}, Actual: {string.Join(", ", actual)}"); - } - } - } - - [TestMethod] - public void ListAddTest() - { - var test = new List { 1f, 2f, 3f, 4f }; - var expected = new List { 3f, 4f, 5f, 6f }; - - var actual = _mathUtil.ListAdd(test, 2); + var actual = _mathUtil.ListSum(test); - for (var i = 0; i < actual.Count; i++) - { - if (Math.Abs(expected[i] - actual[i]) > 0.00001f) - { - Assert.Fail($"ListProduct() Expected: {string.Join(", ", expected)}, Actual: {string.Join(", ", actual)}"); - } - } - } - - [TestMethod] - public void MapToRangeTest() - { - const double expected = 2; - - var actual = _mathUtil.MapToRange(0.5, 0, 1, 1, 3); - - Assert.AreEqual(expected, actual, - $"MapToRange() Expected: {expected}, Actual: {actual}"); - } + Assert.AreEqual( + expected, + actual, + $"ListSum() Expected: {expected}, Actual: {actual}" + ); + } + + [TestMethod] + public void ListCumSumTest() + { + var test = new List { 1f, 2f, 3f, 4f }; + var expected = new List { 1f, 3f, 6f, 10f }; + + var actual = _mathUtil.ListCumSum(test); + + for (var i = 0; i < actual.Count; i++) + if (Math.Abs(expected[i] - actual[i]) > 0.00001f) + Assert.Fail($"ListCumSum() Expected: {string.Join(", ", expected)}, Actual: {string.Join(", ", actual)}"); + } + + [TestMethod] + public void ListProductTest() + { + var test = new List { 1f, 2f, 3f, 4f }; + var expected = new List { 2f, 4f, 6f, 8f }; + + var actual = _mathUtil.ListProduct(test, 2); + + for (var i = 0; i < actual.Count; i++) + if (Math.Abs(expected[i] - actual[i]) > 0.00001f) + Assert.Fail($"ListProduct() Expected: {string.Join(", ", expected)}, Actual: {string.Join(", ", actual)}"); + } + + [TestMethod] + public void ListAddTest() + { + var test = new List { 1f, 2f, 3f, 4f }; + var expected = new List { 3f, 4f, 5f, 6f }; + + var actual = _mathUtil.ListAdd(test, 2); + + for (var i = 0; i < actual.Count; i++) + if (Math.Abs(expected[i] - actual[i]) > 0.00001f) + Assert.Fail($"ListProduct() Expected: {string.Join(", ", expected)}, Actual: {string.Join(", ", actual)}"); + } + + [TestMethod] + public void MapToRangeTest() + { + const double expected = 2; + + var actual = _mathUtil.MapToRange(0.5, 0, 1, 1, 3); + + Assert.AreEqual( + expected, + actual, + $"MapToRange() Expected: {expected}, Actual: {actual}" + ); + } } diff --git a/UnitTests/Tests/Utils/RandomUtilTests.cs b/UnitTests/Tests/Utils/RandomUtilTests.cs index 5719ed10..cc0bbfd2 100644 --- a/UnitTests/Tests/Utils/RandomUtilTests.cs +++ b/UnitTests/Tests/Utils/RandomUtilTests.cs @@ -9,181 +9,161 @@ namespace UnitTests.Tests.Utils; public sealed class RandomUtilTests { private RandomUtil _randomUtil = new(new MockLogger(), new JsonCloner(new JsonUtil())); - - [TestMethod] - public void GetIntTest() - { - // Run 10000 test cases - for (var i = 0; i < 10000; i++) - { - var result = _randomUtil.GetInt(0, 10); - - if (result < 0 || result > 10) - { - Assert.Fail($"GetInt(0, 10) out of range. Expected range [0, 10] but was {result}."); - } - } - } - - [TestMethod] - public void GetIntExTest() - { - // Run 10000 test cases - for (var i = 0; i < 10000; i++) - { - var result = _randomUtil.GetInt(1, 10, true); - - if (result < 1 || result > 9) - { - Assert.Fail($"GetInt(10) out of range. Expected range [1, 9] but was {result}."); - } - } - } - - [TestMethod] - public void GetDoubleTest() - { - // Run 10000 test cases - for (var i = 0; i < 10000; i++) - { - var result = _randomUtil.GetDouble(0D, 10D); - - if (result is < 0d or >= 10d) - { - Assert.Fail($"GetDouble(0d, 10d) out of range. Expected range [0.0d, 9.999d] but was {result}."); - } - } - } - - [TestMethod] - public void GetPercentOfValueTest() - { - const float expected = 45.5f; - var result = _randomUtil.GetPercentOfValue(45.5f, 100f); - - Assert.AreEqual( - expected, - result, - 0.0001f, - $"GetPercentOfValue(45.5f, 100f) out of range. Expected: {expected}. Actual: {result}."); - } - - [TestMethod] - public void ReduceValueByPercentTest() - { - const float expected = 54.5f; - var result = _randomUtil.ReduceValueByPercent(100f, 45.5f); - - Assert.AreEqual( - expected, - result, - 0.0001f, - $"ReduceValueByPercent(100f, 45.5f) out of range. Expected: {expected}. Actual: {result}."); - } - - [TestMethod] - public void GetChance100Test() - { - for (var i = 0; i < 100; i++) - { - const bool expectedTrue = true; - var resultTrue = _randomUtil.GetChance100(100f); - - Assert.AreEqual( - expectedTrue, - resultTrue, - $"GetChance100(100f) out of range. Expected: {expectedTrue}. Actual: {resultTrue}."); - } - - for (var i = 0; i < 100; i++) - { - const bool expectedFalse = false; - var resultFalse = _randomUtil.GetChance100(0f); - - Assert.AreEqual( - expectedFalse, - resultFalse, - $"GetChance100(0f) out of range. Expected: {expectedFalse}. Actual: {resultFalse}."); - } - } - - // TODO: Missing methods between these two - - [TestMethod] - public void RandIntTest() - { - for (var i = 0; i < 100; i++) - { - var result = _randomUtil.RandInt(0, 10); - - if (result < 0 || result > 9) - { - Assert.Fail($"RandInt(0, 10) out of range. Expected range [0, 9] but was {result}."); - } - } - - for (var i = 0; i < 100; i++) - { - var result = _randomUtil.RandInt(10); - - if (result < 0 || result > 9) - { - Assert.Fail($"RandInt(10, null) out of range. Expected range [0, 9] but was {result}."); - } - } - } - - [TestMethod] - public void RandNumTest() - { - for (var i = 0; i < 10000; i++) - { - var result = _randomUtil.RandNum(0, 10, 15); - - if (result < 0 || result >= 10) - { - Assert.Fail($"RandNum(0, 10) out of range. Expected range [0, 9.999d] but was {result}."); - } - - if (_randomUtil.GetNumberPrecision(result) > RandomUtil.MaxSignificantDigits) - { - Assert.Fail($"RandNum(0, 10) precision of {result} exceeds the allowable precision ({RandomUtil.MaxSignificantDigits}) for the given values."); - } - } - - for (var i = 0; i < 10000; i++) - { - var result = _randomUtil.RandNum(10); - - if (result < 0 || result >= 10) - { - Assert.Fail($"RandNum(10) out of range. Expected range [0, 9.999d] but was {result}."); - } - - if (_randomUtil.GetNumberPrecision(result) > RandomUtil.MaxSignificantDigits) - { - Assert.Fail($"RandNum(10) precision of {result} exceeds the allowable precision ({RandomUtil.MaxSignificantDigits}) for the given values."); - } - } - } - - [TestMethod] - public void ShuffleTest() - { - var testList = new List() - { - 1,2,3,4,5,6,7,8,9,10 - }; - - var orig = new List(testList); - - var result = _randomUtil.Shuffle(testList); - - Assert.IsFalse( - result.SequenceEqual(orig), - $"Shuffle test failed. Expected: {string.Join(", ", orig)}, but got {string.Join(", ", result)}"); - } - + + [TestMethod] + public void GetIntTest() + { + // Run 10000 test cases + for (var i = 0; i < 10000; i++) + { + var result = _randomUtil.GetInt(0, 10); + + if (result < 0 || result > 10) Assert.Fail($"GetInt(0, 10) out of range. Expected range [0, 10] but was {result}."); + } + } + + [TestMethod] + public void GetIntExTest() + { + // Run 10000 test cases + for (var i = 0; i < 10000; i++) + { + var result = _randomUtil.GetInt(1, 10, true); + + if (result < 1 || result > 9) Assert.Fail($"GetInt(10) out of range. Expected range [1, 9] but was {result}."); + } + } + + [TestMethod] + public void GetDoubleTest() + { + // Run 10000 test cases + for (var i = 0; i < 10000; i++) + { + var result = _randomUtil.GetDouble(0D, 10D); + + if (result is < 0d or >= 10d) Assert.Fail($"GetDouble(0d, 10d) out of range. Expected range [0.0d, 9.999d] but was {result}."); + } + } + + [TestMethod] + public void GetPercentOfValueTest() + { + const float expected = 45.5f; + var result = _randomUtil.GetPercentOfValue(45.5f, 100f); + + Assert.AreEqual( + expected, + result, + 0.0001f, + $"GetPercentOfValue(45.5f, 100f) out of range. Expected: {expected}. Actual: {result}." + ); + } + + [TestMethod] + public void ReduceValueByPercentTest() + { + const float expected = 54.5f; + var result = _randomUtil.ReduceValueByPercent(100f, 45.5f); + + Assert.AreEqual( + expected, + result, + 0.0001f, + $"ReduceValueByPercent(100f, 45.5f) out of range. Expected: {expected}. Actual: {result}." + ); + } + + [TestMethod] + public void GetChance100Test() + { + for (var i = 0; i < 100; i++) + { + const bool expectedTrue = true; + var resultTrue = _randomUtil.GetChance100(100f); + + Assert.AreEqual( + expectedTrue, + resultTrue, + $"GetChance100(100f) out of range. Expected: {expectedTrue}. Actual: {resultTrue}." + ); + } + + for (var i = 0; i < 100; i++) + { + const bool expectedFalse = false; + var resultFalse = _randomUtil.GetChance100(0f); + + Assert.AreEqual( + expectedFalse, + resultFalse, + $"GetChance100(0f) out of range. Expected: {expectedFalse}. Actual: {resultFalse}." + ); + } + } + + // TODO: Missing methods between these two + + [TestMethod] + public void RandIntTest() + { + for (var i = 0; i < 100; i++) + { + var result = _randomUtil.RandInt(0, 10); + + if (result < 0 || result > 9) Assert.Fail($"RandInt(0, 10) out of range. Expected range [0, 9] but was {result}."); + } + + for (var i = 0; i < 100; i++) + { + var result = _randomUtil.RandInt(10); + + if (result < 0 || result > 9) Assert.Fail($"RandInt(10, null) out of range. Expected range [0, 9] but was {result}."); + } + } + + [TestMethod] + public void RandNumTest() + { + for (var i = 0; i < 10000; i++) + { + var result = _randomUtil.RandNum(0, 10, 15); + + if (result < 0 || result >= 10) Assert.Fail($"RandNum(0, 10) out of range. Expected range [0, 9.999d] but was {result}."); + + if (_randomUtil.GetNumberPrecision(result) > RandomUtil.MaxSignificantDigits) + Assert.Fail($"RandNum(0, 10) precision of {result} exceeds the allowable precision ({RandomUtil.MaxSignificantDigits}) for the given values."); + } + + for (var i = 0; i < 10000; i++) + { + var result = _randomUtil.RandNum(10); + + if (result < 0 || result >= 10) Assert.Fail($"RandNum(10) out of range. Expected range [0, 9.999d] but was {result}."); + + if (_randomUtil.GetNumberPrecision(result) > RandomUtil.MaxSignificantDigits) + Assert.Fail($"RandNum(10) precision of {result} exceeds the allowable precision ({RandomUtil.MaxSignificantDigits}) for the given values."); + } + } + + [TestMethod] + public void ShuffleTest() + { + var testList = new List() + { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 + }; + + var orig = new List(testList); + + var result = _randomUtil.Shuffle(testList); + + Assert.IsFalse( + result.SequenceEqual(orig), + $"Shuffle test failed. Expected: {string.Join(", ", orig)}, but got {string.Join(", ", result)}" + ); + } + [TestMethod] [DataRow(0.1, 1)] [DataRow(0.0001, 4)]