返回提交历史
Modified
src/controllers/api/claimCompletedRecipeController.ts
+7
-9
Modified
src/controllers/api/inventoryController.ts
+28
-13
Modified
src/controllers/api/loginController.ts
+1
-1
Modified
src/controllers/api/setGuildMotdController.ts
+1
-1
Modified
src/controllers/custom/addXpController.ts
+2
-1
Modified
src/helpers/inventoryHelpers.ts
+39
-2
Modified
src/helpers/nemesisHelpers.ts
+2
-1
Modified
src/services/inventoryService.ts
+4
-3
Modified
src/services/missionInventoryUpdateService.ts
+2
-1
Modified
src/services/worldStateService.ts
+1
-17
Modified
src/types/commonTypes.ts
+5
-0
Modified
src/types/inventoryTypes/commonInventoryTypes.ts
+2
-2
Modified
src/types/inventoryTypes/inventoryTypes.ts
+2
-2
XFEstudio/XFESpaceNinjaServer
chore: some initial handling of legacy oid format (#2033)
This at least allows mission inventory update to succeed on U19.5 and below. Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2033 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
f9b3fecc
代码差异
13 个文件
+96
-53
@@ -4,9 +4,9 @@
4
4
import { RequestHandler } from "express";
5
5
import { logger } from "@/src/utils/logger";
6
6
import { getRecipe } from "@/src/services/itemDataService";
7
import { IOid } from "@/src/types/commonTypes";
7
import { IOid, IOidWithLegacySupport } from "@/src/types/commonTypes";
8
8
import { getJSONfromString } from "@/src/helpers/stringHelpers";
9
import { getAccountIdForRequest } from "@/src/services/loginService";
9
import { getAccountForRequest } from "@/src/services/loginService";
10
10
import {
11
11
getInventory,
12
12
updateCurrency,
@@ -18,7 +18,7 @@ import {
18
18
import { IInventoryChanges } from "@/src/types/purchaseTypes";
19
19
import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
20
20
import { InventorySlot } from "@/src/types/inventoryTypes/inventoryTypes";
21
import { toOid } from "@/src/helpers/inventoryHelpers";
21
import { toOid2 } from "@/src/helpers/inventoryHelpers";
22
22
23
23
interface IClaimCompletedRecipeRequest {
24
24
RecipeIds: IOid[];
@@ -26,10 +26,8 @@ interface IClaimCompletedRecipeRequest {
26
26
27
27
export const claimCompletedRecipeController: RequestHandler = async (req, res) => {
28
28
const claimCompletedRecipeRequest = getJSONfromString<IClaimCompletedRecipeRequest>(String(req.body));
29
const accountId = await getAccountIdForRequest(req);
30
if (!accountId) throw new Error("no account id");
31
32
const inventory = await getInventory(accountId);
29
const account = await getAccountForRequest(req);
30
const inventory = await getInventory(account._id.toString());
33
31
const pendingRecipe = inventory.PendingRecipes.id(claimCompletedRecipeRequest.RecipeIds[0].$oid);
34
32
if (!pendingRecipe) {
35
33
throw new Error(`no pending recipe found with id ${claimCompletedRecipeRequest.RecipeIds[0].$oid}`);
@@ -81,7 +79,7 @@ export const claimCompletedRecipeController: RequestHandler = async (req, res) =
81
79
} else {
82
80
logger.debug("Claiming Recipe", { recipe, pendingRecipe });
83
81
84
let BrandedSuits: undefined | IOid[];
82
let BrandedSuits: undefined | IOidWithLegacySupport[];
85
83
if (recipe.secretIngredientAction == "SIA_SPECTRE_LOADOUT_COPY") {
86
84
inventory.PendingSpectreLoadouts ??= [];
87
85
inventory.SpectreLoadouts ??= [];
@@ -106,7 +104,7 @@ export const claimCompletedRecipeController: RequestHandler = async (req, res) =
106
104
inventory.BrandedSuits!.findIndex(x => x.equals(pendingRecipe.SuitToUnbrand)),
107
105
1
108
106
);
109
BrandedSuits = [toOid(pendingRecipe.SuitToUnbrand!)];
107
BrandedSuits = [toOid2(pendingRecipe.SuitToUnbrand!, account.BuildLabel)];
110
108
}
111
109
112
110
let InventoryChanges: IInventoryChanges = {};
@@ -25,10 +25,10 @@ import { logger } from "@/src/utils/logger";
25
25
import { catBreadHash } from "@/src/helpers/stringHelpers";
26
26
import { Types } from "mongoose";
27
27
import { isNemesisCompatibleWithVersion } from "@/src/helpers/nemesisHelpers";
28
import { version_compare } from "@/src/services/worldStateService";
29
28
import { getPersonalRooms } from "@/src/services/personalRoomsService";
30
29
import { IPersonalRoomsClient } from "@/src/types/personalRoomsTypes";
31
30
import { Ship } from "@/src/models/shipModel";
31
import { toLegacyOid, version_compare } from "@/src/helpers/inventoryHelpers";
32
32
33
33
export const inventoryController: RequestHandler = async (request, response) => {
34
34
const account = await getAccountForRequest(request);
@@ -306,19 +306,34 @@ export const getInventoryResponse = async (
306
306
// Set 2FA enabled so trading post can be used
307
307
inventoryResponse.HWIDProtectEnabled = true;
308
308
309
// Fix nemesis for older versions
310
if (
311
inventoryResponse.Nemesis &&
312
buildLabel &&
313
!isNemesisCompatibleWithVersion(inventoryResponse.Nemesis, buildLabel)
314
) {
315
inventoryResponse.Nemesis = undefined;
316
}
309
if (buildLabel) {
310
// Fix nemesis for older versions
311
if (inventoryResponse.Nemesis && !isNemesisCompatibleWithVersion(inventoryResponse.Nemesis, buildLabel)) {
312
inventoryResponse.Nemesis = undefined;
313
}
314
315
if (version_compare(buildLabel, "2018.02.22.14.34") < 0) {
316
const personalRoomsDb = await getPersonalRooms(inventory.accountOwnerId.toString());
317
const personalRooms = personalRoomsDb.toJSON<IPersonalRoomsClient>();
318
inventoryResponse.Ship = personalRooms.Ship;
317
319
318
if (buildLabel && version_compare(buildLabel, "2018.02.22.14.34") < 0) {
319
const personalRoomsDb = await getPersonalRooms(inventory.accountOwnerId.toString());
320
const personalRooms = personalRoomsDb.toJSON<IPersonalRoomsClient>();
321
inventoryResponse.Ship = personalRooms.Ship;
320
if (version_compare(buildLabel, "2016.12.21.19.13") <= 0) {
321
// U19.5 and below use $id instead of $oid
322
for (const category of equipmentKeys) {
323
for (const item of inventoryResponse[category]) {
324
toLegacyOid(item.ItemId);
325
}
326
}
327
for (const upgrade of inventoryResponse.Upgrades) {
328
toLegacyOid(upgrade.ItemId);
329
}
330
if (inventoryResponse.BrandedSuits) {
331
for (const id of inventoryResponse.BrandedSuits) {
332
toLegacyOid(id);
333
}
334
}
335
}
336
}
322
337
}
323
338
324
339
return inventoryResponse;
@@ -7,7 +7,7 @@ import { Account } from "@/src/models/loginModel";
7
7
import { createAccount, isCorrectPassword, isNameTaken } from "@/src/services/loginService";
8
8
import { IDatabaseAccountJson, ILoginRequest, ILoginResponse } from "@/src/types/loginTypes";
9
9
import { logger } from "@/src/utils/logger";
10
import { version_compare } from "@/src/services/worldStateService";
10
import { version_compare } from "@/src/helpers/inventoryHelpers";
11
11
12
12
export const loginController: RequestHandler = async (request, response) => {
13
13
const loginRequest = JSON.parse(String(request.body)) as ILoginRequest; // parse octet stream of json data to json object
@@ -1,8 +1,8 @@
1
import { version_compare } from "@/src/helpers/inventoryHelpers";
1
2
import { Alliance, Guild, GuildMember } from "@/src/models/guildModel";
2
3
import { hasGuildPermissionEx } from "@/src/services/guildService";
3
4
import { getInventory } from "@/src/services/inventoryService";
4
5
import { getAccountForRequest, getSuffixedName } from "@/src/services/loginService";
5
import { version_compare } from "@/src/services/worldStateService";
6
6
import { GuildPermission, ILongMOTD } from "@/src/types/guildTypes";
7
7
import { RequestHandler } from "express";
8
8
@@ -1,5 +1,6 @@
1
1
import { applyClientEquipmentUpdates, getInventory } from "@/src/services/inventoryService";
2
2
import { getAccountIdForRequest } from "@/src/services/loginService";
3
import { IOid } from "@/src/types/commonTypes";
3
4
import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
4
5
import { TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes";
5
6
import { RequestHandler } from "express";
@@ -11,7 +12,7 @@ export const addXpController: RequestHandler = async (req, res) => {
11
12
const request = req.body as IAddXpRequest;
12
13
for (const [category, gear] of Object.entries(request)) {
13
14
for (const clientItem of gear) {
14
const dbItem = inventory[category as TEquipmentKey].id(clientItem.ItemId.$oid);
15
const dbItem = inventory[category as TEquipmentKey].id((clientItem.ItemId as IOid).$oid);
15
16
if (dbItem) {
16
17
if (dbItem.ItemType in ExportMisc.uniqueLevelCaps) {
17
18
if ((dbItem.Polarized ?? 0) < 5) {
@@ -1,9 +1,46 @@
1
import { IMongoDate, IOid } from "@/src/types/commonTypes";
1
import { IMongoDate, IOid, IOidWithLegacySupport } from "@/src/types/commonTypes";
2
2
import { Types } from "mongoose";
3
3
import { TRarity } from "warframe-public-export-plus";
4
4
5
export const version_compare = (a: string, b: string): number => {
6
const a_digits = a
7
.split("/")[0]
8
.split(".")
9
.map(x => parseInt(x));
10
const b_digits = b
11
.split("/")[0]
12
.split(".")
13
.map(x => parseInt(x));
14
for (let i = 0; i != a_digits.length; ++i) {
15
if (a_digits[i] != b_digits[i]) {
16
return a_digits[i] > b_digits[i] ? 1 : -1;
17
}
18
}
19
return 0;
20
};
21
5
22
export const toOid = (objectId: Types.ObjectId): IOid => {
6
return { $oid: objectId.toString() } satisfies IOid;
23
return { $oid: objectId.toString() };
24
};
25
26
export function toOid2(objectId: Types.ObjectId, buildLabel: undefined): IOid;
27
export function toOid2(objectId: Types.ObjectId, buildLabel: string | undefined): IOidWithLegacySupport;
28
export function toOid2(objectId: Types.ObjectId, buildLabel: string | undefined): IOidWithLegacySupport {
29
if (buildLabel && version_compare(buildLabel, "2016.12.21.19.13") <= 0) {
30
return { $id: objectId.toString() };
31
}
32
return { $oid: objectId.toString() };
33
}
34
35
export const toLegacyOid = (oid: IOidWithLegacySupport): void => {
36
if (!("$id" in oid)) {
37
oid.$id = oid.$oid;
38
delete oid.$oid;
39
}
40
};
41
42
export const fromOid = (oid: IOidWithLegacySupport): string => {
43
return (oid.$oid ?? oid.$id)!;
7
44
};
8
45
9
46
export const toMongoDate = (date: Date): IMongoDate => {
@@ -6,9 +6,10 @@ import { logger } from "../utils/logger";
6
6
import { IOid } from "../types/commonTypes";
7
7
import { Types } from "mongoose";
8
8
import { addMods, generateRewardSeed } from "../services/inventoryService";
9
import { isArchwingMission, version_compare } from "../services/worldStateService";
9
import { isArchwingMission } from "../services/worldStateService";
10
10
import { fromStoreItem, toStoreItem } from "../services/itemDataService";
11
11
import { createMessage } from "../services/inboxService";
12
import { version_compare } from "./inventoryHelpers";
12
13
13
14
export const getInfNodes = (faction: string, rank: number): IInfNode[] => {
14
15
const infNodes = [];
@@ -70,6 +70,7 @@ import { createShip } from "./shipService";
70
70
import {
71
71
catbrowDetails,
72
72
fromMongoDate,
73
fromOid,
73
74
kubrowDetails,
74
75
kubrowFurPatternsWeights,
75
76
kubrowWeights,
@@ -423,7 +424,7 @@ export const addItem = async (
423
424
changes.push({
424
425
ItemType: egg.ItemType,
425
426
ExpirationDate: { $date: { $numberLong: "2000000000000" } },
426
ItemId: toOid(egg._id)
427
ItemId: toOid(egg._id) // TODO: Pass on buildLabel from purchaseService
427
428
});
428
429
}
429
430
return {
@@ -1491,9 +1492,9 @@ export const applyClientEquipmentUpdates = (
1491
1492
const category = inventory[categoryName];
1492
1493
1493
1494
gearArray.forEach(({ ItemId, XP, InfestationDate }) => {
1494
const item = category.id(ItemId.$oid);
1495
const item = category.id(fromOid(ItemId));
1495
1496
if (!item) {
1496
throw new Error(`No item with id ${ItemId.$oid} in ${categoryName}`);
1497
throw new Error(`No item with id ${fromOid(ItemId)} in ${categoryName}`);
1497
1498
}
1498
1499
1499
1500
if (XP) {
@@ -62,6 +62,7 @@ import { getLiteSortie, getSortie, idToBountyCycle, idToDay, idToWeek, pushClass
62
62
import { config } from "./configService";
63
63
import libraryDailyTasks from "@/static/fixed_responses/libraryDailyTasks.json";
64
64
import { ISyndicateMissionInfo } from "../types/worldStateTypes";
65
import { fromOid } from "../helpers/inventoryHelpers";
65
66
66
67
const getRotations = (rewardInfo: IRewardInfo, tierOverride?: number): number[] => {
67
68
// For Spy missions, e.g. 3 vaults cracked = A, B, C
@@ -399,7 +400,7 @@ export const addMissionInventoryUpdates = async (
399
400
break;
400
401
case "Upgrades":
401
402
value.forEach(clientUpgrade => {
402
const upgrade = inventory.Upgrades.id(clientUpgrade.ItemId.$oid)!;
403
const upgrade = inventory.Upgrades.id(fromOid(clientUpgrade.ItemId))!;
403
404
upgrade.UpgradeFingerprint = clientUpgrade.UpgradeFingerprint; // primitive way to copy over the riven challenge progress
404
405
});
405
406
break;
@@ -18,6 +18,7 @@ import {
18
18
ISyndicateMissionInfo,
19
19
IWorldState
20
20
} from "../types/worldStateTypes";
21
import { version_compare } from "../helpers/inventoryHelpers";
21
22
22
23
const sortieBosses = [
23
24
"SORTIE_BOSS_HYENA",
@@ -1239,20 +1240,3 @@ export const isArchwingMission = (node: IRegion): boolean => {
1239
1240
}
1240
1241
return false;
1241
1242
};
1242
1243
export const version_compare = (a: string, b: string): number => {
1244
const a_digits = a
1245
.split("/")[0]
1246
.split(".")
1247
.map(x => parseInt(x));
1248
const b_digits = b
1249
.split("/")[0]
1250
.split(".")
1251
.map(x => parseInt(x));
1252
for (let i = 0; i != a_digits.length; ++i) {
1253
if (a_digits[i] != b_digits[i]) {
1254
return a_digits[i] > b_digits[i] ? 1 : -1;
1255
}
1256
}
1257
return 0;
1258
};
@@ -4,6 +4,11 @@ export interface IOid {
4
4
$oid: string;
5
5
}
6
6
7
export interface IOidWithLegacySupport {
8
$oid?: string;
9
$id?: string;
10
}
11
7
12
export interface IMongoDate {
8
13
$date: {
9
14
$numberLong: string;
@@ -1,4 +1,4 @@
1
import { IMongoDate, IOid } from "@/src/types/commonTypes";
1
import { IMongoDate, IOid, IOidWithLegacySupport } from "@/src/types/commonTypes";
2
2
import { Types } from "mongoose";
3
3
import {
4
4
ICrewShipCustomization,
@@ -92,7 +92,7 @@ export interface IEquipmentClient
92
92
IEquipmentDatabase,
93
93
"_id" | "InfestationDate" | "Expiry" | "UpgradesExpiry" | "UmbraDate" | "CrewMembers" | "Details"
94
94
> {
95
ItemId: IOid;
95
ItemId: IOidWithLegacySupport;
96
96
InfestationDate?: IMongoDate;
97
97
Expiry?: IMongoDate;
98
98
UpgradesExpiry?: IMongoDate;