From dcd70fb5b5d143f8c40999f0d68d2d85be1fe526 Mon Sep 17 00:00:00 2001 From: Dev Date: Tue, 12 Mar 2024 14:27:07 +0000 Subject: [PATCH] Allow traders to have timers be based on amount of time to next hour (bsg style) OR spt server start time --- project/assets/configs/trader.json | 1 + project/src/controllers/TraderController.ts | 21 ++++++++++++++++--- .../src/models/spt/config/ITraderConfig.ts | 2 ++ project/src/utils/TimeUtil.ts | 8 +++++++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/project/assets/configs/trader.json b/project/assets/configs/trader.json index 62bbee0a..5d5247f5 100644 --- a/project/assets/configs/trader.json +++ b/project/assets/configs/trader.json @@ -42,6 +42,7 @@ } ], "updateTimeDefault": 3600, + "tradersResetFromServerStart": false, "purchasesAreFoundInRaid": false, "traderPriceMultipler": 1, "persistPurchaseDataInProfile": true, diff --git a/project/src/controllers/TraderController.ts b/project/src/controllers/TraderController.ts index a727532d..ca9cea94 100644 --- a/project/src/controllers/TraderController.ts +++ b/project/src/controllers/TraderController.ts @@ -5,19 +5,26 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { TraderAssortHelper } from "@spt-aki/helpers/TraderAssortHelper"; import { TraderHelper } from "@spt-aki/helpers/TraderHelper"; import { ITraderAssort, ITraderBase } from "@spt-aki/models/eft/common/tables/ITrader"; +import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes"; import { Traders } from "@spt-aki/models/enums/Traders"; +import { ITraderConfig } from "@spt-aki/models/spt/config/ITraderConfig"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; +import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { FenceService } from "@spt-aki/services/FenceService"; import { TraderAssortService } from "@spt-aki/services/TraderAssortService"; import { TraderPurchasePersisterService } from "@spt-aki/services/TraderPurchasePersisterService"; import { JsonUtil } from "@spt-aki/utils/JsonUtil"; +import { TimeUtil } from "@spt-aki/utils/TimeUtil"; @injectable() export class TraderController { + protected traderConfig: ITraderConfig; + constructor( @inject("WinstonLogger") protected logger: ILogger, + @inject("TimeUtil") protected timeUtil: TimeUtil, @inject("DatabaseServer") protected databaseServer: DatabaseServer, @inject("TraderAssortHelper") protected traderAssortHelper: TraderAssortHelper, @inject("ProfileHelper") protected profileHelper: ProfileHelper, @@ -28,16 +35,21 @@ export class TraderController @inject("FenceService") protected fenceService: FenceService, @inject("FenceBaseAssortGenerator") protected fenceBaseAssortGenerator: FenceBaseAssortGenerator, @inject("JsonUtil") protected jsonUtil: JsonUtil, + @inject("ConfigServer") protected configServer: ConfigServer, ) - {} + { + this.traderConfig = this.configServer.getConfig(ConfigTypes.TRADER); + } /** * Runs when onLoad event is fired - * Iterate over traders, ensure an unmolested copy of their assorts is stored in traderAssortService + * Iterate over traders, ensure a pristine copy of their assorts is stored in traderAssortService * Store timestamp of next assort refresh in nextResupply property of traders .base object */ public load(): void { + const nextHourTimestamp = this.timeUtil.getTimestampOfNextHour(); + const traderResetStartsWithServer = this.traderConfig.tradersResetFromServerStart; for (const traderId in this.databaseServer.getTables().traders) { if (traderId === "ragfair" || traderId === Traders.LIGHTHOUSEKEEPER) @@ -63,7 +75,10 @@ export class TraderController this.traderPurchasePersisterService.removeStalePurchasesFromProfiles(traderId); - trader.base.nextResupply = this.traderHelper.getNextUpdateTimestamp(trader.base._id); + // Set to next hour on clock or current time + 60 mins + trader.base.nextResupply = traderResetStartsWithServer + ? this.traderHelper.getNextUpdateTimestamp(trader.base._id) + : nextHourTimestamp; this.databaseServer.getTables().traders[trader.base._id].base = trader.base; } } diff --git a/project/src/models/spt/config/ITraderConfig.ts b/project/src/models/spt/config/ITraderConfig.ts index 9af3fc4d..04c666c8 100644 --- a/project/src/models/spt/config/ITraderConfig.ts +++ b/project/src/models/spt/config/ITraderConfig.ts @@ -7,6 +7,8 @@ export interface ITraderConfig extends IBaseConfig kind: "aki-trader"; updateTime: UpdateTime[]; purchasesAreFoundInRaid: boolean; + /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ + tradersResetFromServerStart: boolean; updateTimeDefault: number; traderPriceMultipler: number; /** Keep track of purchased trader-limited items beyond server restarts to prevent server-restart item scumming */ diff --git a/project/src/utils/TimeUtil.ts b/project/src/utils/TimeUtil.ts index bea77e43..db03ac70 100644 --- a/project/src/utils/TimeUtil.ts +++ b/project/src/utils/TimeUtil.ts @@ -108,4 +108,12 @@ export class TimeUtil { return hours * TimeUtil.ONE_HOUR_AS_SECONDS; } + + public getTimestampOfNextHour(): number + { + const now = new Date(); + const millisecondsUntilNextHour = (60 - now.getMinutes()) * 60 * 1000 - now.getSeconds() * 1000 + - now.getMilliseconds(); + return (now.getTime() + millisecondsUntilNextHour) / 1000; + } }