feat: ignore list (#1711)
Some checks failed
Build / build (push) Has been cancelled
Build Docker image / docker (push) Has been cancelled

Closes #1707

Reviewed-on: #1711
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:
Sainan 2025-04-18 11:16:43 -07:00 committed by Sainan
parent 0c34c87d75
commit f549b042d6
9 changed files with 95 additions and 16 deletions

View File

@ -0,0 +1,30 @@
import { toOid } from "@/src/helpers/inventoryHelpers";
import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { Account, Ignore } from "@/src/models/loginModel";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { IFriendInfo } from "@/src/types/guildTypes";
import { RequestHandler } from "express";
export const addIgnoredUserController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req);
const data = getJSONfromString<IAddIgnoredUserRequest>(String(req.body));
const ignoreeAccount = await Account.findOne(
{ DisplayName: data.playerName.substring(0, data.playerName.length - 1) },
"_id"
);
if (ignoreeAccount) {
await Ignore.create({ ignorer: accountId, ignoree: ignoreeAccount._id });
res.json({
Ignored: {
_id: toOid(ignoreeAccount._id),
DisplayName: data.playerName
} satisfies IFriendInfo
});
} else {
res.status(400).end();
}
};
interface IAddIgnoredUserRequest {
playerName: string;
}

View File

@ -1,16 +1,20 @@
import { toOid } from "@/src/helpers/inventoryHelpers";
import { Account, Ignore } from "@/src/models/loginModel";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { IFriendInfo } from "@/src/types/guildTypes";
import { parallelForeach } from "@/src/utils/async-utils";
import { RequestHandler } from "express"; import { RequestHandler } from "express";
const getIgnoredUsersController: RequestHandler = (_req, res) => { export const getIgnoredUsersController: RequestHandler = async (req, res) => {
res.writeHead(200, { const accountId = await getAccountIdForRequest(req);
"Content-Type": "text/html", const ignores = await Ignore.find({ ignorer: accountId });
"Content-Length": "3" const ignoredUsers: IFriendInfo[] = [];
await parallelForeach(ignores, async ignore => {
const ignoreeAccount = (await Account.findById(ignore.ignoree, "DisplayName"))!;
ignoredUsers.push({
_id: toOid(ignore.ignoree),
DisplayName: ignoreeAccount.DisplayName + ""
}); });
res.end( });
Buffer.from([ res.json({ IgnoredUsers: ignoredUsers });
0x7b, 0x22, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x38, 0x33, 0x30, 0x34, 0x30, 0x37, 0x37, 0x32, 0x32,
0x34, 0x30, 0x32, 0x32, 0x32, 0x36, 0x31, 0x35, 0x30, 0x31, 0x7d
])
);
}; };
export { getIgnoredUsersController };

View File

@ -0,0 +1,21 @@
import { getJSONfromString } from "@/src/helpers/stringHelpers";
import { Account, Ignore } from "@/src/models/loginModel";
import { getAccountForRequest } from "@/src/services/loginService";
import { RequestHandler } from "express";
export const removeIgnoredUserController: RequestHandler = async (req, res) => {
const accountId = await getAccountForRequest(req);
const data = getJSONfromString<IRemoveIgnoredUserRequest>(String(req.body));
const ignoreeAccount = await Account.findOne(
{ DisplayName: data.playerName.substring(0, data.playerName.length - 1) },
"_id"
);
if (ignoreeAccount) {
await Ignore.deleteOne({ ignorer: accountId, ignoree: ignoreeAccount._id });
}
res.end();
};
interface IRemoveIgnoredUserRequest {
playerName: string;
}

View File

@ -1,6 +1,6 @@
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { getAccountIdForRequest } from "@/src/services/loginService"; import { getAccountIdForRequest } from "@/src/services/loginService";
import { Account } from "@/src/models/loginModel"; import { Account, Ignore } from "@/src/models/loginModel";
import { Inbox } from "@/src/models/inboxModel"; import { Inbox } from "@/src/models/inboxModel";
import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import { Inventory } from "@/src/models/inventoryModels/inventoryModel";
import { Loadout } from "@/src/models/inventoryModels/loadoutModel"; import { Loadout } from "@/src/models/inventoryModels/loadoutModel";
@ -23,6 +23,8 @@ export const deleteAccountController: RequestHandler = async (req, res) => {
await Promise.all([ await Promise.all([
Account.deleteOne({ _id: accountId }), Account.deleteOne({ _id: accountId }),
GuildMember.deleteMany({ accountId: accountId }), GuildMember.deleteMany({ accountId: accountId }),
Ignore.deleteMany({ ignorer: accountId }),
Ignore.deleteMany({ ignoree: accountId }),
Inbox.deleteMany({ ownerId: accountId }), Inbox.deleteMany({ ownerId: accountId }),
Inventory.deleteOne({ accountOwnerId: accountId }), Inventory.deleteOne({ accountOwnerId: accountId }),
Leaderboard.deleteMany({ ownerId: accountId }), Leaderboard.deleteMany({ ownerId: accountId }),

View File

@ -1,4 +1,4 @@
import { IDatabaseAccountJson } from "@/src/types/loginTypes"; import { IDatabaseAccountJson, IIgnore } from "@/src/types/loginTypes";
import { model, Schema, SchemaOptions } from "mongoose"; import { model, Schema, SchemaOptions } from "mongoose";
const opts = { const opts = {
@ -37,3 +37,13 @@ databaseAccountSchema.set("toJSON", {
}); });
export const Account = model<IDatabaseAccountJson>("Account", databaseAccountSchema); export const Account = model<IDatabaseAccountJson>("Account", databaseAccountSchema);
const ignoreSchema = new Schema<IIgnore>({
ignorer: Schema.Types.ObjectId,
ignoree: Schema.Types.ObjectId
});
ignoreSchema.index({ ignorer: 1 });
ignoreSchema.index({ ignorer: 1, ignoree: 1 }, { unique: true });
export const Ignore = model<IIgnore>("Ignore", ignoreSchema);

View File

@ -4,6 +4,7 @@ import { abortDojoComponentController } from "@/src/controllers/api/abortDojoCom
import { abortDojoComponentDestructionController } from "@/src/controllers/api/abortDojoComponentDestructionController"; import { abortDojoComponentDestructionController } from "@/src/controllers/api/abortDojoComponentDestructionController";
import { activateRandomModController } from "@/src/controllers/api/activateRandomModController"; import { activateRandomModController } from "@/src/controllers/api/activateRandomModController";
import { addFriendImageController } from "@/src/controllers/api/addFriendImageController"; import { addFriendImageController } from "@/src/controllers/api/addFriendImageController";
import { addIgnoredUserController } from "@/src/controllers/api/addIgnoredUserController";
import { addToAllianceController } from "@/src/controllers/api/addToAllianceController"; import { addToAllianceController } from "@/src/controllers/api/addToAllianceController";
import { addToGuildController } from "@/src/controllers/api/addToGuildController"; import { addToGuildController } from "@/src/controllers/api/addToGuildController";
import { arcaneCommonController } from "@/src/controllers/api/arcaneCommonController"; import { arcaneCommonController } from "@/src/controllers/api/arcaneCommonController";
@ -97,6 +98,7 @@ import { redeemPromoCodeController } from "@/src/controllers/api/redeemPromoCode
import { releasePetController } from "@/src/controllers/api/releasePetController"; import { releasePetController } from "@/src/controllers/api/releasePetController";
import { removeFromAllianceController } from "@/src/controllers/api/removeFromAllianceController"; import { removeFromAllianceController } from "@/src/controllers/api/removeFromAllianceController";
import { removeFromGuildController } from "@/src/controllers/api/removeFromGuildController"; import { removeFromGuildController } from "@/src/controllers/api/removeFromGuildController";
import { removeIgnoredUserController } from "@/src/controllers/api/removeIgnoredUserController";
import { rerollRandomModController } from "@/src/controllers/api/rerollRandomModController"; import { rerollRandomModController } from "@/src/controllers/api/rerollRandomModController";
import { retrievePetFromStasisController } from "@/src/controllers/api/retrievePetFromStasisController"; import { retrievePetFromStasisController } from "@/src/controllers/api/retrievePetFromStasisController";
import { saveDialogueController } from "@/src/controllers/api/saveDialogueController"; import { saveDialogueController } from "@/src/controllers/api/saveDialogueController";
@ -202,6 +204,7 @@ apiRouter.get("/updateSession.php", updateSessionGetController);
apiRouter.post("/abortDojoComponent.php", abortDojoComponentController); apiRouter.post("/abortDojoComponent.php", abortDojoComponentController);
apiRouter.post("/activateRandomMod.php", activateRandomModController); apiRouter.post("/activateRandomMod.php", activateRandomModController);
apiRouter.post("/addFriendImage.php", addFriendImageController); apiRouter.post("/addFriendImage.php", addFriendImageController);
apiRouter.post("/addIgnoredUser.php", addIgnoredUserController);
apiRouter.post("/addToAlliance.php", addToAllianceController); apiRouter.post("/addToAlliance.php", addToAllianceController);
apiRouter.post("/addToGuild.php", addToGuildController); apiRouter.post("/addToGuild.php", addToGuildController);
apiRouter.post("/arcaneCommon.php", arcaneCommonController); apiRouter.post("/arcaneCommon.php", arcaneCommonController);
@ -266,6 +269,7 @@ apiRouter.post("/purchase.php", purchaseController);
apiRouter.post("/redeemPromoCode.php", redeemPromoCodeController); apiRouter.post("/redeemPromoCode.php", redeemPromoCodeController);
apiRouter.post("/releasePet.php", releasePetController); apiRouter.post("/releasePet.php", releasePetController);
apiRouter.post("/removeFromGuild.php", removeFromGuildController); apiRouter.post("/removeFromGuild.php", removeFromGuildController);
apiRouter.post("/removeIgnoredUser.php", removeIgnoredUserController);
apiRouter.post("/rerollRandomMod.php", rerollRandomModController); apiRouter.post("/rerollRandomMod.php", rerollRandomModController);
apiRouter.post("/retrievePetFromStasis.php", retrievePetFromStasisController); apiRouter.post("/retrievePetFromStasis.php", retrievePetFromStasisController);
apiRouter.post("/saveDialogue.php", saveDialogueController); apiRouter.post("/saveDialogue.php", saveDialogueController);

View File

@ -103,12 +103,12 @@ export interface IGuildMemberDatabase {
ShipDecorationsContributed?: ITypeCount[]; ShipDecorationsContributed?: ITypeCount[];
} }
interface IFriendInfo { export interface IFriendInfo {
_id: IOid; _id: IOid;
DisplayName?: string; DisplayName?: string;
PlatformNames?: string[]; PlatformNames?: string[];
PlatformAccountId?: string; PlatformAccountId?: string;
Status: number; Status?: number;
ActiveAvatarImageType?: string; ActiveAvatarImageType?: string;
LastLogin?: IMongoDate; LastLogin?: IMongoDate;
PlayerLevel?: number; PlayerLevel?: number;

View File

@ -1,3 +1,5 @@
import { Types } from "mongoose";
export interface IAccountAndLoginResponseCommons { export interface IAccountAndLoginResponseCommons {
DisplayName: string; DisplayName: string;
CountryCode: string; CountryCode: string;
@ -56,3 +58,8 @@ export interface IGroup {
experiment: string; experiment: string;
experimentGroup: string; experimentGroup: string;
} }
export interface IIgnore {
ignorer: Types.ObjectId;
ignoree: Types.ObjectId;
}

View File

@ -1,3 +1,4 @@
// Misnomer: We have concurrency, not parallelism - oh well!
export const parallelForeach = async <T>(data: T[], op: (datum: T) => Promise<void>): Promise<void> => { export const parallelForeach = async <T>(data: T[], op: (datum: T) => Promise<void>): Promise<void> => {
const promises: Promise<void>[] = []; const promises: Promise<void>[] = [];
for (const datum of data) { for (const datum of data) {