diff --git a/src/controllers/api/getGuildDojoController.ts b/src/controllers/api/getGuildDojoController.ts index e16040aa..9d7ed93f 100644 --- a/src/controllers/api/getGuildDojoController.ts +++ b/src/controllers/api/getGuildDojoController.ts @@ -1,8 +1,7 @@ import { RequestHandler } from "express"; import { Types } from "mongoose"; import { Guild } from "@/src/models/guildModel"; -import { IDojoClient, IDojoComponentClient } from "@/src/types/guildTypes"; -import { toOid, toMongoDate } from "@/src/helpers/inventoryHelpers"; +import { getDojoClient } from "@/src/services/guildService"; export const getGuildDojoController: RequestHandler = async (req, res) => { const guildId = req.query.guildId as string; @@ -26,34 +25,5 @@ export const getGuildDojoController: RequestHandler = async (req, res) => { await guild.save(); } - const dojo: IDojoClient = { - _id: { $oid: guildId }, - Name: guild.Name, - Tier: 1, - FixedContributions: true, - DojoRevision: 1, - RevisionTime: Math.round(Date.now() / 1000), - Energy: guild.DojoEnergy, - Capacity: guild.DojoCapacity, - DojoRequestStatus: 0, - DojoComponents: [] - }; - guild.DojoComponents.forEach(dojoComponent => { - const clientComponent: IDojoComponentClient = { - id: toOid(dojoComponent._id), - pf: dojoComponent.pf, - ppf: dojoComponent.ppf, - DecoCapacity: 600 - }; - if (dojoComponent.pi) { - clientComponent.pi = toOid(dojoComponent.pi); - clientComponent.op = dojoComponent.op!; - clientComponent.pp = dojoComponent.pp!; - } - if (dojoComponent.CompletionTime) { - clientComponent.CompletionTime = toMongoDate(dojoComponent.CompletionTime); - } - dojo.DojoComponents.push(clientComponent); - }); - res.json(dojo); + res.json(getDojoClient(guild, 0)); }; diff --git a/src/controllers/api/queueDojoComponentDestructionController.ts b/src/controllers/api/queueDojoComponentDestructionController.ts index da84c40f..7f612896 100644 --- a/src/controllers/api/queueDojoComponentDestructionController.ts +++ b/src/controllers/api/queueDojoComponentDestructionController.ts @@ -1,4 +1,4 @@ -import { getGuildForRequest } from "@/src/services/guildService"; +import { getDojoClient, getGuildForRequest } from "@/src/services/guildService"; import { RequestHandler } from "express"; import { ExportDojoRecipes } from "warframe-public-export-plus"; @@ -15,7 +15,5 @@ export const queueDojoComponentDestructionController: RequestHandler = async (re guild.DojoEnergy -= room.energy; } await guild.save(); - res.json({ - DojoRequestStatus: 1 - }); + res.json(getDojoClient(guild, 1)); }; diff --git a/src/controllers/api/setDojoComponentMessageController.ts b/src/controllers/api/setDojoComponentMessageController.ts new file mode 100644 index 00000000..714dd7a5 --- /dev/null +++ b/src/controllers/api/setDojoComponentMessageController.ts @@ -0,0 +1,18 @@ +import { RequestHandler } from "express"; +import { getDojoClient, getGuildForRequest } from "@/src/services/guildService"; + +export const setDojoComponentMessageController: RequestHandler = async (req, res) => { + const guild = await getGuildForRequest(req); + // At this point, we know that a member of the guild is making this request. Assuming they are allowed to change the message. + const component = guild.DojoComponents!.find(x => x._id.equals(req.query.componentId as string))!; + const payload = JSON.parse(String(req.body)) as SetDojoComponentMessageRequest; + if ("Name" in payload) { + component.Name = payload.Name; + } else { + component.Message = payload.Message; + } + await guild.save(); + res.json(getDojoClient(guild, 1)); +}; + +type SetDojoComponentMessageRequest = { Name: string } | { Message: string }; diff --git a/src/controllers/api/startDojoRecipeController.ts b/src/controllers/api/startDojoRecipeController.ts index 625912d5..6fd2b5a9 100644 --- a/src/controllers/api/startDojoRecipeController.ts +++ b/src/controllers/api/startDojoRecipeController.ts @@ -1,6 +1,6 @@ import { RequestHandler } from "express"; import { IDojoComponentClient } from "@/src/types/guildTypes"; -import { getGuildForRequest } from "@/src/services/guildService"; +import { getDojoClient, getGuildForRequest } from "@/src/services/guildService"; import { Types } from "mongoose"; import { ExportDojoRecipes } from "warframe-public-export-plus"; @@ -30,7 +30,5 @@ export const startDojoRecipeController: RequestHandler = async (req, res) => { CompletionTime: new Date(Date.now()) // TOOD: Omit this field & handle the "Collecting Materials" state. }); await guild.save(); - res.json({ - DojoRequestStatus: 0 - }); + res.json(getDojoClient(guild, 0)); }; diff --git a/src/models/guildModel.ts b/src/models/guildModel.ts index ab87e719..0582dc64 100644 --- a/src/models/guildModel.ts +++ b/src/models/guildModel.ts @@ -14,6 +14,8 @@ const dojoComponentSchema = new Schema({ pi: Schema.Types.ObjectId, op: String, pp: String, + Name: String, + Message: String, CompletionTime: Date }); diff --git a/src/routes/api.ts b/src/routes/api.ts index 4d2571c0..a0eeba20 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -62,6 +62,7 @@ import { sellController } from "@/src/controllers/api/sellController"; import { setActiveQuestController } from "@/src/controllers/api/setActiveQuestController"; import { setActiveShipController } from "@/src/controllers/api/setActiveShipController"; import { setBootLocationController } from "@/src/controllers/api/setBootLocationController"; +import { setDojoComponentMessageController } from "@/src/controllers/api/setDojoComponentMessageController"; import { setEquippedInstrumentController } from "@/src/controllers/api/setEquippedInstrumentController"; import { setPlacedDecoInfoController } from "@/src/controllers/api/setPlacedDecoInfoController"; import { setShipCustomizationsController } from "@/src/controllers/api/setShipCustomizationsController"; @@ -158,6 +159,7 @@ apiRouter.post("/rerollRandomMod.php", rerollRandomModController); apiRouter.post("/saveDialogue.php", saveDialogueController); apiRouter.post("/saveLoadout.php", saveLoadoutController); apiRouter.post("/sell.php", sellController); +apiRouter.post("/setDojoComponentMessage.php", setDojoComponentMessageController); apiRouter.post("/setEquippedInstrument.php", setEquippedInstrumentController); apiRouter.post("/setPlacedDecoInfo.php", setPlacedDecoInfoController); apiRouter.post("/setShipCustomizations.php", setShipCustomizationsController); diff --git a/src/services/guildService.ts b/src/services/guildService.ts index 1fcddad4..210bc1a6 100644 --- a/src/services/guildService.ts +++ b/src/services/guildService.ts @@ -3,14 +3,20 @@ import { getAccountIdForRequest } from "@/src/services/loginService"; import { getInventory } from "@/src/services/inventoryService"; import { Guild } from "@/src/models/guildModel"; import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; +import { IDojoClient, IDojoComponentClient, IGuildDatabase } from "@/src/types/guildTypes"; +import { Document, Types } from "mongoose"; +import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers"; -export const getGuildForRequest = async (req: Request) => { +export const getGuildForRequest = async (req: Request): Promise => { const accountId = await getAccountIdForRequest(req); const inventory = await getInventory(accountId); return await getGuildForRequestEx(req, inventory); }; -export const getGuildForRequestEx = async (req: Request, inventory: TInventoryDatabaseDocument) => { +export const getGuildForRequestEx = async ( + req: Request, + inventory: TInventoryDatabaseDocument +): Promise => { const guildId = req.query.guildId as string; if (!inventory.GuildId || inventory.GuildId.toString() != guildId) { throw new Error("Account is not in the guild that it has sent a request for"); @@ -21,3 +27,47 @@ export const getGuildForRequestEx = async (req: Request, inventory: TInventoryDa } return guild; }; + +export const getDojoClient = (guild: TGuildDatabaseDocument, status: number): IDojoClient => { + const dojo: IDojoClient = { + _id: { $oid: guild._id.toString() }, + Name: guild.Name, + Tier: 1, + FixedContributions: true, + DojoRevision: 1, + RevisionTime: Math.round(Date.now() / 1000), + Energy: guild.DojoEnergy, + Capacity: guild.DojoCapacity, + DojoRequestStatus: status, + DojoComponents: [] + }; + guild.DojoComponents!.forEach(dojoComponent => { + const clientComponent: IDojoComponentClient = { + id: toOid(dojoComponent._id), + pf: dojoComponent.pf, + ppf: dojoComponent.ppf, + Name: dojoComponent.Name, + Message: dojoComponent.Message, + DecoCapacity: 600 + }; + if (dojoComponent.pi) { + clientComponent.pi = toOid(dojoComponent.pi); + clientComponent.op = dojoComponent.op!; + clientComponent.pp = dojoComponent.pp!; + } + if (dojoComponent.CompletionTime) { + clientComponent.CompletionTime = toMongoDate(dojoComponent.CompletionTime); + } + dojo.DojoComponents.push(clientComponent); + }); + return dojo; +}; + +// eslint-disable-next-line @typescript-eslint/ban-types +export type TGuildDatabaseDocument = Document & + IGuildDatabase & + Required<{ + _id: Types.ObjectId; + }> & { + __v: number; + }; diff --git a/src/types/guildTypes.ts b/src/types/guildTypes.ts index 1778582f..827e5d9a 100644 --- a/src/types/guildTypes.ts +++ b/src/types/guildTypes.ts @@ -34,6 +34,8 @@ export interface IDojoComponentClient { pi?: IOid; // Parent ID. N/A to root. op?: string; // "Open Portal"? N/A to root. pp?: string; // "Parent Portal"? N/A to root. + Name?: string; + Message?: string; RegularCredits?: number; // "Collecting Materials" state: Number of credits that were donated. MiscItems?: IMiscItem[]; // "Collecting Materials" state: Resources that were donated. CompletionTime?: IMongoDate;