返回提交历史
Modified
src/controllers/api/inventoryController.ts
+19
-4
Modified
src/controllers/api/startRecipeController.ts
+9
-5
Modified
src/models/inventoryModels/inventoryModel.ts
+1
-23
Modified
src/services/inventoryService.ts
+35
-24
Modified
src/services/missionInventoryUpdateService.ts
+2
-6
Modified
src/types/inventoryTypes/inventoryTypes.ts
+5
-10
Modified
src/types/requestTypes.ts
+2
-2
XFEstudio/SpaceNinjaServer
chore: migrate away from KubrowPetEggs (#3760)
Closes #3754 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/3760 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
0ec36553
代码差异
7 个文件
+73
-74
@@ -548,11 +548,26 @@ export const getInventoryResponse = async (
548
548
inventoryResponse.Nemesis = undefined;
549
549
}
550
550
551
// U40 changed the path from /Lotus/Types/Game/KubrowPet/Eggs/KubrowPetEggItem to /Lotus/Types/Game/KubrowPet/Eggs/KubrowEgg
551
// U40 migrated from KubrowPetEggs with ItemType /Lotus/Types/Game/KubrowPet/Eggs/KubrowPetEggItem to MiscItems with ItemType /Lotus/Types/Game/KubrowPet/Eggs/KubrowEgg
552
552
// so translate it back for older versions
553
if (inventoryResponse.KubrowPetEggs && version_compare(buildLabel, gameToBuildVersion["40.0.0"]) < 0) {
554
for (const ke of inventoryResponse.KubrowPetEggs) {
555
ke.ItemType = "/Lotus/Types/Game/KubrowPet/Eggs/KubrowPetEggItem";
553
if (version_compare(buildLabel, gameToBuildVersion["40.0.0"]) < 0) {
554
inventoryResponse.KubrowPetEggs = [];
555
const index = inventoryResponse.MiscItems.findIndex(
556
x => x.ItemType == "/Lotus/Types/Game/KubrowPet/Eggs/KubrowEgg"
557
);
558
if (index != -1) {
559
const numKubrowEggs = Math.min(
560
inventoryResponse.MiscItems[index].ItemCount,
561
100 // capped to avoid sending an overly large array
562
);
563
inventoryResponse.MiscItems.splice(index, 1);
564
for (let i = 0; i != numKubrowEggs; ++i) {
565
inventoryResponse.KubrowPetEggs.push({
566
ItemType: "/Lotus/Types/Game/KubrowPet/Eggs/KubrowPetEggItem",
567
ExpirationDate: toMongoDate2(2000000000000, buildLabel),
568
ItemId: toOid2(i.toString().padStart(24, "0"), buildLabel)
569
});
570
}
556
571
}
557
572
}
558
573
@@ -3,7 +3,14 @@ import { getJSONfromString } from "../../helpers/stringHelpers.ts";
3
3
import { logger } from "../../utils/logger.ts";
4
4
import type { RequestHandler } from "express";
5
5
import { getRecipe } from "../../services/itemDataService.ts";
6
import { addItem, addKubrowPet, freeUpSlot, getInventory, updateCurrency } from "../../services/inventoryService.ts";
6
import {
7
addItem,
8
addKubrowPet,
9
addMiscItem,
10
freeUpSlot,
11
getInventory,
12
updateCurrency
13
} from "../../services/inventoryService.ts";
7
14
import { unixTimesInMs } from "../../constants/timeConstants.ts";
8
15
import { Types } from "mongoose";
9
16
import type { ISpectreLoadout } from "../../types/inventoryTypes/inventoryTypes.ts";
@@ -55,10 +62,7 @@ export const startRecipeController: RequestHandler = async (req, res) => {
55
62
recipe.ingredients[i].ItemType == "/Lotus/Types/Game/KubrowPet/Eggs/KubrowEgg" ||
56
63
recipe.ingredients[i].ItemType == "/Lotus/Types/Game/KubrowPet/Eggs/KubrowPetEggItem"
57
64
) {
58
const index = inventory.KubrowPetEggs.findIndex(x => x._id.equals(startRecipeRequest.Ids[i]));
59
if (index != -1) {
60
inventory.KubrowPetEggs.splice(index, 1);
61
}
65
addMiscItem(inventory, "/Lotus/Types/Game/KubrowPet/Eggs/KubrowEgg", -1);
62
66
} else if (recipe.ingredients[i].ItemType.startsWith("/Lotus/Upgrades/")) {
63
67
const index = inventory.Upgrades.findIndex(x => x._id.equals(startRecipeRequest.Ids[i]));
64
68
if (index != -1) {
@@ -46,8 +46,6 @@ import type {
46
46
IDialogueClient,
47
47
IUpgradeDatabase,
48
48
TEquipmentKey,
49
IKubrowPetEggDatabase,
50
IKubrowPetEggClient,
51
49
ICustomMarkers,
52
50
IMarkerInfo,
53
51
IMarker,
@@ -532,26 +530,6 @@ StepSequencersSchema.set("toJSON", {
532
530
}
533
531
});
534
532
535
const kubrowPetEggSchema = new Schema<IKubrowPetEggDatabase>(
536
{
537
ItemType: String
538
},
539
{ id: false }
540
);
541
kubrowPetEggSchema.set("toJSON", {
542
virtuals: true,
543
transform(_document, obj: Record<string, any>) {
544
const client = obj as IKubrowPetEggClient;
545
const db = obj as IKubrowPetEggDatabase;
546
547
client.ExpirationDate = { $date: { $numberLong: "2000000000000" } };
548
client.ItemId = toOid(db._id);
549
550
delete obj._id;
551
delete obj.__v;
552
}
553
});
554
555
533
const weeklyMissionSchema = new Schema<IWeeklyMission>(
556
534
{
557
535
MissionIndex: Number,
@@ -1728,7 +1706,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
1728
1706
//The Mandachord(Octavia) is a step sequencer
1729
1707
StepSequencers: [StepSequencersSchema],
1730
1708
1731
KubrowPetEggs: [kubrowPetEggSchema],
1709
KubrowPetEggs: { type: [], default: undefined },
1732
1710
//Prints Cat(3 Prints)\Kubrow(2 Prints) Pets
1733
1711
KubrowPetPrints: [kubrowPetPrintSchema],
1734
1712
@@ -14,8 +14,6 @@ import type {
14
14
TEquipmentKey,
15
15
IFusionTreasure,
16
16
IDailyAffiliations,
17
IKubrowPetEggDatabase,
18
IKubrowPetEggClient,
19
17
ILibraryDailyTaskInfo,
20
18
IDroneClient,
21
19
IUpgradeClient,
@@ -27,7 +25,8 @@ import type {
27
25
INemesisPetTargetFingerprint,
28
26
IDialogueDatabase,
29
27
IKubrowPetPrintClient,
30
IWeeklyMissionChallengeInfo
28
IWeeklyMissionChallengeInfo,
29
IKubrowPetEgg
31
30
} from "../types/inventoryTypes/inventoryTypes.ts";
32
31
import { InventorySlot, equipmentKeys } from "../types/inventoryTypes/inventoryTypes.ts";
33
32
import type { IGenericUpdate, IUpdateNodeIntrosResponse } from "../types/genericUpdate.ts";
@@ -77,7 +76,9 @@ import {
77
76
kubrowDetails,
78
77
kubrowFurPatternsWeights,
79
78
kubrowWeights,
79
toMongoDate2,
80
80
toOid,
81
toOid2,
81
82
version_compare
82
83
} from "../helpers/inventoryHelpers.ts";
83
84
import { addQuestKey, completeQuest } from "./questService.ts";
@@ -572,26 +573,6 @@ export const addItem = async (
572
573
return {
573
574
ShipDecorations: changes
574
575
};
575
} else if (ExportResources[typeName].productCategory == "KubrowPetEggs") {
576
const changes: IKubrowPetEggClient[] = [];
577
if (quantity < 0 || quantity > 100) {
578
throw new Error(`unexpected acquisition quantity of KubrowPetEggs: got ${quantity}, expected 0..100`);
579
}
580
for (let i = 0; i != quantity; ++i) {
581
const egg: IKubrowPetEggDatabase = {
582
ItemType: "/Lotus/Types/Game/KubrowPet/Eggs/KubrowEgg",
583
_id: new Types.ObjectId()
584
};
585
inventory.KubrowPetEggs.push(egg);
586
changes.push({
587
ItemType: egg.ItemType,
588
ExpirationDate: { $date: { $numberLong: "2000000000000" } },
589
ItemId: toOid(egg._id) // TODO: Pass on buildLabel from purchaseService
590
});
591
}
592
return {
593
KubrowPetEggs: changes
594
};
595
576
} else {
596
577
throw new Error(`unknown product category: ${ExportResources[typeName].productCategory}`);
597
578
}
@@ -1078,9 +1059,33 @@ export const addItem = async (
1078
1059
);
1079
1060
}
1080
1061
return inventoryChanges;
1062
} else if (typeName == "/Lotus/Types/Game/KubrowPet/Eggs/KubrowPetEggItem") {
1063
// pre-U40 acquisition
1064
if (quantity < 0 || quantity > 100) {
1065
throw new Error(
1066
`unexpected acquisition quantity of KubrowPetEggs: got ${quantity}, expected 0..100`
1067
);
1068
}
1069
const idBase = Math.min(
1070
inventory.MiscItems.find(
1071
x => x.ItemType == "/Lotus/Types/Game/KubrowPet/Eggs/KubrowEgg"
1072
)?.ItemCount ?? 0,
1073
100
1074
);
1075
// add to inventory as a MiscItem
1076
addMiscItem(inventory, "/Lotus/Types/Game/KubrowPet/Eggs/KubrowEgg", quantity);
1077
// but give the client the expected response format
1078
const changes: IKubrowPetEgg[] = [];
1079
for (let i = 0; i != quantity; ++i) {
1080
changes.push({
1081
ItemType: "/Lotus/Types/Game/KubrowPet/Eggs/KubrowPetEggItem",
1082
ExpirationDate: toMongoDate2(2000000000000, buildLabel),
1083
ItemId: toOid2((idBase + i).toString().padStart(24, "0"), buildLabel)
1084
});
1085
}
1086
return { KubrowPetEggs: changes };
1081
1087
} else if (
1082
1088
typeName != "/Lotus/Types/Game/KubrowPet/Eggs/KubrowEgg" &&
1083
typeName != "/Lotus/Types/Game/KubrowPet/Eggs/KubrowPetEggItem" &&
1084
1089
typeName != "/Lotus/Types/Game/KubrowPet/BlankTraitPrint" &&
1085
1090
typeName != "/Lotus/Types/Game/KubrowPet/ImprintedTraitPrint"
1086
1091
) {
@@ -2831,6 +2836,12 @@ export const cleanupInventory = (inventory: TInventoryDatabaseDocument): void =>
2831
2836
inventory.KubrowPets.pull({ _id: pet._id });
2832
2837
}
2833
2838
}
2839
2840
if (inventory.KubrowPetEggs) {
2841
addMiscItem(inventory, "/Lotus/Types/Game/KubrowPet/Eggs/KubrowEgg", inventory.KubrowPetEggs.length);
2842
logger.debug(`migrated ${inventory.KubrowPetEggs.length} KubrowPetEggs to MiscItems`);
2843
inventory.KubrowPetEggs = undefined;
2844
}
2834
2845
};
2835
2846
2836
2847
export const getDialogue = (inventory: TInventoryDatabaseDocument, dialogueName: string): IDialogueDatabase => {
@@ -34,6 +34,7 @@ import {
34
34
addKahlProgress,
35
35
addLevelKeys,
36
36
addLoreFragmentScans,
37
addMiscItem,
37
38
addMiscItems,
38
39
addMissionComplete,
39
40
addMods,
@@ -626,12 +627,7 @@ export const addMissionInventoryUpdates = async (
626
627
break;
627
628
}
628
629
case "KubrowPetEggs": {
629
for (let i = 0; i != value.length; ++i) {
630
inventory.KubrowPetEggs.push({
631
ItemType: "/Lotus/Types/Game/KubrowPet/Eggs/KubrowEgg",
632
_id: new Types.ObjectId()
633
});
634
}
630
addMiscItem(inventory, "/Lotus/Types/Game/KubrowPet/Eggs/KubrowEgg", value.length);
635
631
break;
636
632
}
637
633
case "DiscoveredMarkers": {
@@ -183,7 +183,7 @@ export interface IInventoryDatabase
183
183
KahlLoadOuts: IOperatorConfigDatabase[];
184
184
InfestedFoundry?: IInfestedFoundryDatabase;
185
185
DialogueHistory?: IDialogueHistoryDatabase;
186
KubrowPetEggs: IKubrowPetEggDatabase[];
186
KubrowPetEggs?: [];
187
187
KubrowPetPrints: IKubrowPetPrintDatabase[];
188
188
PendingCoupon?: IPendingCouponDatabase;
189
189
Drones: IDroneDatabase[];
@@ -396,7 +396,7 @@ export interface IInventoryClient
396
396
TauntHistory?: ITaunt[];
397
397
StoryModeChoice: string;
398
398
PeriodicMissionCompletions: IPeriodicMissionCompletionResponse[];
399
KubrowPetEggs?: IKubrowPetEggClient[];
399
KubrowPetEggs?: IKubrowPetEgg[];
400
400
LoreFragmentScans: ILoreFragmentScan[];
401
401
EquippedEmotes: string[];
402
402
//PendingTrades: IPendingTrade[];
@@ -812,15 +812,10 @@ export interface IInvasionProgressDatabase extends Omit<IInvasionProgressClient,
812
812
invasionId: Types.ObjectId;
813
813
}
814
814
815
export interface IKubrowPetEggClient {
815
export interface IKubrowPetEgg {
816
816
ItemType: string;
817
ExpirationDate: IMongoDate; // seems to be set to 7 days ahead @ 0 UTC
818
ItemId: IOid;
819
}
820
821
export interface IKubrowPetEggDatabase {
822
ItemType: string;
823
_id: Types.ObjectId;
817
ExpirationDate: IMongoDateWithLegacySupport; // seems to be set to 7 days ahead @ 0 UTC
818
ItemId: IOidWithLegacySupport;
824
819
}
825
820
826
821
export interface IKubrowPetPrintClient {
@@ -20,7 +20,7 @@ import type {
20
20
ILockedWeaponGroupClient,
21
21
IInvasionProgressClient,
22
22
IWeaponSkinClient,
23
IKubrowPetEggClient,
23
IKubrowPetEgg,
24
24
INemesisClient,
25
25
IUpgradeClient,
26
26
IChallengeInstanceStateClient,
@@ -140,7 +140,7 @@ export type IMissionInventoryUpdateRequest = {
140
140
NumExtraRewards: number;
141
141
Count: number;
142
142
}[];
143
KubrowPetEggs?: IKubrowPetEggClient[];
143
KubrowPetEggs?: IKubrowPetEgg[];
144
144
DiscoveredMarkers?: IDiscoveredMarker[];
145
145
BrandedSuits?: IOid; // sent when captured by g3
146
146
LockedWeaponGroup?: ILockedWeaponGroupClient; // sent when captured by zanuka