Improved replaceIDs Method in ItemHelper

- Implemented deep cloning of input Items to prevent mutation.
- Reordered parameters: Items (required) now precede PMC data (optional).
- Updated method calls to bring them inline with these changes.
This commit is contained in:
Refringe 2024-02-05 22:22:03 -05:00
parent c29482394b
commit 42dabc057b
No known key found for this signature in database
GPG Key ID: 64E03E5F892C6F9E
13 changed files with 33 additions and 32 deletions

View File

@ -77,7 +77,7 @@ export class BuildController
// Replace duplicate Id's. The first item is the base item.
// The root ID and the base item ID need to match.
body.Items = this.itemHelper.replaceIDs(pmcData, body.Items);
body.Items = this.itemHelper.replaceIDs(body.Items, pmcData);
body.Root = body.Items[0]._id;
// Create new object ready to save into profile userbuilds.weaponBuilds
@ -112,7 +112,7 @@ export class BuildController
// Replace duplicate ID's. The first item is the base item.
// Root ID and the base item ID need to match.
request.Items = this.itemHelper.replaceIDs(pmcData, request.Items);
request.Items = this.itemHelper.replaceIDs(request.Items, pmcData);
const newBuild: IEquipmentBuild = {
Id: request.Id,

View File

@ -799,7 +799,7 @@ export class HideoutController
const preset = this.presetHelper.getDefaultPreset(recipe.endProduct);
// Ensure preset has unique ids and is cloned so we don't alter the preset data stored in memory
const presetAndMods: Item[] = this.itemHelper.replaceIDs(null, this.jsonUtil.clone(preset._items));
const presetAndMods: Item[] = this.itemHelper.replaceIDs(preset._items);
this.itemHelper.remapRootItemId(presetAndMods);
@ -836,11 +836,7 @@ export class HideoutController
const countOfItemsToReward = recipe.count;
for (let index = 1; index < countOfItemsToReward; index++)
{
const itemAndMods: Item[] = this.itemHelper.replaceIDs(
null,
this.jsonUtil.clone(itemAndChildrenToSendToPlayer[0]),
);
const itemAndMods: Item[] = this.itemHelper.replaceIDs(itemAndChildrenToSendToPlayer[0]);
itemAndChildrenToSendToPlayer.push(...[itemAndMods]);
}
}

View File

@ -141,8 +141,8 @@ export class InraidController
this.markOrRemoveFoundInRaidItems(postRaidRequest);
postRaidRequest.profile.Inventory.items = this.itemHelper.replaceIDs(
postRaidRequest.profile,
postRaidRequest.profile.Inventory.items,
postRaidRequest.profile,
serverPmcProfile.InsuredItems,
postRaidRequest.profile.Inventory.fastPanel,
);
@ -317,8 +317,8 @@ export class InraidController
this.markOrRemoveFoundInRaidItems(postRaidRequest);
postRaidRequest.profile.Inventory.items = this.itemHelper.replaceIDs(
postRaidRequest.profile,
postRaidRequest.profile.Inventory.items,
postRaidRequest.profile,
serverPmcProfile.InsuredItems,
postRaidRequest.profile.Inventory.fastPanel,
);

View File

@ -164,10 +164,10 @@ export class ProfileController
pmcData.UnlockedInfo = { unlockedProductionRecipe: [] };
}
// Change item id's to be unique
// Change item IDs to be unique
pmcData.Inventory.items = this.itemHelper.replaceIDs(
pmcData,
pmcData.Inventory.items,
pmcData,
null,
pmcData.Inventory.fastPanel,
);

View File

@ -124,7 +124,7 @@ export class FenceBaseAssortGenerator
}
// Construct preset + mods
const itemAndChildren: Item[] = this.itemHelper.replaceIDs(null, this.jsonUtil.clone(defaultPreset._items));
const itemAndChildren: Item[] = this.itemHelper.replaceIDs(defaultPreset._items);
// Find root item and add some properties to it
for (let i = 0; i < itemAndChildren.length; i++)

View File

@ -389,7 +389,7 @@ export class LootGenerator
chosenWeaponPreset = this.randomUtil.getArrayValue(this.presetHelper.getPresets(chosenWeaponTpl));
}
const presetAndMods: Item[] = this.itemHelper.replaceIDs(null, this.jsonUtil.clone(chosenWeaponPreset._items));
const presetAndMods: Item[] = this.itemHelper.replaceIDs(chosenWeaponPreset._items);
this.itemHelper.remapRootItemId(presetAndMods);
// Add preset to return object

View File

@ -86,7 +86,7 @@ export class RagfairAssortGenerator
for (const preset of presets)
{
// Update Ids and clone
const presetAndMods: Item[] = this.itemHelper.replaceIDs(null, this.jsonUtil.clone(preset._items));
const presetAndMods: Item[] = this.itemHelper.replaceIDs(preset._items);
this.itemHelper.remapRootItemId(presetAndMods);
// Add presets base item tpl to the processed list so its skipped later on when processing items

View File

@ -311,7 +311,7 @@ export class ScavCaseRewardGenerator
}
// Ensure preset has unique ids and is cloned so we don't alter the preset data stored in memory
const presetAndMods: Item[] = this.itemHelper.replaceIDs(null, this.jsonUtil.clone(preset._items));
const presetAndMods: Item[] = this.itemHelper.replaceIDs(preset._items);
this.itemHelper.remapRootItemId(presetAndMods);
resultItem = presetAndMods;

View File

@ -104,7 +104,7 @@ export class GiveSptCommand implements ISptCommand
for (let i = 0; i < +quantity; i++)
{
// Make sure IDs are unique before adding to array - prevent collisions
const presetToSend = this.itemHelper.replaceIDs(null, this.jsonUtil.clone(preset._items));
const presetToSend = this.itemHelper.replaceIDs(preset._items);
itemsToSend.push(...presetToSend);
}
}

View File

@ -645,30 +645,36 @@ export class ItemHelper
}
/**
* Regenerate all guids with new ids, exceptions are for items that cannot be altered (e.g. stash/sorting table)
* Regenerate all GUIDs with new IDs, for the exception of special item types (e.g. quest, sorting table, etc.) This
* function will not mutate the original items array, but will return a new array with new GUIDs.
*
* @param originalItems Items to adjust the IDs of
* @param pmcData Player profile
* @param items Items to adjust ID values of
* @param insuredItems insured items to not replace ids for
* @param fastPanel
* @param insuredItems Insured items that should not have their IDs replaced
* @param fastPanel Quick slot panel
* @returns Item[]
*/
public replaceIDs(pmcData: IPmcData, items: Item[], insuredItems: InsuredItem[] = null, fastPanel = null): Item[]
public replaceIDs(
originalItems: Item[],
pmcData: IPmcData | null = null,
insuredItems: InsuredItem[] | null = null,
fastPanel = null,
): Item[]
{
// replace bsg shit long ID with proper one
let items = this.jsonUtil.clone(originalItems); // Deep-clone the items to avoid mutation.
let serialisedInventory = this.jsonUtil.serialize(items);
for (const item of items)
{
if (pmcData !== null)
{
// Insured items shouldn't be renamed
// only works for pmcs.
// Insured items should not be renamed. Only works for PMCs.
if (insuredItems?.find((insuredItem) => insuredItem.itemId === item._id))
{
continue;
}
// Do not replace important ID's
// Do not replace the IDs of specific types of items.
if (
item._id === pmcData.Inventory.equipment
|| item._id === pmcData.Inventory.questRaidItems
@ -681,10 +687,9 @@ export class ItemHelper
}
}
// replace id
// Replace the ID of the item in the serialised inventory using a regular expression.
const oldId = item._id;
const newId = this.hashUtil.generate();
serialisedInventory = serialisedInventory.replace(new RegExp(oldId, "g"), newId);
// Also replace in quick slot if the old ID exists.

View File

@ -351,7 +351,7 @@ export class QuestHelper
if (defaultPreset)
{
// Found preset, use mods to hydrate reward item
const presetAndMods: Item[] = this.itemHelper.replaceIDs(null, this.jsonUtil.clone(defaultPreset._items));
const presetAndMods: Item[] = this.itemHelper.replaceIDs(defaultPreset._items);
const newRootId = this.itemHelper.remapRootItemId(presetAndMods);
questReward.items = presetAndMods;

View File

@ -455,7 +455,7 @@ export class FenceService
continue;
}
const desiredAssortItemAndChildrenClone = this.jsonUtil.clone(
let desiredAssortItemAndChildrenClone = this.jsonUtil.clone(
this.itemHelper.findAndReturnChildrenAsItems(baseFenceAssort.items, chosenBaseAssortRoot._id),
);
@ -492,7 +492,7 @@ export class FenceService
}
// MUST randomise Ids as its possible to add the same base fence assort twice = duplicate IDs = dead client
this.itemHelper.replaceIDs(null, desiredAssortItemAndChildrenClone);
desiredAssortItemAndChildrenClone = this.itemHelper.replaceIDs(desiredAssortItemAndChildrenClone);
this.itemHelper.remapRootItemId(desiredAssortItemAndChildrenClone);
const rootItemBeingAdded = desiredAssortItemAndChildrenClone[0];

View File

@ -435,7 +435,7 @@ export class MailSendService
itemsToSendToPlayer = { stash: parentItem.parentId, data: [] };
// Ensure Ids are unique and cont collide with items in player inventory later
messageDetails.items = this.itemHelper.replaceIDs(null, messageDetails.items);
messageDetails.items = this.itemHelper.replaceIDs(messageDetails.items);
for (const reward of messageDetails.items)
{