Clothing service fix (!407)

Server implementation of my `TraderServiceFix` mod.

Since 3.9 trader services were refactored by BSG. Resulting in them hard coding service ID's. This PR allows modders to push their trader ID to the `TraderConfig.moddedTraders.clothingService` array. It is then sent to the client where it adds it to the dictionary. I made this modular with its own interface in-case it needs expanded on in the future. So the this acts as both a fix and a groundwork for similar future fixes if need be as well.

Needs merged with https://dev.sp-tarkov.com/SPT/Modules/pulls/165

Co-authored-by: Cj <161484149+CJ-SPT@users.noreply.github.com>
Reviewed-on: https://dev.sp-tarkov.com/SPT/Server/pulls/407
Co-authored-by: Cj <cj@noreply.dev.sp-tarkov.com>
Co-committed-by: Cj <cj@noreply.dev.sp-tarkov.com>
This commit is contained in:
Cj 2024-09-04 08:31:15 +00:00 committed by chomp
parent 0bd794e39d
commit 4139e85f1f
4 changed files with 41 additions and 2 deletions

View File

@ -367,7 +367,10 @@
],
"coopExtractGift": {
"sendGift": true,
"messageLocaleIds": ["5da89b1886f77439d7741002 0", "5da89b3a86f7742f9026cb83 0"],
"messageLocaleIds": [
"5da89b1886f77439d7741002 0",
"5da89b3a86f7742f9026cb83 0"
],
"giftExpiryHours": 168,
"weaponPresetCount": {
"min": 0,
@ -444,5 +447,8 @@
"allowBossItems": false
},
"btrDeliveryExpireHours": 240
},
"moddedTraders": {
"clothingService": []
}
}
}

View File

@ -4,6 +4,9 @@ import { OnUpdate } from "@spt/di/OnUpdate";
import { IEmptyRequestData } from "@spt/models/eft/common/IEmptyRequestData";
import { ITraderAssort, ITraderBase } from "@spt/models/eft/common/tables/ITrader";
import { IGetBodyResponseData } from "@spt/models/eft/httpResponse/IGetBodyResponseData";
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
import { ITraderConfig, ModdedTraders } from "@spt/models/spt/config/ITraderConfig";
import { ConfigServer } from "@spt/servers/ConfigServer";
import { HttpResponseUtil } from "@spt/utils/HttpResponseUtil";
import { inject, injectable } from "tsyringe";
@ -12,6 +15,7 @@ export class TraderCallbacks implements OnLoad, OnUpdate {
constructor(
@inject("HttpResponseUtil") protected httpResponse: HttpResponseUtil, // TODO: delay required
@inject("TraderController") protected traderController: TraderController,
@inject("ConfigServer") protected configServer: ConfigServer,
) {}
public async onLoad(): Promise<void> {
@ -46,4 +50,14 @@ export class TraderCallbacks implements OnLoad, OnUpdate {
const traderID = url.replace("/client/trading/api/getTraderAssort/", "");
return this.httpResponse.getBody(this.traderController.getAssort(sessionID, traderID));
}
/** Handle /singleplayer/moddedTraders */
public getModdedTraderData(
url: string,
info: IEmptyRequestData,
sessionID: string,
): IGetBodyResponseData<ModdedTraders> {
const traderConfig = this.configServer.getConfig(ConfigTypes.TRADER) as ITraderConfig;
return this.httpResponse.noBody(traderConfig.moddedTraders);
}
}

View File

@ -11,6 +11,7 @@ export interface ITraderConfig extends IBaseConfig {
updateTimeDefault: number;
traderPriceMultipler: number;
fence: FenceConfig;
moddedTraders: ModdedTraders;
}
export interface UpdateTime {
@ -69,3 +70,9 @@ export interface DiscountOptions {
weaponPresetMinMax: MinMax;
equipmentPresetMinMax: MinMax;
}
/** Custom trader data needed client side for things such as the clothing service */
export interface ModdedTraders {
/** Trader Ids to enable the clothing service for */
clothingService: string[];
}

View File

@ -2,6 +2,7 @@ import { TraderCallbacks } from "@spt/callbacks/TraderCallbacks";
import { RouteAction, StaticRouter } from "@spt/di/Router";
import { ITraderBase } from "@spt/models/eft/common/tables/ITrader";
import { IGetBodyResponseData } from "@spt/models/eft/httpResponse/IGetBodyResponseData";
import { ModdedTraders } from "@spt/models/spt/config/ITraderConfig";
import { inject, injectable } from "tsyringe";
@injectable()
@ -19,6 +20,17 @@ export class TraderStaticRouter extends StaticRouter {
return this.traderCallbacks.getTraderSettings(url, info, sessionID);
},
),
new RouteAction(
"/singleplayer/moddedTraders",
async (
url: string,
info: any,
sessionID: string,
output: string,
): Promise<IGetBodyResponseData<ModdedTraders>> => {
return this.traderCallbacks.getModdedTraderData(url, info, sessionID);
},
),
]);
}
}