From 173a726f33c6abbd8b861d253d9314bff3e701cd Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 27 May 2024 20:06:07 +0000 Subject: [PATCH] Removed all null references in favor of undefined (!354) Co-authored-by: clodan Reviewed-on: https://dev.sp-tarkov.com/SPT/Server/pulls/354 Co-authored-by: Alex Co-committed-by: Alex --- project/src/callbacks/ProfileCallbacks.ts | 8 +- project/src/controllers/HideoutController.ts | 12 +- .../src/controllers/InsuranceController.ts | 6 +- .../src/controllers/InventoryController.ts | 6 +- project/src/controllers/MatchController.ts | 6 +- project/src/controllers/ProfileController.ts | 6 +- project/src/controllers/QuestController.ts | 4 +- project/src/controllers/RagfairController.ts | 8 +- .../controllers/RepeatableQuestController.ts | 4 +- project/src/controllers/WeatherController.ts | 2 +- .../generators/BotEquipmentModGenerator.ts | 14 +- project/src/generators/BotGenerator.ts | 6 +- project/src/generators/BotLootGenerator.ts | 22 +- .../generators/FenceBaseAssortGenerator.ts | 10 +- project/src/generators/LocationGenerator.ts | 4 +- project/src/generators/PlayerScavGenerator.ts | 6 +- .../src/generators/RagfairOfferGenerator.ts | 28 +-- .../generators/RepeatableQuestGenerator.ts | 12 +- .../RepeatableQuestRewardGenerator.ts | 2 +- .../ExternalInventoryMagGen.ts | 8 +- project/src/helpers/BotGeneratorHelper.ts | 2 +- project/src/helpers/BotHelper.ts | 7 +- project/src/helpers/ContainerHelper.ts | 13 +- .../ProfileCommand/ProfileSptCommand.ts | 2 +- project/src/helpers/HandbookHelper.ts | 21 +- project/src/helpers/HealthHelper.ts | 8 +- project/src/helpers/HideoutHelper.ts | 21 +- project/src/helpers/ItemHelper.ts | 66 +++--- project/src/helpers/PresetHelper.ts | 4 +- project/src/helpers/ProfileHelper.ts | 31 +-- project/src/helpers/QuestConditionHelper.ts | 10 +- project/src/helpers/QuestHelper.ts | 6 +- project/src/helpers/RagfairHelper.ts | 2 +- project/src/helpers/RagfairOfferHelper.ts | 4 +- project/src/helpers/RagfairServerHelper.ts | 14 -- project/src/helpers/TraderAssortHelper.ts | 2 +- project/src/loaders/ModLoadOrder.ts | 4 +- project/src/loaders/PreSptModLoader.ts | 2 +- .../models/eft/game/IGameModeRequestData.ts | 2 +- .../eft/httpResponse/INullResponseData.ts | 2 +- .../src/models/spt/server/ExhaustableArray.ts | 12 +- project/src/routers/EventOutputHolder.ts | 6 +- .../routers/save_load/HealthSaveLoadRouter.ts | 2 +- .../save_load/ProfileSaveLoadRouter.ts | 2 +- project/src/servers/SaveServer.ts | 15 +- project/src/servers/http/SptHttpListener.ts | 8 +- .../ws/SptWebSocketConnectionHandler.ts | 2 +- .../src/services/BotEquipmentFilterService.ts | 20 +- project/src/services/BotLootCacheService.ts | 2 +- project/src/services/FenceService.ts | 200 +++++++++--------- project/src/services/ProfileFixerService.ts | 18 +- project/src/services/RagfairOfferService.ts | 3 +- project/src/utils/HttpResponseUtil.ts | 2 +- project/src/utils/JsonUtil.ts | 12 +- project/src/utils/RagfairOfferHolder.ts | 4 +- project/src/utils/cloners/RecursiveCloner.ts | 4 +- .../utils/logging/AbstractWinstonLogger.ts | 2 +- 57 files changed, 357 insertions(+), 354 deletions(-) diff --git a/project/src/callbacks/ProfileCallbacks.ts b/project/src/callbacks/ProfileCallbacks.ts index 87dfde56..c009abfb 100644 --- a/project/src/callbacks/ProfileCallbacks.ts +++ b/project/src/callbacks/ProfileCallbacks.ts @@ -91,12 +91,12 @@ export class ProfileCallbacks if (output === "taken") { - return this.httpResponse.getBody(null, 255, "The nickname is already in use"); + return this.httpResponse.getBody(undefined, 255, "The nickname is already in use"); } if (output === "tooshort") { - return this.httpResponse.getBody(null, 1, "The nickname is too short"); + return this.httpResponse.getBody(undefined, 1, "The nickname is too short"); } return this.httpResponse.getBody({ status: 0, nicknamechangedate: this.timeUtil.getTimestamp() }); @@ -115,12 +115,12 @@ export class ProfileCallbacks if (output === "taken") { - return this.httpResponse.getBody(null, 255, "225 - "); + return this.httpResponse.getBody(undefined, 255, "225 - "); } if (output === "tooshort") { - return this.httpResponse.getBody(null, 256, "256 - "); + return this.httpResponse.getBody(undefined, 256, "256 - "); } return this.httpResponse.getBody({ status: "ok" }); diff --git a/project/src/controllers/HideoutController.ts b/project/src/controllers/HideoutController.ts index c85b350f..e0b02ecd 100644 --- a/project/src/controllers/HideoutController.ts +++ b/project/src/controllers/HideoutController.ts @@ -529,7 +529,7 @@ export class HideoutController const request: IAddItemDirectRequest = { itemWithModsToAdd: [itemToReturn], foundInRaid: !!itemToReturn.upd?.SpawnedInSession, - callback: null, + callback: undefined, useSortingTable: false, }; @@ -824,7 +824,7 @@ export class HideoutController let prodId: string; for (const [productionId, production] of productionDict) { - // Skip null production objects + // Skip undefined production objects if (!production) { continue; @@ -981,7 +981,7 @@ export class HideoutController itemsWithModsToAdd: [toolItem], foundInRaid: toolItem[0].upd?.SpawnedInSession ?? false, useSortingTable: false, - callback: null, + callback: undefined, }; this.inventoryHelper.addItemsToStash(sessionID, addToolsRequest, pmcData, output); @@ -996,7 +996,7 @@ export class HideoutController itemsWithModsToAdd: itemAndChildrenToSendToPlayer, foundInRaid: true, useSortingTable: false, - callback: null, + callback: undefined, }; this.inventoryHelper.addItemsToStash(sessionID, addItemsRequest, pmcData, output); if (output.warnings.length > 0) @@ -1118,7 +1118,7 @@ export class HideoutController const addItemsRequest: IAddItemsDirectRequest = { itemsWithModsToAdd: scavCaseRewards, foundInRaid: true, - callback: null, + callback: undefined, useSortingTable: false, }; @@ -1320,7 +1320,7 @@ export class HideoutController } // Null out production data so client gets informed when response send back - pmcData.Hideout.Production[request.recipeId] = null; + pmcData.Hideout.Production[request.recipeId] = undefined; // TODO - handle timestamp somehow? diff --git a/project/src/controllers/InsuranceController.ts b/project/src/controllers/InsuranceController.ts index 8b68dd54..99e6ba96 100644 --- a/project/src/controllers/InsuranceController.ts +++ b/project/src/controllers/InsuranceController.ts @@ -628,14 +628,14 @@ export class InsuranceController * * @param traderId The ID of the trader who insured the item. * @param insuredItem Optional. The item to roll for. Only used for logging. - * @returns true if the insured item should be removed from inventory, false otherwise, or null on error. + * @returns true if the insured item should be removed from inventory, false otherwise, or undefined on error. */ - protected rollForDelete(traderId: string, insuredItem?: Item): boolean | null + protected rollForDelete(traderId: string, insuredItem?: Item): boolean | undefined { const trader = this.traderHelper.getTraderById(traderId); if (!trader) { - return null; + return undefined; } const maxRoll = 9999; diff --git a/project/src/controllers/InventoryController.ts b/project/src/controllers/InventoryController.ts index 3a2e7d9a..b51fabc3 100644 --- a/project/src/controllers/InventoryController.ts +++ b/project/src/controllers/InventoryController.ts @@ -345,7 +345,7 @@ export class InventoryController const sourceItem = inventoryItems.from.find((item) => item._id === body.item); const destinationItem = inventoryItems.to.find((item) => item._id === body.with); - if (sourceItem === null) + if (!sourceItem) { const errorMessage = `Unable to transfer stack, cannot find source: ${body.item}`; this.logger.error(errorMessage); @@ -355,7 +355,7 @@ export class InventoryController return output; } - if (destinationItem === null) + if (!destinationItem) { const errorMessage = `Unable to transfer stack, cannot find destination: ${body.with} `; this.logger.error(errorMessage); @@ -939,7 +939,7 @@ export class InventoryController const addItemsRequest: IAddItemsDirectRequest = { itemsWithModsToAdd: rewards, foundInRaid: foundInRaid, - callback: null, + callback: undefined, useSortingTable: true, }; this.inventoryHelper.addItemsToStash(sessionID, addItemsRequest, pmcData, output); diff --git a/project/src/controllers/MatchController.ts b/project/src/controllers/MatchController.ts index 9040fbc5..98e6ec13 100644 --- a/project/src/controllers/MatchController.ts +++ b/project/src/controllers/MatchController.ts @@ -92,9 +92,9 @@ export class MatchController location: "TODO get location", raidMode: "Online", mode: "deathmatch", - shortId: null, + shortId: undefined, // eslint-disable-next-line @typescript-eslint/naming-convention - additional_info: null, + additional_info: undefined, }); return output; @@ -268,7 +268,7 @@ export class MatchController */ protected extractWasViaCar(extractName: string): boolean { - // exit name is null on death + // exit name is undefined on death if (!extractName) { return false; diff --git a/project/src/controllers/ProfileController.ts b/project/src/controllers/ProfileController.ts index 8d783c00..a8614d4a 100644 --- a/project/src/controllers/ProfileController.ts +++ b/project/src/controllers/ProfileController.ts @@ -167,7 +167,7 @@ export class ProfileController pmcData.Inventory.items = this.itemHelper.replaceIDs( pmcData.Inventory.items, pmcData, - null, + undefined, pmcData.Inventory.fastPanel, ); pmcData.Inventory.hideoutAreaStashes = {}; @@ -419,10 +419,10 @@ export class ProfileController const response: GetProfileStatusResponseData = { maxPveCountExceeded: false, profiles: [ - { profileid: account.scavId, profileToken: null, status: "Free", sid: "", ip: "", port: 0 }, + { profileid: account.scavId, profileToken: undefined, status: "Free", sid: "", ip: "", port: 0 }, { profileid: account.id, - profileToken: null, + profileToken: undefined, status: "Free", sid: "", ip: "", diff --git a/project/src/controllers/QuestController.ts b/project/src/controllers/QuestController.ts index 1acbc848..886189a3 100644 --- a/project/src/controllers/QuestController.ts +++ b/project/src/controllers/QuestController.ts @@ -602,7 +602,7 @@ export class QuestController protected getQuestsWithDifferentStatuses( preQuestStatusus: IQuestStatus[], postQuestStatuses: IQuestStatus[], - ): IQuestStatus[] + ): IQuestStatus[] | undefined { const result: IQuestStatus[] = []; @@ -618,7 +618,7 @@ export class QuestController if (result.length === 0) { - return null; + return undefined; } return result; diff --git a/project/src/controllers/RagfairController.ts b/project/src/controllers/RagfairController.ts index e81da26a..3246ec43 100644 --- a/project/src/controllers/RagfairController.ts +++ b/project/src/controllers/RagfairController.ts @@ -620,10 +620,10 @@ export class RagfairController protected getItemsToListOnFleaFromInventory( pmcData: IPmcData, itemIdsFromFleaOfferRequest: string[], - ): { items: Item[] | null, errorMessage: string | null } + ): { items: Item[] | undefined, errorMessage: string | undefined } { const itemsToReturn = []; - let errorMessage: string | null = null; + let errorMessage: string | undefined = undefined; // Count how many items are being sold and multiply the requested amount accordingly for (const itemId of itemIdsFromFleaOfferRequest) @@ -636,7 +636,7 @@ export class RagfairController }); this.logger.error(errorMessage); - return { items: null, errorMessage }; + return { items: undefined, errorMessage }; } item = this.itemHelper.fixItemStackCount(item); @@ -648,7 +648,7 @@ export class RagfairController errorMessage = this.localisationService.getText("ragfair-unable_to_find_requested_items_in_inventory"); this.logger.error(errorMessage); - return { items: null, errorMessage }; + return { items: undefined, errorMessage }; } return { items: itemsToReturn, errorMessage }; diff --git a/project/src/controllers/RepeatableQuestController.ts b/project/src/controllers/RepeatableQuestController.ts index 77c36adb..6af55cdc 100644 --- a/project/src/controllers/RepeatableQuestController.ts +++ b/project/src/controllers/RepeatableQuestController.ts @@ -147,7 +147,7 @@ export class RepeatableQuestController // Add daily quests for (let i = 0; i < this.getQuestCount(repeatableConfig, pmcData); i++) { - let quest = null; + let quest: IRepeatableQuest | undefined = undefined; let lifeline = 0; while (!quest && questTypePool.types.length > 0) { @@ -535,7 +535,7 @@ export class RepeatableQuestController repeatableConfig: IRepeatableQuestConfig, ): IRepeatableQuest { - let newRepeatableQuest: IRepeatableQuest = null; + let newRepeatableQuest: IRepeatableQuest = undefined; let attemptsToGenerateQuest = 0; while (!newRepeatableQuest && questTypePool.types.length > 0) { diff --git a/project/src/controllers/WeatherController.ts b/project/src/controllers/WeatherController.ts index 91c92ec2..2acae6e4 100644 --- a/project/src/controllers/WeatherController.ts +++ b/project/src/controllers/WeatherController.ts @@ -23,7 +23,7 @@ export class WeatherController /** Handle client/weather */ public generate(): IWeatherData { - let result: IWeatherData = { acceleration: 0, time: "", date: "", weather: null, season: 1 }; // defaults, hydrated below + let result: IWeatherData = { acceleration: 0, time: "", date: "", weather: undefined, season: 1 }; // defaults, hydrated below result = this.weatherGenerator.calculateGameTime(result); result.weather = this.weatherGenerator.generateWeather(); diff --git a/project/src/generators/BotEquipmentModGenerator.ts b/project/src/generators/BotEquipmentModGenerator.ts index 6dfd0f21..b4263864 100644 --- a/project/src/generators/BotEquipmentModGenerator.ts +++ b/project/src/generators/BotEquipmentModGenerator.ts @@ -223,7 +223,7 @@ export class BotEquipmentModGenerator armorItem: ITemplateItem, ): IFilterPlateModsForSlotByLevelResult { - const result: IFilterPlateModsForSlotByLevelResult = { result: Result.UNKNOWN_FAILURE, plateModTpls: null }; + const result: IFilterPlateModsForSlotByLevelResult = { result: Result.UNKNOWN_FAILURE, plateModTpls: undefined }; // Not pmc or not a plate slot, return original mod pool array if (!this.itemHelper.isRemovablePlateSlot(modSlot)) @@ -796,7 +796,7 @@ export class BotEquipmentModGenerator { // Nothing in mod pool + item not required this.logger.debug(`Mod pool for slot: ${request.modSlot} on item: ${request.parentTemplate._name} was empty, skipping mod`); - return null; + return undefined; } // Filter out non-whitelisted scopes, use full modpool if filtered pool would have no elements @@ -844,7 +844,7 @@ export class BotEquipmentModGenerator if (chosenModResult.slotBlocked && !parentSlot._required) { // Don't bother trying to fit mod, slot is completely blocked - return null; + return undefined; } // Log if mod chosen was incompatible @@ -864,7 +864,7 @@ export class BotEquipmentModGenerator // Compatible item not found + not required if (!chosenModResult.found && parentSlot !== undefined && !parentSlot._required) { - return null; + return undefined; } if (!chosenModResult.found && parentSlot !== undefined) @@ -876,7 +876,7 @@ export class BotEquipmentModGenerator ); } - return null; + return undefined; } return this.itemHelper.getItem(chosenModResult.chosenTpl); @@ -1141,7 +1141,7 @@ export class BotEquipmentModGenerator } // No mod found - return null; + return undefined; } /** @@ -1336,7 +1336,7 @@ export class BotEquipmentModGenerator itemModPool = modPool[parentTemplate._id]; } - let exhaustableModPool = null; + let exhaustableModPool = undefined; let modSlot = "cartridges"; const camoraFirstSlot = "camora_000"; if (modSlot in itemModPool) diff --git a/project/src/generators/BotGenerator.ts b/project/src/generators/BotGenerator.ts index 83e3f419..38e83128 100644 --- a/project/src/generators/BotGenerator.ts +++ b/project/src/generators/BotGenerator.ts @@ -176,7 +176,7 @@ export class BotGenerator // Remove hideout data if bot is not a PMC or pscav if (!(botGenerationDetails.isPmc || botGenerationDetails.isPlayerScav)) { - bot.Hideout = null; + bot.Hideout = undefined; } bot.Info.Experience = botLevel.exp; @@ -436,7 +436,7 @@ export class BotGenerator const skill = skills[skillKey]; if (!skill) { - return null; + return undefined; } // All skills have id and progress props @@ -451,7 +451,7 @@ export class BotGenerator return skillToAdd; }) - .filter((x) => x !== null); + .filter((x) => x !== undefined); } /** diff --git a/project/src/generators/BotLootGenerator.ts b/project/src/generators/BotLootGenerator.ts index 44fb6c46..a067d4e6 100644 --- a/project/src/generators/BotLootGenerator.ts +++ b/project/src/generators/BotLootGenerator.ts @@ -170,7 +170,7 @@ export class BotLootGenerator healingItemCount, botInventory, botRole, - null, + undefined, 0, isPmc, containersIdFull, @@ -183,7 +183,7 @@ export class BotLootGenerator drugItemCount, botInventory, botRole, - null, + undefined, 0, isPmc, containersIdFull, @@ -196,7 +196,7 @@ export class BotLootGenerator foodItemCount, botInventory, botRole, - null, + undefined, 0, isPmc, containersIdFull, @@ -209,7 +209,7 @@ export class BotLootGenerator drinkItemCount, botInventory, botRole, - null, + undefined, 0, isPmc, containersIdFull, @@ -222,7 +222,7 @@ export class BotLootGenerator currencyItemCount, botInventory, botRole, - null, + undefined, 0, isPmc, containersIdFull, @@ -248,7 +248,7 @@ export class BotLootGenerator grenadeCount, botInventory, botRole, - null, + undefined, 0, isPmc, containersIdFull, @@ -327,7 +327,7 @@ export class BotLootGenerator 50, botInventory, botRole, - null, + undefined, -1, isPmc, containersIdFull, @@ -372,7 +372,7 @@ export class BotLootGenerator 1, botInventory, botRole, - null, + undefined, 0, true, ); @@ -385,7 +385,7 @@ export class BotLootGenerator 10, botInventory, botRole, - null, + undefined, 0, true, ); @@ -421,7 +421,7 @@ export class BotLootGenerator totalItemCount: number, inventoryToAddItemsTo: PmcInventory, botRole: string, - itemSpawnLimits: IItemSpawnLimitSettings = null, + itemSpawnLimits: IItemSpawnLimitSettings = undefined, totalValueLimitRub = 0, isPmc = false, containersIdFull = new Set(), @@ -628,7 +628,7 @@ export class BotLootGenerator // Must add soft inserts/plates else if (this.itemHelper.itemRequiresSoftInserts(itemToAddTemplate._id)) { - this.itemHelper.addChildSlotItems(itemToAddChildrenTo, itemToAddTemplate, null, false); + this.itemHelper.addChildSlotItems(itemToAddChildrenTo, itemToAddTemplate, undefined, false); } } diff --git a/project/src/generators/FenceBaseAssortGenerator.ts b/project/src/generators/FenceBaseAssortGenerator.ts index 3694cce8..55f0366e 100644 --- a/project/src/generators/FenceBaseAssortGenerator.ts +++ b/project/src/generators/FenceBaseAssortGenerator.ts @@ -199,7 +199,7 @@ export class FenceBaseAssortGenerator protected isAmmoAbovePenetrationLimit(rootItemDb: ITemplateItem): boolean { const ammoPenetrationPower = this.getAmmoPenetrationPower(rootItemDb); - if (ammoPenetrationPower === null) + if (ammoPenetrationPower === undefined) { this.logger.warning(this.localisationService.getText("fence-unable_to_get_ammo_penetration_value", rootItemDb._id)); @@ -212,9 +212,9 @@ export class FenceBaseAssortGenerator /** * Get the penetration power value of an ammo, works with ammo boxes and raw ammos * @param rootItemDb Ammo box or ammo item from items.db - * @returns Penetration power of passed in item, null if it doesnt have a power + * @returns Penetration power of passed in item, undefined if it doesnt have a power */ - protected getAmmoPenetrationPower(rootItemDb: ITemplateItem): number + protected getAmmoPenetrationPower(rootItemDb: ITemplateItem): number | undefined { if (this.itemHelper.isOfBaseclass(rootItemDb._id, BaseClasses.AMMO_BOX)) { @@ -227,7 +227,7 @@ export class FenceBaseAssortGenerator { this.logger.warning(this.localisationService.getText("fence-ammo_not_found_in_db", cartridgeTplInBox)); - return null; + return undefined; } return ammoItemDb[1]._props.PenetrationPower; @@ -240,7 +240,7 @@ export class FenceBaseAssortGenerator } // Not an ammobox or ammo - return null; + return undefined; } /** diff --git a/project/src/generators/LocationGenerator.ts b/project/src/generators/LocationGenerator.ts index 3fd02451..d3b52991 100644 --- a/project/src/generators/LocationGenerator.ts +++ b/project/src/generators/LocationGenerator.ts @@ -896,7 +896,7 @@ export class LocationGenerator magazineItem, itemTemplate, // Magazine template staticAmmoDist, - null, + undefined, this.locationConfig.minFillLooseMagazinePercent / 100, ); } @@ -1108,7 +1108,7 @@ export class LocationGenerator magazineWithCartridges, itemTemplate, staticAmmoDist, - null, + undefined, this.locationConfig.minFillStaticMagazinePercent / 100, ); diff --git a/project/src/generators/PlayerScavGenerator.ts b/project/src/generators/PlayerScavGenerator.ts index 1e9cf1d5..5ee88aff 100644 --- a/project/src/generators/PlayerScavGenerator.ts +++ b/project/src/generators/PlayerScavGenerator.ts @@ -90,7 +90,7 @@ export class PlayerScavGenerator this.botLootCacheService.clearCache(); // Add scav metadata - scavData.savage = null; + scavData.savage = undefined; scavData.aid = pmcDataClone.aid; scavData.TradersInfo = pmcDataClone.TradersInfo; scavData.Info.Settings = {} as Settings; @@ -311,7 +311,7 @@ export class PlayerScavGenerator protected getScavLevel(scavProfile: IPmcData): number { - // Info can be null on initial account creation + // Info can be undefined on initial account creation if (!scavProfile.Info?.Level) { return 1; @@ -322,7 +322,7 @@ export class PlayerScavGenerator protected getScavExperience(scavProfile: IPmcData): number { - // Info can be null on initial account creation + // Info can be undefined on initial account creation if (!scavProfile.Info?.Experience) { return 0; diff --git a/project/src/generators/RagfairOfferGenerator.ts b/project/src/generators/RagfairOfferGenerator.ts index d3a2b39d..31d8c349 100644 --- a/project/src/generators/RagfairOfferGenerator.ts +++ b/project/src/generators/RagfairOfferGenerator.ts @@ -185,17 +185,17 @@ export class RagfairOfferGenerator }; } - const isPlayerOffer = this.ragfairServerHelper.isPlayer(userID); + const isPlayerOffer = this.profileHelper.isPlayer(userID); if (isPlayerOffer) { - const playerProfile = this.profileHelper.getPmcProfile(userID); + const playerProfile = this.profileHelper.getPmcProfile(userID)!; return { id: playerProfile._id, memberType: MemberCategory.DEFAULT, nickname: playerProfile.Info.Nickname, rating: playerProfile.RagfairInfo.rating, isRatingGrowing: playerProfile.RagfairInfo.isRatingGrowing, - avatar: null, + avatar: undefined, aid: playerProfile.aid, }; } @@ -209,7 +209,7 @@ export class RagfairOfferGenerator this.ragfairConfig.dynamic.rating.min, this.ragfairConfig.dynamic.rating.max), isRatingGrowing: this.randomUtil.getBool(), - avatar: null, + avatar: undefined, aid: this.hashUtil.generateAccountId(), }; } @@ -271,7 +271,7 @@ export class RagfairOfferGenerator */ protected getTraderId(userId: string): string { - if (this.ragfairServerHelper.isPlayer(userId)) + if (this.profileHelper.isPlayer(userId)) { return this.saveServer.getProfile(userId).characters.pmc._id; } @@ -286,7 +286,7 @@ export class RagfairOfferGenerator */ protected getRating(userId: string): number { - if (this.ragfairServerHelper.isPlayer(userId)) + if (this.profileHelper.isPlayer(userId)) { // Player offer return this.saveServer.getProfile(userId).characters.pmc.RagfairInfo.rating; @@ -309,7 +309,7 @@ export class RagfairOfferGenerator */ protected getRatingGrowing(userID: string): boolean { - if (this.ragfairServerHelper.isPlayer(userID)) + if (this.profileHelper.isPlayer(userID)) { // player offer return this.saveServer.getProfile(userID).characters.pmc.RagfairInfo.isRatingGrowing; @@ -334,18 +334,18 @@ export class RagfairOfferGenerator */ protected getOfferEndTime(userID: string, time: number): number { - if (this.ragfairServerHelper.isPlayer(userID)) + if (this.profileHelper.isPlayer(userID)) { // Player offer = current time + offerDurationTimeInHour; const offerDurationTimeHours - = this.databaseServer.getTables().globals.config.RagFair.offerDurationTimeInHour; + = this.databaseServer.getTables().globals!.config.RagFair.offerDurationTimeInHour; return this.timeUtil.getTimestamp() + Math.round(offerDurationTimeHours * TimeUtil.ONE_HOUR_AS_SECONDS); } if (this.ragfairServerHelper.isTrader(userID)) { // Trader offer - return this.databaseServer.getTables().traders[userID].base.nextResupply; + return this.databaseServer.getTables().traders![userID].base.nextResupply; } // Generated fake-player offer @@ -362,14 +362,14 @@ export class RagfairOfferGenerator * Create multiple offers for items by using a unique list of items we've generated previously * @param expiredOffers optional, expired offers to regenerate */ - public async generateDynamicOffers(expiredOffers: Item[][] = null): Promise + public async generateDynamicOffers(expiredOffers?: Item[][]): Promise { - const replacingExpiredOffers = expiredOffers?.length > 0; + const replacingExpiredOffers = (expiredOffers?.length ?? 0) > 0; const config = this.ragfairConfig.dynamic; // get assort items from param if they exist, otherwise grab freshly generated assorts const assortItemsToProcess: Item[][] = replacingExpiredOffers - ? expiredOffers + ? expiredOffers! : this.ragfairAssortGenerator.getAssortItems(); // Store all functions to create an offer for every item and pass into Promise.all to run async @@ -658,7 +658,7 @@ export class RagfairOfferGenerator // Add any missing properties to first item in array this.addMissingConditions(itemWithMods[0]); - if (!(this.ragfairServerHelper.isPlayer(userID) || this.ragfairServerHelper.isTrader(userID))) + if (!(this.profileHelper.isPlayer(userID) || this.ragfairServerHelper.isTrader(userID))) { const parentId = this.getDynamicConditionIdForTpl(itemDetails._id); if (!parentId) diff --git a/project/src/generators/RepeatableQuestGenerator.ts b/project/src/generators/RepeatableQuestGenerator.ts index f8e52af5..26539823 100644 --- a/project/src/generators/RepeatableQuestGenerator.ts +++ b/project/src/generators/RepeatableQuestGenerator.ts @@ -153,7 +153,7 @@ export class RepeatableQuestGenerator dist: number, kill: number, weaponRequirement: number, - ): number + ): number | undefined { return Math.sqrt(Math.sqrt(target) + bodyPart + dist + weaponRequirement) * kill; } @@ -167,7 +167,7 @@ export class RepeatableQuestGenerator // also if only bosses are left we need to leave otherwise it's a guaranteed boss elimination // -> then it would not be a quest with low probability anymore questTypePool.types = questTypePool.types.filter((t) => t !== "Elimination"); - return null; + return undefined; } const targetKey = targetsConfig.draw()[0]; @@ -208,7 +208,7 @@ export class RepeatableQuestGenerator } // draw the target body part and calculate the difficulty factor - let bodyPartsToClient = null; + let bodyPartsToClient = undefined; let bodyPartDifficulty = 0; if (eliminationConfig.bodyPartProb > Math.random()) { @@ -231,7 +231,7 @@ export class RepeatableQuestGenerator } // Draw a distance condition - let distance = null; + let distance = undefined; let distanceDifficulty = 0; let isDistanceRequirementAllowed = !eliminationConfig.distLocationBlacklist.includes(locationKey); @@ -555,7 +555,7 @@ export class RepeatableQuestGenerator ), ); - return null; + return undefined; } // Draw items to ask player to retrieve @@ -698,7 +698,7 @@ export class RepeatableQuestGenerator { // there are no more locations left for exploration; delete it as a possible quest type questTypePool.types = questTypePool.types.filter((t) => t !== "Exploration"); - return null; + return undefined; } // If location drawn is factory, it's possible to either get factory4_day and factory4_night or only one diff --git a/project/src/generators/RepeatableQuestRewardGenerator.ts b/project/src/generators/RepeatableQuestRewardGenerator.ts index bf2667b9..965dd888 100644 --- a/project/src/generators/RepeatableQuestRewardGenerator.ts +++ b/project/src/generators/RepeatableQuestRewardGenerator.ts @@ -391,7 +391,7 @@ export class RepeatableQuestRewardGenerator * @param {integer} index All rewards will be appended to a list, for unknown reasons the client wants the index * @returns {object} Object of "Reward"-item-type */ - protected generateRewardItem(tpl: string, value: number, index: number, preset: Item[] = null): IQuestReward + protected generateRewardItem(tpl: string, value: number, index: number, preset?: Item[]): IQuestReward { const id = this.objectId.generate(); const rewardItem: IQuestReward = { target: id, value: value, type: QuestRewardType.ITEM, index: index }; diff --git a/project/src/generators/weapongen/implementations/ExternalInventoryMagGen.ts b/project/src/generators/weapongen/implementations/ExternalInventoryMagGen.ts index 0579bd7b..33938190 100644 --- a/project/src/generators/weapongen/implementations/ExternalInventoryMagGen.ts +++ b/project/src/generators/weapongen/implementations/ExternalInventoryMagGen.ts @@ -150,13 +150,13 @@ export class ExternalInventoryMagGen implements IInventoryMagGen protected getRandomExternalMagazineForInternalMagazineGun( weaponTpl: string, magazineBlacklist: string[], - ): ITemplateItem + ): ITemplateItem | undefined { // The mag Slot data for the weapon const magSlot = this.itemHelper.getItem(weaponTpl)[1]._props.Slots.find((x) => x._name === "mod_magazine"); if (!magSlot) { - return null; + return undefined; } // All possible mags that fit into the weapon excluding blacklisted @@ -165,14 +165,14 @@ export class ExternalInventoryMagGen implements IInventoryMagGen ); if (!magazinePool) { - return null; + return undefined; } // Non-internal magazines that fit into the weapon const externalMagazineOnlyPool = magazinePool.filter((x) => x._props.ReloadMagType !== "InternalMagazine"); if (!externalMagazineOnlyPool || externalMagazineOnlyPool?.length === 0) { - return null; + return undefined; } // Randomly chosen external magazine diff --git a/project/src/helpers/BotGeneratorHelper.ts b/project/src/helpers/BotGeneratorHelper.ts index f0238bf2..f819d881 100644 --- a/project/src/helpers/BotGeneratorHelper.ts +++ b/project/src/helpers/BotGeneratorHelper.ts @@ -194,7 +194,7 @@ export class BotGeneratorHelper * Get the chance for the weapon attachment or helmet equipment to be set as activated * @param botRole role of bot with weapon/helmet * @param setting the setting of the weapon attachment/helmet equipment to be activated - * @param defaultValue default value for the chance of activation if the botrole or bot equipment role is null + * @param defaultValue default value for the chance of activation if the botrole or bot equipment role is undefined * @returns Percent chance to be active */ protected getBotEquipmentSettingFromConfig( diff --git a/project/src/helpers/BotHelper.ts b/project/src/helpers/BotHelper.ts index 23d62a14..7699e54e 100644 --- a/project/src/helpers/BotHelper.ts +++ b/project/src/helpers/BotHelper.ts @@ -152,12 +152,15 @@ export class BotHelper * @param botEquipConfig bot equipment json * @returns RandomisationDetails */ - public getBotRandomizationDetails(botLevel: number, botEquipConfig: EquipmentFilters): RandomisationDetails + public getBotRandomizationDetails( + botLevel: number, + botEquipConfig: EquipmentFilters, + ): RandomisationDetails | undefined { // No randomisation details found, skip if (!botEquipConfig || Object.keys(botEquipConfig).length === 0 || !botEquipConfig.randomisation) { - return null; + return undefined; } return botEquipConfig.randomisation.find((x) => botLevel >= x.levelRange.min && botLevel <= x.levelRange.max); diff --git a/project/src/helpers/ContainerHelper.ts b/project/src/helpers/ContainerHelper.ts index cb32052b..9c3889c5 100644 --- a/project/src/helpers/ContainerHelper.ts +++ b/project/src/helpers/ContainerHelper.ts @@ -2,17 +2,8 @@ import { injectable } from "tsyringe"; export class FindSlotResult { - success: boolean; - x: any; - y: any; - rotation: boolean; - constructor(success = false, x = null, y = null, rotation = false) - { - this.success = success; - this.x = x; - this.y = y; - this.rotation = rotation; - } + constructor(public success = false, public x?: number, public y?: number, public rotation = false) + {} } @injectable() diff --git a/project/src/helpers/Dialogue/Commando/SptCommands/ProfileCommand/ProfileSptCommand.ts b/project/src/helpers/Dialogue/Commando/SptCommands/ProfileCommand/ProfileSptCommand.ts index ba572716..25a708e2 100644 --- a/project/src/helpers/Dialogue/Commando/SptCommands/ProfileCommand/ProfileSptCommand.ts +++ b/project/src/helpers/Dialogue/Commando/SptCommands/ProfileCommand/ProfileSptCommand.ts @@ -155,7 +155,7 @@ export class ProfileSptCommand implements ISptCommand _id: this.hashUtil.generate(), Type: ProfileChangeEventType.PROFILE_LEVEL, value: exp, - entity: null, + entity: undefined, }; return event; } diff --git a/project/src/helpers/HandbookHelper.ts b/project/src/helpers/HandbookHelper.ts index 082cbabe..05abdd77 100644 --- a/project/src/helpers/HandbookHelper.ts +++ b/project/src/helpers/HandbookHelper.ts @@ -56,25 +56,28 @@ export class HandbookHelper // Add handbook overrides found in items.json config into db for (const itemTpl in this.itemConfig.handbookPriceOverride) { - let itemToUpdate = this.databaseServer - .getTables() - .templates.handbook.Items.find((item) => item.Id === itemTpl); + let itemToUpdate = this.databaseServer.getTables() + .templates! + .handbook + .Items.find((item) => item.Id === itemTpl); if (!itemToUpdate) { - this.databaseServer.getTables().templates.handbook.Items.push({ + this.databaseServer.getTables().templates!.handbook.Items.push({ Id: itemTpl, - ParentId: this.databaseServer.getTables().templates.items[itemTpl]._parent, + ParentId: this.databaseServer.getTables().templates!.items[itemTpl]._parent, Price: this.itemConfig.handbookPriceOverride[itemTpl], }); itemToUpdate = this.databaseServer .getTables() - .templates.handbook.Items.find((item) => item.Id === itemTpl); + .templates! + .handbook + .Items.find((item) => item.Id === itemTpl); } itemToUpdate.Price = this.itemConfig.handbookPriceOverride[itemTpl]; } - const handbookDbClone = this.cloner.clone(this.databaseServer.getTables().templates.handbook); + const handbookDbClone = this.cloner.clone(this.databaseServer.getTables().templates!.handbook); for (const handbookItem of handbookDbClone.Items) { this.handbookPriceCache.items.byId.set(handbookItem.Id, handbookItem.Price); @@ -87,7 +90,7 @@ export class HandbookHelper for (const handbookCategory of handbookDbClone.Categories) { - this.handbookPriceCache.categories.byId.set(handbookCategory.Id, handbookCategory.ParentId || null); + this.handbookPriceCache.categories.byId.set(handbookCategory.Id, handbookCategory.ParentId || undefined); if (handbookCategory.ParentId) { if (!this.handbookPriceCache.categories.byParent.has(handbookCategory.ParentId)) @@ -118,7 +121,7 @@ export class HandbookHelper return this.handbookPriceCache.items.byId.get(tpl); } - const handbookItem = this.databaseServer.getTables().templates.handbook.Items.find((x) => x.Id === tpl); + const handbookItem = this.databaseServer.getTables().templates!.handbook.Items.find((x) => x.Id === tpl); if (!handbookItem) { const newValue = 0; diff --git a/project/src/helpers/HealthHelper.ts b/project/src/helpers/HealthHelper.ts index 91a40e7c..3e7a8b32 100644 --- a/project/src/helpers/HealthHelper.ts +++ b/project/src/helpers/HealthHelper.ts @@ -38,7 +38,7 @@ export class HealthHelper if (!profile.vitality) { // Occurs on newly created profiles - profile.vitality = { health: null, effects: null }; + profile.vitality = { health: undefined!, effects: undefined! }; } profile.vitality.health = { Hydration: 0, @@ -87,9 +87,9 @@ export class HealthHelper const profileHealth = profile.vitality.health; const profileEffects = profile.vitality.effects; - profileHealth.Hydration = request.Hydration; - profileHealth.Energy = request.Energy; - profileHealth.Temperature = request.Temperature; + profileHealth.Hydration = request.Hydration!; + profileHealth.Energy = request.Energy!; + profileHealth.Temperature = request.Temperature!; // Transfer properties from request to profile for (const bodyPart in postRaidBodyParts) diff --git a/project/src/helpers/HideoutHelper.ts b/project/src/helpers/HideoutHelper.ts index 2544ca59..7cde0d51 100644 --- a/project/src/helpers/HideoutHelper.ts +++ b/project/src/helpers/HideoutHelper.ts @@ -266,13 +266,13 @@ export class HideoutHelper const craft = pmcData.Hideout.Production[prodId]; if (!craft) { - // Craft value is null, get rid of it (could be from cancelling craft that needs cleaning up) + // Craft value is undefined, get rid of it (could be from cancelling craft that needs cleaning up) delete pmcData.Hideout.Production[prodId]; continue; } - if (craft.Progress === undefined || craft.Progress === null) + if (craft.Progress === undefined) { this.logger.warning(this.localisationService.getText("hideout-craft_has_undefined_progress_value_defaulting", prodId)); craft.Progress = 0; @@ -692,7 +692,7 @@ export class HideoutHelper // How many units of filter are left let resourceValue = waterFilterItemInSlot.upd?.Resource ? waterFilterItemInSlot.upd.Resource.Value - : null; + : undefined; if (!resourceValue) { // Missing, is new filter, add default and subtract usage @@ -853,7 +853,7 @@ export class HideoutHelper { let resourceValue = airFilterArea.slots[i].item[0].upd?.Resource ? airFilterArea.slots[i].item[0].upd.Resource.Value - : null; + : undefined; if (!resourceValue) { resourceValue = 300 - filterDrainRate; @@ -891,12 +891,13 @@ export class HideoutHelper } } - protected updateBitcoinFarm(pmcData: IPmcData, btcFarmCGs: number, isGeneratorOn: boolean): Production + protected updateBitcoinFarm(pmcData: IPmcData, btcFarmCGs: number, isGeneratorOn: boolean): Production | undefined { const btcProd = pmcData.Hideout.Production[HideoutHelper.bitcoinFarm]; const bitcoinProdData = this.databaseServer .getTables() - .hideout.production.find((production) => production._id === HideoutHelper.bitcoinProductionId); + .hideout! + .production.find((production) => production._id === HideoutHelper.bitcoinProductionId); const coinSlotCount = this.getBTCSlots(pmcData); // Full on bitcoins, halt progress @@ -973,7 +974,7 @@ export class HideoutHelper return btcProd; } - return null; + return undefined; } /** @@ -1003,7 +1004,7 @@ export class HideoutHelper protected getTimeElapsedSinceLastServerTick( pmcData: IPmcData, isGeneratorOn: boolean, - recipe: IHideoutProduction = null, + recipe?: IHideoutProduction, ): number { // Reduce time elapsed (and progress) when generator is off @@ -1017,7 +1018,7 @@ export class HideoutHelper if (!isGeneratorOn) { - timeElapsed *= this.databaseServer.getTables().hideout.settings.generatorSpeedWithoutFuel; + timeElapsed *= this.databaseServer.getTables().hideout!.settings.generatorSpeedWithoutFuel; } return timeElapsed; @@ -1169,7 +1170,7 @@ export class HideoutHelper itemsWithModsToAdd: itemsToAdd, foundInRaid: true, useSortingTable: false, - callback: null, + callback: undefined, }; // Add FiR coins to player inventory diff --git a/project/src/helpers/ItemHelper.ts b/project/src/helpers/ItemHelper.ts index b4cd7c5b..af9d0a73 100644 --- a/project/src/helpers/ItemHelper.ts +++ b/project/src/helpers/ItemHelper.ts @@ -184,7 +184,7 @@ export class ItemHelper * @param {string} tpl the template id / tpl * @returns boolean; true for items that may be in player possession and not quest items */ - public isValidItem(tpl: string, invalidBaseTypes: string[] = null): boolean + public isValidItem(tpl: string, invalidBaseTypes?: string[]): boolean { const baseTypes = invalidBaseTypes || this.defaultInvalidBaseTypes; const itemDetails = this.getItem(tpl); @@ -496,12 +496,12 @@ export class ItemHelper if (item.upd) { - const medkit = item.upd.MedKit ? item.upd.MedKit : null; - const repairable = item.upd.Repairable ? item.upd.Repairable : null; - const foodDrink = item.upd.FoodDrink ? item.upd.FoodDrink : null; - const key = item.upd.Key ? item.upd.Key : null; - const resource = item.upd.Resource ? item.upd.Resource : null; - const repairKit = item.upd.RepairKit ? item.upd.RepairKit : null; + const medkit = item.upd.MedKit ? item.upd.MedKit : undefined; + const repairable = item.upd.Repairable ? item.upd.Repairable : undefined; + const foodDrink = item.upd.FoodDrink ? item.upd.FoodDrink : undefined; + const key = item.upd.Key ? item.upd.Key : undefined; + const resource = item.upd.Resource ? item.upd.Resource : undefined; + const repairKit = item.upd.RepairKit ? item.upd.RepairKit : undefined; const itemDetails = this.getItem(item._tpl)[1]; @@ -725,7 +725,7 @@ export class ItemHelper */ public splitStack(itemToSplit: Item): Item[] { - if (!(itemToSplit?.upd?.StackObjectsCount != null)) + if (itemToSplit?.upd?.StackObjectsCount === undefined) { return [itemToSplit]; } @@ -834,9 +834,9 @@ export class ItemHelper */ public replaceIDs( originalItems: Item[], - pmcData: IPmcData | null = null, - insuredItems: InsuredItem[] | null = null, - fastPanel = null, + pmcData?: IPmcData, + insuredItems?: InsuredItem[], + fastPanel?: any, ): Item[] { let items = this.cloner.clone(originalItems); // Deep-clone the items to avoid mutation. @@ -844,7 +844,7 @@ export class ItemHelper for (const item of items) { - if (pmcData !== null) + if (pmcData) { // Insured items should not be renamed. Only works for PMCs. if (insuredItems?.find((insuredItem) => insuredItem.itemId === item._id)) @@ -871,7 +871,7 @@ export class ItemHelper serialisedInventory = serialisedInventory.replace(new RegExp(oldId, "g"), newId); // Also replace in quick slot if the old ID exists. - if (fastPanel !== null) + if (fastPanel) { for (const itemSlot in fastPanel) { @@ -1031,14 +1031,14 @@ export class ItemHelper * * @param item The item to be checked * @param parent The parent of the item to be checked - * @returns True if the item is actually moddable, false if it is not, and null if the check cannot be performed. + * @returns True if the item is actually moddable, false if it is not, and undefined if the check cannot be performed. */ - public isRaidModdable(item: Item, parent: Item): boolean | null + public isRaidModdable(item: Item, parent: Item): boolean | undefined { // This check requires the item to have the slotId property populated. if (!item.slotId) { - return null; + return undefined; } const itemTemplate = this.getItem(item._tpl); @@ -1077,9 +1077,9 @@ export class ItemHelper * * @param itemId - The unique identifier of the item for which to find the main parent. * @param itemsMap - A Map containing item IDs mapped to their corresponding Item objects for quick lookup. - * @returns The Item object representing the top-most parent of the given item, or `null` if no such parent exists. + * @returns The Item object representing the top-most parent of the given item, or `undefined` if no such parent exists. */ - public getAttachmentMainParent(itemId: string, itemsMap: Map): Item | null + public getAttachmentMainParent(itemId: string, itemsMap: Map): Item | undefined { let currentItem = itemsMap.get(itemId); while (currentItem && this.isAttachmentAttached(currentItem)) @@ -1087,7 +1087,7 @@ export class ItemHelper currentItem = itemsMap.get(currentItem.parentId); if (!currentItem) { - return null; + return undefined; } } return currentItem; @@ -1123,9 +1123,9 @@ export class ItemHelper * * @param itemId - The unique identifier of the item for which to find the equipment parent. * @param itemsMap - A Map containing item IDs mapped to their corresponding Item objects for quick lookup. - * @returns The Item object representing the equipment parent of the given item, or `null` if no such parent exists. + * @returns The Item object representing the equipment parent of the given item, or `undefined` if no such parent exists. */ - public getEquipmentParent(itemId: string, itemsMap: Map): Item | null + public getEquipmentParent(itemId: string, itemsMap: Map): Item | undefined { let currentItem = itemsMap.get(itemId); const equipmentSlots = Object.values(EquipmentSlots).map((value) => value as string); @@ -1135,7 +1135,7 @@ export class ItemHelper currentItem = itemsMap.get(currentItem.parentId); if (!currentItem) { - return null; + return undefined; } } return currentItem; @@ -1197,14 +1197,14 @@ export class ItemHelper * @param item Db item template to look up Cartridge filter values from * @returns Caliber of cartridge */ - public getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string | null + public getRandomCompatibleCaliberTemplateId(item: ITemplateItem): string | undefined { const cartridges = item?._props?.Cartridges[0]?._props?.filters[0]?.Filter; if (!cartridges) { this.logger.warning(`Failed to find cartridge for item: ${item?._id} ${item?._name}`); - return null; + return undefined; } return this.randomUtil.getArrayValue(cartridges); @@ -1467,8 +1467,8 @@ export class ItemHelper caliber: string, staticAmmoDist: Record, fallbackCartridgeTpl: string, - cartridgeWhitelist: string[] = null, - ): string + cartridgeWhitelist?: string[], + ): string | undefined { const ammos = staticAmmoDist[caliber]; if (!ammos && fallbackCartridgeTpl) @@ -1581,7 +1581,7 @@ export class ItemHelper public addChildSlotItems( itemToAdd: Item[], itemToAddTemplate: ITemplateItem, - modSpawnChanceDict: Record = null, + modSpawnChanceDict?: Record, requiredOnly = false, ): Item[] { @@ -1641,16 +1641,16 @@ export class ItemHelper * Get a compatible tpl from the array provided where it is not found in the provided incompatible mod tpls parameter * @param possibleTpls Tpls to randomly choose from * @param incompatibleModTpls Incompatible tpls to not allow - * @returns Chosen tpl or null + * @returns Chosen tpl or undefined */ - public getCompatibleTplFromArray(possibleTpls: string[], incompatibleModTpls: Set): string + public getCompatibleTplFromArray(possibleTpls: string[], incompatibleModTpls: Set): string | undefined { if (possibleTpls.length === 0) { - return null; + return undefined; } - let chosenTpl = null; + let chosenTpl: string | undefined = undefined; let count = 0; while (!chosenTpl) { @@ -1662,7 +1662,7 @@ export class ItemHelper count++; if (count >= possibleTpls.length) { - return null; + return undefined; } continue; } @@ -1818,7 +1818,7 @@ export class ItemHelper * @param warningMessageWhenMissing text to write to log when upd object was not found * @returns True when upd object was added */ - public addUpdObjectToItem(item: Item, warningMessageWhenMissing: string = null): boolean + public addUpdObjectToItem(item: Item, warningMessageWhenMissing?: string): boolean { if (!item.upd) { diff --git a/project/src/helpers/PresetHelper.ts b/project/src/helpers/PresetHelper.ts index 03667a7c..7132b7b8 100644 --- a/project/src/helpers/PresetHelper.ts +++ b/project/src/helpers/PresetHelper.ts @@ -138,11 +138,11 @@ export class PresetHelper * @param templateId Item id to get preset for * @returns Null if no default preset, otherwise IPreset */ - public getDefaultPreset(templateId: string): IPreset + public getDefaultPreset(templateId: string): IPreset | undefined { if (!this.hasPreset(templateId)) { - return null; + return undefined; } const allPresets = this.getPresets(templateId); diff --git a/project/src/helpers/ProfileHelper.ts b/project/src/helpers/ProfileHelper.ts index bc05d262..236780b9 100644 --- a/project/src/helpers/ProfileHelper.ts +++ b/project/src/helpers/ProfileHelper.ts @@ -218,7 +218,7 @@ export class ProfileHelper public getExperience(level: number): number { let playerLevel = level; - const expTable = this.databaseServer.getTables().globals.config.exp.level.exp_table; + const expTable = this.databaseServer.getTables().globals!.config.exp.level.exp_table; let exp = 0; if (playerLevel >= expTable.length) @@ -241,7 +241,7 @@ export class ProfileHelper */ public getMaxLevel(): number { - return this.databaseServer.getTables().globals.config.exp.level.exp_table.length - 1; + return this.databaseServer.getTables().globals!.config.exp.level.exp_table.length - 1; } public getDefaultSptDataObject(): any @@ -254,14 +254,11 @@ export class ProfileHelper * @param sessionID Profile id to get * @returns ISptProfile object */ - public getFullProfile(sessionID: string): ISptProfile + public getFullProfile(sessionID: string): ISptProfile | undefined { - if (this.saveServer.getProfile(sessionID) === undefined) - { - return undefined; - } - - return this.saveServer.getProfile(sessionID); + return this.saveServer.profileExists(sessionID) + ? this.saveServer.getProfile(sessionID) + : undefined; } /** @@ -269,10 +266,10 @@ export class ProfileHelper * @param sessionID Profile id to return * @returns IPmcData object */ - public getPmcProfile(sessionID: string): IPmcData + public getPmcProfile(sessionID: string): IPmcData | undefined { const fullProfile = this.getFullProfile(sessionID); - if (fullProfile === undefined || fullProfile.characters.pmc === undefined) + if (!fullProfile?.characters?.pmc) { return undefined; } @@ -280,6 +277,16 @@ export class ProfileHelper return this.saveServer.getProfile(sessionID).characters.pmc; } + /** + * Is this user id the logged in player + * @param userId Id to test + * @returns True is the current player + */ + public isPlayer(userId: string): boolean + { + return this.saveServer.profileExists(userId); + } + /** * Get a full profiles scav-specific sub-profile * @param sessionID Profiles id @@ -299,7 +306,7 @@ export class ProfileHelper return { Eft: { CarriedQuestItems: [], - DamageHistory: { LethalDamagePart: "Head", LethalDamage: undefined, BodyParts: [] }, + DamageHistory: { LethalDamagePart: "Head", LethalDamage: undefined!, BodyParts: [] }, DroppedItems: [], ExperienceBonusMult: 0, FoundInRaidItems: [], diff --git a/project/src/helpers/QuestConditionHelper.ts b/project/src/helpers/QuestConditionHelper.ts index d93742cd..6260fdf5 100644 --- a/project/src/helpers/QuestConditionHelper.ts +++ b/project/src/helpers/QuestConditionHelper.ts @@ -6,7 +6,7 @@ export class QuestConditionHelper { public getQuestConditions( q: IQuestCondition[], - furtherFilter: (a: IQuestCondition) => IQuestCondition[] = null, + furtherFilter?: (a: IQuestCondition) => IQuestCondition[], ): IQuestCondition[] { return this.filterConditions(q, "Quest", furtherFilter); @@ -14,7 +14,7 @@ export class QuestConditionHelper public getLevelConditions( q: IQuestCondition[], - furtherFilter: (a: IQuestCondition) => IQuestCondition[] = null, + furtherFilter?: (a: IQuestCondition) => IQuestCondition[], ): IQuestCondition[] { return this.filterConditions(q, "Level", furtherFilter); @@ -22,7 +22,7 @@ export class QuestConditionHelper public getLoyaltyConditions( q: IQuestCondition[], - furtherFilter: (a: IQuestCondition) => IQuestCondition[] = null, + furtherFilter?: (a: IQuestCondition) => IQuestCondition[], ): IQuestCondition[] { return this.filterConditions(q, "TraderLoyalty", furtherFilter); @@ -30,7 +30,7 @@ export class QuestConditionHelper public getStandingConditions( q: IQuestCondition[], - furtherFilter: (a: IQuestCondition) => IQuestCondition[] = null, + furtherFilter?: (a: IQuestCondition) => IQuestCondition[], ): IQuestCondition[] { return this.filterConditions(q, "TraderStanding", furtherFilter); @@ -39,7 +39,7 @@ export class QuestConditionHelper protected filterConditions( q: IQuestCondition[], questType: string, - furtherFilter: (a: IQuestCondition) => IQuestCondition[] = null, + furtherFilter?: (a: IQuestCondition) => IQuestCondition[], ): IQuestCondition[] { const filteredQuests = q.filter((c) => diff --git a/project/src/helpers/QuestHelper.ts b/project/src/helpers/QuestHelper.ts index 8b1bafb8..f115e5cd 100644 --- a/project/src/helpers/QuestHelper.ts +++ b/project/src/helpers/QuestHelper.ts @@ -374,7 +374,7 @@ export class QuestHelper const itemDbData = this.itemHelper.getItem(originalRewardRootItem._tpl)[1]; // Hydrate reward with only 'required' mods - necessary for things like helmets otherwise you end up with nvgs/visors etc - questReward.items = this.itemHelper.addChildSlotItems(questReward.items, itemDbData, null, true); + questReward.items = this.itemHelper.addChildSlotItems(questReward.items, itemDbData, undefined, true); } /** @@ -716,7 +716,7 @@ export class QuestHelper pmcData: IPmcData, failRequest: IFailQuestRequestData, sessionID: string, - output: IItemEventRouterResponse = null, + output?: IItemEventRouterResponse, ): void { let updatedOutput = output; @@ -751,7 +751,7 @@ export class QuestHelper { this.mailSendService.sendLocalisedNpcMessageToPlayer( sessionID, - this.traderHelper.getTraderById(quest?.traderId ?? matchingRepeatableQuest?.traderId), // Can be null when repeatable quest has been moved to inactiveQuests + this.traderHelper.getTraderById(quest?.traderId ?? matchingRepeatableQuest?.traderId), // Can be undefined when repeatable quest has been moved to inactiveQuests MessageType.QUEST_FAIL, quest.failMessageText, questRewards, diff --git a/project/src/helpers/RagfairHelper.ts b/project/src/helpers/RagfairHelper.ts index e5c787d8..65a98cd1 100644 --- a/project/src/helpers/RagfairHelper.ts +++ b/project/src/helpers/RagfairHelper.ts @@ -151,7 +151,7 @@ export class RagfairHelper public mergeStackable(items: Item[]): Item[] { const list = []; - let rootItem = null; + let rootItem = undefined; for (let item of items) { diff --git a/project/src/helpers/RagfairOfferHelper.ts b/project/src/helpers/RagfairOfferHelper.ts index a7a3dc7c..0a8d3039 100644 --- a/project/src/helpers/RagfairOfferHelper.ts +++ b/project/src/helpers/RagfairOfferHelper.ts @@ -510,7 +510,7 @@ export class RagfairOfferHelper itemsToSend, this.timeUtil.getHoursAsSeconds( this.questHelper.getMailItemRedeemTimeHoursForProfile(this.profileHelper.getPmcProfile(sessionID))), - null, + undefined, ragfairDetails, ); @@ -755,7 +755,7 @@ export class RagfairOfferHelper if (Number.isNaN(offer.requirementsCost)) { - // don't include offers with null or NaN in it + // don't include offers with undefined or NaN in it return false; } diff --git a/project/src/helpers/RagfairServerHelper.ts b/project/src/helpers/RagfairServerHelper.ts index af9486a1..c4f7436d 100644 --- a/project/src/helpers/RagfairServerHelper.ts +++ b/project/src/helpers/RagfairServerHelper.ts @@ -147,20 +147,6 @@ export class RagfairServerHelper return traderId in this.databaseServer.getTables().traders; } - /** - * Is this user id the logged in player - * @param userId Id to test - * @returns True is the current player - */ - public isPlayer(userId: string): boolean - { - if (this.profileHelper.getPmcProfile(userId) !== undefined) - { - return true; - } - return false; - } - /** * Send items back to player * @param sessionID Player to send items to diff --git a/project/src/helpers/TraderAssortHelper.ts b/project/src/helpers/TraderAssortHelper.ts index 40e65718..0345675b 100644 --- a/project/src/helpers/TraderAssortHelper.ts +++ b/project/src/helpers/TraderAssortHelper.ts @@ -292,7 +292,7 @@ export class TraderAssortHelper items: this.ragfairAssortGenerator.getAssortItems().flat(), barter_scheme: {}, loyal_level_items: {}, - nextResupply: null, + nextResupply: undefined, }; } } diff --git a/project/src/loaders/ModLoadOrder.ts b/project/src/loaders/ModLoadOrder.ts index 65c9db0f..036d27bb 100644 --- a/project/src/loaders/ModLoadOrder.ts +++ b/project/src/loaders/ModLoadOrder.ts @@ -116,9 +116,9 @@ export class ModLoadOrder // Additional info to help debug this.logger.debug(this.localisationService.getText("modloader-checking_mod", mod)); this.logger.debug(`${this.localisationService.getText("modloader-checked")}:`); - this.logger.debug(JSON.stringify(this.loadOrder, null, "\t")); + this.logger.debug(JSON.stringify(this.loadOrder, undefined, "\t")); this.logger.debug(`${this.localisationService.getText("modloader-visited")}:`); - this.logger.debug(JSON.stringify(visited, null, "\t")); + this.logger.debug(JSON.stringify(visited, undefined, "\t")); throw new Error(this.localisationService.getText("modloader-cyclic_dependency")); } diff --git a/project/src/loaders/PreSptModLoader.ts b/project/src/loaders/PreSptModLoader.ts index 70bb1030..7ee8aa84 100644 --- a/project/src/loaders/PreSptModLoader.ts +++ b/project/src/loaders/PreSptModLoader.ts @@ -136,7 +136,7 @@ export class PreSptModLoader implements IModLoader this.logger.info(this.localisationService.getText("modloader-mod_order_missing")); // Write file with empty order array to disk - this.vfs.writeFile(this.modOrderPath, this.jsonUtil.serializeAdvanced({ order: [] }, null, 4)); + this.vfs.writeFile(this.modOrderPath, this.jsonUtil.serializeAdvanced({ order: [] }, undefined, 4)); } else { diff --git a/project/src/models/eft/game/IGameModeRequestData.ts b/project/src/models/eft/game/IGameModeRequestData.ts index 6b4b13d1..eb3e5de0 100644 --- a/project/src/models/eft/game/IGameModeRequestData.ts +++ b/project/src/models/eft/game/IGameModeRequestData.ts @@ -1,4 +1,4 @@ export interface IGameModeRequestData { - sessionMode: string | null + sessionMode: string | undefined } diff --git a/project/src/models/eft/httpResponse/INullResponseData.ts b/project/src/models/eft/httpResponse/INullResponseData.ts index 5c778e0f..7403774b 100644 --- a/project/src/models/eft/httpResponse/INullResponseData.ts +++ b/project/src/models/eft/httpResponse/INullResponseData.ts @@ -2,5 +2,5 @@ export interface INullResponseData { err: number errmsg: any - data: null + data: undefined } diff --git a/project/src/models/spt/server/ExhaustableArray.ts b/project/src/models/spt/server/ExhaustableArray.ts index 2b87caf0..85a18c65 100644 --- a/project/src/models/spt/server/ExhaustableArray.ts +++ b/project/src/models/spt/server/ExhaustableArray.ts @@ -14,11 +14,11 @@ export class ExhaustableArray implements IExhaustableArray this.pool = this.cloner.clone(itemPool); } - public getRandomValue(): T + public getRandomValue(): T | undefined { if (!this.pool?.length) { - return null; + return undefined; } const index = this.randomUtil.getInt(0, this.pool.length - 1); @@ -27,11 +27,11 @@ export class ExhaustableArray implements IExhaustableArray return toReturn; } - public getFirstValue(): T + public getFirstValue(): T | undefined { if (!this.pool?.length) { - return null; + return undefined; } const toReturn = this.cloner.clone(this.pool[0]); @@ -52,7 +52,7 @@ export class ExhaustableArray implements IExhaustableArray export interface IExhaustableArray { - getRandomValue(): T - getFirstValue(): T + getRandomValue(): T | undefined + getFirstValue(): T | undefined hasValues(): boolean } diff --git a/project/src/routers/EventOutputHolder.ts b/project/src/routers/EventOutputHolder.ts index adb7661d..bf3ac9e7 100644 --- a/project/src/routers/EventOutputHolder.ts +++ b/project/src/routers/EventOutputHolder.ts @@ -144,7 +144,7 @@ export class EventOutputHolder */ protected getProductionsFromProfileAndFlagComplete( productions: Record, - ): Record + ): Record | undefined { for (const productionKey in productions) { @@ -182,8 +182,8 @@ export class EventOutputHolder } } - // Return null if there's no crafts to send to client to match live behaviour - return Object.keys(productions).length > 0 ? productions : null; + // Return undefined if there's no crafts to send to client to match live behaviour + return Object.keys(productions).length > 0 ? productions : undefined; } /** diff --git a/project/src/routers/save_load/HealthSaveLoadRouter.ts b/project/src/routers/save_load/HealthSaveLoadRouter.ts index 8192d36c..9adb96ed 100644 --- a/project/src/routers/save_load/HealthSaveLoadRouter.ts +++ b/project/src/routers/save_load/HealthSaveLoadRouter.ts @@ -15,7 +15,7 @@ export class HealthSaveLoadRouter extends SaveLoadRouter if (!profile.vitality) { // Occurs on newly created profiles - profile.vitality = { health: null, effects: null }; + profile.vitality = { health: undefined!, effects: undefined! }; } profile.vitality.health = { Hydration: 0, diff --git a/project/src/routers/save_load/ProfileSaveLoadRouter.ts b/project/src/routers/save_load/ProfileSaveLoadRouter.ts index 330201dd..b5bdcddc 100644 --- a/project/src/routers/save_load/ProfileSaveLoadRouter.ts +++ b/project/src/routers/save_load/ProfileSaveLoadRouter.ts @@ -13,7 +13,7 @@ export class ProfileSaveLoadRouter extends SaveLoadRouter public override handleLoad(profile: ISptProfile): ISptProfile { - if (profile.characters === null) + if (!profile.characters) { profile.characters = { pmc: {} as IPmcData, scav: {} as IPmcData }; } diff --git a/project/src/servers/SaveServer.ts b/project/src/servers/SaveServer.ts index dcf5c32e..ef689516 100644 --- a/project/src/servers/SaveServer.ts +++ b/project/src/servers/SaveServer.ts @@ -46,7 +46,7 @@ export class SaveServer */ public removeBeforeSaveCallback(id: string): void { - this.onBeforeSaveCallbacks[id] = null; + this.onBeforeSaveCallbacks[id] = undefined; } /** @@ -102,12 +102,12 @@ export class SaveServer throw new Error("session id provided was empty, did you restart the server while the game was running?"); } - if (this.profiles === null) + if (!this.profiles) { throw new Error(`no profiles found in saveServer with id: ${sessionId}`); } - if (this.profiles[sessionId] === null) + if (!this.profiles[sessionId]) { throw new Error(`no profile found for sessionId: ${sessionId}`); } @@ -115,6 +115,11 @@ export class SaveServer return this.profiles[sessionId]; } + public profileExists(id: string): boolean + { + return !!this.profiles[id]; + } + /** * Get all profiles from memory * @returns Dictionary of ISptProfile @@ -131,7 +136,7 @@ export class SaveServer */ public deleteProfileById(sessionID: string): boolean { - if (this.profiles[sessionID] != null) + if (this.profiles[sessionID]) { delete this.profiles[sessionID]; return true; @@ -146,7 +151,7 @@ export class SaveServer */ public createProfile(profileInfo: Info): void { - if (this.profiles[profileInfo.id] != null) + if (this.profiles[profileInfo.id]) { throw new Error(`profile already exists for sessionId: ${profileInfo.id}`); } diff --git a/project/src/servers/http/SptHttpListener.ts b/project/src/servers/http/SptHttpListener.ts index 36472b83..32651597 100644 --- a/project/src/servers/http/SptHttpListener.ts +++ b/project/src/servers/http/SptHttpListener.ts @@ -34,8 +34,8 @@ export class SptHttpListener implements IHttpListener { case "GET": { - const response = await this.getResponse(sessionId, req, null); - this.sendResponse(sessionId, req, resp, null, response); + const response = await this.getResponse(sessionId, req, undefined); + this.sendResponse(sessionId, req, resp, undefined, response); break; } // these are handled almost identically. @@ -152,12 +152,12 @@ export class SptHttpListener implements IHttpListener { this.logger.error(this.localisationService.getText("unhandled_response", req.url)); this.logger.info(info); - output = ( this.httpResponse.getBody(null, 404, `UNHANDLED RESPONSE: ${req.url}`)); + output = ( this.httpResponse.getBody(undefined, 404, `UNHANDLED RESPONSE: ${req.url}`)); } return output; } - protected getBodyInfo(body: Buffer, requestUrl = null): any + protected getBodyInfo(body: Buffer, requestUrl = undefined): any { const text = body ? body.toString() : "{}"; const info = text ? this.jsonUtil.deserialize(text, requestUrl) : {}; diff --git a/project/src/servers/ws/SptWebSocketConnectionHandler.ts b/project/src/servers/ws/SptWebSocketConnectionHandler.ts index 150eb513..374a944f 100644 --- a/project/src/servers/ws/SptWebSocketConnectionHandler.ts +++ b/project/src/servers/ws/SptWebSocketConnectionHandler.ts @@ -20,7 +20,7 @@ export class SptWebSocketConnectionHandler implements IWebSocketConnectionHandle protected webSockets: Map = new Map(); protected defaultNotification: IWsNotificationEvent = { type: NotificationEventType.PING, eventId: "ping" }; - protected websocketPingHandler = null; + protected websocketPingHandler: NodeJS.Timeout | undefined; constructor( @inject("WinstonLogger") protected logger: ILogger, @inject("ProfileHelper") protected profileHelper: ProfileHelper, diff --git a/project/src/services/BotEquipmentFilterService.ts b/project/src/services/BotEquipmentFilterService.ts index e25930ac..7410f49c 100644 --- a/project/src/services/BotEquipmentFilterService.ts +++ b/project/src/services/BotEquipmentFilterService.ts @@ -152,13 +152,13 @@ export class BotEquipmentFilterService * @param botEquipmentRole equipment role of bot to look up * @returns Dictionary of weapon type and their whitelisted scope types */ - public getBotWeaponSightWhitelist(botEquipmentRole: string): Record + public getBotWeaponSightWhitelist(botEquipmentRole: string): Record | undefined { const botEquipmentSettings = this.botEquipmentConfig[botEquipmentRole]; if (!botEquipmentSettings) { - return null; + return undefined; } return botEquipmentSettings.weaponSightWhitelist; @@ -170,7 +170,7 @@ export class BotEquipmentFilterService * @param playerLevel Level of the player * @returns EquipmentBlacklistDetails object */ - public getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails + public getBotEquipmentBlacklist(botRole: string, playerLevel: number): EquipmentFilterDetails | undefined { const blacklistDetailsForBot = this.botEquipmentConfig[botRole]; @@ -181,7 +181,7 @@ export class BotEquipmentFilterService || !blacklistDetailsForBot.blacklist ) { - return null; + return undefined; } return blacklistDetailsForBot.blacklist.find( @@ -195,14 +195,14 @@ export class BotEquipmentFilterService * @param playerLevel Players level * @returns EquipmentFilterDetails object */ - protected getBotEquipmentWhitelist(botRole: string, playerLevel: number): EquipmentFilterDetails + protected getBotEquipmentWhitelist(botRole: string, playerLevel: number): EquipmentFilterDetails | undefined { const botEquipmentConfig = this.botEquipmentConfig[botRole]; // No equipment blacklist found, skip if (!botEquipmentConfig || Object.keys(botEquipmentConfig).length === 0 || !botEquipmentConfig.whitelist) { - return null; + return undefined; } return botEquipmentConfig.whitelist.find( @@ -216,7 +216,7 @@ export class BotEquipmentFilterService * @param botLevel Level of bot * @returns Weighting adjustments for bot items */ - protected getBotWeightingAdjustments(botRole: string, botLevel: number): WeightingAdjustmentDetails + protected getBotWeightingAdjustments(botRole: string, botLevel: number): WeightingAdjustmentDetails | undefined { const botEquipmentConfig = this.botEquipmentConfig[botRole]; @@ -227,7 +227,7 @@ export class BotEquipmentFilterService || !botEquipmentConfig.weightingAdjustmentsByBotLevel ) { - return null; + return undefined; } return botEquipmentConfig.weightingAdjustmentsByBotLevel.find( @@ -244,7 +244,7 @@ export class BotEquipmentFilterService protected getBotWeightingAdjustmentsByPlayerLevel( botRole: string, playerlevel: number, - ): WeightingAdjustmentDetails + ): WeightingAdjustmentDetails | undefined { const botEquipmentConfig = this.botEquipmentConfig[botRole]; @@ -255,7 +255,7 @@ export class BotEquipmentFilterService || !botEquipmentConfig.weightingAdjustmentsByPlayerLevel ) { - return null; + return undefined; } return botEquipmentConfig.weightingAdjustmentsByPlayerLevel.find( diff --git a/project/src/services/BotLootCacheService.ts b/project/src/services/BotLootCacheService.ts index 364e0348..5132d81a 100644 --- a/project/src/services/BotLootCacheService.ts +++ b/project/src/services/BotLootCacheService.ts @@ -532,7 +532,7 @@ export class BotLootCacheService } /** - * If lootcache is null, init with empty property arrays + * If lootcache is undefined, init with empty property arrays * @param botRole Bot role to hydrate */ protected initCacheForBotRole(botRole: string): void diff --git a/project/src/services/FenceService.ts b/project/src/services/FenceService.ts index a23d258c..2a152058 100644 --- a/project/src/services/FenceService.ts +++ b/project/src/services/FenceService.ts @@ -38,10 +38,10 @@ export class FenceService protected nextPartialRefreshTimestamp: number; /** Main assorts you see at all rep levels */ - protected fenceAssort: ITraderAssort = undefined; + protected fenceAssort?: ITraderAssort = undefined; /** Assorts shown on a separate tab when you max out fence rep */ - protected fenceDiscountAssort: ITraderAssort = undefined; + protected fenceDiscountAssort?: ITraderAssort = undefined; /** Desired baseline counts - Hydrated on initial assort generation as part of generateFenceAssorts() */ protected desiredAssortCounts: IFenceAssortGenerationValues; @@ -96,7 +96,7 @@ export class FenceService * Get main fence assort * @return ITraderAssort */ - public getMainFenceAssort(): ITraderAssort + public getMainFenceAssort(): ITraderAssort | undefined { return this.fenceAssort; } @@ -105,7 +105,7 @@ export class FenceService * Get discount fence assort * @return ITraderAssort */ - public getDiscountFenceAssort(): ITraderAssort + public getDiscountFenceAssort(): ITraderAssort | undefined { return this.fenceDiscountAssort; } @@ -135,23 +135,23 @@ export class FenceService // Clone assorts so we can adjust prices before sending to client const assort = this.cloner.clone(this.fenceAssort); - this.adjustAssortItemPricesByConfigMultiplier(assort, 1, this.traderConfig.fence.presetPriceMult); + this.adjustAssortItemPricesByConfigMultiplier(assort!, 1, this.traderConfig.fence.presetPriceMult); // merge normal fence assorts + discount assorts if player standing is large enough if (pmcProfile.TradersInfo[Traders.FENCE].standing >= 6) { const discountAssort = this.cloner.clone(this.fenceDiscountAssort); this.adjustAssortItemPricesByConfigMultiplier( - discountAssort, + discountAssort!, this.traderConfig.fence.discountOptions.itemPriceMult, this.traderConfig.fence.discountOptions.presetPriceMult, ); - const mergedAssorts = this.mergeAssorts(assort, discountAssort); + const mergedAssorts = this.mergeAssorts(assort!, discountAssort!); return mergedAssorts; } - return assort; + return assort!; } /** @@ -184,7 +184,7 @@ export class FenceService createAssort.sptItems.push(clonedItems); createAssort.loyal_level_items[root._id] = 1; - this.updateFenceAssorts(createAssort, this.fenceAssort); + this.updateFenceAssorts(createAssort, this.fenceAssort!); } /** @@ -213,7 +213,7 @@ export class FenceService { if (this.itemHelper.isOfBaseclass(item._tpl, BaseClasses.AMMO)) { - total += this.handbookHelper.getTemplatePrice(item._tpl) * (item.upd.StackObjectsCount ?? 1); + total += this.handbookHelper.getTemplatePrice(item._tpl) * (item.upd?.StackObjectsCount ?? 1); } } @@ -310,7 +310,7 @@ export class FenceService */ public getRawFenceAssorts(): ITraderAssort { - return this.mergeAssorts(this.cloner.clone(this.fenceAssort), this.cloner.clone(this.fenceDiscountAssort)); + return this.mergeAssorts(this.cloner.clone(this.fenceAssort!), this.cloner.clone(this.fenceDiscountAssort!)); } /** @@ -333,49 +333,49 @@ export class FenceService ); // Simulate players buying items - this.deleteRandomAssorts(itemCountToReplace, this.fenceAssort); - this.deleteRandomAssorts(discountItemCountToReplace, this.fenceDiscountAssort); + this.deleteRandomAssorts(itemCountToReplace, this.fenceAssort!); + this.deleteRandomAssorts(discountItemCountToReplace, this.fenceDiscountAssort!); const normalItemCountsToGenerate = this.getItemCountsToGenerate( - this.fenceAssort.items, + this.fenceAssort!.items, this.desiredAssortCounts.normal, ); const newItems = this.createAssorts(normalItemCountsToGenerate, 1); // Push newly generated assorts into existing data - this.updateFenceAssorts(newItems, this.fenceAssort); + this.updateFenceAssorts(newItems, this.fenceAssort!); const discountItemCountsToGenerate = this.getItemCountsToGenerate( - this.fenceDiscountAssort.items, + this.fenceDiscountAssort!.items, this.desiredAssortCounts.discount, ); const newDiscountItems = this.createAssorts(discountItemCountsToGenerate, 2); // Push newly generated discount assorts into existing data - this.updateFenceAssorts(newDiscountItems, this.fenceDiscountAssort); + this.updateFenceAssorts(newDiscountItems, this.fenceDiscountAssort!); // Add new barter items to fence barter scheme for (const barterItemKey in newItems.barter_scheme) { - this.fenceAssort.barter_scheme[barterItemKey] = newItems.barter_scheme[barterItemKey]; + this.fenceAssort!.barter_scheme[barterItemKey] = newItems.barter_scheme[barterItemKey]; } // Add loyalty items to fence assorts loyalty object for (const loyaltyItemKey in newItems.loyal_level_items) { - this.fenceAssort.loyal_level_items[loyaltyItemKey] = newItems.loyal_level_items[loyaltyItemKey]; + this.fenceAssort!.loyal_level_items[loyaltyItemKey] = newItems.loyal_level_items[loyaltyItemKey]; } // Add new barter items to fence assorts discounted barter scheme for (const barterItemKey in newDiscountItems.barter_scheme) { - this.fenceDiscountAssort.barter_scheme[barterItemKey] = newDiscountItems.barter_scheme[barterItemKey]; + this.fenceDiscountAssort!.barter_scheme[barterItemKey] = newDiscountItems.barter_scheme[barterItemKey]; } // Add loyalty items to fence discount assorts loyalty object for (const loyaltyItemKey in newDiscountItems.loyal_level_items) { - this.fenceDiscountAssort.loyal_level_items[loyaltyItemKey] + this.fenceDiscountAssort!.loyal_level_items[loyaltyItemKey] = newDiscountItems.loyal_level_items[loyaltyItemKey]; } @@ -428,13 +428,13 @@ export class FenceService ) { // Guard against a missing stack count - if (!existingRootItem.upd.StackObjectsCount) + if (existingRootItem.upd?.StackObjectsCount === undefined) { - existingRootItem.upd.StackObjectsCount = 1; + 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; + existingRootItem.upd!.StackObjectsCount += newRootItem?.upd?.StackObjectsCount ?? 1; continue; } @@ -547,7 +547,7 @@ export class FenceService } // Reduce stack to at smallest, 1 - rootItemToAdjust.upd.StackObjectsCount -= Math.max(1, itemCountToRemove); + rootItemToAdjust.upd!.StackObjectsCount! -= Math.max(1, itemCountToRemove); return; } @@ -694,7 +694,7 @@ export class FenceService { const result: ICreateFenceAssortsResult = { sptItems: [], barter_scheme: {}, loyal_level_items: {} }; - const baseFenceAssortClone = this.cloner.clone(this.databaseServer.getTables().traders[Traders.FENCE].assort); + const baseFenceAssortClone = this.cloner.clone(this.databaseServer.getTables().traders![Traders.FENCE].assort!); const itemTypeLimitCounts = this.initItemLimitCounter(this.traderConfig.fence.itemTypeLimits); if (itemCounts.item > 0) @@ -750,7 +750,7 @@ export class FenceService if (!chosenBaseAssortRoot) { this.logger.error( - this.localisationService.getText("fence-unable_to_find_assort_by_id", chosenBaseAssortRoot._id), + this.localisationService.getText("fence-unable_to_find_assort_by_id"), ); continue; @@ -760,7 +760,7 @@ export class FenceService ); const itemDbDetails = this.itemHelper.getItem(chosenBaseAssortRoot._tpl)[1]; - const itemLimitCount = this.getMatchingItemLimit(itemTypeLimits, itemDbDetails._id); + const itemLimitCount = this.getMatchingItemLimit(itemTypeLimits, itemDbDetails._id)!; if (itemLimitCount?.current >= itemLimitCount?.max) { // Skip adding item as assort as limit reached, decrement i counter so we still get another item @@ -798,23 +798,23 @@ export class FenceService const rootItemBeingAdded = desiredAssortItemAndChildrenClone[0]; // Set stack size based on possible overrides, e.g. ammos, otherwise set to 1 - rootItemBeingAdded.upd.StackObjectsCount = this.getSingleItemStackCount(itemDbDetails); + rootItemBeingAdded.upd!.StackObjectsCount = this.getSingleItemStackCount(itemDbDetails); // Only randomise upd values for single - const isSingleStack = rootItemBeingAdded.upd.StackObjectsCount === 1; + const isSingleStack = (rootItemBeingAdded.upd?.StackObjectsCount ?? 0) === 1; if (isSingleStack) { this.randomiseItemUpdProperties(itemDbDetails, rootItemBeingAdded); } // Skip items already in the assort if it exists in the prevent duplicate list - const existingItemThatMatches = this.getMatchingItem(rootItemBeingAdded, itemDbDetails, assorts.sptItems); + const existingItemThatMatches = this.getMatchingItem(rootItemBeingAdded, itemDbDetails, assorts.sptItems)!; const shouldBeStacked = this.itemShouldBeForceStacked(existingItemThatMatches, itemDbDetails); if (shouldBeStacked && existingItemThatMatches) { // Decrement loop counter so another items gets added i--; - existingItemThatMatches.upd.StackObjectsCount++; + existingItemThatMatches.upd!.StackObjectsCount!++; continue; } @@ -853,7 +853,7 @@ export class FenceService rootItemBeingAdded: Item, itemDbDetails: ITemplateItem, itemsWithChildren: Item[][], - ): Item + ): Item | undefined { // Get matching root items const matchingItems = itemsWithChildren @@ -864,7 +864,7 @@ export class FenceService if (matchingItems.length === 0) { // Nothing matches by tpl and is root item, exit early - return null; + return undefined; } const isMedical = this.itemHelper.isOfBaseclasses(rootItemBeingAdded._tpl, [ @@ -875,7 +875,7 @@ export class FenceService = this.itemHelper.isOfBaseclasses(rootItemBeingAdded._tpl, [ BaseClasses.ARMORED_EQUIPMENT, BaseClasses.SEARCHABLE_ITEM, - ]) && itemDbDetails._props.Slots.length > 0; + ]) && (itemDbDetails._props.Slots?.length ?? 0) > 0; // Only one match and its not medical or armored gear if (matchingItems.length === 1 && !(isMedical || isGearAndHasSlots)) @@ -886,25 +886,25 @@ export class FenceService // Items have sub properties that need to be checked against for (const item of matchingItems) { - if (isMedical && rootItemBeingAdded.upd.MedKit?.HpResource === item.upd.MedKit?.HpResource) + if (isMedical && rootItemBeingAdded.upd!.MedKit?.HpResource === item.upd!.MedKit?.HpResource) { // e.g. bandages with multiple use - // Both null === both max resoruce left + // Both undefined === both max resoruce left return item; } // Armors/helmets etc if ( isGearAndHasSlots - && rootItemBeingAdded.upd.Repairable?.Durability === item.upd.Repairable?.Durability - && rootItemBeingAdded.upd.Repairable?.MaxDurability === item.upd.Repairable?.MaxDurability + && rootItemBeingAdded.upd!.Repairable?.Durability === item.upd!.Repairable?.Durability + && rootItemBeingAdded.upd!.Repairable?.MaxDurability === item.upd!.Repairable?.MaxDurability ) { return item; } } - return null; + return undefined; } /** @@ -951,7 +951,7 @@ export class FenceService // Healing items if (itemRoot.upd?.MedKit) { - const itemTotalMax = itemTemplate._props.MaxHpResource; + const itemTotalMax = itemTemplate._props.MaxHpResource!; const current = itemRoot.upd.MedKit.HpResource; // Current and max match, no adjustment necessary @@ -981,7 +981,7 @@ export class FenceService protected getMatchingItemLimit( itemTypeLimits: Record, itemTpl: string, - ): { current: number, max: number } + ): { current: number, max: number } | undefined { for (const baseTypeKey in itemTypeLimits) { @@ -1143,20 +1143,20 @@ export class FenceService protected randomiseArmorModDurability(armor: Item[], itemDbDetails: ITemplateItem): void { // Armor has no mods, make no changes - const hasMods = itemDbDetails._props.Slots.length > 0; + const hasMods = (itemDbDetails._props.Slots?.length ?? 0) > 0; if (!hasMods) { return; } // Check for and adjust soft insert durability values - const requiredSlots = itemDbDetails._props.Slots.filter((slot) => slot._required); - const hasRequiredSlots = requiredSlots.length > 0; + const requiredSlots = itemDbDetails._props.Slots?.filter((slot) => slot._required); + const hasRequiredSlots = (requiredSlots?.length ?? 0) > 0; if (hasRequiredSlots) { - for (const requiredSlot of requiredSlots) + for (const requiredSlot of requiredSlots!) { - const modItemDbDetails = this.itemHelper.getItem(requiredSlot._props.filters[0].Plate)[1]; + const modItemDbDetails = this.itemHelper.getItem(requiredSlot._props.filters[0].Plate!)[1]; const durabilityValues = this.getRandomisedArmorDurabilityValues( modItemDbDetails, this.traderConfig.fence.armorMaxDurabilityPercentMinMax, @@ -1170,42 +1170,42 @@ export class FenceService // Find items mod to apply dura changes to const modItemToAdjust = armor.find( - (mod) => mod.slotId.toLowerCase() === requiredSlot._name.toLowerCase(), - ); + (mod) => mod.slotId!.toLowerCase() === requiredSlot._name.toLowerCase(), + )!; this.itemHelper.addUpdObjectToItem(modItemToAdjust); - if (!modItemToAdjust.upd.Repairable) + if (!modItemToAdjust.upd!.Repairable) { - modItemToAdjust.upd.Repairable = { - Durability: modItemDbDetails._props.MaxDurability, - MaxDurability: modItemDbDetails._props.MaxDurability, + modItemToAdjust.upd!.Repairable = { + Durability: modItemDbDetails._props.MaxDurability!, + MaxDurability: modItemDbDetails._props.MaxDurability!, }; } - modItemToAdjust.upd.Repairable.Durability = durabilityValues.Durability; - modItemToAdjust.upd.Repairable.MaxDurability = durabilityValues.MaxDurability; + modItemToAdjust.upd!.Repairable.Durability = durabilityValues.Durability; + modItemToAdjust.upd!.Repairable.MaxDurability = durabilityValues.MaxDurability; // 25% chance to add shots to visor when its below max durability if ( this.randomUtil.getChance100(25) && modItemToAdjust.parentId === BaseClasses.ARMORED_EQUIPMENT && modItemToAdjust.slotId === "mod_equipment_000" - && modItemToAdjust.upd.Repairable.Durability < modItemDbDetails._props.MaxDurability + && modItemToAdjust.upd!.Repairable.Durability < modItemDbDetails._props.MaxDurability! ) { // Is damaged - modItemToAdjust.upd.FaceShield = { Hits: this.randomUtil.getInt(1, 3) }; + modItemToAdjust.upd!.FaceShield = { Hits: this.randomUtil.getInt(1, 3) }; } } } // Check for and adjust plate durability values - const plateSlots = itemDbDetails._props.Slots.filter((slot) => + const plateSlots = itemDbDetails._props.Slots?.filter((slot) => this.itemHelper.isRemovablePlateSlot(slot._name), ); - if (plateSlots.length > 0) + if ((plateSlots?.length ?? 0) > 0) { - for (const plateSlot of plateSlots) + for (const plateSlot of plateSlots!) { // Chance to not add plate if (!this.randomUtil.getChance100(this.traderConfig.fence.chancePlateExistsInArmorPercent)) @@ -1226,19 +1226,19 @@ export class FenceService ); // Find items mod to apply dura changes to - const modItemToAdjust = armor.find((mod) => mod.slotId.toLowerCase() === plateSlot._name.toLowerCase()); - this.itemHelper.addUpdObjectToItem(modItemToAdjust); + const modItemToAdjust = armor.find((mod) => mod.slotId!.toLowerCase() === plateSlot._name.toLowerCase()); + this.itemHelper.addUpdObjectToItem(modItemToAdjust!); - if (!modItemToAdjust.upd.Repairable) + if (!modItemToAdjust?.upd?.Repairable) { - modItemToAdjust.upd.Repairable = { - Durability: modItemDbDetails._props.MaxDurability, - MaxDurability: modItemDbDetails._props.MaxDurability, + modItemToAdjust!.upd!.Repairable = { + Durability: modItemDbDetails._props.MaxDurability!, + MaxDurability: modItemDbDetails._props.MaxDurability!, }; } - modItemToAdjust.upd.Repairable.Durability = durabilityValues.Durability; - modItemToAdjust.upd.Repairable.MaxDurability = durabilityValues.MaxDurability; + modItemToAdjust!.upd!.Repairable.Durability = durabilityValues.Durability; + modItemToAdjust!.upd!.Repairable.MaxDurability = durabilityValues.MaxDurability; } } } @@ -1261,7 +1261,7 @@ export class FenceService // No override, use stack max size from item db return itemDbDetails._props.StackMaxSize === 1 ? 1 - : this.randomUtil.getInt(itemDbDetails._props.StackMinRandom, itemDbDetails._props.StackMaxRandom); + : this.randomUtil.getInt(itemDbDetails._props.StackMinRandom!, itemDbDetails._props.StackMaxRandom!); } // Check for override in config, use values if exists @@ -1326,7 +1326,7 @@ export class FenceService protected presetModItemWillBeRemoved(weaponMod: Item, itemsBeingDeleted: string[]): boolean { const slotIdsThatCanFail = this.traderConfig.fence.presetSlotsToRemoveChancePercent; - const removalChance = slotIdsThatCanFail[weaponMod.slotId]; + const removalChance = slotIdsThatCanFail[weaponMod.slotId!]; if (!removalChance) { return false; @@ -1355,9 +1355,9 @@ export class FenceService } // Randomise hp resource of med items - if ("MaxHpResource" in itemDetails._props && itemDetails._props.MaxHpResource > 0) + if ("MaxHpResource" in itemDetails._props && (itemDetails._props.MaxHpResource ?? 0) > 0) { - itemToAdjust.upd.MedKit = { HpResource: this.randomUtil.getInt(1, itemDetails._props.MaxHpResource) }; + itemToAdjust.upd!.MedKit = { HpResource: this.randomUtil.getInt(1, itemDetails._props.MaxHpResource!) }; } // Randomise armor durability @@ -1365,14 +1365,14 @@ export class FenceService (itemDetails._parent === BaseClasses.ARMORED_EQUIPMENT || itemDetails._parent === BaseClasses.FACECOVER || itemDetails._parent === BaseClasses.ARMOR_PLATE) - && itemDetails._props.MaxDurability > 0 + && (itemDetails._props.MaxDurability ?? 0) > 0 ) { const values = this.getRandomisedArmorDurabilityValues( itemDetails, this.traderConfig.fence.armorMaxDurabilityPercentMinMax, ); - itemToAdjust.upd.Repairable = { Durability: values.Durability, MaxDurability: values.MaxDurability }; + itemToAdjust.upd!.Repairable = { Durability: values.Durability, MaxDurability: values.MaxDurability }; return; } @@ -1381,25 +1381,25 @@ export class FenceService if (this.itemHelper.isOfBaseclass(itemDetails._id, BaseClasses.WEAPON)) { const weaponDurabilityLimits = this.traderConfig.fence.weaponDurabilityPercentMinMax; - const maxDuraMin = (weaponDurabilityLimits.max.min / 100) * itemDetails._props.MaxDurability; - const maxDuraMax = (weaponDurabilityLimits.max.max / 100) * itemDetails._props.MaxDurability; + const maxDuraMin = (weaponDurabilityLimits.max.min / 100) * itemDetails._props.MaxDurability!; + const maxDuraMax = (weaponDurabilityLimits.max.max / 100) * itemDetails._props.MaxDurability!; const chosenMaxDurability = this.randomUtil.getInt(maxDuraMin, maxDuraMax); - const currentDuraMin = (weaponDurabilityLimits.current.min / 100) * itemDetails._props.MaxDurability; - const currentDuraMax = (weaponDurabilityLimits.current.max / 100) * itemDetails._props.MaxDurability; + const currentDuraMin = (weaponDurabilityLimits.current.min / 100) * itemDetails._props.MaxDurability!; + const currentDuraMax = (weaponDurabilityLimits.current.max / 100) * itemDetails._props.MaxDurability!; const currentDurability = Math.min( this.randomUtil.getInt(currentDuraMin, currentDuraMax), chosenMaxDurability, ); - itemToAdjust.upd.Repairable = { Durability: currentDurability, MaxDurability: chosenMaxDurability }; + itemToAdjust.upd!.Repairable = { Durability: currentDurability, MaxDurability: chosenMaxDurability }; return; } if (this.itemHelper.isOfBaseclass(itemDetails._id, BaseClasses.REPAIR_KITS)) { - itemToAdjust.upd.RepairKit = { Resource: this.randomUtil.getInt(1, itemDetails._props.MaxRepairResource) }; + itemToAdjust.upd!.RepairKit = { Resource: this.randomUtil.getInt(1, itemDetails._props.MaxRepairResource!) }; return; } @@ -1407,23 +1407,23 @@ export class FenceService // Mechanical key + has limited uses if ( this.itemHelper.isOfBaseclass(itemDetails._id, BaseClasses.KEY_MECHANICAL) - && itemDetails._props.MaximumNumberOfUsage > 1 + && (itemDetails._props.MaximumNumberOfUsage ?? 0) > 1 ) { - itemToAdjust.upd.Key = { - NumberOfUsages: this.randomUtil.getInt(0, itemDetails._props.MaximumNumberOfUsage - 1), + itemToAdjust.upd!.Key = { + NumberOfUsages: this.randomUtil.getInt(0, itemDetails._props.MaximumNumberOfUsage! - 1), }; return; } // Randomise items that use resources (e.g. fuel) - if (itemDetails._props.MaxResource > 0) + if ((itemDetails._props.MaxResource ?? 0) > 0) { - const resourceMax = itemDetails._props.MaxResource; - const resourceCurrent = this.randomUtil.getInt(1, itemDetails._props.MaxResource); + const resourceMax = itemDetails._props.MaxResource!; + const resourceCurrent = this.randomUtil.getInt(1, itemDetails._props.MaxResource!); - itemToAdjust.upd.Resource = { Value: resourceMax - resourceCurrent, UnitsConsumed: resourceCurrent }; + itemToAdjust.upd!.Resource = { Value: resourceMax - resourceCurrent, UnitsConsumed: resourceCurrent }; } } @@ -1438,12 +1438,12 @@ export class FenceService equipmentDurabilityLimits: IItemDurabilityCurrentMax, ): Repairable { - const maxDuraMin = (equipmentDurabilityLimits.max.min / 100) * itemDetails._props.MaxDurability; - const maxDuraMax = (equipmentDurabilityLimits.max.max / 100) * itemDetails._props.MaxDurability; + const maxDuraMin = (equipmentDurabilityLimits.max.min / 100) * itemDetails._props.MaxDurability!; + const maxDuraMax = (equipmentDurabilityLimits.max.max / 100) * itemDetails._props.MaxDurability!; const chosenMaxDurability = this.randomUtil.getInt(maxDuraMin, maxDuraMax); - const currentDuraMin = (equipmentDurabilityLimits.current.min / 100) * itemDetails._props.MaxDurability; - const currentDuraMax = (equipmentDurabilityLimits.current.max / 100) * itemDetails._props.MaxDurability; + const currentDuraMin = (equipmentDurabilityLimits.current.min / 100) * itemDetails._props.MaxDurability!; + const currentDuraMax = (equipmentDurabilityLimits.current.max / 100) * itemDetails._props.MaxDurability!; const chosenCurrentDurability = Math.min( this.randomUtil.getInt(currentDuraMin, currentDuraMax), chosenMaxDurability, @@ -1486,7 +1486,7 @@ export class FenceService */ protected getFenceRefreshTime(): number { - const fence = this.traderConfig.updateTime.find((x) => x.traderId === Traders.FENCE).seconds; + const fence = this.traderConfig.updateTime.find((x) => x.traderId === Traders.FENCE)!.seconds; return this.randomUtil.getInt(fence.min, fence.max); } @@ -1498,7 +1498,7 @@ export class FenceService */ public getFenceInfo(pmcData: IPmcData): IFenceLevel { - const fenceSettings = this.databaseServer.getTables().globals.config.FenceSettings; + const fenceSettings = this.databaseServer.getTables().globals!.config.FenceSettings; const pmcFenceInfo = pmcData.TradersInfo[fenceSettings.FenceId]; if (!pmcFenceInfo) @@ -1532,11 +1532,11 @@ export class FenceService public amendOrRemoveFenceOffer(assortId: string, buyCount: number): void { let isNormalAssort = true; - let fenceAssortItem = this.fenceAssort.items.find((item) => item._id === assortId); + let fenceAssortItem = this.fenceAssort!.items.find((item) => item._id === assortId); if (!fenceAssortItem) { // Not in main assorts, check secondary section - fenceAssortItem = this.fenceDiscountAssort.items.find((item) => item._id === assortId); + fenceAssortItem = this.fenceDiscountAssort!.items.find((item) => item._id === assortId); if (!fenceAssortItem) { this.logger.error(this.localisationService.getText("fence-unable_to_find_offer_by_id", assortId)); @@ -1547,15 +1547,15 @@ export class FenceService } // Player wants to buy whole stack, delete stack - if (fenceAssortItem.upd.StackObjectsCount === buyCount) + if (fenceAssortItem.upd!.StackObjectsCount === buyCount) { - this.deleteOffer(assortId, isNormalAssort ? this.fenceAssort.items : this.fenceDiscountAssort.items); + this.deleteOffer(assortId, isNormalAssort ? this.fenceAssort!.items : this.fenceDiscountAssort!.items); return; } // Adjust stack size - fenceAssortItem.upd.StackObjectsCount -= buyCount; + fenceAssortItem.upd!.StackObjectsCount! -= buyCount; } protected deleteOffer(assortId: string, assorts: Item[]): void @@ -1569,8 +1569,8 @@ export class FenceService // No offer found in main assort, check discount items if (indexToRemove === -1) { - indexToRemove = this.fenceDiscountAssort.items.findIndex((item) => item._id === itemToRemove._id); - this.fenceDiscountAssort.items.splice(indexToRemove, 1); + indexToRemove = this.fenceDiscountAssort!.items.findIndex((item) => item._id === itemToRemove._id); + this.fenceDiscountAssort!.items.splice(indexToRemove, 1); if (indexToRemove === -1) { diff --git a/project/src/services/ProfileFixerService.ts b/project/src/services/ProfileFixerService.ts index af2fd677..0e6d3457 100644 --- a/project/src/services/ProfileFixerService.ts +++ b/project/src/services/ProfileFixerService.ts @@ -518,9 +518,9 @@ export class ProfileFixerService for (const traderId in pmcProfile.TradersInfo) { const trader = pmcProfile.TradersInfo[traderId]; - if (trader && trader.salesSum === null) + if (trader?.salesSum === undefined) { - this.logger.warning(`trader ${traderId} has a null salesSum value, resetting to 0`); + this.logger.warning(`trader ${traderId} has a undefined salesSum value, resetting to 0`); trader.salesSum = 0; } } @@ -1096,7 +1096,7 @@ export class ProfileFixerService { for (const item of magazineBuild.Items) { - // Magazine builds can have null items in them, skip those + // Magazine builds can have undefined items in them, skip those if (!item) { continue; @@ -1187,10 +1187,10 @@ export class ProfileFixerService item.upd.Tag.Name = item.upd.Tag.Name.replace(regxp, ""); } - // Check items with StackObjectsCount (null) - if (item.upd.StackObjectsCount === null) + // Check items with StackObjectsCount (undefined) + if (item.upd?.StackObjectsCount === undefined) { - this.logger.warning(`Fixed item: ${item._id}s null StackObjectsCount value, now set to 1`); + this.logger.warning(`Fixed item: ${item._id}s undefined StackObjectsCount value, now set to 1`); item.upd.StackObjectsCount = 1; } } @@ -1449,15 +1449,15 @@ export class ProfileFixerService /** * If someone has run a mod from pre-3.8.0, it results in an invalid `nextResupply` value - * Resolve this by setting the nextResupply to 0 if it's null + * Resolve this by setting the nextResupply to 0 if it's undefined */ protected fixNullTraderNextResupply(pmcProfile: IPmcData): void { for (const [traderId, trader] of Object.entries(pmcProfile.TradersInfo)) { - if (trader && trader.nextResupply === null) + if (trader?.nextResupply === undefined) { - this.logger.warning(`trader ${traderId} has a null nextResupply value, resetting to 0`); + this.logger.warning(`trader ${traderId} has a undefined nextResupply value, resetting to 0`); trader.nextResupply = 0; } } diff --git a/project/src/services/RagfairOfferService.ts b/project/src/services/RagfairOfferService.ts index bbd4eee2..867c2eb0 100644 --- a/project/src/services/RagfairOfferService.ts +++ b/project/src/services/RagfairOfferService.ts @@ -42,6 +42,7 @@ export class RagfairOfferService this.ragfairOfferHandler = new RagfairOfferHolder( this.ragfairConfig.dynamic.offerItemCount.max, ragfairServerHelper, + profileHelper, ); } @@ -221,7 +222,7 @@ export class RagfairOfferService { const staleOfferUserId = staleOffer.user.id; const isTrader = this.ragfairServerHelper.isTrader(staleOfferUserId); - const isPlayer = this.ragfairServerHelper.isPlayer(staleOfferUserId.replace(/^pmc/, "")); + const isPlayer = this.profileHelper.isPlayer(staleOfferUserId.replace(/^pmc/, "")); // Skip trader offers, managed by RagfairServer.update() if (isTrader) diff --git a/project/src/utils/HttpResponseUtil.ts b/project/src/utils/HttpResponseUtil.ts index fa2cc8e5..628110f1 100644 --- a/project/src/utils/HttpResponseUtil.ts +++ b/project/src/utils/HttpResponseUtil.ts @@ -61,7 +61,7 @@ export class HttpResponseUtil public nullResponse(): INullResponseData { - return this.clearString(this.getUnclearedBody(null, 0, undefined)); + return this.clearString(this.getUnclearedBody(undefined, 0, undefined)); } public emptyArrayResponse(): IGetBodyResponseData diff --git a/project/src/utils/JsonUtil.ts b/project/src/utils/JsonUtil.ts index 307d3572..a1d31897 100644 --- a/project/src/utils/JsonUtil.ts +++ b/project/src/utils/JsonUtil.ts @@ -31,7 +31,7 @@ export class JsonUtil { if (prettify) { - return JSON.stringify(data, null, "\t"); + return JSON.stringify(data, undefined, "\t"); } return JSON.stringify(data); @@ -60,7 +60,11 @@ export class JsonUtil * @param options Stringify options or a replacer. * @returns The string converted from the JavaScript value */ - public serializeJsonC(data: any, filename?: string | null, options?: IStringifyOptions | Reviver): string | undefined + public serializeJsonC( + data: any, + filename?: string | undefined, + options?: IStringifyOptions | Reviver, + ): string | undefined { try { @@ -74,13 +78,13 @@ export class JsonUtil } } - public serializeJson5(data: any, filename?: string | null, prettify = false): string | undefined + public serializeJson5(data: any, filename?: string | undefined, prettify = false): string | undefined { try { if (prettify) { - return stringify(data, null, "\t"); + return stringify(data, undefined, "\t"); } return stringify(data); diff --git a/project/src/utils/RagfairOfferHolder.ts b/project/src/utils/RagfairOfferHolder.ts index 5bb86f50..d730b78a 100644 --- a/project/src/utils/RagfairOfferHolder.ts +++ b/project/src/utils/RagfairOfferHolder.ts @@ -1,3 +1,4 @@ +import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { RagfairServerHelper } from "@spt/helpers/RagfairServerHelper"; import { IRagfairOffer } from "@spt/models/eft/ragfair/IRagfairOffer"; @@ -10,6 +11,7 @@ export class RagfairOfferHolder constructor( protected maxOffersPerTemplate: number, protected ragfairServerHelper: RagfairServerHelper, + protected profileHelper: ProfileHelper, ) { this.offersById = new Map(); @@ -69,7 +71,7 @@ export class RagfairOfferHolder // If its an NPC PMC offer AND we have already reached the maximum amount of possible offers // for this template, just dont add in more if ( - !(this.ragfairServerHelper.isTrader(trader) || this.ragfairServerHelper.isPlayer(trader)) + !(this.ragfairServerHelper.isTrader(trader) || this.profileHelper.isPlayer(trader)) && (this.getOffersByTemplate(itemTpl)?.length ?? 0) >= this.maxOffersPerTemplate ) { diff --git a/project/src/utils/cloners/RecursiveCloner.ts b/project/src/utils/cloners/RecursiveCloner.ts index 93a763b7..0d920264 100644 --- a/project/src/utils/cloners/RecursiveCloner.ts +++ b/project/src/utils/cloners/RecursiveCloner.ts @@ -37,9 +37,9 @@ export class RecursiveCloner implements ICloner { // If the value of the original property is null, ensure the cloned value is also null // This fixes an issue where null arrays were incorrectly being converted to empty objects - if (obj[propOf1] === null) + if (obj[propOf1] === null || obj[propOf1] === undefined) { - newObj[propOf1.toString()] = null; + newObj[propOf1.toString()] = undefined; continue; } diff --git a/project/src/utils/logging/AbstractWinstonLogger.ts b/project/src/utils/logging/AbstractWinstonLogger.ts index 7ed7e4d9..4c6101be 100644 --- a/project/src/utils/logging/AbstractWinstonLogger.ts +++ b/project/src/utils/logging/AbstractWinstonLogger.ts @@ -163,7 +163,7 @@ export abstract class AbstractWinstonLogger implements ILogger { command = { uuid: crypto.randomUUID(), - cmd: async () => await tmpLogger.log("custom", JSON.stringify(data, null, 4)), + cmd: async () => await tmpLogger.log("custom", JSON.stringify(data, undefined, 4)), }; }