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: initial foundry for U8 (#3014)

endpoints should work, but we don't have data for required recipe items for U8, so in most cases, an unknown error will occur in the game, and a more detailed error will occur in the server console. Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/3014 Reviewed-by: Sainan <63328889+sainan@users.noreply.github.com> Co-authored-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com> Co-committed-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>

48b7138c
AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
提交于

代码差异

4 个文件 +81 -21
Added src/controllers/api/checkPendingRecipesController.ts +24 -0
@@ -0,0 +1,24 @@
1 import { getAccountIdForRequest } from "../../services/loginService.ts";
2 import type { RequestHandler } from "express";
3 import { getInventory } from "../../services/inventoryService.ts";
4
5 export const checkPendingRecipesController: RequestHandler = async (req, res) => {
6 const accountId = await getAccountIdForRequest(req);
7 const inventory = await getInventory(accountId, "PendingRecipes");
8 const now = Date.now();
9 const resp: ICheckPendingRecipesResponse = {
10 PendingRecipes: inventory.PendingRecipes.map(recipe => ({
11 ItemType: recipe.ItemType,
12 SecondsRemaining: Math.max(0, Math.floor((recipe.CompletionDate.getTime() - now) / 1000))
13 }))
14 };
15
16 res.send(resp);
17 };
18
19 interface ICheckPendingRecipesResponse {
20 PendingRecipes: {
21 ItemType: string;
22 SecondsRemaining: number;
23 }[];
24 }
Modified src/controllers/api/claimCompletedRecipeController.ts +42 -19
@@ -38,39 +38,62 @@ interface IClaimCompletedRecipeResponse {
38 38 }
39 39
40 40 export const claimCompletedRecipeController: RequestHandler = async (req, res) => {
41 const claimCompletedRecipeRequest = getJSONfromString<IClaimCompletedRecipeRequest>(String(req.body));
42 41 const account = await getAccountForRequest(req);
43 42 const inventory = await getInventory(account._id.toString());
44 43 const resp: IClaimCompletedRecipeResponse = {
45 44 InventoryChanges: {}
46 45 };
47 for (const recipeId of claimCompletedRecipeRequest.RecipeIds) {
48 const pendingRecipe = inventory.PendingRecipes.id(fromOid(recipeId));
46 if (!req.query.recipeName) {
47 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 }
53
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 // }
58
59 inventory.PendingRecipes.pull(pendingRecipe._id);
60
61 const recipe = getRecipe(pendingRecipe.ItemType);
62 if (!recipe) {
63 throw new Error(`no completed item found for recipe ${pendingRecipe._id.toString()}`);
64 }
65
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 }
73
74 await claimCompletedRecipe(account, inventory, recipe, pendingRecipe, resp, req.query.rush);
75 }
76 } else {
77 const recipeName = String(req.query.recipeName); // U8
78 const pendingRecipe = inventory.PendingRecipes.find(r => r.ItemType == recipeName);
49 79 if (!pendingRecipe) {
50 throw new Error(`no pending recipe found with id ${fromOid(recipeId)}`);
80 throw new Error(`no pending recipe found with ItemType ${recipeName}`);
51 81 }
52 82
53 //check recipe is indeed ready to be completed
54 // if (pendingRecipe.CompletionDate > new Date()) {
55 // throw new Error(`recipe ${pendingRecipe._id} is not ready to be completed`);
56 // }
57
58 83 inventory.PendingRecipes.pull(pendingRecipe._id);
59 84
60 85 const recipe = getRecipe(pendingRecipe.ItemType);
61 86 if (!recipe) {
62 87 throw new Error(`no completed item found for recipe ${pendingRecipe._id.toString()}`);
63 88 }
64
65 if (req.query.cancel) {
66 const inventoryChanges: IInventoryChanges = {};
67 await refundRecipeIngredients(inventory, inventoryChanges, recipe, pendingRecipe);
68 await inventory.save();
69 res.json(inventoryChanges); // Not a bug: In the specific case of cancelling a recipe, InventoryChanges are expected to be the root.
70 return;
71 }
72
73 await claimCompletedRecipe(account, inventory, recipe, pendingRecipe, resp, req.query.rush);
89 await claimCompletedRecipe(
90 account,
91 inventory,
92 recipe,
93 pendingRecipe,
94 resp,
95 req.path.includes("instantCompleteRecipe.php")
96 );
74 97 }
75 98 await inventory.save();
76 99 res.json(resp);
Modified src/controllers/api/startRecipeController.ts +12 -2
@@ -24,7 +24,8 @@ export const startRecipeController: RequestHandler = async (req, res) => {
24 24
25 25 const accountId = await getAccountIdForRequest(req);
26 26
27 const recipeName = startRecipeRequest.RecipeName;
27 let recipeName = startRecipeRequest.RecipeName;
28 if (req.query.recipeName) recipeName = String(req.query.recipeName); // U8
28 29 const recipe = getRecipe(recipeName);
29 30
30 31 if (!recipe) {
@@ -68,7 +69,16 @@ export const startRecipeController: RequestHandler = async (req, res) => {
68 69 freeUpSlot(inventory, InventorySlot.WEAPONS);
69 70 }
70 71 } else {
71 await addItem(inventory, recipe.ingredients[i].ItemType, recipe.ingredients[i].ItemCount * -1);
72 const itemType = recipe.ingredients[i].ItemType;
73 const itemCount = recipe.ingredients[i].ItemCount;
74 const inventoryItem = inventory.MiscItems.find(i => i.ItemType === itemType);
75 if (inventoryItem && inventoryItem.ItemCount >= itemCount) {
76 await addItem(inventory, itemType, itemCount * -1);
77 } else {
78 throw new Error(
79 `insufficient ${itemType} (in inventory ${inventoryItem?.ItemCount} - needed ${itemCount}) for recipe ${recipeName}`
80 );
81 }
72 82 }
73 83 }
74 84
Modified src/routes/api.ts +3 -0
@@ -20,6 +20,7 @@ import { cancelGuildAdvertisementController } from "../controllers/api/cancelGui
20 20 import { changeDojoRootController } from "../controllers/api/changeDojoRootController.ts";
21 21 import { changeGuildRankController } from "../controllers/api/changeGuildRankController.ts";
22 22 import { checkDailyMissionBonusController } from "../controllers/api/checkDailyMissionBonusController.ts";
23 import { checkPendingRecipesController } from "../controllers/api/checkPendingRecipesController.ts";
23 24 import { claimCompletedRecipeController } from "../controllers/api/claimCompletedRecipeController.ts";
24 25 import { claimJunctionChallengeRewardController } from "../controllers/api/claimJunctionChallengeRewardController.ts";
25 26 import { claimLibraryDailyTaskRewardController } from "../controllers/api/claimLibraryDailyTaskRewardController.ts";
@@ -184,6 +185,7 @@ apiRouter.get("/cancelGuildAdvertisement.php", cancelGuildAdvertisementControlle
184 185 apiRouter.get("/changeDojoRoot.php", changeDojoRootController);
185 186 apiRouter.get("/changeGuildRank.php", changeGuildRankController);
186 187 apiRouter.get("/checkDailyMissionBonus.php", checkDailyMissionBonusController);
188 apiRouter.get("/checkPendingRecipes.php", checkPendingRecipesController); // U8
187 189 apiRouter.get("/claimLibraryDailyTaskReward.php", claimLibraryDailyTaskRewardController);
188 190 apiRouter.get("/completeCalendarEvent.php", completeCalendarEventController);
189 191 apiRouter.get("/confirmAllianceInvitation.php", confirmAllianceInvitationController);
@@ -305,6 +307,7 @@ apiRouter.post("/guildTech.php", guildTechController);
305 307 apiRouter.post("/hostSession.php", hostSessionController);
306 308 apiRouter.post("/hubBlessing.php", hubBlessingController);
307 309 apiRouter.post("/infestedFoundry.php", infestedFoundryController);
310 apiRouter.post("/instantCompleteRecipe.php", claimCompletedRecipeController); // U8
308 311 apiRouter.post("/inventorySlots.php", inventorySlotsController);
309 312 apiRouter.post("/joinSession.php", joinSessionController);
310 313 apiRouter.post("/login.php", loginController);