feat: dojo room destruction stage

This commit is contained in:
Sainan 2025-03-06 09:13:50 +01:00
parent 6daa8ab5da
commit f9bcd6969a
13 changed files with 52 additions and 18 deletions

View File

@ -9,7 +9,6 @@ export const abortDojoComponentController: RequestHandler = async (req, res) =>
const guild = await getGuildForRequestEx(req, inventory); const guild = await getGuildForRequestEx(req, inventory);
const request = JSON.parse(String(req.body)) as IAbortDojoComponentRequest; const request = JSON.parse(String(req.body)) as IAbortDojoComponentRequest;
// TODO: Move already-contributed credits & items to the clan vault
if (request.DecoId) { if (request.DecoId) {
removeDojoDeco(guild, request.ComponentId, request.DecoId); removeDojoDeco(guild, request.ComponentId, request.DecoId);
} else { } else {
@ -17,7 +16,7 @@ export const abortDojoComponentController: RequestHandler = async (req, res) =>
} }
await guild.save(); await guild.save();
res.json(getDojoClient(guild, 0, request.ComponentId)); res.json(await getDojoClient(guild, 0, request.ComponentId));
}; };
interface IAbortDojoComponentRequest { interface IAbortDojoComponentRequest {

View File

@ -0,0 +1,12 @@
import { getDojoClient, getGuildForRequest } from "@/src/services/guildService";
import { RequestHandler } from "express";
export const abortDojoComponentDestructionController: RequestHandler = async (req, res) => {
const guild = await getGuildForRequest(req);
const componentId = req.query.componentId as string;
guild.DojoComponents.id(componentId)!.DestructionTime = undefined;
await guild.save();
res.json(await getDojoClient(guild, 0, componentId));
};

View File

@ -58,7 +58,7 @@ export const changeDojoRootController: RequestHandler = async (req, res) => {
await guild.save(); await guild.save();
res.json(getDojoClient(guild, 0)); res.json(await getDojoClient(guild, 0));
}; };
interface INode { interface INode {

View File

@ -50,7 +50,7 @@ export const contributeToDojoComponentController: RequestHandler = async (req, r
await guild.save(); await guild.save();
await inventory.save(); await inventory.save();
res.json({ res.json({
...getDojoClient(guild, 0, component._id), ...(await getDojoClient(guild, 0, component._id)),
InventoryChanges: inventoryChanges InventoryChanges: inventoryChanges
}); });
}; };

View File

@ -6,10 +6,9 @@ export const destroyDojoDecoController: RequestHandler = async (req, res) => {
const request = JSON.parse(String(req.body)) as IDestroyDojoDecoRequest; const request = JSON.parse(String(req.body)) as IDestroyDojoDecoRequest;
removeDojoDeco(guild, request.ComponentId, request.DecoId); removeDojoDeco(guild, request.ComponentId, request.DecoId);
// TODO: The client says this is supposed to refund the resources to the clan vault, so we should probably do that.
await guild.save(); await guild.save();
res.json(getDojoClient(guild, 0, request.ComponentId)); res.json(await getDojoClient(guild, 0, request.ComponentId));
}; };
interface IDestroyDojoDecoRequest { interface IDestroyDojoDecoRequest {

View File

@ -35,7 +35,7 @@ export const dojoComponentRushController: RequestHandler = async (req, res) => {
await guild.save(); await guild.save();
await inventory.save(); await inventory.save();
res.json({ res.json({
...getDojoClient(guild, 0, component._id), ...(await getDojoClient(guild, 0, component._id)),
InventoryChanges: inventoryChanges InventoryChanges: inventoryChanges
}); });
}; };

View File

@ -24,5 +24,5 @@ export const getGuildDojoController: RequestHandler = async (req, res) => {
await guild.save(); await guild.save();
} }
res.json(getDojoClient(guild, 0)); res.json(await getDojoClient(guild, 0));
}; };

View File

@ -30,7 +30,7 @@ export const placeDecoInComponentController: RequestHandler = async (req, res) =
} }
await guild.save(); await guild.save();
res.json(getDojoClient(guild, 0, component._id)); res.json(await getDojoClient(guild, 0, component._id));
}; };
interface IPlaceDecoInComponentRequest { interface IPlaceDecoInComponentRequest {

View File

@ -1,12 +1,12 @@
import { getDojoClient, getGuildForRequest, removeDojoRoom } from "@/src/services/guildService"; import { getDojoClient, getGuildForRequest } from "@/src/services/guildService";
import { RequestHandler } from "express"; import { RequestHandler } from "express";
export const queueDojoComponentDestructionController: RequestHandler = async (req, res) => { export const queueDojoComponentDestructionController: RequestHandler = async (req, res) => {
const guild = await getGuildForRequest(req); const guild = await getGuildForRequest(req);
const componentId = req.query.componentId as string; const componentId = req.query.componentId as string;
removeDojoRoom(guild, componentId); guild.DojoComponents.id(componentId)!.DestructionTime = new Date(Date.now() + 2 * 3600_000);
await guild.save(); await guild.save();
res.json(getDojoClient(guild, 1)); res.json(await getDojoClient(guild, 0, componentId));
}; };

View File

@ -12,7 +12,7 @@ export const setDojoComponentMessageController: RequestHandler = async (req, res
component.Message = payload.Message; component.Message = payload.Message;
} }
await guild.save(); await guild.save();
res.json(getDojoClient(guild, 0, component._id)); res.json(await getDojoClient(guild, 0, component._id));
}; };
type SetDojoComponentMessageRequest = { Name: string } | { Message: string }; type SetDojoComponentMessageRequest = { Name: string } | { Message: string };

View File

@ -37,5 +37,5 @@ export const startDojoRecipeController: RequestHandler = async (req, res) => {
component.CompletionTime = new Date(Date.now()); component.CompletionTime = new Date(Date.now());
} }
await guild.save(); await guild.save();
res.json(getDojoClient(guild, 0)); res.json(await getDojoClient(guild, 0));
}; };

View File

@ -1,6 +1,7 @@
import express from "express"; import express from "express";
import { abandonLibraryDailyTaskController } from "@/src/controllers/api/abandonLibraryDailyTaskController"; import { abandonLibraryDailyTaskController } from "@/src/controllers/api/abandonLibraryDailyTaskController";
import { abortDojoComponentController } from "@/src/controllers/api/abortDojoComponentController"; import { abortDojoComponentController } from "@/src/controllers/api/abortDojoComponentController";
import { abortDojoComponentDestructionController } from "@/src/controllers/api/abortDojoComponentDestructionController";
import { activateRandomModController } from "@/src/controllers/api/activateRandomModController"; import { activateRandomModController } from "@/src/controllers/api/activateRandomModController";
import { addFriendImageController } from "@/src/controllers/api/addFriendImageController"; import { addFriendImageController } from "@/src/controllers/api/addFriendImageController";
import { arcaneCommonController } from "@/src/controllers/api/arcaneCommonController"; import { arcaneCommonController } from "@/src/controllers/api/arcaneCommonController";
@ -105,6 +106,7 @@ const apiRouter = express.Router();
// get // get
apiRouter.get("/abandonLibraryDailyTask.php", abandonLibraryDailyTaskController); apiRouter.get("/abandonLibraryDailyTask.php", abandonLibraryDailyTaskController);
apiRouter.get("/abortDojoComponentDestruction.php", abortDojoComponentDestructionController);
apiRouter.get("/checkDailyMissionBonus.php", checkDailyMissionBonusController); apiRouter.get("/checkDailyMissionBonus.php", checkDailyMissionBonusController);
apiRouter.get("/claimLibraryDailyTaskReward.php", claimLibraryDailyTaskRewardController); apiRouter.get("/claimLibraryDailyTaskReward.php", claimLibraryDailyTaskRewardController);
apiRouter.get("/credits.php", creditsController); apiRouter.get("/credits.php", creditsController);

View File

@ -7,6 +7,7 @@ import { IDojoClient, IDojoComponentClient } from "@/src/types/guildTypes";
import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers"; import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers";
import { Types } from "mongoose"; import { Types } from "mongoose";
import { ExportDojoRecipes } from "warframe-public-export-plus"; import { ExportDojoRecipes } from "warframe-public-export-plus";
import { logger } from "../utils/logger";
export const getGuildForRequest = async (req: Request): Promise<TGuildDatabaseDocument> => { export const getGuildForRequest = async (req: Request): Promise<TGuildDatabaseDocument> => {
const accountId = await getAccountIdForRequest(req); const accountId = await getAccountIdForRequest(req);
@ -29,11 +30,11 @@ export const getGuildForRequestEx = async (
return guild; return guild;
}; };
export const getDojoClient = ( export const getDojoClient = async (
guild: TGuildDatabaseDocument, guild: TGuildDatabaseDocument,
status: number, status: number,
componentId: Types.ObjectId | string | undefined = undefined componentId: Types.ObjectId | string | undefined = undefined
): IDojoClient => { ): Promise<IDojoClient> => {
const dojo: IDojoClient = { const dojo: IDojoClient = {
_id: { $oid: guild._id.toString() }, _id: { $oid: guild._id.toString() },
Name: guild.Name, Name: guild.Name,
@ -46,6 +47,7 @@ export const getDojoClient = (
DojoRequestStatus: status, DojoRequestStatus: status,
DojoComponents: [] DojoComponents: []
}; };
const roomsToRemove: Types.ObjectId[] = [];
guild.DojoComponents.forEach(dojoComponent => { guild.DojoComponents.forEach(dojoComponent => {
if (!componentId || dojoComponent._id.equals(componentId)) { if (!componentId || dojoComponent._id.equals(componentId)) {
const clientComponent: IDojoComponentClient = { const clientComponent: IDojoComponentClient = {
@ -63,6 +65,13 @@ export const getDojoClient = (
} }
if (dojoComponent.CompletionTime) { if (dojoComponent.CompletionTime) {
clientComponent.CompletionTime = toMongoDate(dojoComponent.CompletionTime); clientComponent.CompletionTime = toMongoDate(dojoComponent.CompletionTime);
if (dojoComponent.DestructionTime) {
if (Date.now() >= dojoComponent.DestructionTime.getTime()) {
roomsToRemove.push(dojoComponent._id);
return;
}
clientComponent.DestructionTime = toMongoDate(dojoComponent.DestructionTime);
}
} else { } else {
clientComponent.RegularCredits = dojoComponent.RegularCredits; clientComponent.RegularCredits = dojoComponent.RegularCredits;
clientComponent.MiscItems = dojoComponent.MiscItems; clientComponent.MiscItems = dojoComponent.MiscItems;
@ -84,6 +93,13 @@ export const getDojoClient = (
dojo.DojoComponents.push(clientComponent); dojo.DojoComponents.push(clientComponent);
} }
}); });
if (roomsToRemove.length) {
logger.debug(`removing now-destroyed rooms`, roomsToRemove);
for (const id of roomsToRemove) {
removeDojoRoom(guild, id);
}
await guild.save();
}
return dojo; return dojo;
}; };
@ -92,7 +108,7 @@ export const scaleRequiredCount = (count: number): number => {
return Math.max(1, Math.trunc(count / 100)); return Math.max(1, Math.trunc(count / 100));
}; };
export const removeDojoRoom = (guild: TGuildDatabaseDocument, componentId: string): void => { export const removeDojoRoom = (guild: TGuildDatabaseDocument, componentId: Types.ObjectId | string): void => {
const component = guild.DojoComponents.splice( const component = guild.DojoComponents.splice(
guild.DojoComponents.findIndex(x => x._id.equals(componentId)), guild.DojoComponents.findIndex(x => x._id.equals(componentId)),
1 1
@ -102,9 +118,14 @@ export const removeDojoRoom = (guild: TGuildDatabaseDocument, componentId: strin
guild.DojoCapacity -= meta.capacity; guild.DojoCapacity -= meta.capacity;
guild.DojoEnergy -= meta.energy; guild.DojoEnergy -= meta.energy;
} }
// TODO: Add resources spent to the clan vault
}; };
export const removeDojoDeco = (guild: TGuildDatabaseDocument, componentId: string, decoId: string): void => { export const removeDojoDeco = (
guild: TGuildDatabaseDocument,
componentId: Types.ObjectId | string,
decoId: string
): void => {
const component = guild.DojoComponents.id(componentId)!; const component = guild.DojoComponents.id(componentId)!;
const deco = component.Decos!.splice( const deco = component.Decos!.splice(
component.Decos!.findIndex(x => x._id.equals(decoId)), component.Decos!.findIndex(x => x._id.equals(decoId)),
@ -114,4 +135,5 @@ export const removeDojoDeco = (guild: TGuildDatabaseDocument, componentId: strin
if (meta && meta.capacityCost) { if (meta && meta.capacityCost) {
component.DecoCapacity! += meta.capacityCost; component.DecoCapacity! += meta.capacityCost;
} }
// TODO: Add resources spent to the clan vault
}; };