返回提交历史
Modified
src/controllers/api/abortDojoComponentController.ts
+1
-1
Added
src/controllers/api/reduceGuildTierController.ts
+28
-0
Modified
src/controllers/api/startDojoRecipeController.ts
+10
-0
Modified
src/models/guildModel.ts
+1
-0
Modified
src/routes/api.ts
+2
-0
Modified
src/services/guildService.ts
+25
-38
Modified
src/types/guildTypes.ts
+3
-1
XFEstudio/SpaceNinjaServer
feat: reduceGuildTier (#4059)
Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/4059 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
f570e455
代码差异
7 个文件
+70
-40
@@ -54,7 +54,7 @@ const abortDojoComponent = async (
54
54
return { DojoRequestStatus: -1 };
55
55
}
56
56
57
await removeDojoRoom(guild, componentId);
57
removeDojoRoom(guild, componentId);
58
58
await guild.save();
59
59
return await getDojoClient(guild, 0, undefined, account.BuildLabel);
60
60
}
@@ -0,0 +1,28 @@
1
import type { RequestHandler } from "express";
2
import { getAccountForRequest } from "../../services/loginService.ts";
3
import { getInventory } from "../../services/inventoryService.ts";
4
import {
5
getGuildForRequestEx,
6
hasAccessToDojo,
7
hasGuildPermission,
8
setGuildTier
9
} from "../../services/guildService.ts";
10
import { GuildPermission } from "../../types/guildTypes.ts";
11
import { unixTimesInMs } from "../../constants/timeConstants.ts";
12
13
export const reduceGuildTierController: RequestHandler = async (req, res) => {
14
const account = await getAccountForRequest(req);
15
const inventory = await getInventory(account._id, "GuildId LevelKeys");
16
const guild = await getGuildForRequestEx(req, inventory);
17
18
// TOVERIFY: Which permission is required for this?
19
if (!hasAccessToDojo(inventory) || !(await hasGuildPermission(guild, account._id, GuildPermission.Ruler))) {
20
res.json({ DojoRequestStatus: -1 });
21
return;
22
}
23
24
await setGuildTier(guild, parseInt(req.query.newTier as string));
25
guild.GuildTierIncMoratorium = new Date(Date.now() + unixTimesInMs.day * 60);
26
await guild.save();
27
res.json({ NewTier: guild.Tier });
28
};
@@ -4,6 +4,7 @@ import { GuildPermission } from "../../types/guildTypes.ts";
4
4
import {
5
5
getDojoClient,
6
6
getGuildForRequestEx,
7
getNewTierFromPrefab,
7
8
hasAccessToDojo,
8
9
hasGuildPermission,
9
10
processDojoBuildMaterialsGathered,
@@ -30,6 +31,15 @@ export const startDojoRecipeController: RequestHandler = async (req, res) => {
30
31
}
31
32
const request = JSON.parse(String(req.body)) as IStartDojoRecipeRequest;
32
33
34
if (
35
getNewTierFromPrefab(request.PlacedComponent.pf) &&
36
guild.GuildTierIncMoratorium &&
37
guild.GuildTierIncMoratorium.getTime() > Date.now()
38
) {
39
res.json({ DojoRequestStatus: -7 });
40
return;
41
}
42
33
43
const room = Object.values(ExportDojoRecipes.rooms).find(x => x.resultType == request.PlacedComponent.pf);
34
44
if (room) {
35
45
guild.DojoCapacity += room.capacity;
@@ -230,6 +230,7 @@ const guildSchema = new Schema<IGuildDatabase>(
230
230
Ranks: { type: [guildRankSchema], default: defaultRanks },
231
231
TradeTax: { type: Number, default: 0 },
232
232
Tier: { type: Number, default: 1 },
233
GuildTierIncMoratorium: Date,
233
234
Emblem: Boolean,
234
235
AutoContributeFromVault: Boolean,
235
236
AllianceId: Types.ObjectId,
@@ -120,6 +120,7 @@ import { purchaseGetController, purchasePostController } from "../controllers/ap
120
120
import { questControlController } from "../controllers/api/questControlController.ts";
121
121
import { queueDojoComponentDestructionController } from "../controllers/api/queueDojoComponentDestructionController.ts";
122
122
import { redeemPromoCodeController } from "../controllers/api/redeemPromoCodeController.ts";
123
import { reduceGuildTierController } from "../controllers/api/reduceGuildTierController.ts";
123
124
import { refillRevivesController } from "../controllers/api/refillRevivesController.ts";
124
125
import { releasePetController } from "../controllers/api/releasePetController.ts";
125
126
import { removeFriendGetController, removeFriendPostController } from "../controllers/api/removeFriendController.ts";
@@ -248,6 +249,7 @@ apiRouter.get("/playedParkourTutorial.php", playedParkourTutorialController);
248
249
apiRouter.get("/purchase.php", purchaseGetController); // U8
249
250
apiRouter.get("/questControl.php", questControlController);
250
251
apiRouter.get("/queueDojoComponentDestruction.php", queueDojoComponentDestructionController);
252
apiRouter.get("/reduceGuildTier.php", reduceGuildTierController);
251
253
apiRouter.get("/removeFriend.php", removeFriendGetController);
252
254
apiRouter.get("/removeFromAlliance.php", removeFromAllianceController);
253
255
apiRouter.get("/removeFromGuild.php", removeFromGuildGetController);
@@ -23,7 +23,7 @@ import type {
23
23
IVaultPendingRecipeClient
24
24
} from "../types/guildTypes.ts";
25
25
import { GuildPermission } from "../types/guildTypes.ts";
26
import { toMongoDate, toOid2, version_compare } from "../helpers/inventoryHelpers.ts";
26
import { toMongoDate, toMongoDate2, toOid2, version_compare } from "../helpers/inventoryHelpers.ts";
27
27
import type { Types } from "mongoose";
28
28
import type { IDojoBuild, IDojoResearch } from "warframe-public-export-plus";
29
29
import { ExportDojoRecipes, ExportResources } from "warframe-public-export-plus";
@@ -143,6 +143,9 @@ export const getGuildClient = async (
143
143
Members: members,
144
144
Ranks: ranks,
145
145
Tier: guild.Tier,
146
GuildTierIncMoratorium: guild.GuildTierIncMoratorium
147
? toMongoDate2(guild.GuildTierIncMoratorium, account.BuildLabel)
148
: undefined,
146
149
Emblem: guild.Emblem,
147
150
Vault: await getGuildVault(guild, account.BuildLabel),
148
151
ActiveDojoColorResearch: guild.ActiveDojoColorResearch,
@@ -150,7 +153,9 @@ export const getGuildClient = async (
150
153
XP: guild.XP,
151
154
IsContributor: !!guild.CeremonyContributors?.find(x => x.equals(account._id)),
152
155
NumContributors: guild.CeremonyContributors?.length ?? 0,
153
CeremonyResetDate: guild.CeremonyResetDate ? toMongoDate(guild.CeremonyResetDate) : undefined,
156
CeremonyResetDate: guild.CeremonyResetDate
157
? toMongoDate2(guild.CeremonyResetDate, account.BuildLabel)
158
: undefined,
154
159
AutoContributeFromVault: guild.AutoContributeFromVault,
155
160
AllianceId: guild.AllianceId ? toOid2(guild.AllianceId, account.BuildLabel) : undefined,
156
161
GoalProgress: guild.GoalProgress
@@ -394,21 +399,7 @@ export const getDojoClient = async (
394
399
needSave = true;
395
400
}
396
401
397
let newTier: number | undefined;
398
switch (dojoComponent.pf) {
399
case "/Lotus/Levels/ClanDojo/ClanDojoBarracksShadow.level":
400
newTier = 2;
401
break;
402
case "/Lotus/Levels/ClanDojo/ClanDojoBarracksStorm.level":
403
newTier = 3;
404
break;
405
case "/Lotus/Levels/ClanDojo/ClanDojoBarracksMountain.level":
406
newTier = 4;
407
break;
408
case "/Lotus/Levels/ClanDojo/ClanDojoBarracksMoon.level":
409
newTier = 5;
410
break;
411
}
402
const newTier = getNewTierFromPrefab(dojoComponent.pf);
412
403
if (newTier) {
413
404
logger.debug(`clan finished building barracks, updating to tier ${newTier}`);
414
405
await setGuildTier(guild, newTier);
@@ -476,7 +467,7 @@ export const getDojoClient = async (
476
467
if (roomsToRemove.length) {
477
468
logger.debug(`removing now-destroyed rooms`, roomsToRemove);
478
469
for (const id of roomsToRemove) {
479
await removeDojoRoom(guild, id);
470
removeDojoRoom(guild, id);
480
471
}
481
472
needSave = true;
482
473
}
@@ -496,6 +487,20 @@ export const getDojoClient = async (
496
487
return dojo;
497
488
};
498
489
490
export const getNewTierFromPrefab = (pf: string): number | null => {
491
switch (pf) {
492
case "/Lotus/Levels/ClanDojo/ClanDojoBarracksShadow.level":
493
return 2;
494
case "/Lotus/Levels/ClanDojo/ClanDojoBarracksStorm.level":
495
return 3;
496
case "/Lotus/Levels/ClanDojo/ClanDojoBarracksMountain.level":
497
return 4;
498
case "/Lotus/Levels/ClanDojo/ClanDojoBarracksMoon.level":
499
return 5;
500
}
501
return null;
502
};
503
499
504
const guildTierScalingFactors = [0.01, 0.03, 0.1, 0.3, 1];
500
505
export const scaleRequiredCount = (tier: number, count: number, disableScaling?: boolean): number => {
501
506
if (disableScaling) {
@@ -505,10 +510,7 @@ export const scaleRequiredCount = (tier: number, count: number, disableScaling?:
505
510
return Math.max(1, Math.trunc(count * guildTierScalingFactors[tier - 1]));
506
511
};
507
512
508
export const removeDojoRoom = async (
509
guild: TGuildDatabaseDocument,
510
componentId: Types.ObjectId | string
511
): Promise<void> => {
513
export const removeDojoRoom = (guild: TGuildDatabaseDocument, componentId: Types.ObjectId | string): void => {
512
514
const component = guild.DojoComponents.splice(
513
515
guild.DojoComponents.findIndex(x => x._id.equals(componentId)),
514
516
1
@@ -527,21 +529,6 @@ export const removeDojoRoom = async (
527
529
guild.RoomChanges.splice(index, 1);
528
530
}
529
531
}
530
531
switch (component.pf) {
532
case "/Lotus/Levels/ClanDojo/ClanDojoBarracksShadow.level":
533
await setGuildTier(guild, 1);
534
break;
535
case "/Lotus/Levels/ClanDojo/ClanDojoBarracksStorm.level":
536
await setGuildTier(guild, 2);
537
break;
538
case "/Lotus/Levels/ClanDojo/ClanDojoBarracksMountain.level":
539
await setGuildTier(guild, 3);
540
break;
541
case "/Lotus/Levels/ClanDojo/ClanDojoBarracksMoon.level":
542
await setGuildTier(guild, 4);
543
break;
544
}
545
532
};
546
533
547
534
export const removeDojoDeco = (
@@ -857,7 +844,7 @@ export const setGuildTechLogState = (
857
844
return true;
858
845
};
859
846
860
const setGuildTier = async (guild: TGuildDatabaseDocument, newTier: number): Promise<void> => {
847
export const setGuildTier = async (guild: TGuildDatabaseDocument, newTier: number): Promise<void> => {
861
848
const oldTier = guild.Tier;
862
849
guild.Tier = newTier;
863
850
if (guild.TechProjects) {
@@ -23,6 +23,7 @@ export interface IGuildClient {
23
23
Members: IGuildMemberClient[];
24
24
Ranks: IGuildRank[];
25
25
Tier: number;
26
GuildTierIncMoratorium?: IMongoDateWithLegacySupport;
26
27
Emblem?: boolean;
27
28
Vault: IGuildVaultClient;
28
29
ActiveDojoColorResearch: string;
@@ -31,7 +32,7 @@ export interface IGuildClient {
31
32
IsContributor: boolean;
32
33
NumContributors: number;
33
34
FixedContributions?: boolean;
34
CeremonyResetDate?: IMongoDate;
35
CeremonyResetDate?: IMongoDateWithLegacySupport;
35
36
CrossPlatformEnabled?: boolean;
36
37
AutoContributeFromVault?: boolean;
37
38
AllianceId?: IOidWithLegacySupport;
@@ -56,6 +57,7 @@ export interface IGuildDatabase extends IGuildCheats, IVaultDatabase {
56
57
Ranks: IGuildRank[];
57
58
TradeTax: number;
58
59
Tier: number;
60
GuildTierIncMoratorium?: Date;
59
61
Emblem?: boolean;
60
62
AutoContributeFromVault?: boolean;
61
63
AllianceId?: Types.ObjectId;