0
0
mirror of https://github.com/sp-tarkov/server.git synced 2025-02-12 15:50:42 -05:00

Fix issue where insurance messages would appear as received if you only lost gear you were wearing (#993)

- Insurance messages each need a unique "stash" ID, properly handle this
as part of the processing side of insurance
- Remove handling of parent IDs from the insurance storing side of
insurance, as we don't need to do that processing twice
- Add a new step to the profileFixer service that resolves any already
broken trader messages with attached insurance items

---------

Co-authored-by: DrakiaXYZ <565558+TheDgtl@users.noreply.github.com>
Co-authored-by: Chomp <27521899+chompDev@users.noreply.github.com>
This commit is contained in:
DrakiaXYZ 2024-12-23 05:26:10 -08:00 committed by GitHub
parent 74e1119b8c
commit 49414b8805
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 45 additions and 34 deletions

View File

@ -148,6 +148,10 @@ export class GameController {
fullProfile.characters.scav.WishList = {}; fullProfile.characters.scav.WishList = {};
} }
if (fullProfile.dialogues) {
this.profileFixerService.checkForAndFixDialogueAttachments(fullProfile);
}
this.logger.debug(`Started game with sessionId: ${sessionID} ${fullProfile.info.username}`); this.logger.debug(`Started game with sessionId: ${sessionID} ${fullProfile.info.username}`);
const pmcProfile = fullProfile.characters.pmc; const pmcProfile = fullProfile.characters.pmc;

View File

@ -123,11 +123,14 @@ export class InsuranceController {
)} items, in profile ${sessionID}`, )} items, in profile ${sessionID}`,
); );
// Fetch the root Item parentId property value that should be used for insurance packages.
const rootItemParentID = this.insuranceService.getRootItemParentID(sessionID);
// Iterate over each of the insurance packages. // Iterate over each of the insurance packages.
for (const insured of insuranceDetails) { for (const insured of insuranceDetails) {
// Create a new root parent ID for the message we'll be sending the player
const rootItemParentID = this.hashUtil.generate();
// Update the insured items to have the new root parent ID for root/orphaned items
insured.items = this.itemHelper.adoptOrphanedItems(rootItemParentID, insured.items);
const simulateItemsBeingTaken = this.insuranceConfig.simulateItemsBeingTaken; const simulateItemsBeingTaken = this.insuranceConfig.simulateItemsBeingTaken;
if (simulateItemsBeingTaken) { if (simulateItemsBeingTaken) {
// Find items that could be taken by another player off the players body // Find items that could be taken by another player off the players body
@ -135,10 +138,10 @@ export class InsuranceController {
// Actually remove them. // Actually remove them.
this.removeItemsFromInsurance(insured, itemsToDelete); this.removeItemsFromInsurance(insured, itemsToDelete);
}
// Ensure that all items have a valid parent. // There's a chance we've orphaned weapon attachments, so adopt any orphaned items again
insured.items = this.itemHelper.adoptOrphanedItems(rootItemParentID, insured.items); insured.items = this.itemHelper.adoptOrphanedItems(rootItemParentID, insured.items);
}
// Send the mail to the player. // Send the mail to the player.
this.sendMail(sessionID, insured); this.sendMail(sessionID, insured);

View File

@ -176,21 +176,6 @@ export class InsuranceService {
return this.timeUtil.getTimestamp() + finalReturnTimeSeconds; return this.timeUtil.getTimestamp() + finalReturnTimeSeconds;
} }
/**
* Take the insurance item packages within a profile session and ensure that each of the items in that package are
* not orphaned from their parent ID.
*
* @param sessionID The session ID to update insurance equipment packages in.
* @returns void
*/
protected adoptOrphanedInsEquipment(sessionID: string): void {
const rootID = this.getRootItemParentID(sessionID);
const insuranceData = this.getInsurance(sessionID);
for (const [traderId, items] of Object.entries(insuranceData)) {
this.insured[sessionID][traderId] = this.itemHelper.adoptOrphanedItems(rootID, items);
}
}
protected getMaxInsuranceStorageTime(traderBase: ITraderBase): number { protected getMaxInsuranceStorageTime(traderBase: ITraderBase): number {
if (this.insuranceConfig.storageTimeOverrideSeconds > 0) { if (this.insuranceConfig.storageTimeOverrideSeconds > 0) {
// Override exists, use instead of traders value // Override exists, use instead of traders value
@ -209,9 +194,6 @@ export class InsuranceService {
for (const gear of equipmentPkg) { for (const gear of equipmentPkg) {
this.addGearToSend(gear); this.addGearToSend(gear);
} }
// Items are separated into their individual trader packages, now we can ensure that they all have valid parents
this.adoptOrphanedInsEquipment(sessionID);
} }
/** /**
@ -347,14 +329,4 @@ export class InsuranceService {
return Math.ceil(price); return Math.ceil(price);
} }
/**
* Returns the ID that should be used for a root-level Item's parentId property value within in the context of insurance.
* @param sessionID Players id
* @returns The root item Id.
*/
public getRootItemParentID(sessionID: string): string {
// Try to use the equipment id from the profile. I'm not sure this is strictly required, but it feels neat.
return this.saveServer.getProfile(sessionID)?.characters?.pmc?.Inventory?.equipment ?? this.hashUtil.generate();
}
} }

View File

@ -75,6 +75,38 @@ export class ProfileFixerService {
} }
} }
/**
* Resolve any dialogue attachments that were accidentally created using the player's equipment ID as
* the stash root object ID
* @param fullProfile
*/
public checkForAndFixDialogueAttachments(fullProfile: ISptProfile): void {
for (const traderDialogues of Object.values(fullProfile.dialogues)) {
for (const message of traderDialogues?.messages) {
// Skip any messages without attached items
if (!message.items?.data || !message.items?.stash) {
continue;
}
// Skip any messages that don't have a stashId collision with the player's equipment ID
if (message.items?.stash !== fullProfile.characters?.pmc?.Inventory?.equipment) {
continue;
}
// Otherwise we need to generate a new unique stash ID for this message's attachments
message.items.stash = this.hashUtil.generate();
message.items.data = this.itemHelper.adoptOrphanedItems(message.items.stash, message.items.data);
// Because `adoptOrphanedItems` sets the slotId to `hideout`, we need to re-set it to `main` to work with mail
for (const item of message.items.data) {
if (item.slotId === "hideout") {
item.slotId = "main";
}
}
}
}
}
/** /**
* Find issues in the scav profile data that may cause issues * Find issues in the scav profile data that may cause issues
* @param scavProfile profile to check and fix * @param scavProfile profile to check and fix