forked from OpenWF/SpaceNinjaServer
		
	chore: handle account switching guilds (#1398)
Plus some additional inventory cleanup when a guild is being deleted forcefully. Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									9e0dd3e0a5
								
							
						
					
					
						commit
						42e08faaaf
					
				@ -1,23 +1,47 @@
 | 
			
		||||
import { Guild, GuildMember } from "@/src/models/guildModel";
 | 
			
		||||
import { getGuildClient, updateInventoryForConfirmedGuildJoin } from "@/src/services/guildService";
 | 
			
		||||
import { deleteGuild, getGuildClient, removeDojoKeyItems } from "@/src/services/guildService";
 | 
			
		||||
import { addRecipes, combineInventoryChanges, getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { getAccountForRequest, getSuffixedName } from "@/src/services/loginService";
 | 
			
		||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
import { Types } from "mongoose";
 | 
			
		||||
 | 
			
		||||
export const confirmGuildInvitationController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const account = await getAccountForRequest(req);
 | 
			
		||||
    const guildMember = await GuildMember.findOne({
 | 
			
		||||
    const invitedGuildMember = await GuildMember.findOne({
 | 
			
		||||
        accountId: account._id,
 | 
			
		||||
        guildId: req.query.clanId as string
 | 
			
		||||
    });
 | 
			
		||||
    if (guildMember) {
 | 
			
		||||
        guildMember.status = 0;
 | 
			
		||||
        await guildMember.save();
 | 
			
		||||
    if (invitedGuildMember) {
 | 
			
		||||
        let inventoryChanges: IInventoryChanges = {};
 | 
			
		||||
 | 
			
		||||
        await updateInventoryForConfirmedGuildJoin(
 | 
			
		||||
            account._id.toString(),
 | 
			
		||||
            new Types.ObjectId(req.query.clanId as string)
 | 
			
		||||
        );
 | 
			
		||||
        // If this account is already in a guild, we need to do cleanup first.
 | 
			
		||||
        const guildMember = await GuildMember.findOneAndDelete({ accountId: account._id, status: 0 });
 | 
			
		||||
        if (guildMember) {
 | 
			
		||||
            const inventory = await getInventory(account._id.toString(), "LevelKeys Recipes");
 | 
			
		||||
            inventoryChanges = removeDojoKeyItems(inventory);
 | 
			
		||||
            await inventory.save();
 | 
			
		||||
 | 
			
		||||
            if (guildMember.rank == 0) {
 | 
			
		||||
                await deleteGuild(guildMember.guildId);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Now that we're sure this account is not in a guild right now, we can just proceed with the normal updates.
 | 
			
		||||
        invitedGuildMember.status = 0;
 | 
			
		||||
        await invitedGuildMember.save();
 | 
			
		||||
 | 
			
		||||
        const inventory = await getInventory(account._id.toString(), "GuildId LevelKeys Recipes");
 | 
			
		||||
        inventory.GuildId = new Types.ObjectId(req.query.clanId as string);
 | 
			
		||||
        const recipeChanges = [
 | 
			
		||||
            {
 | 
			
		||||
                ItemType: "/Lotus/Types/Keys/DojoKeyBlueprint",
 | 
			
		||||
                ItemCount: 1
 | 
			
		||||
            }
 | 
			
		||||
        ];
 | 
			
		||||
        addRecipes(inventory, recipeChanges);
 | 
			
		||||
        combineInventoryChanges(inventoryChanges, { Recipes: recipeChanges });
 | 
			
		||||
        await inventory.save();
 | 
			
		||||
 | 
			
		||||
        const guild = (await Guild.findById(req.query.clanId as string))!;
 | 
			
		||||
 | 
			
		||||
@ -31,14 +55,7 @@ export const confirmGuildInvitationController: RequestHandler = async (req, res)
 | 
			
		||||
 | 
			
		||||
        res.json({
 | 
			
		||||
            ...(await getGuildClient(guild, account._id.toString())),
 | 
			
		||||
            InventoryChanges: {
 | 
			
		||||
                Recipes: [
 | 
			
		||||
                    {
 | 
			
		||||
                        ItemType: "/Lotus/Types/Keys/DojoKeyBlueprint",
 | 
			
		||||
                        ItemCount: 1
 | 
			
		||||
                    }
 | 
			
		||||
                ]
 | 
			
		||||
            }
 | 
			
		||||
            InventoryChanges: inventoryChanges
 | 
			
		||||
        });
 | 
			
		||||
    } else {
 | 
			
		||||
        res.end();
 | 
			
		||||
 | 
			
		||||
@ -2,11 +2,8 @@ import { RequestHandler } from "express";
 | 
			
		||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
			
		||||
import { Guild, GuildMember } from "@/src/models/guildModel";
 | 
			
		||||
import {
 | 
			
		||||
    createUniqueClanName,
 | 
			
		||||
    getGuildClient,
 | 
			
		||||
    updateInventoryForConfirmedGuildJoin
 | 
			
		||||
} from "@/src/services/guildService";
 | 
			
		||||
import { createUniqueClanName, getGuildClient } from "@/src/services/guildService";
 | 
			
		||||
import { addRecipes, getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
 | 
			
		||||
export const createGuildController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const accountId = await getAccountIdForRequest(req);
 | 
			
		||||
@ -26,7 +23,15 @@ export const createGuildController: RequestHandler = async (req, res) => {
 | 
			
		||||
        rank: 0
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    await updateInventoryForConfirmedGuildJoin(accountId, guild._id);
 | 
			
		||||
    const inventory = await getInventory(accountId, "GuildId Recipes");
 | 
			
		||||
    inventory.GuildId = guild._id;
 | 
			
		||||
    addRecipes(inventory, [
 | 
			
		||||
        {
 | 
			
		||||
            ItemType: "/Lotus/Types/Keys/DojoKeyBlueprint",
 | 
			
		||||
            ItemCount: 1
 | 
			
		||||
        }
 | 
			
		||||
    ]);
 | 
			
		||||
    await inventory.save();
 | 
			
		||||
 | 
			
		||||
    res.json({
 | 
			
		||||
        ...(await getGuildClient(guild, accountId)),
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
import { GuildMember } from "@/src/models/guildModel";
 | 
			
		||||
import { Inbox } from "@/src/models/inboxModel";
 | 
			
		||||
import { Account } from "@/src/models/loginModel";
 | 
			
		||||
import { deleteGuild, getGuildForRequest, hasGuildPermission } from "@/src/services/guildService";
 | 
			
		||||
import { deleteGuild, getGuildForRequest, hasGuildPermission, removeDojoKeyItems } from "@/src/services/guildService";
 | 
			
		||||
import { getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { getAccountForRequest, getSuffixedName } from "@/src/services/loginService";
 | 
			
		||||
import { GuildPermission } from "@/src/types/guildTypes";
 | 
			
		||||
@ -22,22 +22,9 @@ export const removeFromGuildController: RequestHandler = async (req, res) => {
 | 
			
		||||
        await deleteGuild(guild._id);
 | 
			
		||||
    } else {
 | 
			
		||||
        if (guildMember.status == 0) {
 | 
			
		||||
            const inventory = await getInventory(payload.userId);
 | 
			
		||||
            const inventory = await getInventory(payload.userId, "GuildId LevelKeys Recipes");
 | 
			
		||||
            inventory.GuildId = undefined;
 | 
			
		||||
 | 
			
		||||
            // Remove clan key or blueprint from kicked member
 | 
			
		||||
            const itemIndex = inventory.LevelKeys.findIndex(x => x.ItemType == "/Lotus/Types/Keys/DojoKey");
 | 
			
		||||
            if (itemIndex != -1) {
 | 
			
		||||
                inventory.LevelKeys.splice(itemIndex, 1);
 | 
			
		||||
            } else {
 | 
			
		||||
                const recipeIndex = inventory.Recipes.findIndex(
 | 
			
		||||
                    x => x.ItemType == "/Lotus/Types/Keys/DojoKeyBlueprint"
 | 
			
		||||
                );
 | 
			
		||||
                if (recipeIndex != -1) {
 | 
			
		||||
                    inventory.Recipes.splice(recipeIndex, 1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            removeDojoKeyItems(inventory);
 | 
			
		||||
            await inventory.save();
 | 
			
		||||
        } else if (guildMember.status == 2) {
 | 
			
		||||
            // Delete the inbox message for the invite
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
import { Request } from "express";
 | 
			
		||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { addRecipes, getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { Guild, GuildAd, GuildMember, TGuildDatabaseDocument } from "@/src/models/guildModel";
 | 
			
		||||
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
 | 
			
		||||
import {
 | 
			
		||||
@ -25,6 +25,7 @@ import { Account } from "../models/loginModel";
 | 
			
		||||
import { getRandomInt } from "./rngService";
 | 
			
		||||
import { Inbox } from "../models/inboxModel";
 | 
			
		||||
import { ITypeCount } from "../types/inventoryTypes/inventoryTypes";
 | 
			
		||||
import { IInventoryChanges } from "../types/purchaseTypes";
 | 
			
		||||
 | 
			
		||||
export const getGuildForRequest = async (req: Request): Promise<TGuildDatabaseDocument> => {
 | 
			
		||||
    const accountId = await getAccountIdForRequest(req);
 | 
			
		||||
@ -350,26 +351,6 @@ export const fillInInventoryDataForGuildMember = async (member: IGuildMemberClie
 | 
			
		||||
    member.ActiveAvatarImageType = inventory.ActiveAvatarImageType;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const updateInventoryForConfirmedGuildJoin = async (
 | 
			
		||||
    accountId: string,
 | 
			
		||||
    guildId: Types.ObjectId
 | 
			
		||||
): Promise<void> => {
 | 
			
		||||
    const inventory = await getInventory(accountId, "GuildId Recipes");
 | 
			
		||||
 | 
			
		||||
    // Set GuildId
 | 
			
		||||
    inventory.GuildId = guildId;
 | 
			
		||||
 | 
			
		||||
    // Give clan key blueprint
 | 
			
		||||
    addRecipes(inventory, [
 | 
			
		||||
        {
 | 
			
		||||
            ItemType: "/Lotus/Types/Keys/DojoKeyBlueprint",
 | 
			
		||||
            ItemCount: 1
 | 
			
		||||
        }
 | 
			
		||||
    ]);
 | 
			
		||||
 | 
			
		||||
    await inventory.save();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const createUniqueClanName = async (name: string): Promise<string> => {
 | 
			
		||||
    const initialDiscriminator = getRandomInt(0, 999);
 | 
			
		||||
    let discriminator = initialDiscriminator;
 | 
			
		||||
@ -518,8 +499,45 @@ const setGuildTier = async (guild: TGuildDatabaseDocument, newTier: number): Pro
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const removeDojoKeyItems = (inventory: TInventoryDatabaseDocument): IInventoryChanges => {
 | 
			
		||||
    const inventoryChanges: IInventoryChanges = {};
 | 
			
		||||
 | 
			
		||||
    const itemIndex = inventory.LevelKeys.findIndex(x => x.ItemType == "/Lotus/Types/Keys/DojoKey");
 | 
			
		||||
    if (itemIndex != -1) {
 | 
			
		||||
        inventoryChanges.LevelKeys = [
 | 
			
		||||
            {
 | 
			
		||||
                ItemType: "/Lotus/Types/Keys/DojoKey",
 | 
			
		||||
                ItemCount: inventory.LevelKeys[itemIndex].ItemCount * -1
 | 
			
		||||
            }
 | 
			
		||||
        ];
 | 
			
		||||
        inventory.LevelKeys.splice(itemIndex, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const recipeIndex = inventory.Recipes.findIndex(x => x.ItemType == "/Lotus/Types/Keys/DojoKeyBlueprint");
 | 
			
		||||
    if (recipeIndex != -1) {
 | 
			
		||||
        inventoryChanges.Recipes = [
 | 
			
		||||
            {
 | 
			
		||||
                ItemType: "/Lotus/Types/Keys/DojoKeyBlueprint",
 | 
			
		||||
                ItemCount: inventory.Recipes[recipeIndex].ItemCount * -1
 | 
			
		||||
            }
 | 
			
		||||
        ];
 | 
			
		||||
        inventory.Recipes.splice(recipeIndex, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return inventoryChanges;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const deleteGuild = async (guildId: Types.ObjectId): Promise<void> => {
 | 
			
		||||
    await Guild.deleteOne({ _id: guildId });
 | 
			
		||||
 | 
			
		||||
    const guildMembers = await GuildMember.find({ guildId, status: 0 }, "accountId");
 | 
			
		||||
    for (const member of guildMembers) {
 | 
			
		||||
        const inventory = await getInventory(member.accountId.toString(), "GuildId LevelKeys Recipes");
 | 
			
		||||
        inventory.GuildId = undefined;
 | 
			
		||||
        removeDojoKeyItems(inventory);
 | 
			
		||||
        await inventory.save();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    await GuildMember.deleteMany({ guildId });
 | 
			
		||||
 | 
			
		||||
    // If guild sent any invites, delete those inbox messages as well.
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user