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

SpaceNinjaServer

A simple server for a small space ninja game

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

XFEstudio/SpaceNinjaServer

feat: argon crystal decay (#1195)

Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/1195

2d6e096f
Sainan <sainan@calamity.inc>
提交于

代码差异

14 个文件 +81 -17
Modified config.json.example +1 -0
@@ -29,6 +29,7 @@
29 29 "unlockExilusEverywhere": false,
30 30 "unlockArcanesEverywhere": false,
31 31 "noDailyStandingLimits": false,
32 "noArgonCrystalDecay": false,
32 33 "noVendorPurchaseLimits": true,
33 34 "instantResourceExtractorDrones": false,
34 35 "noDojoRoomBuildStage": false,
Modified src/controllers/api/inventoryController.ts +45 -12
@@ -1,5 +1,5 @@
1 1 import { RequestHandler } from "express";
2 import { getAccountForRequest } from "@/src/services/loginService";
2 import { getAccountIdForRequest } 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";
@@ -14,12 +14,13 @@ import {
14 14 ExportVirtuals
15 15 } from "warframe-public-export-plus";
16 16 import { applyCheatsToInfestedFoundry, handleSubsumeCompletion } from "./infestedFoundryController";
17 import { allDailyAffiliationKeys, createLibraryDailyTask } from "@/src/services/inventoryService";
17 import { addMiscItems, allDailyAffiliationKeys, createLibraryDailyTask } from "@/src/services/inventoryService";
18 import { logger } from "@/src/utils/logger";
18 19
19 20 export const inventoryController: RequestHandler = async (request, response) => {
20 const account = await getAccountForRequest(request);
21 const accountId = await getAccountIdForRequest(request);
21 22
22 const inventory = await Inventory.findOne({ accountOwnerId: account._id.toString() });
23 const inventory = await Inventory.findOne({ accountOwnerId: accountId });
23 24
24 25 if (!inventory) {
25 26 response.status(400).json({ error: "inventory was undefined" });
@@ -27,11 +28,7 @@ export const inventoryController: RequestHandler = async (request, response) =>
27 28 }
28 29
29 30 // Handle daily reset
30 const today: number = Math.trunc(new Date().getTime() / 86400000);
31 if (account.LastLoginDay != today) {
32 account.LastLoginDay = today;
33 await account.save();
34
31 if (!inventory.NextRefill || Date.now() >= inventory.NextRefill.getTime()) {
35 32 for (const key of allDailyAffiliationKeys) {
36 33 inventory[key] = 16000 + inventory.PlayerLevel * 500;
37 34 }
@@ -39,6 +36,45 @@ export const inventoryController: RequestHandler = async (request, response) =>
39 36
40 37 inventory.LibraryAvailableDailyTaskInfo = createLibraryDailyTask();
41 38
39 if (inventory.NextRefill) {
40 if (config.noArgonCrystalDecay) {
41 inventory.FoundToday = undefined;
42 } else {
43 const lastLoginDay = Math.trunc(inventory.NextRefill.getTime() / 86400000) - 1;
44 const today = Math.trunc(Date.now() / 86400000);
45 const daysPassed = today - lastLoginDay;
46 for (let i = 0; i != daysPassed; ++i) {
47 const numArgonCrystals =
48 inventory.MiscItems.find(x => x.ItemType == "/Lotus/Types/Items/MiscItems/ArgonCrystal")
49 ?.ItemCount ?? 0;
50 if (numArgonCrystals == 0) {
51 break;
52 }
53 const numStableArgonCrystals =
54 inventory.FoundToday?.find(x => x.ItemType == "/Lotus/Types/Items/MiscItems/ArgonCrystal")
55 ?.ItemCount ?? 0;
56 const numDecayingArgonCrystals = numArgonCrystals - numStableArgonCrystals;
57 const numDecayingArgonCrystalsToRemove = Math.ceil(numDecayingArgonCrystals / 2);
58 logger.debug(`ticking argon crystals for day ${i + 1} of ${daysPassed}`, {
59 numArgonCrystals,
60 numStableArgonCrystals,
61 numDecayingArgonCrystals,
62 numDecayingArgonCrystalsToRemove
63 });
64 // Remove half of owned decaying argon crystals
65 addMiscItems(inventory, [
66 {
67 ItemType: "/Lotus/Types/Items/MiscItems/ArgonCrystal",
68 ItemCount: numDecayingArgonCrystalsToRemove * -1
69 }
70 ]);
71 // All stable argon crystals are now decaying
72 inventory.FoundToday = undefined;
73 }
74 }
75 }
76
77 inventory.NextRefill = new Date((Math.trunc(Date.now() / 86400000) + 1) * 86400000);
42 78 await inventory.save();
43 79 }
44 80
@@ -219,9 +255,6 @@ export const getInventoryResponse = async (
219 255 applyCheatsToInfestedFoundry(inventoryResponse.InfestedFoundry);
220 256 }
221 257
222 // Fix for #380
223 inventoryResponse.NextRefill = { $date: { $numberLong: "9999999999999" } };
224
225 258 // This determines if the "void fissures" tab is shown in navigation.
226 259 inventoryResponse.HasOwnedVoidProjectionsPreviously = true;
227 260
Modified src/models/inventoryModels/inventoryModel.ts +6 -2
@@ -1161,7 +1161,8 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
1161 1161 ChallengeProgress: [challengeProgressSchema],
1162 1162
1163 1163 //Account Item like Ferrite,Form,Kuva etc
1164 MiscItems: [typeCountSchema],
1164 MiscItems: { type: [typeCountSchema], default: [] },
1165 FoundToday: { type: [typeCountSchema], default: undefined },
1165 1166
1166 1167 //Non Upgrade Mods Example:I have 999 item WeaponElectricityDamageMod (only "ItemCount"+"ItemType")
1167 1168 RawUpgrades: [RawUpgrades],
@@ -1360,7 +1361,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
1360 1361 //https://warframe.fandom.com/wiki/Helminth
1361 1362 InfestedFoundry: infestedFoundrySchema,
1362 1363
1363 NextRefill: Schema.Types.Mixed, // Date, convert to IMongoDate
1364 NextRefill: { type: Date, default: undefined },
1364 1365
1365 1366 //Purchase this new permanent skin from the Lotus customization options in Personal Quarters located in your Orbiter.
1366 1367 //https://warframe.fandom.com/wiki/Lotus#The_New_War
@@ -1435,6 +1436,9 @@ inventorySchema.set("toJSON", {
1435 1436 if (inventoryDatabase.BlessingCooldown) {
1436 1437 inventoryResponse.BlessingCooldown = toMongoDate(inventoryDatabase.BlessingCooldown);
1437 1438 }
1439 if (inventoryDatabase.NextRefill) {
1440 inventoryResponse.NextRefill = toMongoDate(inventoryDatabase.NextRefill);
1441 }
1438 1442 }
1439 1443 });
1440 1444
Modified src/models/loginModel.ts +0 -1
@@ -21,7 +21,6 @@ const databaseAccountSchema = new Schema<IDatabaseAccountJson>(
21 21 TrackedSettings: { type: [String], default: [] },
22 22 Nonce: { type: Number, default: 0 },
23 23 Dropped: Boolean,
24 LastLoginDay: { type: Number },
25 24 LatestEventMessageDate: { type: Date, default: 0 }
26 25 },
27 26 opts
Modified src/services/configService.ts +1 -0
@@ -55,6 +55,7 @@ interface IConfig {
55 55 unlockExilusEverywhere?: boolean;
56 56 unlockArcanesEverywhere?: boolean;
57 57 noDailyStandingLimits?: boolean;
58 noArgonCrystalDecay?: boolean;
58 59 noVendorPurchaseLimits?: boolean;
59 60 instantResourceExtractorDrones?: boolean;
60 61 noDojoRoomBuildStage?: boolean;
Modified src/services/inventoryService.ts +16 -0
@@ -1045,6 +1045,22 @@ export const addMiscItems = (inventory: TInventoryDatabaseDocument, itemsArray:
1045 1045 }
1046 1046
1047 1047 MiscItems[itemIndex].ItemCount += ItemCount;
1048
1049 if (ItemType == "/Lotus/Types/Items/MiscItems/ArgonCrystal") {
1050 inventory.FoundToday ??= [];
1051 let foundTodayIndex = inventory.FoundToday.findIndex(x => x.ItemType == ItemType);
1052 if (foundTodayIndex == -1) {
1053 foundTodayIndex = inventory.FoundToday.push({ ItemType, ItemCount: 0 }) - 1;
1054 }
1055 inventory.FoundToday[foundTodayIndex].ItemCount += ItemCount;
1056 if (inventory.FoundToday[foundTodayIndex].ItemCount <= 0) {
1057 inventory.FoundToday.splice(foundTodayIndex, 1);
1058 }
1059 if (inventory.FoundToday.length == 0) {
1060 inventory.FoundToday = undefined;
1061 }
1062 }
1063
1048 1064 if (MiscItems[itemIndex].ItemCount == 0) {
1049 1065 MiscItems.splice(itemIndex, 1);
1050 1066 } else if (MiscItems[itemIndex].ItemCount <= 0) {
Modified src/types/inventoryTypes/inventoryTypes.ts +3 -1
@@ -42,6 +42,7 @@ export interface IInventoryDatabase
42 42 | "PendingCoupon"
43 43 | "Drones"
44 44 | "RecentVendorPurchases"
45 | "NextRefill"
45 46 | TEquipmentKey
46 47 >,
47 48 InventoryDatabaseEquipment {
@@ -69,6 +70,7 @@ export interface IInventoryDatabase
69 70 PendingCoupon?: IPendingCouponDatabase;
70 71 Drones: IDroneDatabase[];
71 72 RecentVendorPurchases?: IRecentVendorPurchaseDatabase[];
73 NextRefill?: Date;
72 74 }
73 75
74 76 export interface IQuestKeyDatabase {
@@ -307,7 +309,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
307 309 UseAdultOperatorLoadout?: boolean;
308 310 NemesisAbandonedRewards: string[];
309 311 LastInventorySync: IOid;
310 NextRefill: IMongoDate; // Next time argon crystals will have a decay tick
312 NextRefill?: IMongoDate;
311 313 FoundToday?: IMiscItem[]; // for Argon Crystals
312 314 CustomMarkers?: ICustomMarkers[];
313 315 ActiveLandscapeTraps: any[];
Modified src/types/loginTypes.ts +0 -1
@@ -15,7 +15,6 @@ export interface IDatabaseAccount extends IAccountAndLoginResponseCommons {
15 15 email: string;
16 16 password: string;
17 17 Dropped?: boolean;
18 LastLoginDay?: number;
19 18 LatestEventMessageDate: Date;
20 19 }
21 20
Modified static/webui/index.html +4 -0
@@ -517,6 +517,10 @@
517 517 <input class="form-check-input" type="checkbox" id="noDailyStandingLimits" />
518 518 <label class="form-check-label" for="noDailyStandingLimits" data-loc="cheats_noDailyStandingLimits"></label>
519 519 </div>
520 <div class="form-check">
521 <input class="form-check-input" type="checkbox" id="noArgonCrystalDecay" />
522 <label class="form-check-label" for="noArgonCrystalDecay" data-loc="cheats_noArgonCrystalDecay"></label>
523 </div>
520 524 <div class="form-check">
521 525 <input class="form-check-input" type="checkbox" id="noVendorPurchaseLimits" />
522 526 <label class="form-check-label" for="noVendorPurchaseLimits" data-loc="cheats_noVendorPurchaseLimits"></label>
Modified static/webui/translations/de.js +1 -0
@@ -110,6 +110,7 @@ dict = {
110 110 cheats_unlockExilusEverywhere: `Exilus-Adapter überall`,
111 111 cheats_unlockArcanesEverywhere: `Arkana-Adapter überall`,
112 112 cheats_noDailyStandingLimits: `Kein tägliches Ansehenslimit`,
113 cheats_noArgonCrystalDecay: `[UNTRANSLATED] No Argon Crystal Decay`,
113 114 cheats_noVendorPurchaseLimits: `Keine Kaufbeschränkungen bei Händlern`,
114 115 cheats_instantResourceExtractorDrones: `Sofortige Ressourcen-Extraktor-Drohnen`,
115 116 cheats_noDojoRoomBuildStage: `Kein Dojo-Raum-Bauvorgang`,
Modified static/webui/translations/en.js +1 -0
@@ -109,6 +109,7 @@ dict = {
109 109 cheats_unlockExilusEverywhere: `Exilus Adapters Everywhere`,
110 110 cheats_unlockArcanesEverywhere: `Arcane Adapters Everywhere`,
111 111 cheats_noDailyStandingLimits: `No Daily Standing Limits`,
112 cheats_noArgonCrystalDecay: `No Argon Crystal Decay`,
112 113 cheats_noVendorPurchaseLimits: `No Vendor Purchase Limits`,
113 114 cheats_instantResourceExtractorDrones: `Instant Resource Extractor Drones`,
114 115 cheats_noDojoRoomBuildStage: `No Dojo Room Build Stage`,
Modified static/webui/translations/fr.js +1 -0
@@ -110,6 +110,7 @@ dict = {
110 110 cheats_unlockExilusEverywhere: `Adaptateurs Exilus partout`,
111 111 cheats_unlockArcanesEverywhere: `Adaptateur d'Arcanes partout`,
112 112 cheats_noDailyStandingLimits: `Pas de limite de réputation journalière`,
113 cheats_noArgonCrystalDecay: `[UNTRANSLATED] No Argon Crystal Decay`,
113 114 cheats_noVendorPurchaseLimits: `[UNTRANSLATED] No Vendor Purchase Limits`,
114 115 cheats_instantResourceExtractorDrones: `Ressources de drone d'extraction instantannées`,
115 116 cheats_noDojoRoomBuildStage: `No Dojo Room Build Stage`,
Modified static/webui/translations/ru.js +1 -0
Modified static/webui/translations/zh.js +1 -0