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