返回提交历史
Modified
src/controllers/api/claimCompletedRecipeController.ts
+48
-27
XFEstudio/SpaceNinjaServer
fix: claiming recipes in U22.20-U24.1 + disable rush cost scaling for builds older than U18 (#3024)
With this, the Foundry should be fully functional in all game versions now (excluding incorrect recipe data for things that got changed over the years). This also disables rush cost scaling for versions older than U18, as U18 is the version that introduced it. Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/3024 Reviewed-by: Sainan <63328889+sainan@users.noreply.github.com> Co-authored-by: VoltPrime <subsonicjackal@gmail.com> Co-committed-by: VoltPrime <subsonicjackal@gmail.com>
90ffd894
代码差异
1 个文件
+48
-27
@@ -22,14 +22,15 @@ import {
22
22
import type { IInventoryChanges } from "../../types/purchaseTypes.ts";
23
23
import type { IPendingRecipeDatabase } from "../../types/inventoryTypes/inventoryTypes.ts";
24
24
import { InventorySlot } from "../../types/inventoryTypes/inventoryTypes.ts";
25
import { fromOid, toOid2 } from "../../helpers/inventoryHelpers.ts";
25
import { fromOid, toOid2, version_compare } from "../../helpers/inventoryHelpers.ts";
26
26
import type { TInventoryDatabaseDocument } from "../../models/inventoryModels/inventoryModel.ts";
27
27
import type { IRecipe } from "warframe-public-export-plus";
28
28
import type { IEquipmentClient } from "../../types/equipmentTypes.ts";
29
29
import { EquipmentFeatures, Status } from "../../types/equipmentTypes.ts";
30
30
31
31
interface IClaimCompletedRecipeRequest {
32
RecipeIds: IOidWithLegacySupport[];
32
RecipeIds?: IOidWithLegacySupport[]; // U24.4 and beyond
33
recipeNames?: string[]; // Builds before U24.4 down to U22.20
33
34
}
34
35
35
36
interface IClaimCompletedRecipeResponse {
@@ -45,33 +46,46 @@ export const claimCompletedRecipeController: RequestHandler = async (req, res) =
45
46
};
46
47
if (!req.query.recipeName) {
47
48
const claimCompletedRecipeRequest = getJSONfromString<IClaimCompletedRecipeRequest>(String(req.body));
48
for (const recipeId of claimCompletedRecipeRequest.RecipeIds) {
49
const pendingRecipe = inventory.PendingRecipes.id(fromOid(recipeId));
50
if (!pendingRecipe) {
51
throw new Error(`no pending recipe found with id ${fromOid(recipeId)}`);
52
}
49
const recipes = claimCompletedRecipeRequest.recipeNames ?? claimCompletedRecipeRequest.RecipeIds;
50
if (recipes) {
51
for (const recipeId of recipes) {
52
let pendingRecipe;
53
if (typeof recipeId === "string") {
54
pendingRecipe = inventory.PendingRecipes.find(r => r.ItemType == recipeId);
55
if (!pendingRecipe) {
56
throw new Error(`no pending recipe found of type ${recipeId}`);
57
}
58
} else {
59
pendingRecipe = inventory.PendingRecipes.id(fromOid(recipeId));
60
if (!pendingRecipe) {
61
throw new Error(`no pending recipe found with id ${fromOid(recipeId)}`);
62
}
63
}
53
64
54
//check recipe is indeed ready to be completed
55
// if (pendingRecipe.CompletionDate > new Date()) {
56
// throw new Error(`recipe ${pendingRecipe._id} is not ready to be completed`);
57
// }
65
//check recipe is indeed ready to be completed
66
// if (pendingRecipe.CompletionDate > new Date()) {
67
// throw new Error(`recipe ${pendingRecipe._id} is not ready to be completed`);
68
// }
58
69
59
inventory.PendingRecipes.pull(pendingRecipe._id);
70
inventory.PendingRecipes.pull(pendingRecipe._id);
60
71
61
const recipe = getRecipe(pendingRecipe.ItemType);
62
if (!recipe) {
63
throw new Error(`no completed item found for recipe ${pendingRecipe._id.toString()}`);
64
}
72
const recipe = getRecipe(pendingRecipe.ItemType);
73
if (!recipe) {
74
throw new Error(`no completed item found for recipe ${pendingRecipe._id.toString()}`);
75
}
65
76
66
if (req.query.cancel) {
67
const inventoryChanges: IInventoryChanges = {};
68
await refundRecipeIngredients(inventory, inventoryChanges, recipe, pendingRecipe);
69
await inventory.save();
70
res.json(inventoryChanges); // Not a bug: In the specific case of cancelling a recipe, InventoryChanges are expected to be the root.
71
return;
72
}
77
if (req.query.cancel) {
78
const inventoryChanges: IInventoryChanges = {};
79
await refundRecipeIngredients(inventory, inventoryChanges, recipe, pendingRecipe);
80
await inventory.save();
81
res.json(inventoryChanges); // Not a bug: In the specific case of cancelling a recipe, InventoryChanges are expected to be the root.
82
return;
83
}
73
84
74
await claimCompletedRecipe(account, inventory, recipe, pendingRecipe, resp, req.query.rush);
85
await claimCompletedRecipe(account, inventory, recipe, pendingRecipe, resp, req.query.rush);
86
}
87
} else {
88
throw new Error(`recipe list from request was undefined?`);
75
89
}
76
90
} else {
77
91
const recipeName = String(req.query.recipeName); // U8
@@ -92,7 +106,7 @@ export const claimCompletedRecipeController: RequestHandler = async (req, res) =
92
106
recipe,
93
107
pendingRecipe,
94
108
resp,
95
req.path.includes("instantCompleteRecipe.php")
109
req.path.includes("instantCompleteRecipe.php") || req.query.rush
96
110
);
97
111
}
98
112
await inventory.save();
@@ -144,13 +158,20 @@ const claimCompletedRecipe = async (
144
158
}
145
159
146
160
if (rush) {
161
let cost = recipe.skipBuildTimePrice;
147
162
const end = Math.trunc(pendingRecipe.CompletionDate.getTime() / 1000);
148
163
const start = end - recipe.buildTime;
149
164
const secondsElapsed = Math.trunc(Date.now() / 1000) - start;
150
165
const progress = secondsElapsed / recipe.buildTime;
151
166
logger.debug(`rushing recipe at ${Math.trunc(progress * 100)}% completion`);
152
const cost =
153
progress > 0.5 ? Math.round(recipe.skipBuildTimePrice * (1 - (progress - 0.5))) : recipe.skipBuildTimePrice;
167
// U18 introduced rush cost scaling, don't use it for older versions.
168
if (account.BuildLabel && version_compare(account.BuildLabel, "2015.12.03.00.00") >= 0) {
169
// Haven't found the real build label for U18.0.0 yet, but this works
170
cost =
171
progress > 0.5
172
? Math.round(recipe.skipBuildTimePrice * (1 - (progress - 0.5)))
173
: recipe.skipBuildTimePrice;
174
}
154
175
combineInventoryChanges(resp.InventoryChanges, updateCurrency(inventory, cost, true));
155
176
}
156
177