feat: track RoomChanges in clan log #1174
| @ -4,7 +4,8 @@ import { | ||||
|     getDojoClient, | ||||
|     getGuildForRequestEx, | ||||
|     processDojoBuildMaterialsGathered, | ||||
|     scaleRequiredCount | ||||
|     scaleRequiredCount, | ||||
|     setDojoRoomLogFunded | ||||
| } from "@/src/services/guildService"; | ||||
| import { addMiscItems, getInventory, updateCurrency } from "@/src/services/inventoryService"; | ||||
| import { getAccountIdForRequest } from "@/src/services/loginService"; | ||||
| @ -40,6 +41,10 @@ export const contributeToDojoComponentController: RequestHandler = async (req, r | ||||
|         } | ||||
|         const meta = Object.values(ExportDojoRecipes.rooms).find(x => x.resultType == component.pf)!; | ||||
|         processContribution(guild, request, inventory, inventoryChanges, meta, component); | ||||
|         // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
 | ||||
|         if (component.CompletionTime) { | ||||
|             setDojoRoomLogFunded(guild, component); | ||||
|         } | ||||
|     } else { | ||||
|         // Room is past "Collecting Materials"
 | ||||
|         if (request.DecoId) { | ||||
|  | ||||
| @ -35,6 +35,11 @@ export const dojoComponentRushController: RequestHandler = async (req, res) => { | ||||
|     } else { | ||||
|         const meta = Object.values(ExportDojoRecipes.rooms).find(x => x.resultType == component.pf)!; | ||||
|         processContribution(component, meta, platinumDonated); | ||||
| 
 | ||||
|         const entry = guild.RoomChanges?.find(x => x.componentId.equals(component._id)); | ||||
|         if (entry) { | ||||
|             entry.dateTime = component.CompletionTime!; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     await guild.save(); | ||||
|  | ||||
| @ -18,6 +18,13 @@ export const getGuildLogController: RequestHandler = async (req, res) => { | ||||
|                 StandingsUpdates: [], | ||||
|                 ClassChanges: [] | ||||
|             }; | ||||
|             guild.RoomChanges?.forEach(entry => { | ||||
|                 log.RoomChanges.push({ | ||||
|                     dateTime: toMongoDate(entry.dateTime), | ||||
|                     entryType: entry.entryType, | ||||
|                     details: entry.details | ||||
|                 }); | ||||
|             }); | ||||
|             guild.TechChanges?.forEach(entry => { | ||||
|                 log.TechChanges.push({ | ||||
|                     dateTime: toMongoDate(entry.dateTime), | ||||
|  | ||||
| @ -1,6 +1,11 @@ | ||||
| import { RequestHandler } from "express"; | ||||
| import { IDojoComponentClient } from "@/src/types/guildTypes"; | ||||
| import { getDojoClient, getGuildForRequest, processDojoBuildMaterialsGathered } from "@/src/services/guildService"; | ||||
| import { | ||||
|     getDojoClient, | ||||
|     getGuildForRequest, | ||||
|     processDojoBuildMaterialsGathered, | ||||
|     setDojoRoomLogFunded | ||||
| } from "@/src/services/guildService"; | ||||
| import { Types } from "mongoose"; | ||||
| import { ExportDojoRecipes } from "warframe-public-export-plus"; | ||||
| import { config } from "@/src/services/configService"; | ||||
| @ -21,10 +26,20 @@ export const startDojoRecipeController: RequestHandler = async (req, res) => { | ||||
|         guild.DojoEnergy += room.energy; | ||||
|     } | ||||
| 
 | ||||
|     const componentId = new Types.ObjectId(); | ||||
| 
 | ||||
|     guild.RoomChanges ??= []; | ||||
|     guild.RoomChanges.push({ | ||||
|         dateTime: new Date(), | ||||
|         entryType: 2, | ||||
|         details: request.PlacedComponent.pf, | ||||
|         componentId: componentId | ||||
|     }); | ||||
| 
 | ||||
|     const component = | ||||
|         guild.DojoComponents[ | ||||
|             guild.DojoComponents.push({ | ||||
|                 _id: new Types.ObjectId(), | ||||
|                 _id: componentId, | ||||
|                 pf: request.PlacedComponent.pf, | ||||
|                 ppf: request.PlacedComponent.ppf, | ||||
|                 pi: new Types.ObjectId(request.PlacedComponent.pi!.$oid), | ||||
| @ -38,6 +53,7 @@ export const startDojoRecipeController: RequestHandler = async (req, res) => { | ||||
|         if (room) { | ||||
|             processDojoBuildMaterialsGathered(guild, room); | ||||
|         } | ||||
|         setDojoRoomLogFunded(guild, component); | ||||
|     } | ||||
|     await guild.save(); | ||||
|     res.json(await getDojoClient(guild, 0)); | ||||
|  | ||||
| @ -7,7 +7,8 @@ import { | ||||
|     IGuildMemberDatabase, | ||||
|     IGuildLogEntryNumber, | ||||
|     IGuildLogEntryString, | ||||
|     IGuildRank | ||||
|     IGuildRank, | ||||
|     IGuildLogRoomChange | ||||
| } from "@/src/types/guildTypes"; | ||||
| import { Document, Model, model, Schema, Types } from "mongoose"; | ||||
| import { fusionTreasuresSchema, typeCountSchema } from "./inventoryModels/inventoryModel"; | ||||
| @ -34,6 +35,7 @@ const dojoComponentSchema = new Schema<IDojoComponentDatabase>({ | ||||
|     RegularCredits: Number, | ||||
|     MiscItems: { type: [typeCountSchema], default: undefined }, | ||||
|     CompletionTime: Date, | ||||
|     CompletionLogPending: Boolean, | ||||
|     RushPlatinum: Number, | ||||
|     DestructionTime: Date, | ||||
|     Decos: [dojoDecoSchema], | ||||
| @ -115,6 +117,16 @@ const guildLogEntryStringSchema = new Schema<IGuildLogEntryString>( | ||||
|     { _id: false } | ||||
| ); | ||||
| 
 | ||||
| const guildLogRoomChangeSchema = new Schema<IGuildLogRoomChange>( | ||||
|     { | ||||
|         dateTime: Date, | ||||
|         entryType: Number, | ||||
|         details: String, | ||||
|         componentId: Types.ObjectId | ||||
|     }, | ||||
|     { _id: false } | ||||
| ); | ||||
| 
 | ||||
| const guildLogEntryNumberSchema = new Schema<IGuildLogEntryNumber>( | ||||
|     { | ||||
|         dateTime: Date, | ||||
| @ -146,6 +158,7 @@ const guildSchema = new Schema<IGuildDatabase>( | ||||
|         CeremonyContributors: { type: [Types.ObjectId], default: undefined }, | ||||
|         CeremonyResetDate: Date, | ||||
|         CeremonyEndo: Number, | ||||
|         RoomChanges: { type: [guildLogRoomChangeSchema], default: undefined }, | ||||
|         TechChanges: { type: [guildLogEntryStringSchema], default: undefined }, | ||||
|         RosterActivity: { type: [guildLogEntryStringSchema], default: undefined }, | ||||
|         ClassChanges: { type: [guildLogEntryNumberSchema], default: undefined } | ||||
|  | ||||
| @ -6,6 +6,7 @@ import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/invento | ||||
| import { | ||||
|     IDojoClient, | ||||
|     IDojoComponentClient, | ||||
|     IDojoComponentDatabase, | ||||
|     IDojoContributable, | ||||
|     IDojoDecoClient, | ||||
|     IGuildClient, | ||||
| @ -126,7 +127,8 @@ export const getDojoClient = async ( | ||||
|         DojoComponents: [] | ||||
|     }; | ||||
|     const roomsToRemove: Types.ObjectId[] = []; | ||||
|     guild.DojoComponents.forEach(dojoComponent => { | ||||
|     let needSave = false; | ||||
|     for (const dojoComponent of guild.DojoComponents) { | ||||
|         if (!componentId || dojoComponent._id.equals(componentId)) { | ||||
|             const clientComponent: IDojoComponentClient = { | ||||
|                 id: toOid(dojoComponent._id), | ||||
| @ -143,10 +145,18 @@ export const getDojoClient = async ( | ||||
|             } | ||||
|             if (dojoComponent.CompletionTime) { | ||||
|                 clientComponent.CompletionTime = toMongoDate(dojoComponent.CompletionTime); | ||||
|                 if (dojoComponent.CompletionLogPending && Date.now() >= dojoComponent.CompletionTime.getTime()) { | ||||
|                     const entry = guild.RoomChanges?.find(x => x.componentId.equals(dojoComponent._id)); | ||||
|                     if (entry) { | ||||
|                         dojoComponent.CompletionLogPending = undefined; | ||||
|                         entry.entryType = 1; | ||||
|                         needSave = true; | ||||
|                     } | ||||
|                 } | ||||
|                 if (dojoComponent.DestructionTime) { | ||||
|                     if (Date.now() >= dojoComponent.DestructionTime.getTime()) { | ||||
|                         roomsToRemove.push(dojoComponent._id); | ||||
|                         return; | ||||
|                         continue; | ||||
|                     } | ||||
|                     clientComponent.DestructionTime = toMongoDate(dojoComponent.DestructionTime); | ||||
|                 } | ||||
| @ -175,12 +185,15 @@ export const getDojoClient = async ( | ||||
|             } | ||||
|             dojo.DojoComponents.push(clientComponent); | ||||
|         } | ||||
|     }); | ||||
|     } | ||||
|     if (roomsToRemove.length) { | ||||
|         logger.debug(`removing now-destroyed rooms`, roomsToRemove); | ||||
|         for (const id of roomsToRemove) { | ||||
|             removeDojoRoom(guild, id); | ||||
|         } | ||||
|         needSave = true; | ||||
|     } | ||||
|     if (needSave) { | ||||
|         await guild.save(); | ||||
|     } | ||||
|     return dojo; | ||||
| @ -203,6 +216,13 @@ export const removeDojoRoom = (guild: TGuildDatabaseDocument, componentId: Types | ||||
|     } | ||||
|     moveResourcesToVault(guild, component); | ||||
|     component.Decos?.forEach(deco => moveResourcesToVault(guild, deco)); | ||||
| 
 | ||||
|     if (guild.RoomChanges) { | ||||
|         const index = guild.RoomChanges.findIndex(x => x.componentId.equals(component._id)); | ||||
|         if (index != -1) { | ||||
|             guild.RoomChanges.splice(index, 1); | ||||
|         } | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| export const removeDojoDeco = ( | ||||
| @ -254,6 +274,16 @@ export const processDojoBuildMaterialsGathered = (guild: TGuildDatabaseDocument, | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| // guild.save(); is expected some time after this function is called
 | ||||
| export const setDojoRoomLogFunded = (guild: TGuildDatabaseDocument, component: IDojoComponentDatabase): void => { | ||||
|     const entry = guild.RoomChanges?.find(x => x.componentId.equals(component._id)); | ||||
|     if (entry && entry.entryType == 2) { | ||||
|         entry.entryType = 0; | ||||
|         entry.dateTime = component.CompletionTime!; | ||||
|         component.CompletionLogPending = true; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| export const fillInInventoryDataForGuildMember = async (member: IGuildMemberClient): Promise<void> => { | ||||
|     const inventory = await getInventory(member._id.$oid, "PlayerLevel ActiveAvatarImageType"); | ||||
|     member.PlayerLevel = config.spoofMasteryRank == -1 ? inventory.PlayerLevel : config.spoofMasteryRank; | ||||
|  | ||||
| @ -48,6 +48,7 @@ export interface IGuildDatabase { | ||||
|     CeremonyContributors?: Types.ObjectId[]; | ||||
|     CeremonyResetDate?: Date; | ||||
| 
 | ||||
|     RoomChanges?: IGuildLogRoomChange[]; | ||||
|     TechChanges?: IGuildLogEntryString[]; | ||||
|     RosterActivity?: IGuildLogEntryString[]; | ||||
|     ClassChanges?: IGuildLogEntryNumber[]; | ||||
| @ -146,6 +147,7 @@ export interface IDojoComponentDatabase | ||||
|     _id: Types.ObjectId; | ||||
|     pi?: Types.ObjectId; | ||||
|     CompletionTime?: Date; | ||||
|     CompletionLogPending?: boolean; | ||||
|     DestructionTime?: Date; | ||||
|     Decos?: IDojoDecoDatabase[]; | ||||
| } | ||||
| @ -193,6 +195,10 @@ export interface IGuildLogEntryString { | ||||
|     details: string; | ||||
| } | ||||
| 
 | ||||
| export interface IGuildLogRoomChange extends IGuildLogEntryString { | ||||
|     componentId: Types.ObjectId; | ||||
| } | ||||
| 
 | ||||
| export interface IGuildLogEntryNumber { | ||||
|     dateTime: Date; | ||||
|     entryType: number; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user