chore: handle account switching guilds
Some checks failed
Build / build (20) (push) Has been cancelled
Build / build (18) (push) Has been cancelled
Build / build (22) (push) Has been cancelled
Build / build (22) (pull_request) Failing after 45s
Build / build (18) (pull_request) Failing after 1m16s
Build / build (20) (pull_request) Failing after 1m14s

This commit is contained in:
Sainan 2025-03-30 22:47:58 +02:00
parent 054abee62c
commit fad57f00b2
4 changed files with 86 additions and 59 deletions

View File

@ -1,23 +1,47 @@
import { Guild, GuildMember } from "@/src/models/guildModel"; 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 { getAccountForRequest, getSuffixedName } from "@/src/services/loginService";
import { IInventoryChanges } from "@/src/types/purchaseTypes";
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { Types } from "mongoose"; import { Types } from "mongoose";
export const confirmGuildInvitationController: RequestHandler = async (req, res) => { export const confirmGuildInvitationController: RequestHandler = async (req, res) => {
const account = await getAccountForRequest(req); const account = await getAccountForRequest(req);
const guildMember = await GuildMember.findOne({ const invitedGuildMember = await GuildMember.findOne({
accountId: account._id, accountId: account._id,
guildId: req.query.clanId as string guildId: req.query.clanId as string
}); });
if (guildMember) { if (invitedGuildMember) {
guildMember.status = 0; let inventoryChanges: IInventoryChanges = {};
await guildMember.save();
await updateInventoryForConfirmedGuildJoin( // If this account is already in a guild, we need to do cleanup first.
account._id.toString(), const guildMember = await GuildMember.findOneAndDelete({ accountId: account._id, status: 0 });
new Types.ObjectId(req.query.clanId as string) 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))!; const guild = (await Guild.findById(req.query.clanId as string))!;
@ -31,14 +55,7 @@ export const confirmGuildInvitationController: RequestHandler = async (req, res)
res.json({ res.json({
...(await getGuildClient(guild, account._id.toString())), ...(await getGuildClient(guild, account._id.toString())),
InventoryChanges: { InventoryChanges: inventoryChanges
Recipes: [
{
ItemType: "/Lotus/Types/Keys/DojoKeyBlueprint",
ItemCount: 1
}
]
}
}); });
} else { } else {
res.end(); res.end();

View File

@ -2,11 +2,8 @@ import { RequestHandler } from "express";
import { getAccountIdForRequest } from "@/src/services/loginService"; import { getAccountIdForRequest } from "@/src/services/loginService";
import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { Guild, GuildMember } from "@/src/models/guildModel"; import { Guild, GuildMember } from "@/src/models/guildModel";
import { import { createUniqueClanName, getGuildClient } from "@/src/services/guildService";
createUniqueClanName, import { addRecipes, getInventory } from "@/src/services/inventoryService";
getGuildClient,
updateInventoryForConfirmedGuildJoin
} from "@/src/services/guildService";
export const createGuildController: RequestHandler = async (req, res) => { export const createGuildController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req); const accountId = await getAccountIdForRequest(req);
@ -26,7 +23,15 @@ export const createGuildController: RequestHandler = async (req, res) => {
rank: 0 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({ res.json({
...(await getGuildClient(guild, accountId)), ...(await getGuildClient(guild, accountId)),

View File

@ -1,7 +1,7 @@
import { GuildMember } from "@/src/models/guildModel"; import { GuildMember } from "@/src/models/guildModel";
import { Inbox } from "@/src/models/inboxModel"; import { Inbox } from "@/src/models/inboxModel";
import { Account } from "@/src/models/loginModel"; 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 { getInventory } from "@/src/services/inventoryService";
import { getAccountForRequest, getSuffixedName } from "@/src/services/loginService"; import { getAccountForRequest, getSuffixedName } from "@/src/services/loginService";
import { GuildPermission } from "@/src/types/guildTypes"; import { GuildPermission } from "@/src/types/guildTypes";
@ -22,22 +22,9 @@ export const removeFromGuildController: RequestHandler = async (req, res) => {
await deleteGuild(guild._id); await deleteGuild(guild._id);
} else { } else {
if (guildMember.status == 0) { if (guildMember.status == 0) {
const inventory = await getInventory(payload.userId); const inventory = await getInventory(payload.userId, "GuildId LevelKeys Recipes");
inventory.GuildId = undefined; inventory.GuildId = undefined;
removeDojoKeyItems(inventory);
// 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);
}
}
await inventory.save(); await inventory.save();
} else if (guildMember.status == 2) { } else if (guildMember.status == 2) {
// Delete the inbox message for the invite // Delete the inbox message for the invite

View File

@ -25,6 +25,7 @@ import { Account } from "../models/loginModel";
import { getRandomInt } from "./rngService"; import { getRandomInt } from "./rngService";
import { Inbox } from "../models/inboxModel"; import { Inbox } from "../models/inboxModel";
import { ITypeCount } from "../types/inventoryTypes/inventoryTypes"; import { ITypeCount } from "../types/inventoryTypes/inventoryTypes";
import { IInventoryChanges } from "../types/purchaseTypes";
export const getGuildForRequest = async (req: Request): Promise<TGuildDatabaseDocument> => { export const getGuildForRequest = async (req: Request): Promise<TGuildDatabaseDocument> => {
const accountId = await getAccountIdForRequest(req); const accountId = await getAccountIdForRequest(req);
@ -350,26 +351,6 @@ export const fillInInventoryDataForGuildMember = async (member: IGuildMemberClie
member.ActiveAvatarImageType = inventory.ActiveAvatarImageType; 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> => { export const createUniqueClanName = async (name: string): Promise<string> => {
const initialDiscriminator = getRandomInt(0, 999); const initialDiscriminator = getRandomInt(0, 999);
let discriminator = initialDiscriminator; 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> => { export const deleteGuild = async (guildId: Types.ObjectId): Promise<void> => {
await Guild.deleteOne({ _id: guildId }); 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 }); await GuildMember.deleteMany({ guildId });
// If guild sent any invites, delete those inbox messages as well. // If guild sent any invites, delete those inbox messages as well.