From c793b7e0b369606e76260c0528472ead3df60317 Mon Sep 17 00:00:00 2001 From: DrakiaXYZ Date: Tue, 3 Sep 2024 06:09:23 +0000 Subject: [PATCH] Fix repair prices for all traders being the same (Should also fix other loyalty related issues) (!405) - The client doesn't expect to receive the player's loyalty level in their profile, so set it to 0 before sending the profile - Slight refactor of `getCompleteProfile` to always clone, so we can modify the data sent to the client without changing it on the server Co-authored-by: DrakiaXYZ <565558+TheDgtl@users.noreply.github.com> Reviewed-on: https://dev.sp-tarkov.com/SPT/Server/pulls/405 Co-authored-by: DrakiaXYZ Co-committed-by: DrakiaXYZ --- project/src/helpers/ProfileHelper.ts | 32 +++++++++++++------ .../src/models/eft/common/tables/IBotBase.ts | 2 +- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/project/src/helpers/ProfileHelper.ts b/project/src/helpers/ProfileHelper.ts index e8a53680..5de033ea 100644 --- a/project/src/helpers/ProfileHelper.ts +++ b/project/src/helpers/ProfileHelper.ts @@ -80,21 +80,24 @@ export class ProfileHelper { return output; } - const fullProfile = this.getFullProfile(sessionId); + const fullProfileClone = this.cloner.clone(this.getFullProfile(sessionId)); + + // Sanitize any data the client can not receive + this.sanitizeProfileForClient(fullProfileClone); // Edge-case, true post raid if (this.profileSnapshotService.hasProfileSnapshot(sessionId)) { return this.postRaidXpWorkaroundFix( sessionId, - fullProfile.characters.pmc, - fullProfile.characters.scav, + fullProfileClone.characters.pmc, + fullProfileClone.characters.scav, output, ); } // PMC must be at array index 0, scav at 1 - output.push(fullProfile.characters.pmc); - output.push(fullProfile.characters.scav); + output.push(fullProfileClone.characters.pmc); + output.push(fullProfileClone.characters.scav); return output; } @@ -113,13 +116,10 @@ export class ProfileHelper { */ protected postRaidXpWorkaroundFix( sessionId: string, - pmcProfile: IPmcData, - scavProfile: IPmcData, + clonedPmc: IPmcData, + clonedScav: IPmcData, output: IPmcData[], ): IPmcData[] { - const clonedPmc = this.cloner.clone(pmcProfile); - const clonedScav = this.cloner.clone(scavProfile); - const profileSnapshot = this.profileSnapshotService.getProfileSnapshot(sessionId); clonedPmc.Info.Level = profileSnapshot.characters.pmc.Info.Level; clonedPmc.Info.Experience = profileSnapshot.characters.pmc.Info.Experience; @@ -135,6 +135,18 @@ export class ProfileHelper { return output; } + /** + * Sanitize any information from the profile that the client does not expect to receive + * @param clonedProfile A clone of the full player profile + */ + protected sanitizeProfileForClient(clonedProfile: ISptProfile) { + // Remove `loyaltyLevel` from `TradersInfo`, as otherwise it causes the client to not + // properly calculate the player's `loyaltyLevel` + for (const traderInfo of Object.values(clonedProfile.characters.pmc.TradersInfo)) { + traderInfo.loyaltyLevel = undefined; + } + } + /** * Check if a nickname is used by another profile loaded by the server * @param nicknameRequest nickname request object diff --git a/project/src/models/eft/common/tables/IBotBase.ts b/project/src/models/eft/common/tables/IBotBase.ts index 4f60501c..ba58badd 100644 --- a/project/src/models/eft/common/tables/IBotBase.ts +++ b/project/src/models/eft/common/tables/IBotBase.ts @@ -458,7 +458,7 @@ export interface IQuestStatus { } export interface TraderInfo { - loyaltyLevel: number; + loyaltyLevel?: number; salesSum: number; standing: number; nextResupply: number;