返回提交历史
Modified
src/controllers/api/adoptPetController.ts
+2
-2
Modified
src/controllers/api/claimCompletedRecipeController.ts
+2
-2
Modified
src/controllers/api/inventoryController.ts
+3
-1
Modified
src/controllers/api/maturePetController.ts
+1
-1
Modified
src/controllers/api/modularWeaponCraftingController.ts
+2
-2
Modified
src/controllers/api/renamePetController.ts
+1
-1
Modified
src/controllers/api/retrievePetFromStasisController.ts
+3
-3
Modified
src/controllers/api/startRecipeController.ts
+1
-1
Modified
src/models/inventoryModels/inventoryModel.ts
+12
-3
Modified
src/services/importService.ts
+3
-2
Modified
src/services/inventoryService.ts
+0
-7
Modified
src/types/equipmentTypes.ts
+4
-1
Modified
src/types/inventoryTypes/inventoryTypes.ts
+3
-0
XFEstudio/SpaceNinjaServer
chore: guarantee that KubrowPets have Details by schema validation (#4005)
Also changed the typings accordingly. Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/4005 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
f5eb3a02
代码差异
13 个文件
+37
-26
@@ -8,11 +8,11 @@ export const adoptPetController: RequestHandler = async (req, res) => {
8
8
const accountId = await getAccountIdForRequest(req);
9
9
const inventory = await getInventory(accountId, "KubrowPets");
10
10
const data = getJSONfromString<IAdoptPetRequest>(String(req.body));
11
const details = inventory.KubrowPets.id(data.petId)!.Details!;
11
const details = inventory.KubrowPets.id(data.petId)!.Details;
12
12
details.Name = data.name;
13
13
let canSetActive = true;
14
14
for (const pet of inventory.KubrowPets) {
15
if (pet.Details!.Status == Status.StatusAvailable) {
15
if (pet.Details.Status == Status.StatusAvailable) {
16
16
canSetActive = false;
17
17
break;
18
18
}
@@ -185,13 +185,13 @@ const claimCompletedRecipe = async (
185
185
if (recipe.secretIngredientAction == "SIA_CREATE_KUBROW") {
186
186
// This request is sent automatically once the pending recipe is completed.
187
187
const pet = inventory.KubrowPets.id(pendingRecipe.KubrowPet!)!;
188
pet.Details!.Status = Status.StatusIncubated;
188
pet.Details.Status = Status.StatusIncubated;
189
189
} else if (recipe.secretIngredientAction == "SIA_DISTILL_PRINT") {
190
190
const pet = inventory.KubrowPets.id(pendingRecipe.KubrowPet!)!;
191
191
addKubrowPetPrint(
192
192
inventory,
193
193
"/Lotus/Types/Game/KubrowPet/ImprintedTraitPrint",
194
pet.Details!,
194
pet.Details,
195
195
resp.InventoryChanges
196
196
);
197
197
} else if (recipe.secretIngredientAction != "SIA_UNBRAND") {
@@ -337,7 +337,9 @@ export const inventoryController: RequestHandler = async (request, response) =>
337
337
}
338
338
339
339
if (inventory.QuestKeys.some(x => x.ItemType.endsWith("KubrowQuestKeyChain") && x.Completed)) {
340
inventory.KubrowPets.forEach(item => item.Details && (item.Details.HasCollar = true));
340
for (const item of inventory.KubrowPets) {
341
item.Details.HasCollar = true;
342
}
341
343
}
342
344
await handleTauMemories(inventory);
343
345
@@ -8,7 +8,7 @@ export const maturePetController: RequestHandler = async (req, res) => {
8
8
const accountId = await getAccountIdForRequest(req);
9
9
const inventory = await getInventory(accountId, "KubrowPets");
10
10
const data = getJSONfromString<IMaturePetRequest>(String(req.body));
11
const details = inventory.KubrowPets.id(data.petId)!.Details!;
11
const details = inventory.KubrowPets.id(data.petId)!.Details;
12
12
details.IsPuppy = data.revert;
13
13
await inventory.save();
14
14
res.json({
@@ -19,7 +19,7 @@ import { modularWeaponTypes } from "../../helpers/modularWeaponHelper.ts";
19
19
import { getRandomInt } from "../../services/rngService.ts";
20
20
import type { IDefaultUpgrade } from "warframe-public-export-plus";
21
21
import { ExportSentinels, ExportWeapons } from "warframe-public-export-plus";
22
import type { IEquipmentDatabase } from "../../types/equipmentTypes.ts";
22
import type { IKubrowPetDatabase } from "../../types/equipmentTypes.ts";
23
23
import { Status } from "../../types/equipmentTypes.ts";
24
24
25
25
interface IModularCraftRequest {
@@ -38,7 +38,7 @@ export const modularWeaponCraftingController: RequestHandler = async (req, res)
38
38
const inventory = await getInventory(accountId);
39
39
40
40
let defaultUpgrades: IDefaultUpgrade[] | undefined;
41
const defaultOverwrites: Partial<IEquipmentDatabase> = {
41
const defaultOverwrites: Partial<IKubrowPetDatabase> = {
42
42
ModularParts: data.Parts
43
43
};
44
44
const inventoryChanges: IInventoryChanges = {};
@@ -9,7 +9,7 @@ export const renamePetController: RequestHandler = async (req, res) => {
9
9
const accountId = await getAccountIdForRequest(req);
10
10
const inventory = await getInventory(accountId, "KubrowPets PremiumCredits PremiumCreditsFree");
11
11
const data = getJSONfromString<IRenamePetRequest>(String(req.body));
12
const details = inventory.KubrowPets.id(data.petId)!.Details!;
12
const details = inventory.KubrowPets.id(data.petId)!.Details;
13
13
14
14
details.Name = data.name;
15
15
@@ -11,14 +11,14 @@ export const retrievePetFromStasisController: RequestHandler = async (req, res)
11
11
12
12
let oldPetId: string | undefined;
13
13
for (const pet of inventory.KubrowPets) {
14
if (pet.Details!.Status == Status.StatusAvailable) {
15
pet.Details!.Status = Status.StatusStasis;
14
if (pet.Details.Status == Status.StatusAvailable) {
15
pet.Details.Status = Status.StatusStasis;
16
16
oldPetId = pet._id.toString();
17
17
break;
18
18
}
19
19
}
20
20
21
inventory.KubrowPets.id(data.petId)!.Details!.Status = Status.StatusAvailable;
21
inventory.KubrowPets.id(data.petId)!.Details.Status = Status.StatusAvailable;
22
22
23
23
await inventory.save();
24
24
res.json({
@@ -110,7 +110,7 @@ export const startRecipeController: RequestHandler = async (req, res) => {
110
110
} else if (recipe.secretIngredientAction == "SIA_DISTILL_PRINT") {
111
111
pr.KubrowPet = new Types.ObjectId(startRecipeRequest.Ids[recipe.ingredients.length]);
112
112
const pet = inventory.KubrowPets.id(pr.KubrowPet)!;
113
pet.Details!.PrintsRemaining -= 1;
113
pet.Details.PrintsRemaining -= 1;
114
114
} else if (recipe.secretIngredientAction == "SIA_SPECTRE_LOADOUT_COPY") {
115
115
const spectreLoadout: ISpectreLoadout = {
116
116
ItemType: recipe.resultType,
@@ -126,6 +126,7 @@ import type {
126
126
ICrewShipWeaponEmplacementsDatabase,
127
127
IEquipmentClient,
128
128
IEquipmentDatabase,
129
IKubrowPetDatabase,
129
130
IKubrowPetDetailsClient,
130
131
IKubrowPetDetailsDatabase,
131
132
ITraits
@@ -1149,7 +1150,6 @@ const EquipmentSchema = new Schema<IEquipmentDatabase>(
1149
1150
Customization: crewShipCustomizationSchema,
1150
1151
RailjackImage: FlavourItemSchema,
1151
1152
CrewMembers: crewShipMembersSchema,
1152
Details: detailsSchema,
1153
1153
Favorite: Boolean,
1154
1154
IsNew: Boolean,
1155
1155
AltWeaponModeId: Types.ObjectId,
@@ -1192,10 +1192,18 @@ EquipmentSchema.set("toJSON", {
1192
1192
}
1193
1193
});
1194
1194
1195
const equipmentFields: Record<string, { type: (typeof EquipmentSchema)[] }> = {};
1195
const kubrowPetSchema = new Schema<IKubrowPetDatabase>().add(EquipmentSchema).add({
1196
Details: { type: detailsSchema, required: true }
1197
});
1198
1199
const equipmentFields: Record<string, { type: [Schema]; required: true }> = {
1200
KubrowPets: { type: [kubrowPetSchema], required: true }
1201
};
1196
1202
1197
1203
equipmentKeys.forEach(key => {
1198
equipmentFields[key] = { type: [EquipmentSchema] };
1204
if (key != "KubrowPets") {
1205
equipmentFields[key] = { type: [EquipmentSchema], required: true };
1206
}
1199
1207
});
1200
1208
1201
1209
const pendingRecipeSchema = new Schema<IPendingRecipeDatabase>(
@@ -2103,6 +2111,7 @@ export type InventoryDocumentProps = {
2103
2111
CrewShipSalvagedWeaponSkins: Types.DocumentArray<IUpgradeDatabase>;
2104
2112
PersonalTechProjects: Types.DocumentArray<IPersonalTechProjectDatabase>;
2105
2113
CrewMembers: Types.DocumentArray<ICrewMemberDatabase>;
2114
KubrowPets: Types.DocumentArray<IKubrowPetDatabase>;
2106
2115
KubrowPetPrints: Types.DocumentArray<IKubrowPetPrintDatabase>;
2107
2116
HybridFusionTreasures: Types.DocumentArray<IHybridFusionTreasure>;
2108
2117
} & { [K in TEquipmentKey]: Types.DocumentArray<IEquipmentDatabase> };
@@ -60,6 +60,7 @@ import {
60
60
type IEquipmentDatabase,
61
61
type IEquipmentSelectionClient,
62
62
type IEquipmentSelectionDatabase,
63
type IKubrowPetDatabase,
63
64
type IKubrowPetDetailsClient,
64
65
type IKubrowPetDetailsDatabase
65
66
} from "../types/equipmentTypes.ts";
@@ -94,7 +95,7 @@ const convertOptionalDate = (value: IMongoDateWithLegacySupport | undefined): Da
94
95
return value ? fromMongoDate(value) : undefined;
95
96
};
96
97
97
const convertEquipment = (client: IEquipmentClient): IEquipmentDatabase => {
98
const convertEquipment = (client: IEquipmentClient): IEquipmentDatabase | IKubrowPetDatabase => {
98
99
const { ItemId, ...rest } = client;
99
100
return {
100
101
...rest,
@@ -590,7 +591,7 @@ export const importInventory = (db: TInventoryDatabaseDocument, client: Partial<
590
591
for (const pr of db.PendingRecipes) {
591
592
const recipe = getRecipe(pr.ItemType);
592
593
if (recipe?.secretIngredientAction == "SIA_CREATE_KUBROW" && !pr.KubrowPet) {
593
pr.KubrowPet = db.KubrowPets.find(x => x.Details!.Status == Status.StatusIncubating)?._id;
594
pr.KubrowPet = db.KubrowPets.find(x => x.Details.Status == Status.StatusIncubating)?._id;
594
595
logger.warn(
595
596
`imported recipe ${pr._id.toString()} (${pr.ItemType}) had no TargetItemId; best guess fixup is ${pr.KubrowPet?.toString()}`
596
597
);
@@ -2893,13 +2893,6 @@ export const cleanupInventory = (inventory: TInventoryDatabaseDocument): void =>
2893
2893
}
2894
2894
}
2895
2895
2896
for (const pet of inventory.KubrowPets) {
2897
if (!pet.Details) {
2898
logger.debug(`removing invalid pet ${pet.ItemType} (${pet._id.toString()})`);
2899
inventory.KubrowPets.pull({ _id: pet._id });
2900
}
2901
}
2902
2903
2896
if (inventory.KubrowPetEggs) {
2904
2897
addMiscItem(inventory, "/Lotus/Types/Game/KubrowPet/Eggs/KubrowEgg", inventory.KubrowPetEggs.length);
2905
2898
logger.debug(`migrated ${inventory.KubrowPetEggs.length} KubrowPetEggs to MiscItems`);
@@ -60,7 +60,6 @@ export interface IEquipmentDatabase {
60
60
Customization?: ICrewShipCustomization;
61
61
RailjackImage?: IFlavourItem;
62
62
CrewMembers?: ICrewShipMembersDatabase;
63
Details?: IKubrowPetDetailsDatabase;
64
63
Favorite?: boolean;
65
64
IsNew?: boolean;
66
65
AltWeaponModeId?: Types.ObjectId;
@@ -69,6 +68,10 @@ export interface IEquipmentDatabase {
69
68
_id: Types.ObjectId;
70
69
}
71
70
71
export interface IKubrowPetDatabase extends IEquipmentDatabase {
72
Details: IKubrowPetDetailsDatabase;
73
}
74
72
75
export interface IEquipmentClient extends Omit<
73
76
IEquipmentDatabase,
74
77
| "_id"