From c9f1c95c7a4e58934716e2bc1e9552382c8bb08d Mon Sep 17 00:00:00 2001 From: Sainan <63328889+Sainan@users.noreply.github.com> Date: Sun, 6 Apr 2025 23:24:51 +0200 Subject: [PATCH] feat: polychrome --- .../api/placeDecoInComponentController.ts | 7 +++- .../api/setDojoComponentColorsController.ts | 34 +++++++++++++++++++ src/models/guildModel.ts | 8 ++++- src/routes/api.ts | 2 ++ src/services/guildService.ts | 29 ++++++++++++++++ src/types/guildTypes.ts | 13 ++++++- 6 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 src/controllers/api/setDojoComponentColorsController.ts diff --git a/src/controllers/api/placeDecoInComponentController.ts b/src/controllers/api/placeDecoInComponentController.ts index ea40dae3..7dab5bbf 100644 --- a/src/controllers/api/placeDecoInComponentController.ts +++ b/src/controllers/api/placeDecoInComponentController.ts @@ -64,7 +64,12 @@ export const placeDecoInComponentController: RequestHandler = async (req, res) = } if (!meta || (meta.price == 0 && meta.ingredients.length == 0)) { deco.CompletionTime = new Date(); - } else if (guild.AutoContributeFromVault && guild.VaultRegularCredits && guild.VaultMiscItems) { + } else if ( + guild.AutoContributeFromVault && + guild.VaultRegularCredits && + guild.VaultMiscItems && + deco.Type != "/Lotus/Objects/Tenno/Props/TnoPaintBotDojoDeco" + ) { if (guild.VaultRegularCredits >= scaleRequiredCount(guild.Tier, meta.price)) { let enoughMiscItems = true; for (const ingredient of meta.ingredients) { diff --git a/src/controllers/api/setDojoComponentColorsController.ts b/src/controllers/api/setDojoComponentColorsController.ts new file mode 100644 index 00000000..ac069242 --- /dev/null +++ b/src/controllers/api/setDojoComponentColorsController.ts @@ -0,0 +1,34 @@ +import { getJSONfromString } from "@/src/helpers/stringHelpers"; +import { getDojoClient, getGuildForRequestEx, hasAccessToDojo, hasGuildPermission } from "@/src/services/guildService"; +import { getInventory } from "@/src/services/inventoryService"; +import { getAccountIdForRequest } from "@/src/services/loginService"; +import { GuildPermission } from "@/src/types/guildTypes"; +import { RequestHandler } from "express"; + +export const setDojoComponentColorsController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); + const inventory = await getInventory(accountId, "GuildId LevelKeys"); + const guild = await getGuildForRequestEx(req, inventory); + if (!hasAccessToDojo(inventory) || !(await hasGuildPermission(guild, accountId, GuildPermission.Decorator))) { + res.json({ DojoRequestStatus: -1 }); + return; + } + const data = getJSONfromString(String(req.body)); + const component = guild.DojoComponents.id(data.ComponentId)!; + //const deco = component.Decos!.find(x => x._id.equals(data.DecoId))!; + //deco.Pending = true; + //component.PaintBot = new Types.ObjectId(data.DecoId); + if ("lights" in req.query) { + component.PendingLights = data.Colours; + } else { + component.PendingColors = data.Colours; + } + await guild.save(); + res.json(await getDojoClient(guild, 0, component._id)); +}; + +interface ISetDojoComponentColorsRequest { + ComponentId: string; + DecoId: string; + Colours: number[]; +} diff --git a/src/models/guildModel.ts b/src/models/guildModel.ts index 563cb7d2..df2f860a 100644 --- a/src/models/guildModel.ts +++ b/src/models/guildModel.ts @@ -29,7 +29,8 @@ const dojoDecoSchema = new Schema({ MiscItems: { type: [typeCountSchema], default: undefined }, CompletionTime: Date, RushPlatinum: Number, - PictureFrameInfo: pictureFrameInfoSchema + PictureFrameInfo: pictureFrameInfoSchema, + Pending: Boolean }); const dojoLeaderboardEntrySchema = new Schema( @@ -57,6 +58,11 @@ const dojoComponentSchema = new Schema({ DestructionTime: Date, Decos: [dojoDecoSchema], DecoCapacity: Number, + PaintBot: Schema.Types.ObjectId, + PendingColors: { type: [Number], default: undefined }, + Colors: { type: [Number], default: undefined }, + PendingLights: { type: [Number], default: undefined }, + Lights: { type: [Number], default: undefined }, Leaderboard: { type: [dojoLeaderboardEntrySchema], default: undefined } }); diff --git a/src/routes/api.ts b/src/routes/api.ts index 81415dc6..7970c29d 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -105,6 +105,7 @@ import { setActiveQuestController } from "@/src/controllers/api/setActiveQuestCo import { setActiveShipController } from "@/src/controllers/api/setActiveShipController"; import { setAllianceGuildPermissionsController } from "@/src/controllers/api/setAllianceGuildPermissionsController"; import { setBootLocationController } from "@/src/controllers/api/setBootLocationController"; +import { setDojoComponentColorsController } from "@/src/controllers/api/setDojoComponentColorsController"; import { setDojoComponentMessageController } from "@/src/controllers/api/setDojoComponentMessageController"; import { setEquippedInstrumentController } from "@/src/controllers/api/setEquippedInstrumentController"; import { setGuildMotdController } from "@/src/controllers/api/setGuildMotdController"; @@ -261,6 +262,7 @@ apiRouter.post("/saveLoadout.php", saveLoadoutController); apiRouter.post("/saveSettings.php", saveSettingsController); apiRouter.post("/saveVaultAutoContribute.php", saveVaultAutoContributeController); apiRouter.post("/sell.php", sellController); +apiRouter.post("/setDojoComponentColors.php", setDojoComponentColorsController); apiRouter.post("/setDojoComponentMessage.php", setDojoComponentMessageController); apiRouter.post("/setEquippedInstrument.php", setEquippedInstrumentController); apiRouter.post("/setGuildMotd.php", setGuildMotdController); diff --git a/src/services/guildService.ts b/src/services/guildService.ts index 6388acef..32ff25a9 100644 --- a/src/services/guildService.ts +++ b/src/services/guildService.ts @@ -141,6 +141,7 @@ export const getDojoClient = async ( DojoComponents: [] }; const roomsToRemove: Types.ObjectId[] = []; + const decosToRemoveNoRefund: { componentId: Types.ObjectId; decoId: Types.ObjectId }[] = []; let needSave = false; for (const dojoComponent of guild.DojoComponents) { if (!componentId || dojoComponent._id.equals(componentId)) { @@ -212,6 +213,21 @@ export const getDojoClient = async ( PictureFrameInfo: deco.PictureFrameInfo }; if (deco.CompletionTime) { + if ( + deco.Type == "/Lotus/Objects/Tenno/Props/TnoPaintBotDojoDeco" && + Date.now() >= deco.CompletionTime.getTime() + ) { + if (dojoComponent.PendingColors) { + dojoComponent.Colors = dojoComponent.PendingColors; + dojoComponent.PendingColors = undefined; + } + if (dojoComponent.PendingLights) { + dojoComponent.Lights = dojoComponent.PendingLights; + dojoComponent.PendingLights = undefined; + } + decosToRemoveNoRefund.push({ componentId: dojoComponent._id, decoId: deco._id }); + continue; + } clientDeco.CompletionTime = toMongoDate(deco.CompletionTime); } else { clientDeco.RegularCredits = deco.RegularCredits; @@ -220,6 +236,10 @@ export const getDojoClient = async ( clientComponent.Decos.push(clientDeco); } } + clientComponent.PendingColors = dojoComponent.PendingColors; + clientComponent.Colors = dojoComponent.Colors; + clientComponent.PendingLights = dojoComponent.PendingLights; + clientComponent.Lights = dojoComponent.Lights; dojo.DojoComponents.push(clientComponent); } } @@ -230,6 +250,15 @@ export const getDojoClient = async ( } needSave = true; } + for (const deco of decosToRemoveNoRefund) { + logger.debug(`removing polychrome`, deco); + const component = guild.DojoComponents.id(deco.componentId)!; + component.Decos!.splice( + component.Decos!.findIndex(x => x._id.equals(deco.decoId)), + 1 + ); + needSave = true; + } if (needSave) { await guild.save(); } diff --git a/src/types/guildTypes.ts b/src/types/guildTypes.ts index 8af68809..7746f2bb 100644 --- a/src/types/guildTypes.ts +++ b/src/types/guildTypes.ts @@ -161,6 +161,7 @@ export interface IDojoClient { export interface IDojoComponentClient { id: IOid; + SortId?: IOid; pf: string; // Prefab (.level) ppf: string; pi?: IOid; // Parent ID. N/A to root. @@ -175,16 +176,25 @@ export interface IDojoComponentClient { DestructionTime?: IMongoDate; Decos?: IDojoDecoClient[]; DecoCapacity?: number; + PaintBot?: IOid; + PendingColors?: number[]; + Colors?: number[]; + PendingLights?: number[]; + Lights?: number[]; } export interface IDojoComponentDatabase - extends Omit { + extends Omit< + IDojoComponentClient, + "id" | "SortId" | "pi" | "CompletionTime" | "DestructionTime" | "Decos" | "PaintBot" + > { _id: Types.ObjectId; pi?: Types.ObjectId; CompletionTime?: Date; CompletionLogPending?: boolean; DestructionTime?: Date; Decos?: IDojoDecoDatabase[]; + PaintBot?: Types.ObjectId; Leaderboard?: IDojoLeaderboardEntry[]; } @@ -200,6 +210,7 @@ export interface IDojoDecoClient { CompletionTime?: IMongoDate; RushPlatinum?: number; PictureFrameInfo?: IPictureFrameInfo; + Pending?: boolean; } export interface IDojoDecoDatabase extends Omit {