XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESpaceNinjaServer

A simple server for a small space ninja game

公开
关注 0 Fork 0 Star 0
返回提交历史

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
Sainan <63328889+Sainan@users.noreply.github.com>
提交于

代码差异

13 个文件 +96 -53
Modified src/controllers/api/claimCompletedRecipeController.ts +7 -9
@@ -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 = {};
Modified src/controllers/api/inventoryController.ts +28 -13
@@ -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;
Modified src/controllers/api/loginController.ts +1 -1
@@ -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
Modified src/controllers/api/setGuildMotdController.ts +1 -1
@@ -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
Modified src/controllers/custom/addXpController.ts +2 -1
@@ -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) {
Modified src/helpers/inventoryHelpers.ts +39 -2
@@ -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 => {
Modified src/helpers/nemesisHelpers.ts +2 -1
@@ -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 = [];
Modified src/services/inventoryService.ts +4 -3
@@ -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) {
Modified src/services/missionInventoryUpdateService.ts +2 -1
@@ -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;
Modified src/services/worldStateService.ts +1 -17
@@ -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 };
Modified src/types/commonTypes.ts +5 -0
@@ -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;
Modified src/types/inventoryTypes/commonInventoryTypes.ts +2 -2
@@ -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;
Modified src/types/inventoryTypes/inventoryTypes.ts +2 -2