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:
parent
74e1119b8c
commit
49414b8805
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user