返回提交历史
Added
src/controllers/api/customObstacleCourseLeaderboardController.ts
+48
-0
Modified
src/models/guildModel.ts
+13
-2
Modified
src/routes/api.ts
+2
-0
Modified
src/types/guildTypes.ts
+7
-0
XFEstudio/XFESpaceNinjaServer
feat: custom obstacle course leaderboard (#1326)
Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/1326
5597bfe8
代码差异
4 个文件
+70
-2
@@ -0,0 +1,48 @@
1
import { getJSONfromString } from "@/src/helpers/stringHelpers";
2
import { Guild } from "@/src/models/guildModel";
3
import { getAccountForRequest } from "@/src/services/loginService";
4
import { logger } from "@/src/utils/logger";
5
import { RequestHandler } from "express";
6
7
export const customObstacleCourseLeaderboardController: RequestHandler = async (req, res) => {
8
const data = getJSONfromString<ICustomObstacleCourseLeaderboardRequest>(String(req.body));
9
const guild = (await Guild.findById(data.g, "DojoComponents"))!;
10
const component = guild.DojoComponents.id(data.c)!;
11
if (req.query.act == "f") {
12
res.json({
13
results: component.Leaderboard ?? []
14
});
15
} else if (req.query.act == "p") {
16
const account = await getAccountForRequest(req);
17
component.Leaderboard ??= [];
18
const entry = component.Leaderboard.find(x => x.n == account.DisplayName);
19
if (entry) {
20
entry.s = data.s!;
21
} else {
22
component.Leaderboard.push({
23
s: data.s!,
24
n: account.DisplayName,
25
r: 0
26
});
27
}
28
component.Leaderboard.sort((a, b) => a.s - b.s); // In this case, the score is the time in milliseconds, so smaller is better.
29
if (component.Leaderboard.length > 10) {
30
component.Leaderboard.shift();
31
}
32
let r = 0;
33
for (const entry of component.Leaderboard) {
34
entry.r = ++r;
35
}
36
await guild.save();
37
res.status(200).end();
38
} else {
39
logger.debug(`data provided to ${req.path}: ${String(req.body)}`);
40
throw new Error(`unknown customObstacleCourseLeaderboard act: ${String(req.query.act)}`);
41
}
42
};
43
44
interface ICustomObstacleCourseLeaderboardRequest {
45
g: string;
46
c: string;
47
s?: number; // act=p
48
}
@@ -9,7 +9,8 @@ import {
9
9
IGuildRank,
10
10
IGuildLogRoomChange,
11
11
IGuildLogEntryRoster,
12
IGuildLogEntryContributable
12
IGuildLogEntryContributable,
13
IDojoLeaderboardEntry
13
14
} from "@/src/types/guildTypes";
14
15
import { Document, Model, model, Schema, Types } from "mongoose";
15
16
import { fusionTreasuresSchema, typeCountSchema } from "./inventoryModels/inventoryModel";
@@ -25,6 +26,15 @@ const dojoDecoSchema = new Schema<IDojoDecoDatabase>({
25
26
RushPlatinum: Number
26
27
});
27
28
29
const dojoLeaderboardEntrySchema = new Schema<IDojoLeaderboardEntry>(
30
{
31
s: Number,
32
r: Number,
33
n: String
34
},
35
{ _id: false }
36
);
37
28
38
const dojoComponentSchema = new Schema<IDojoComponentDatabase>({
29
39
pf: { type: String, required: true },
30
40
ppf: String,
@@ -40,7 +50,8 @@ const dojoComponentSchema = new Schema<IDojoComponentDatabase>({
40
50
RushPlatinum: Number,
41
51
DestructionTime: Date,
42
52
Decos: [dojoDecoSchema],
43
DecoCapacity: Number
53
DecoCapacity: Number,
54
Leaderboard: { type: [dojoLeaderboardEntrySchema], default: undefined }
44
55
});
45
56
46
57
const techProjectSchema = new Schema<ITechProjectDatabase>(
@@ -24,6 +24,7 @@ import { contributeToVaultController } from "@/src/controllers/api/contributeToV
24
24
import { createGuildController } from "@/src/controllers/api/createGuildController";
25
25
import { creditsController } from "@/src/controllers/api/creditsController";
26
26
import { customizeGuildRanksController } from "@/src/controllers/api/customizeGuildRanksController";
27
import { customObstacleCourseLeaderboardController } from "@/src/controllers/api/customObstacleCourseLeaderboardController";
27
28
import { declineGuildInviteController } from "@/src/controllers/api/declineGuildInviteController";
28
29
import { deleteSessionController } from "@/src/controllers/api/deleteSessionController";
29
30
import { destroyDojoDecoController } from "@/src/controllers/api/destroyDojoDecoController";
@@ -183,6 +184,7 @@ apiRouter.post("/contributeToDojoComponent.php", contributeToDojoComponentContro
183
184
apiRouter.post("/contributeToVault.php", contributeToVaultController);
184
185
apiRouter.post("/createGuild.php", createGuildController);
185
186
apiRouter.post("/customizeGuildRanks.php", customizeGuildRanksController);
187
apiRouter.post("/customObstacleCourseLeaderboard.php", customObstacleCourseLeaderboardController);
186
188
apiRouter.post("/destroyDojoDeco.php", destroyDojoDecoController);
187
189
apiRouter.post("/dojoComponentRush.php", dojoComponentRushController);
188
190
apiRouter.post("/drones.php", dronesController);
@@ -152,6 +152,7 @@ export interface IDojoComponentDatabase
152
152
CompletionLogPending?: boolean;
153
153
DestructionTime?: Date;
154
154
Decos?: IDojoDecoDatabase[];
155
Leaderboard?: IDojoLeaderboardEntry[];
155
156
}
156
157
157
158
export interface IDojoDecoClient {
@@ -212,3 +213,9 @@ export interface IGuildLogEntryNumber {
212
213
entryType: number;
213
214
details: number;
214
215
}
216
217
export interface IDojoLeaderboardEntry {
218
s: number; // score
219
r: number; // rank
220
n: string; // displayName
221
}