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 { 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();
|
||||||
|
@ -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)),
|
||||||
|
@ -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
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Request } from "express";
|
import { Request } from "express";
|
||||||
import { getAccountIdForRequest } from "@/src/services/loginService";
|
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 { Guild, GuildAd, GuildMember, TGuildDatabaseDocument } from "@/src/models/guildModel";
|
||||||
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
|
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
|
||||||
import {
|
import {
|
||||||
@ -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.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user