返回提交历史
Modified
src/controllers/api/inventoryController.ts
+18
-5
Modified
src/controllers/api/loginController.ts
+3
-1
Modified
src/controllers/api/missionInventoryUpdateController.ts
+5
-5
Modified
src/helpers/nemesisHelpers.ts
+28
-4
Modified
src/models/loginModel.ts
+1
-0
Modified
src/types/loginTypes.ts
+1
-0
XFEstudio/XFESpaceNinjaServer
fix: spoof nemesis to avoid script errors in older versions (#1936)
Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/1936 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
9b652f5c
代码差异
6 个文件
+56
-15
@@ -1,5 +1,5 @@
1
1
import { RequestHandler } from "express";
2
import { getAccountIdForRequest } from "@/src/services/loginService";
2
import { getAccountForRequest } from "@/src/services/loginService";
3
3
import { Inventory, TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
4
4
import { config } from "@/src/services/configService";
5
5
import allDialogue from "@/static/fixed_responses/allDialogue.json";
@@ -24,11 +24,12 @@ import {
24
24
import { logger } from "@/src/utils/logger";
25
25
import { catBreadHash } from "@/src/helpers/stringHelpers";
26
26
import { Types } from "mongoose";
27
import { isNemesisCompatibleWithVersion } from "@/src/helpers/nemesisHelpers";
27
28
28
29
export const inventoryController: RequestHandler = async (request, response) => {
29
const accountId = await getAccountIdForRequest(request);
30
const account = await getAccountForRequest(request);
30
31
31
const inventory = await Inventory.findOne({ accountOwnerId: accountId });
32
const inventory = await Inventory.findOne({ accountOwnerId: account._id });
32
33
33
34
if (!inventory) {
34
35
response.status(400).json({ error: "inventory was undefined" });
@@ -119,12 +120,15 @@ export const inventoryController: RequestHandler = async (request, response) =>
119
120
inventory.LastInventorySync = new Types.ObjectId();
120
121
await inventory.save();
121
122
122
response.json(await getInventoryResponse(inventory, "xpBasedLevelCapDisabled" in request.query));
123
response.json(
124
await getInventoryResponse(inventory, "xpBasedLevelCapDisabled" in request.query, account.BuildLabel)
125
);
123
126
};
124
127
125
128
export const getInventoryResponse = async (
126
129
inventory: TInventoryDatabaseDocument,
127
xpBasedLevelCapDisabled: boolean
130
xpBasedLevelCapDisabled: boolean,
131
buildLabel: string | undefined
128
132
): Promise<IInventoryClient> => {
129
133
const inventoryWithLoadOutPresets = await inventory.populate<{ LoadOutPresets: ILoadoutDatabase }>(
130
134
"LoadOutPresets"
@@ -299,6 +303,15 @@ export const getInventoryResponse = async (
299
303
// Set 2FA enabled so trading post can be used
300
304
inventoryResponse.HWIDProtectEnabled = true;
301
305
306
// Fix nemesis for older versions
307
if (
308
inventoryResponse.Nemesis &&
309
buildLabel &&
310
!isNemesisCompatibleWithVersion(inventoryResponse.Nemesis, buildLabel)
311
) {
312
inventoryResponse.Nemesis = undefined;
313
}
314
302
315
return inventoryResponse;
303
316
};
304
317
@@ -47,7 +47,8 @@ export const loginController: RequestHandler = async (request, response) => {
47
47
ForceLogoutVersion: 0,
48
48
ConsentNeeded: false,
49
49
TrackedSettings: [],
50
Nonce: nonce
50
Nonce: nonce,
51
BuildLabel: buildLabel
51
52
});
52
53
logger.debug("created new account");
53
54
response.json(createLoginResponse(myAddress, newAccount, buildLabel));
@@ -88,6 +89,7 @@ export const loginController: RequestHandler = async (request, response) => {
88
89
account.ClientType = loginRequest.ClientType;
89
90
account.Nonce = nonce;
90
91
account.CountryCode = loginRequest.lang.toUpperCase();
92
account.BuildLabel = buildLabel;
91
93
}
92
94
await account.save();
93
95
@@ -1,6 +1,6 @@
1
1
import { RequestHandler } from "express";
2
2
import { getJSONfromString } from "@/src/helpers/stringHelpers";
3
import { getAccountIdForRequest } from "@/src/services/loginService";
3
import { getAccountForRequest } from "@/src/services/loginService";
4
4
import { IMissionInventoryUpdateRequest } from "@/src/types/requestTypes";
5
5
import { addMissionInventoryUpdates, addMissionRewards } from "@/src/services/missionInventoryUpdateService";
6
6
import { generateRewardSeed, getInventory } from "@/src/services/inventoryService";
@@ -49,11 +49,11 @@ import { IMissionInventoryUpdateResponse } from "@/src/types/missionTypes";
49
49
*/
50
50
//move credit calc in here, return MissionRewards: [] if no reward info
51
51
export const missionInventoryUpdateController: RequestHandler = async (req, res): Promise<void> => {
52
const accountId = await getAccountIdForRequest(req);
52
const account = await getAccountForRequest(req);
53
53
const missionReport = getJSONfromString<IMissionInventoryUpdateRequest>((req.body as string).toString());
54
54
logger.debug("mission report:", missionReport);
55
55
56
const inventory = await getInventory(accountId);
56
const inventory = await getInventory(account._id.toString());
57
57
const firstCompletion = missionReport.SortieId
58
58
? inventory.CompletedSorties.indexOf(missionReport.SortieId) == -1
59
59
: false;
@@ -65,7 +65,7 @@ export const missionInventoryUpdateController: RequestHandler = async (req, res)
65
65
) {
66
66
inventory.RewardSeed = generateRewardSeed();
67
67
await inventory.save();
68
const inventoryResponse = await getInventoryResponse(inventory, true);
68
const inventoryResponse = await getInventoryResponse(inventory, true, account.BuildLabel);
69
69
res.json({
70
70
InventoryJson: JSON.stringify(inventoryResponse),
71
71
MissionRewards: []
@@ -84,7 +84,7 @@ export const missionInventoryUpdateController: RequestHandler = async (req, res)
84
84
85
85
inventory.RewardSeed = generateRewardSeed();
86
86
await inventory.save();
87
const inventoryResponse = await getInventoryResponse(inventory, true);
87
const inventoryResponse = await getInventoryResponse(inventory, true, account.BuildLabel);
88
88
89
89
//TODO: figure out when to send inventory. it is needed for many cases.
90
90
res.json({
@@ -6,7 +6,7 @@ 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 } from "../services/worldStateService";
9
import { isArchwingMission, version_compare } from "../services/worldStateService";
10
10
import { fromStoreItem, toStoreItem } from "../services/itemDataService";
11
11
import { createMessage } from "../services/inboxService";
12
12
@@ -237,15 +237,39 @@ const corpusVersionThreeWeapons = [
237
237
238
238
export const getWeaponsForManifest = (manifest: string): readonly string[] => {
239
239
switch (manifest) {
240
case "/Lotus/Types/Game/Nemesis/KuvaLich/KuvaLichManifestVersionSix":
240
case "/Lotus/Types/Game/Nemesis/KuvaLich/KuvaLichManifestVersionSix": // >= 35.6.0
241
241
return kuvaLichVersionSixWeapons;
242
case "/Lotus/Types/Enemies/Corpus/Lawyers/LawyerManifestVersionThree":
243
case "/Lotus/Types/Enemies/Corpus/Lawyers/LawyerManifestVersionFour":
242
case "/Lotus/Types/Enemies/Corpus/Lawyers/LawyerManifestVersionThree": // >= 35.6.0
243
case "/Lotus/Types/Enemies/Corpus/Lawyers/LawyerManifestVersionFour": // >= 37.0.0
244
244
return corpusVersionThreeWeapons;
245
245
}
246
246
throw new Error(`unknown nemesis manifest: ${manifest}`);
247
247
};
248
248
249
export const isNemesisCompatibleWithVersion = (
250
nemesis: { manifest: string; Faction: string },
251
buildLabel: string
252
): boolean => {
253
// Anything below 35.6.0 is not going to be okay given our set of supported manifests.
254
if (version_compare(buildLabel, "2024.05.15.11.07") < 0) {
255
return false;
256
}
257
258
if (nemesis.Faction == "FC_INFESTATION") {
259
// Anything below 38.5.0 isn't gonna like an infested lich.
260
if (version_compare(buildLabel, "2025.03.18.16.07") < 0) {
261
return false;
262
}
263
} else if (nemesis.manifest == "/Lotus/Types/Enemies/Corpus/Lawyers/LawyerManifestVersionFour") {
264
// Anything below 37.0.0 isn't gonna know version 4, but version 3 is identical in terms of weapon choices, so we can spoof it to that.
265
if (version_compare(buildLabel, "2024.10.01.11.03") < 0) {
266
nemesis.manifest = "/Lotus/Types/Enemies/Corpus/Lawyers/LawyerManifestVersionThree";
267
}
268
}
269
270
return true;
271
};
272
249
273
export const getInnateDamageTag = (
250
274
KillingSuit: string
251
275
):
@@ -20,6 +20,7 @@ const databaseAccountSchema = new Schema<IDatabaseAccountJson>(
20
20
ConsentNeeded: { type: Boolean, required: true },
21
21
TrackedSettings: { type: [String], default: [] },
22
22
Nonce: { type: Number, default: 0 },
23
BuildLabel: String,
23
24
Dropped: Boolean,
24
25
LatestEventMessageDate: { type: Date, default: 0 },
25
26
LastLoginRewardDate: { type: Number, default: 0 },
@@ -16,6 +16,7 @@ export interface IAccountAndLoginResponseCommons {
16
16
export interface IDatabaseAccountRequiredFields extends IAccountAndLoginResponseCommons {
17
17
email: string;
18
18
password: string;
19
BuildLabel?: string;
19
20
}
20
21
21
22
export interface IDatabaseAccount extends IDatabaseAccountRequiredFields {