返回提交历史
Added
src/controllers/api/changeDojoRootController.ts
+90
-0
Modified
src/routes/api.ts
+2
-0
Modified
src/types/guildTypes.ts
+2
-2
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
代码差异
3 个文件
+94
-2
@@ -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
};
@@ -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);
@@ -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.