From baf06bbda247def3f0a1050714183016afd7d0b2 Mon Sep 17 00:00:00 2001 From: Sainan <63328889+Sainan@users.noreply.github.com> Date: Thu, 3 Apr 2025 16:40:57 +0200 Subject: [PATCH 1/5] instantly finish dojo decos without metadata --- src/controllers/api/placeDecoInComponentController.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/controllers/api/placeDecoInComponentController.ts b/src/controllers/api/placeDecoInComponentController.ts index 08f814da..393dfbbd 100644 --- a/src/controllers/api/placeDecoInComponentController.ts +++ b/src/controllers/api/placeDecoInComponentController.ts @@ -40,9 +40,9 @@ export const placeDecoInComponentController: RequestHandler = async (req, res) = if (meta.capacityCost) { component.DecoCapacity -= meta.capacityCost; } - if (meta.price == 0 && meta.ingredients.length == 0) { - deco.CompletionTime = new Date(); - } + } + if (!meta || (meta.price == 0 && meta.ingredients.length == 0)) { + deco.CompletionTime = new Date(); } await guild.save(); -- 2.47.2 From 2a09f6a1d1c906e3e3453a27a72ecad12249053d Mon Sep 17 00:00:00 2001 From: Sainan <63328889+Sainan@users.noreply.github.com> Date: Thu, 3 Apr 2025 16:33:04 +0200 Subject: [PATCH 2/5] handle dojo decos in setPlacedDecoInfo --- src/models/guildModel.ts | 4 +++- src/models/personalRoomsModel.ts | 2 +- src/services/guildService.ts | 3 ++- src/services/shipCustomizationsService.ts | 14 ++++++++++++++ src/types/guildTypes.ts | 2 ++ src/types/shipTypes.ts | 4 +++- 6 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/models/guildModel.ts b/src/models/guildModel.ts index 70f94256..b2453aab 100644 --- a/src/models/guildModel.ts +++ b/src/models/guildModel.ts @@ -17,6 +17,7 @@ import { } from "@/src/types/guildTypes"; import { Document, Model, model, Schema, Types } from "mongoose"; import { fusionTreasuresSchema, typeCountSchema } from "./inventoryModels/inventoryModel"; +import { pictureFrameInfoSchema } from "./personalRoomsModel"; const dojoDecoSchema = new Schema({ Type: String, @@ -26,7 +27,8 @@ const dojoDecoSchema = new Schema({ RegularCredits: Number, MiscItems: { type: [typeCountSchema], default: undefined }, CompletionTime: Date, - RushPlatinum: Number + RushPlatinum: Number, + PictureFrameInfo: pictureFrameInfoSchema }); const dojoLeaderboardEntrySchema = new Schema( diff --git a/src/models/personalRoomsModel.ts b/src/models/personalRoomsModel.ts index b8049d6f..1c6a7c6d 100644 --- a/src/models/personalRoomsModel.ts +++ b/src/models/personalRoomsModel.ts @@ -12,7 +12,7 @@ import { } from "@/src/types/shipTypes"; import { Schema, model } from "mongoose"; -const pictureFrameInfoSchema = new Schema( +export const pictureFrameInfoSchema = new Schema( { Image: String, Filter: String, diff --git a/src/services/guildService.ts b/src/services/guildService.ts index b622987e..54c5b5bf 100644 --- a/src/services/guildService.ts +++ b/src/services/guildService.ts @@ -202,7 +202,8 @@ export const getDojoClient = async ( Type: deco.Type, Pos: deco.Pos, Rot: deco.Rot, - Name: deco.Name + Name: deco.Name, + PictureFrameInfo: deco.PictureFrameInfo }; if (deco.CompletionTime) { clientDeco.CompletionTime = toMongoDate(deco.CompletionTime); diff --git a/src/services/shipCustomizationsService.ts b/src/services/shipCustomizationsService.ts index 20c3d4ca..47764917 100644 --- a/src/services/shipCustomizationsService.ts +++ b/src/services/shipCustomizationsService.ts @@ -10,6 +10,9 @@ import { logger } from "@/src/utils/logger"; import { Types } from "mongoose"; import { addShipDecorations, getInventory } from "./inventoryService"; import { config } from "./configService"; +import { Guild } from "../models/guildModel"; +import { hasGuildPermission } from "./guildService"; +import { GuildPermission } from "../types/guildTypes"; export const setShipCustomizations = async ( accountId: string, @@ -154,6 +157,17 @@ export const handleSetShipDecorations = async ( }; export const handleSetPlacedDecoInfo = async (accountId: string, req: ISetPlacedDecoInfoRequest): Promise => { + if (req.GuildId && req.ComponentId) { + const guild = (await Guild.findById(req.GuildId))!; + if (await hasGuildPermission(guild, accountId, GuildPermission.Decorator)) { + const component = guild.DojoComponents.id(req.ComponentId)!; + const deco = component.Decos!.find(x => x._id.equals(req.DecoId))!; + deco.PictureFrameInfo = req.PictureFrameInfo; + await guild.save(); + } + return; + } + const personalRooms = await getPersonalRooms(accountId); const room = personalRooms.Ship.Rooms.find(room => room.Name === req.Room); diff --git a/src/types/guildTypes.ts b/src/types/guildTypes.ts index 9361df80..6438956e 100644 --- a/src/types/guildTypes.ts +++ b/src/types/guildTypes.ts @@ -1,6 +1,7 @@ import { Types } from "mongoose"; import { IOid, IMongoDate } from "@/src/types/commonTypes"; import { IFusionTreasure, IMiscItem, ITypeCount } from "@/src/types/inventoryTypes/inventoryTypes"; +import { IPictureFrameInfo } from "./shipTypes"; export interface IGuildClient { _id: IOid; @@ -194,6 +195,7 @@ export interface IDojoDecoClient { MiscItems?: IMiscItem[]; CompletionTime?: IMongoDate; RushPlatinum?: number; + PictureFrameInfo?: IPictureFrameInfo; } export interface IDojoDecoDatabase extends Omit { diff --git a/src/types/shipTypes.ts b/src/types/shipTypes.ts index 936a5cc6..23c46c48 100644 --- a/src/types/shipTypes.ts +++ b/src/types/shipTypes.ts @@ -127,7 +127,9 @@ export interface ISetPlacedDecoInfoRequest { DecoId: string; Room: string; PictureFrameInfo: IPictureFrameInfo; - BootLocation: string; + BootLocation?: string; + ComponentId?: string; + GuildId?: string; } export interface IPictureFrameInfo { -- 2.47.2 From 9b8c4beb8f9ae3b0e8750aaf71402c592ed478dc Mon Sep 17 00:00:00 2001 From: Sainan <63328889+Sainan@users.noreply.github.com> Date: Thu, 3 Apr 2025 18:35:26 +0200 Subject: [PATCH 3/5] save sockets for placed ayatan treasures --- src/controllers/api/placeDecoInComponentController.ts | 4 +++- src/models/guildModel.ts | 1 + src/services/guildService.ts | 1 + src/types/guildTypes.ts | 1 + 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/controllers/api/placeDecoInComponentController.ts b/src/controllers/api/placeDecoInComponentController.ts index 393dfbbd..ac791b22 100644 --- a/src/controllers/api/placeDecoInComponentController.ts +++ b/src/controllers/api/placeDecoInComponentController.ts @@ -31,7 +31,8 @@ export const placeDecoInComponentController: RequestHandler = async (req, res) = Type: request.Type, Pos: request.Pos, Rot: request.Rot, - Name: request.Name + Name: request.Name, + Sockets: request.Sockets }) - 1 ]; @@ -56,4 +57,5 @@ interface IPlaceDecoInComponentRequest { Pos: number[]; Rot: number[]; Name?: string; + Sockets?: number; } diff --git a/src/models/guildModel.ts b/src/models/guildModel.ts index b2453aab..2ccaef1a 100644 --- a/src/models/guildModel.ts +++ b/src/models/guildModel.ts @@ -24,6 +24,7 @@ const dojoDecoSchema = new Schema({ Pos: [Number], Rot: [Number], Name: String, + Sockets: Number, RegularCredits: Number, MiscItems: { type: [typeCountSchema], default: undefined }, CompletionTime: Date, diff --git a/src/services/guildService.ts b/src/services/guildService.ts index 54c5b5bf..5a982afe 100644 --- a/src/services/guildService.ts +++ b/src/services/guildService.ts @@ -203,6 +203,7 @@ export const getDojoClient = async ( Pos: deco.Pos, Rot: deco.Rot, Name: deco.Name, + Sockets: deco.Sockets, PictureFrameInfo: deco.PictureFrameInfo }; if (deco.CompletionTime) { diff --git a/src/types/guildTypes.ts b/src/types/guildTypes.ts index 6438956e..b65b7a28 100644 --- a/src/types/guildTypes.ts +++ b/src/types/guildTypes.ts @@ -191,6 +191,7 @@ export interface IDojoDecoClient { Pos: number[]; Rot: number[]; Name?: string; // for teleporters + Sockets?: number; RegularCredits?: number; MiscItems?: IMiscItem[]; CompletionTime?: IMongoDate; -- 2.47.2 From 5e6d958358276187dbd74cc13125eb657aa25197 Mon Sep 17 00:00:00 2001 From: Sainan <63328889+Sainan@users.noreply.github.com> Date: Thu, 3 Apr 2025 18:42:33 +0200 Subject: [PATCH 4/5] handle dojo deco being moved --- .../api/placeDecoInComponentController.ts | 45 +++++++++++-------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/src/controllers/api/placeDecoInComponentController.ts b/src/controllers/api/placeDecoInComponentController.ts index ac791b22..5a3eb68c 100644 --- a/src/controllers/api/placeDecoInComponentController.ts +++ b/src/controllers/api/placeDecoInComponentController.ts @@ -24,26 +24,31 @@ export const placeDecoInComponentController: RequestHandler = async (req, res) = } component.Decos ??= []; - const deco = - component.Decos[ - component.Decos.push({ - _id: new Types.ObjectId(), - Type: request.Type, - Pos: request.Pos, - Rot: request.Rot, - Name: request.Name, - Sockets: request.Sockets - }) - 1 - ]; - - const meta = Object.values(ExportDojoRecipes.decos).find(x => x.resultType == request.Type); - if (meta) { - if (meta.capacityCost) { - component.DecoCapacity -= meta.capacityCost; + if (request.MoveId) { + const deco = component.Decos.find(x => x._id.equals(request.MoveId))!; + deco.Pos = request.Pos; + deco.Rot = request.Rot; + } else { + const deco = + component.Decos[ + component.Decos.push({ + _id: new Types.ObjectId(), + Type: request.Type, + Pos: request.Pos, + Rot: request.Rot, + Name: request.Name, + Sockets: request.Sockets + }) - 1 + ]; + const meta = Object.values(ExportDojoRecipes.decos).find(x => x.resultType == request.Type); + if (meta) { + if (meta.capacityCost) { + component.DecoCapacity -= meta.capacityCost; + } + } + if (!meta || (meta.price == 0 && meta.ingredients.length == 0)) { + deco.CompletionTime = new Date(); } - } - if (!meta || (meta.price == 0 && meta.ingredients.length == 0)) { - deco.CompletionTime = new Date(); } await guild.save(); @@ -58,4 +63,6 @@ interface IPlaceDecoInComponentRequest { Rot: number[]; Name?: string; Sockets?: number; + Scale?: number; // only provided alongside MoveId and seems to always be 1 + MoveId?: string; } -- 2.47.2 From 0588d6e5c6995265cf1d7bf3d4ad10eebc0ad606 Mon Sep 17 00:00:00 2001 From: Sainan <63328889+Sainan@users.noreply.github.com> Date: Thu, 3 Apr 2025 19:33:47 +0200 Subject: [PATCH 5/5] remove placed decos from vault & re-add on removal --- package-lock.json | 8 +- package.json | 2 +- .../api/contributeToVaultController.ts | 14 ++-- .../api/placeDecoInComponentController.ts | 12 ++- src/services/guildService.ts | 74 ++++++++++++++++--- 5 files changed, 87 insertions(+), 23 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0be5183e..890754cc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "morgan": "^1.10.0", "ncp": "^2.0.0", "typescript": ">=5.5 <5.6.0", - "warframe-public-export-plus": "^0.5.49", + "warframe-public-export-plus": "^0.5.50", "warframe-riven-info": "^0.1.2", "winston": "^3.17.0", "winston-daily-rotate-file": "^5.0.0" @@ -3789,9 +3789,9 @@ } }, "node_modules/warframe-public-export-plus": { - "version": "0.5.49", - "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.49.tgz", - "integrity": "sha512-11HA8qEMhFfl12W2qIjjk7fhas+/5G2yXbrOEb8FRZby6tWka0CyUnB6tLT+PCqBEIoU+kwhz0g7CLh3Zmy7Pw==" + "version": "0.5.50", + "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.50.tgz", + "integrity": "sha512-KlhdY/Q5sRAIn/RhmdviKBoX3gk+Jtuen0cWnFB2zqK7eKYMDtd79bKOtTPtnK9zCNzh6gFug2wEeDVam3Bwlw==" }, "node_modules/warframe-riven-info": { "version": "0.1.2", diff --git a/package.json b/package.json index e0eb4c8f..36bf7738 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "morgan": "^1.10.0", "ncp": "^2.0.0", "typescript": ">=5.5 <5.6.0", - "warframe-public-export-plus": "^0.5.49", + "warframe-public-export-plus": "^0.5.50", "warframe-riven-info": "^0.1.2", "winston": "^3.17.0", "winston-daily-rotate-file": "^5.0.0" diff --git a/src/controllers/api/contributeToVaultController.ts b/src/controllers/api/contributeToVaultController.ts index fc03e2ca..507d1aa7 100644 --- a/src/controllers/api/contributeToVaultController.ts +++ b/src/controllers/api/contributeToVaultController.ts @@ -1,7 +1,10 @@ import { Alliance, GuildMember } from "@/src/models/guildModel"; import { addGuildMemberMiscItemContribution, + addGuildMemberShipDecoContribution, + addVaultFusionTreasures, addVaultMiscItems, + addVaultShipDecos, getGuildForRequestEx } from "@/src/services/guildService"; import { @@ -51,26 +54,21 @@ export const contributeToVaultController: RequestHandler = async (req, res) => { } if (request.MiscItems.length) { addVaultMiscItems(guild, request.MiscItems); - for (const item of request.MiscItems) { addGuildMemberMiscItemContribution(guildMember, item); - addMiscItems(inventory, [{ ...item, ItemCount: item.ItemCount * -1 }]); } } if (request.ShipDecorations.length) { - guild.VaultShipDecorations ??= []; - guildMember.ShipDecorationsContributed ??= []; + addVaultShipDecos(guild, request.ShipDecorations); for (const item of request.ShipDecorations) { - guild.VaultShipDecorations.push(item); - guildMember.ShipDecorationsContributed.push(item); + addGuildMemberShipDecoContribution(guildMember, item); addShipDecorations(inventory, [{ ...item, ItemCount: item.ItemCount * -1 }]); } } if (request.FusionTreasures.length) { - guild.VaultFusionTreasures ??= []; + addVaultFusionTreasures(guild, request.FusionTreasures); for (const item of request.FusionTreasures) { - guild.VaultFusionTreasures.push(item); addFusionTreasures(inventory, [{ ...item, ItemCount: item.ItemCount * -1 }]); } } diff --git a/src/controllers/api/placeDecoInComponentController.ts b/src/controllers/api/placeDecoInComponentController.ts index 5a3eb68c..b50a9c5b 100644 --- a/src/controllers/api/placeDecoInComponentController.ts +++ b/src/controllers/api/placeDecoInComponentController.ts @@ -4,7 +4,7 @@ import { getAccountIdForRequest } from "@/src/services/loginService"; import { GuildPermission } from "@/src/types/guildTypes"; import { RequestHandler } from "express"; import { Types } from "mongoose"; -import { ExportDojoRecipes } from "warframe-public-export-plus"; +import { ExportDojoRecipes, ExportResources } from "warframe-public-export-plus"; export const placeDecoInComponentController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); @@ -45,6 +45,14 @@ export const placeDecoInComponentController: RequestHandler = async (req, res) = if (meta.capacityCost) { component.DecoCapacity -= meta.capacityCost; } + } else { + const itemType = Object.entries(ExportResources).find(arr => arr[1].deco == deco.Type)![0]; + if (deco.Sockets !== undefined) { + guild.VaultFusionTreasures!.find(x => x.ItemType == itemType && x.Sockets == deco.Sockets)!.ItemCount -= + 1; + } else { + guild.VaultShipDecorations!.find(x => x.ItemType == itemType)!.ItemCount -= 1; + } } if (!meta || (meta.price == 0 && meta.ingredients.length == 0)) { deco.CompletionTime = new Date(); @@ -65,4 +73,6 @@ interface IPlaceDecoInComponentRequest { Sockets?: number; Scale?: number; // only provided alongside MoveId and seems to always be 1 MoveId?: string; + ShipDeco?: boolean; + VaultDeco?: boolean; } diff --git a/src/services/guildService.ts b/src/services/guildService.ts index 5a982afe..e415d873 100644 --- a/src/services/guildService.ts +++ b/src/services/guildService.ts @@ -21,13 +21,13 @@ import { } from "@/src/types/guildTypes"; import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers"; import { Types } from "mongoose"; -import { ExportDojoRecipes, IDojoBuild, IDojoResearch } from "warframe-public-export-plus"; +import { ExportDojoRecipes, ExportResources, IDojoBuild, IDojoResearch } from "warframe-public-export-plus"; import { logger } from "../utils/logger"; import { config } from "./configService"; import { Account } from "../models/loginModel"; import { getRandomInt } from "./rngService"; import { Inbox } from "../models/inboxModel"; -import { ITypeCount } from "../types/inventoryTypes/inventoryTypes"; +import { IFusionTreasure, ITypeCount } from "../types/inventoryTypes/inventoryTypes"; import { IInventoryChanges } from "../types/purchaseTypes"; export const getGuildForRequest = async (req: Request): Promise => { @@ -287,8 +287,28 @@ export const removeDojoDeco = ( 1 )[0]; const meta = Object.values(ExportDojoRecipes.decos).find(x => x.resultType == deco.Type); - if (meta && meta.capacityCost) { - component.DecoCapacity! += meta.capacityCost; + if (meta) { + if (meta.capacityCost) { + component.DecoCapacity! += meta.capacityCost; + } + } else { + const itemType = Object.entries(ExportResources).find(arr => arr[1].deco == deco.Type)![0]; + if (deco.Sockets !== undefined) { + addVaultFusionTreasures(guild, [ + { + ItemType: itemType, + ItemCount: 1, + Sockets: deco.Sockets + } + ]); + } else { + addVaultShipDecos(guild, [ + { + ItemType: itemType, + ItemCount: 1 + } + ]); + } } moveResourcesToVault(guild, deco); }; @@ -313,12 +333,38 @@ export const getVaultMiscItemCount = (guild: TGuildDatabaseDocument, itemType: s export const addVaultMiscItems = (guild: TGuildDatabaseDocument, miscItems: ITypeCount[]): void => { guild.VaultMiscItems ??= []; - for (const miscItem of miscItems) { - const vaultMiscItem = guild.VaultMiscItems.find(x => x.ItemType == miscItem.ItemType); - if (vaultMiscItem) { - vaultMiscItem.ItemCount += miscItem.ItemCount; + for (const item of miscItems) { + const vaultItem = guild.VaultMiscItems.find(x => x.ItemType == item.ItemType); + if (vaultItem) { + vaultItem.ItemCount += item.ItemCount; } else { - guild.VaultMiscItems.push(miscItem); + guild.VaultMiscItems.push(item); + } + } +}; + +export const addVaultShipDecos = (guild: TGuildDatabaseDocument, shipDecos: ITypeCount[]): void => { + guild.VaultShipDecorations ??= []; + for (const item of shipDecos) { + const vaultItem = guild.VaultShipDecorations.find(x => x.ItemType == item.ItemType); + if (vaultItem) { + vaultItem.ItemCount += item.ItemCount; + } else { + guild.VaultShipDecorations.push(item); + } + } +}; + +export const addVaultFusionTreasures = (guild: TGuildDatabaseDocument, fusionTreasures: IFusionTreasure[]): void => { + guild.VaultFusionTreasures ??= []; + for (const item of fusionTreasures) { + const vaultItem = guild.VaultFusionTreasures.find( + x => x.ItemType == item.ItemType && x.Sockets == item.Sockets + ); + if (vaultItem) { + vaultItem.ItemCount += item.ItemCount; + } else { + guild.VaultFusionTreasures.push(item); } } }; @@ -333,6 +379,16 @@ export const addGuildMemberMiscItemContribution = (guildMember: IGuildMemberData } }; +export const addGuildMemberShipDecoContribution = (guildMember: IGuildMemberDatabase, item: ITypeCount): void => { + guildMember.ShipDecorationsContributed ??= []; + const shipDecoContribution = guildMember.ShipDecorationsContributed.find(x => x.ItemType == item.ItemType); + if (shipDecoContribution) { + shipDecoContribution.ItemCount += item.ItemCount; + } else { + guildMember.ShipDecorationsContributed.push(item); + } +}; + export const processDojoBuildMaterialsGathered = (guild: TGuildDatabaseDocument, build: IDojoBuild): void => { if (build.guildXpValue) { guild.ClaimedXP ??= []; -- 2.47.2