Skip to content

Commit d34eca3

Browse files
DrakiaXYZchompDev
andauthored
Further favorite item/weapon functionality and fixes (#974)
- Resolve issue where we were storing favorites in the incorrect format, resulting in a client error on game load - Resolve issue where we were clearing favorites when they were meant to be saved - On login, fix any previously corrupted favorites array - Properly implement favorite data in `getOtherProfile`, now shows your favorites when viewing your profile Co-authored-by: DrakiaXYZ <565558+TheDgtl@users.noreply.github.com> Co-authored-by: Chomp <27521899+chompDev@users.noreply.github.com>
1 parent fdca5d3 commit d34eca3

File tree

5 files changed

+56
-17
lines changed

5 files changed

+56
-17
lines changed

project/src/controllers/InventoryController.ts

+8-15
Original file line numberDiff line numberDiff line change
@@ -928,24 +928,17 @@ export class InventoryController {
928928
}
929929

930930
public setFavoriteItem(pmcData: IPmcData, request: ISetFavoriteItems, sessionId: string): void {
931-
if (!pmcData.Inventory.favoriteItems) {
932-
pmcData.Inventory.favoriteItems = [];
933-
}
931+
// The client sends the full list of favorite items, so clear the current favorites
932+
pmcData.Inventory.favoriteItems = [];
934933

935934
for (const itemId of request.items) {
936-
// If id already exists in array, we're removing it
937-
const indexOfItemAlreadyFavorited = pmcData.Inventory.favoriteItems.findIndex((x) => x._id === itemId);
938-
if (indexOfItemAlreadyFavorited > -1) {
939-
pmcData.Inventory.favoriteItems.splice(indexOfItemAlreadyFavorited, 1);
940-
} else {
941-
const item = pmcData.Inventory.items.find((i) => i._id === itemId);
942-
943-
if (item === undefined) {
944-
continue;
945-
}
946-
947-
pmcData.Inventory.favoriteItems.push(item);
935+
// Leaving this in as validation that the item exists in the profile
936+
const item = pmcData.Inventory.items.find((i) => i._id === itemId);
937+
if (item === undefined) {
938+
continue;
948939
}
940+
941+
pmcData.Inventory.favoriteItems.push(itemId);
949942
}
950943
}
951944

project/src/controllers/ProfileController.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,9 @@ export class ProfileController {
401401
return response;
402402
}
403403

404+
/**
405+
* Handle client/profile/view
406+
*/
404407
public getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse {
405408
const player = this.profileHelper.getFullProfile(sessionId);
406409
const playerPmc = player.characters.pmc;
@@ -431,7 +434,7 @@ export class ProfileController {
431434
Items: playerPmc.Inventory.items,
432435
},
433436
achievements: playerPmc.Achievements,
434-
favoriteItems: playerPmc.Inventory.favoriteItems ?? [],
437+
favoriteItems: this.profileHelper.getOtherProfileFavorites(playerPmc),
435438
pmcStats: {
436439
eft: {
437440
totalInGameTime: playerPmc.Stats.Eft.TotalInGameTime,

project/src/helpers/ProfileHelper.ts

+25
Original file line numberDiff line numberDiff line change
@@ -533,4 +533,29 @@ export class ProfileHelper {
533533
public getQuestItemsInProfile(profile: IPmcData): IItem[] {
534534
return profile.Inventory.items.filter((item) => item.parentId === profile.Inventory.questRaidItems);
535535
}
536+
537+
/**
538+
* Return a favorites array in the format expected by the getOtherProfile call
539+
* @param profile
540+
* @returns An array of IItem objects representing the favorited data
541+
*/
542+
public getOtherProfileFavorites(profile: IPmcData): IItem[] {
543+
let fullFavorites = [];
544+
545+
for (const itemId of profile.Inventory.favoriteItems ?? [])
546+
{
547+
// When viewing another users profile, the client expects a full item with children, so get that
548+
const itemAndChildren = this.itemHelper.findAndReturnChildrenAsItems(profile.Inventory.items, itemId);
549+
if (itemAndChildren && itemAndChildren.length > 0)
550+
{
551+
// To get the client to actually see the items, we set the main item's parent to null, so it's treated as a root item
552+
const clonedItems = this.cloner.clone(itemAndChildren);
553+
clonedItems[0].parentId = null;
554+
555+
fullFavorites = fullFavorites.concat(clonedItems);
556+
}
557+
}
558+
559+
return fullFavorites;
560+
}
536561
}

project/src/models/eft/common/tables/IBotBase.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ export interface IInventory {
169169
/** Key is hideout area enum numeric as string e.g. "24", value is area _id */
170170
hideoutAreaStashes: Record<string, string>;
171171
fastPanel: Record<string, string>;
172-
favoriteItems: IItem[];
172+
favoriteItems: string[];
173173
}
174174

175175
export interface IBaseJsonSkills {

project/src/services/ProfileFixerService.ts

+18
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ export class ProfileFixerService {
6464
this.removeDanglingTaskConditionCounters(pmcProfile);
6565
this.removeOrphanedQuests(pmcProfile);
6666
this.verifyQuestProductionUnlocks(pmcProfile);
67+
this.fixFavorites(pmcProfile);
6768

6869
if (pmcProfile.Hideout) {
6970
this.addHideoutEliteSlots(pmcProfile);
@@ -341,6 +342,23 @@ export class ProfileFixerService {
341342
}
342343
}
343344

345+
/**
346+
* Initial release of SPT 3.10 used an incorrect favorites structure, reformat
347+
* the structure to the correct MongoID array structure
348+
* @param pmcProfile
349+
*/
350+
protected fixFavorites(pmcProfile: IPmcData): void {
351+
const favoritesAsAny = pmcProfile.Inventory?.favoriteItems as any;
352+
if (favoritesAsAny)
353+
{
354+
const correctedFavorites = favoritesAsAny.map((favorite) => {
355+
return favorite._id ?? favorite;
356+
});
357+
358+
pmcProfile.Inventory.favoriteItems = correctedFavorites ?? [];
359+
}
360+
}
361+
344362
/**
345363
* If the profile has elite Hideout Managment skill, add the additional slots from globals
346364
* NOTE: This seems redundant, but we will leave it here just incase.

0 commit comments

Comments
 (0)