返回提交历史
Modified
src/controllers/api/confirmGuildInvitationController.ts
+34
-17
Modified
src/controllers/api/createGuildController.ts
+11
-6
Modified
src/controllers/api/removeFromGuildController.ts
+3
-16
Modified
src/services/guildService.ts
+39
-21
XFEstudio/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>
42e08faa
代码差异
4 个文件
+87
-60
@@ -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();
@@ -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)),
@@ -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
@@ -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.