XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESpaceNinjaServer

A simple server for a small space ninja game

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/XFESpaceNinjaServer

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>

42e08faa
Sainan <63328889+Sainan@users.noreply.github.com>
提交于

代码差异

4 个文件 +87 -60
Modified src/controllers/api/confirmGuildInvitationController.ts +34 -17
@@ -1,23 +1,47 @@
1 1 import { Guild, GuildMember } from "@/src/models/guildModel";
2 import { getGuildClient, updateInventoryForConfirmedGuildJoin } from "@/src/services/guildService";
2 import { deleteGuild, getGuildClient, removeDojoKeyItems } from "@/src/services/guildService";
3 import { addRecipes, combineInventoryChanges, getInventory } from "@/src/services/inventoryService";
3 4 import { getAccountForRequest, getSuffixedName } from "@/src/services/loginService";
5 import { IInventoryChanges } from "@/src/types/purchaseTypes";
4 6 import { RequestHandler } from "express";
5 7 import { Types } from "mongoose";
6 8
7 9 export const confirmGuildInvitationController: RequestHandler = async (req, res) => {
8 10 const account = await getAccountForRequest(req);
9 const guildMember = await GuildMember.findOne({
11 const invitedGuildMember = await GuildMember.findOne({
10 12 accountId: account._id,
11 13 guildId: req.query.clanId as string
12 14 });
13 if (guildMember) {
14 guildMember.status = 0;
15 await guildMember.save();
15 if (invitedGuildMember) {
16 let inventoryChanges: IInventoryChanges = {};
16 17
17 await updateInventoryForConfirmedGuildJoin(
18 account._id.toString(),
19 new Types.ObjectId(req.query.clanId as string)
20 );
18 // If this account is already in a guild, we need to do cleanup first.
19 const guildMember = await GuildMember.findOneAndDelete({ accountId: account._id, status: 0 });
20 if (guildMember) {
21 const inventory = await getInventory(account._id.toString(), "LevelKeys Recipes");
22 inventoryChanges = removeDojoKeyItems(inventory);
23 await inventory.save();
24
25 if (guildMember.rank == 0) {
26 await deleteGuild(guildMember.guildId);
27 }
28 }
29
30 // Now that we're sure this account is not in a guild right now, we can just proceed with the normal updates.
31 invitedGuildMember.status = 0;
32 await invitedGuildMember.save();
33
34 const inventory = await getInventory(account._id.toString(), "GuildId LevelKeys Recipes");
35 inventory.GuildId = new Types.ObjectId(req.query.clanId as string);
36 const recipeChanges = [
37 {
38 ItemType: "/Lotus/Types/Keys/DojoKeyBlueprint",
39 ItemCount: 1
40 }
41 ];
42 addRecipes(inventory, recipeChanges);
43 combineInventoryChanges(inventoryChanges, { Recipes: recipeChanges });
44 await inventory.save();
21 45
22 46 const guild = (await Guild.findById(req.query.clanId as string))!;
23 47
@@ -31,14 +55,7 @@ export const confirmGuildInvitationController: RequestHandler = async (req, res)
31 55
32 56 res.json({
33 57 ...(await getGuildClient(guild, account._id.toString())),
34 InventoryChanges: {
35 Recipes: [
36 {
37 ItemType: "/Lotus/Types/Keys/DojoKeyBlueprint",
38 ItemCount: 1
39 }
40 ]
41 }
58 InventoryChanges: inventoryChanges
42 59 });
43 60 } else {
44 61 res.end();
Modified src/controllers/api/createGuildController.ts +11 -6
@@ -2,11 +2,8 @@ import { RequestHandler } from "express";
2 2 import { getAccountIdForRequest } from "@/src/services/loginService";
3 3 import { getJSONfromString } from "@/src/helpers/stringHelpers";
4 4 import { Guild, GuildMember } from "@/src/models/guildModel";
5 import {
6 createUniqueClanName,
7 getGuildClient,
8 updateInventoryForConfirmedGuildJoin
9 } from "@/src/services/guildService";
5 import { createUniqueClanName, getGuildClient } from "@/src/services/guildService";
6 import { addRecipes, getInventory } from "@/src/services/inventoryService";
10 7
11 8 export const createGuildController: RequestHandler = async (req, res) => {
12 9 const accountId = await getAccountIdForRequest(req);
@@ -26,7 +23,15 @@ export const createGuildController: RequestHandler = async (req, res) => {
26 23 rank: 0
27 24 });
28 25
29 await updateInventoryForConfirmedGuildJoin(accountId, guild._id);
26 const inventory = await getInventory(accountId, "GuildId Recipes");
27 inventory.GuildId = guild._id;
28 addRecipes(inventory, [
29 {
30 ItemType: "/Lotus/Types/Keys/DojoKeyBlueprint",
31 ItemCount: 1
32 }
33 ]);
34 await inventory.save();
30 35
31 36 res.json({
32 37 ...(await getGuildClient(guild, accountId)),
Modified src/controllers/api/removeFromGuildController.ts +3 -16
@@ -1,7 +1,7 @@
1 1 import { GuildMember } from "@/src/models/guildModel";
2 2 import { Inbox } from "@/src/models/inboxModel";
3 3 import { Account } from "@/src/models/loginModel";
4 import { deleteGuild, getGuildForRequest, hasGuildPermission } from "@/src/services/guildService";
4 import { deleteGuild, getGuildForRequest, hasGuildPermission, removeDojoKeyItems } from "@/src/services/guildService";
5 5 import { getInventory } from "@/src/services/inventoryService";
6 6 import { getAccountForRequest, getSuffixedName } from "@/src/services/loginService";
7 7 import { GuildPermission } from "@/src/types/guildTypes";
@@ -22,22 +22,9 @@ export const removeFromGuildController: RequestHandler = async (req, res) => {
22 22 await deleteGuild(guild._id);
23 23 } else {
24 24 if (guildMember.status == 0) {
25 const inventory = await getInventory(payload.userId);
25 const inventory = await getInventory(payload.userId, "GuildId LevelKeys Recipes");
26 26 inventory.GuildId = undefined;
27
28 // Remove clan key or blueprint from kicked member
29 const itemIndex = inventory.LevelKeys.findIndex(x => x.ItemType == "/Lotus/Types/Keys/DojoKey");
30 if (itemIndex != -1) {
31 inventory.LevelKeys.splice(itemIndex, 1);
32 } else {
33 const recipeIndex = inventory.Recipes.findIndex(
34 x => x.ItemType == "/Lotus/Types/Keys/DojoKeyBlueprint"
35 );
36 if (recipeIndex != -1) {
37 inventory.Recipes.splice(recipeIndex, 1);
38 }
39 }
40
27 removeDojoKeyItems(inventory);
41 28 await inventory.save();
42 29 } else if (guildMember.status == 2) {
43 30 // Delete the inbox message for the invite
Modified src/services/guildService.ts +39 -21
@@ -1,6 +1,6 @@
1 1 import { Request } from "express";
2 2 import { getAccountIdForRequest } from "@/src/services/loginService";
3 import { addRecipes, getInventory } from "@/src/services/inventoryService";
3 import { getInventory } from "@/src/services/inventoryService";
4 4 import { Guild, GuildAd, GuildMember, TGuildDatabaseDocument } from "@/src/models/guildModel";
5 5 import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
6 6 import {
@@ -25,6 +25,7 @@ import { Account } from "../models/loginModel";
25 25 import { getRandomInt } from "./rngService";
26 26 import { Inbox } from "../models/inboxModel";
27 27 import { ITypeCount } from "../types/inventoryTypes/inventoryTypes";
28 import { IInventoryChanges } from "../types/purchaseTypes";
28 29
29 30 export const getGuildForRequest = async (req: Request): Promise<TGuildDatabaseDocument> => {
30 31 const accountId = await getAccountIdForRequest(req);
@@ -350,26 +351,6 @@ export const fillInInventoryDataForGuildMember = async (member: IGuildMemberClie
350 351 member.ActiveAvatarImageType = inventory.ActiveAvatarImageType;
351 352 };
352 353
353 export const updateInventoryForConfirmedGuildJoin = async (
354 accountId: string,
355 guildId: Types.ObjectId
356 ): Promise<void> => {
357 const inventory = await getInventory(accountId, "GuildId Recipes");
358
359 // Set GuildId
360 inventory.GuildId = guildId;
361
362 // Give clan key blueprint
363 addRecipes(inventory, [
364 {
365 ItemType: "/Lotus/Types/Keys/DojoKeyBlueprint",
366 ItemCount: 1
367 }
368 ]);
369
370 await inventory.save();
371 };
372
373 354 export const createUniqueClanName = async (name: string): Promise<string> => {
374 355 const initialDiscriminator = getRandomInt(0, 999);
375 356 let discriminator = initialDiscriminator;
@@ -518,8 +499,45 @@ const setGuildTier = async (guild: TGuildDatabaseDocument, newTier: number): Pro
518 499 }
519 500 };
520 501
502 export const removeDojoKeyItems = (inventory: TInventoryDatabaseDocument): IInventoryChanges => {
503 const inventoryChanges: IInventoryChanges = {};
504
505 const itemIndex = inventory.LevelKeys.findIndex(x => x.ItemType == "/Lotus/Types/Keys/DojoKey");
506 if (itemIndex != -1) {
507 inventoryChanges.LevelKeys = [
508 {
509 ItemType: "/Lotus/Types/Keys/DojoKey",
510 ItemCount: inventory.LevelKeys[itemIndex].ItemCount * -1
511 }
512 ];
513 inventory.LevelKeys.splice(itemIndex, 1);
514 }
515
516 const recipeIndex = inventory.Recipes.findIndex(x => x.ItemType == "/Lotus/Types/Keys/DojoKeyBlueprint");
517 if (recipeIndex != -1) {
518 inventoryChanges.Recipes = [
519 {
520 ItemType: "/Lotus/Types/Keys/DojoKeyBlueprint",
521 ItemCount: inventory.Recipes[recipeIndex].ItemCount * -1
522 }
523 ];
524 inventory.Recipes.splice(recipeIndex, 1);
525 }
526
527 return inventoryChanges;
528 };
529
521 530 export const deleteGuild = async (guildId: Types.ObjectId): Promise<void> => {
522 531 await Guild.deleteOne({ _id: guildId });
532
533 const guildMembers = await GuildMember.find({ guildId, status: 0 }, "accountId");
534 for (const member of guildMembers) {
535 const inventory = await getInventory(member.accountId.toString(), "GuildId LevelKeys Recipes");
536 inventory.GuildId = undefined;
537 removeDojoKeyItems(inventory);
538 await inventory.save();
539 }
540
523 541 await GuildMember.deleteMany({ guildId });
524 542
525 543 // If guild sent any invites, delete those inbox messages as well.