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

SpaceNinjaServer

A simple server for a small space ninja game

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

XFEstudio/SpaceNinjaServer

feat: batch remove friends (#2032)

Closes #1947 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2032 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>

31043b55
Sainan <63328889+Sainan@users.noreply.github.com>
提交于

代码差异

2 个文件 +68 -4
Modified src/controllers/api/removeFriendController.ts +66 -3
@@ -1,8 +1,13 @@
1 1 import { toOid } from "@/src/helpers/inventoryHelpers";
2 import { getJSONfromString } from "@/src/helpers/stringHelpers";
2 3 import { Friendship } from "@/src/models/friendModel";
4 import { Account } from "@/src/models/loginModel";
5 import { getInventory } from "@/src/services/inventoryService";
3 6 import { getAccountIdForRequest } from "@/src/services/loginService";
4 7 import { IOid } from "@/src/types/commonTypes";
8 import { parallelForeach } from "@/src/utils/async-utils";
5 9 import { RequestHandler } from "express";
10 import { Types } from "mongoose";
6 11
7 12 export const removeFriendGetController: RequestHandler = async (req, res) => {
8 13 const accountId = await getAccountIdForRequest(req);
@@ -22,7 +27,7 @@ export const removeFriendGetController: RequestHandler = async (req, res) => {
22 27 await Promise.all(promises);
23 28 res.json({
24 29 Friends: friends
25 });
30 } satisfies IRemoveFriendsResponse);
26 31 } else {
27 32 const friendId = req.query.friendId as string;
28 33 await Promise.all([
@@ -30,7 +35,65 @@ export const removeFriendGetController: RequestHandler = async (req, res) => {
30 35 Friendship.deleteOne({ owner: friendId, friend: accountId })
31 36 ]);
32 37 res.json({
33 Friends: [{ $oid: friendId } satisfies IOid]
34 });
38 Friends: [{ $oid: friendId }]
39 } satisfies IRemoveFriendsResponse);
35 40 }
36 41 };
42
43 export const removeFriendPostController: RequestHandler = async (req, res) => {
44 const accountId = await getAccountIdForRequest(req);
45 const data = getJSONfromString<IBatchRemoveFriendsRequest>(String(req.body));
46 const friends = new Set((await Friendship.find({ owner: accountId }, "friend")).map(x => x.friend));
47 // TOVERIFY: Should pending friendships also be kept?
48
49 // Keep friends that have been online within threshold
50 await parallelForeach([...friends], async friend => {
51 const account = (await Account.findById(friend, "LastLogin"))!;
52 const daysLoggedOut = (Date.now() - account.LastLogin.getTime()) / 86400_000;
53 if (daysLoggedOut < data.DaysLoggedOut) {
54 friends.delete(friend);
55 }
56 });
57
58 if (data.SkipClanmates) {
59 const inventory = await getInventory(accountId, "GuildId");
60 if (inventory.GuildId) {
61 await parallelForeach([...friends], async friend => {
62 const friendInventory = await getInventory(friend.toString(), "GuildId");
63 if (friendInventory.GuildId?.equals(inventory.GuildId)) {
64 friends.delete(friend);
65 }
66 });
67 }
68 }
69
70 // Remove all remaining friends that aren't in SkipFriendIds & give response.
71 const promises = [];
72 const response: IOid[] = [];
73 for (const friend of friends) {
74 if (!data.SkipFriendIds.find(skipFriendId => checkFriendId(skipFriendId, friend))) {
75 promises.push(Friendship.deleteOne({ owner: accountId, friend: friend }));
76 promises.push(Friendship.deleteOne({ owner: friend, friend: accountId }));
77 response.push(toOid(friend));
78 }
79 }
80 await Promise.all(promises);
81 res.json({
82 Friends: response
83 } satisfies IRemoveFriendsResponse);
84 };
85
86 // The friend ids format is a bit weird, e.g. when 6633b81e9dba0b714f28ff02 (A) is friends with 67cdac105ef1f4b49741c267 (B), A's friend id for B is 808000105ef1f40560ca079e and B's friend id for A is 8000b81e9dba0b06408a8075.
87 const checkFriendId = (friendId: string, b: Types.ObjectId): boolean => {
88 return friendId.substring(6, 6 + 8) == b.toString().substring(6, 6 + 8);
89 };
90
91 interface IBatchRemoveFriendsRequest {
92 DaysLoggedOut: number;
93 SkipClanmates: boolean;
94 SkipFriendIds: string[];
95 }
96
97 interface IRemoveFriendsResponse {
98 Friends: IOid[];
99 }
Modified src/routes/api.ts +2 -1
@@ -103,7 +103,7 @@ import { questControlController } from "@/src/controllers/api/questControlContro
103 103 import { queueDojoComponentDestructionController } from "@/src/controllers/api/queueDojoComponentDestructionController";
104 104 import { redeemPromoCodeController } from "@/src/controllers/api/redeemPromoCodeController";
105 105 import { releasePetController } from "@/src/controllers/api/releasePetController";
106 import { removeFriendGetController } from "@/src/controllers/api/removeFriendController";
106 import { removeFriendGetController, removeFriendPostController } from "@/src/controllers/api/removeFriendController";
107 107 import { removeFromAllianceController } from "@/src/controllers/api/removeFromAllianceController";
108 108 import { removeFromGuildController } from "@/src/controllers/api/removeFromGuildController";
109 109 import { removeIgnoredUserController } from "@/src/controllers/api/removeIgnoredUserController";
@@ -290,6 +290,7 @@ apiRouter.post("/purchase.php", purchaseController);
290 290 apiRouter.post("/questControl.php", questControlController); // U17
291 291 apiRouter.post("/redeemPromoCode.php", redeemPromoCodeController);
292 292 apiRouter.post("/releasePet.php", releasePetController);
293 apiRouter.post("/removeFriend.php", removeFriendPostController);
293 294 apiRouter.post("/removeFromGuild.php", removeFromGuildController);
294 295 apiRouter.post("/removeIgnoredUser.php", removeIgnoredUserController);
295 296 apiRouter.post("/rerollRandomMod.php", rerollRandomModController);