XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESpaceNinjaServer

A simple server for a small space ninja game

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/XFESpaceNinjaServer

feat: custom obstacle course leaderboard (#1326)

Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/1326

5597bfe8
Sainan <sainan@calamity.inc>
提交于

代码差异

4 个文件 +70 -2
Added src/controllers/api/customObstacleCourseLeaderboardController.ts +48 -0
@@ -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 }
Modified src/models/guildModel.ts +13 -2
@@ -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>(
Modified src/routes/api.ts +2 -0
@@ -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);
Modified src/types/guildTypes.ts +7 -0
@@ -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 }