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: change dojo spawn room (#949)

Closes #524 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/949 Co-authored-by: Sainan <sainan@calamity.inc> Co-committed-by: Sainan <sainan@calamity.inc>

7e7e4e2e
Sainan <sainan@calamity.inc>
提交于

代码差异

3 个文件 +94 -2
Added src/controllers/api/changeDojoRootController.ts +90 -0
@@ -0,0 +1,90 @@
1 import { RequestHandler } from "express";
2 import { getDojoClient, getGuildForRequest } from "@/src/services/guildService";
3 import { logger } from "@/src/utils/logger";
4 import { IDojoComponentDatabase } from "@/src/types/guildTypes";
5 import { Types } from "mongoose";
6
7 export const changeDojoRootController: RequestHandler = async (req, res) => {
8 const guild = await getGuildForRequest(req);
9 // At this point, we know that a member of the guild is making this request. Assuming they are allowed to change the root.
10
11 const idToNode: Record<string, INode> = {};
12 guild.DojoComponents!.forEach(x => {
13 idToNode[x._id.toString()] = {
14 component: x,
15 parent: undefined,
16 children: []
17 };
18 });
19
20 let oldRoot: INode | undefined;
21 guild.DojoComponents!.forEach(x => {
22 const node = idToNode[x._id.toString()];
23 if (x.pi) {
24 idToNode[x.pi.toString()].children.push(node);
25 node.parent = idToNode[x.pi.toString()];
26 } else {
27 oldRoot = node;
28 }
29 });
30 logger.debug("Old tree:\n" + treeToString(oldRoot!));
31
32 const newRoot = idToNode[req.query.newRoot as string];
33 recursivelyTurnParentsIntoChildren(newRoot);
34 newRoot.component.pi = undefined;
35 newRoot.component.op = undefined;
36 newRoot.component.pp = undefined;
37 newRoot.parent = undefined;
38
39 // Don't even ask me why this is needed because I don't know either
40 const stack: INode[] = [newRoot];
41 let i = 0;
42 const idMap: Record<string, Types.ObjectId> = {};
43 while (stack.length != 0) {
44 const top = stack.shift()!;
45 idMap[top.component._id.toString()] = new Types.ObjectId(
46 (++i).toString(16).padStart(8, "0") + top.component._id.toString().substr(8)
47 );
48 top.children.forEach(x => stack.push(x));
49 }
50 guild.DojoComponents!.forEach(x => {
51 x._id = idMap[x._id.toString()];
52 if (x.pi) {
53 x.pi = idMap[x.pi.toString()];
54 }
55 });
56
57 logger.debug("New tree:\n" + treeToString(newRoot));
58
59 await guild.save();
60
61 res.json(getDojoClient(guild, 0));
62 };
63
64 interface INode {
65 component: IDojoComponentDatabase;
66 parent: INode | undefined;
67 children: INode[];
68 }
69
70 const treeToString = (root: INode, depth: number = 0): string => {
71 let str = " ".repeat(depth * 4) + root.component.pf + " (" + root.component._id.toString() + ")\n";
72 root.children.forEach(x => {
73 str += treeToString(x, depth + 1);
74 });
75 return str;
76 };
77
78 const recursivelyTurnParentsIntoChildren = (node: INode): void => {
79 if (node.parent!.parent) {
80 recursivelyTurnParentsIntoChildren(node.parent!);
81 }
82
83 node.parent!.component.pi = node.component._id;
84 node.parent!.component.op = node.component.pp;
85 node.parent!.component.pp = node.component.op;
86
87 node.parent!.parent = node;
88 node.parent!.children.splice(node.parent!.children.indexOf(node), 1);
89 node.children.push(node.parent!);
90 };
Modified src/routes/api.ts +2 -0
@@ -4,6 +4,7 @@ import { addFriendImageController } from "@/src/controllers/api/addFriendImageCo
4 4 import { arcaneCommonController } from "@/src/controllers/api/arcaneCommonController";
5 5 import { archonFusionController } from "@/src/controllers/api/archonFusionController";
6 6 import { artifactsController } from "../controllers/api/artifactsController";
7 import { changeDojoRootController } from "../controllers/api/changeDojoRootController";
7 8 import { checkDailyMissionBonusController } from "@/src/controllers/api/checkDailyMissionBonusController";
8 9 import { claimCompletedRecipeController } from "@/src/controllers/api/claimCompletedRecipeController";
9 10 import { clearDialogueHistoryController } from "@/src/controllers/api/clearDialogueHistoryController";
@@ -127,6 +128,7 @@ apiRouter.post("/addFriendImage.php", addFriendImageController);
127 128 apiRouter.post("/arcaneCommon.php", arcaneCommonController);
128 129 apiRouter.post("/archonFusion.php", archonFusionController);
129 130 apiRouter.post("/artifacts.php", artifactsController);
131 apiRouter.post("/changeDojoRoot.php", changeDojoRootController);
130 132 apiRouter.post("/claimCompletedRecipe.php", claimCompletedRecipeController);
131 133 apiRouter.post("/clearDialogueHistory.php", clearDialogueHistoryController);
132 134 apiRouter.post("/createGuild.php", createGuildController);
Modified src/types/guildTypes.ts +2 -2
@@ -32,8 +32,8 @@ export interface IDojoComponentClient {
32 32 pf: string; // Prefab (.level)
33 33 ppf: string;
34 34 pi?: IOid; // Parent ID. N/A to root.
35 op?: string; // "Open Portal"? N/A to root.
36 pp?: string; // "Parent Portal"? N/A to root.
35 op?: string; // Name of the door within this room that leads to its parent. N/A to root.
36 pp?: string; // Name of the door within the parent that leads to this room. N/A to root.
37 37 Name?: string;
38 38 Message?: string;
39 39 RegularCredits?: number; // "Collecting Materials" state: Number of credits that were donated.