Something went wrong. Try again.
General purpose moderation bot for Stoat. automod.vale.rocks
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142import { File } from "./File";import { bitwiseAndEq, Permission } from "../permissions";
export class ServerMember { private collection: any; id: { server: string; user: string };
constructor(collection: any, id: { server: string; user: string }) { this.collection = collection; this.id = id; }
private get client(): any { return this.collection.client; } private get data(): any { return this.collection.getUnderlyingObject(this.id.server + this.id.user) || {}; }
get user() { return this.client.users.get(this.id.user); } get server() { return this.client.servers.get(this.id.server); } get nickname() { return this.data.nickname; } get pronouns() { return this.data.pronouns; } get avatar() { const a = this.data.avatar; return a ? new File(this.client, a) : undefined; } get roles(): string[] { return this.data.roles ?? []; } get joinedAt() { const raw = this.data.joinedAt ?? this.data.joined_at; return raw ? new Date(raw) : undefined; } get displayName() { return this.nickname ?? this.user?.displayName; } get avatarURL() { return this.avatar?.createFileURL() ?? this.user?.avatarURL; }
get roleColour() { const ordered = this.orderedRoles; const coloured = ordered.filter((x: any) => x.colour || x.color); return coloured.length > 0 ? (coloured[coloured.length - 1].colour ?? coloured[coloured.length - 1].color) : null; }
get ranking() { if (this.id.user === this.server?.ownerId) return -Infinity; const roles = this.orderedRoles; if (roles.length > 0) return roles[roles.length - 1].rank ?? Infinity; return Infinity; }
get orderedRoles() { const server = this.server; if (!server) return []; const serverRoles = server.roles; return (this.roles ?? []) .map((id: string) => { const role = serverRoles?.get(id); return role ? { id, ...role } : null; }) .filter((role) => role) .sort((a: any, b: any) => (b.rank ?? 0) - (a.rank ?? 0)); }
hasPermission(target: any, ...permission: string[]) { // Server owner always has all permissions const server = target.serverId ? target.server : target; if (server && this.id.user === server.ownerId) { return bitwiseAndEq((1n << 64n) - 1n, ...permission.map((x) => (Permission as any)[x])); }
let perms = 0n;
if (target.serverId) { // target is a Channel: compute server-level perms for THIS member, then apply channel overrides if (server) { perms = BigInt(server.defaultPermissions ?? 0); for (const role of this.orderedRoles) { if (role?.permissions) { perms |= BigInt(role.permissions.a ?? 0n); perms &= ~BigInt(role.permissions.d ?? 0n); } } } // Apply channel-level overrides const dp = target.data?.defaultPermissions ?? target.data?.default_permissions; if (dp) { if (typeof dp === "number") { perms |= BigInt(dp); } else { perms |= BigInt(dp.a ?? 0n); perms &= ~BigInt(dp.d ?? 0n); } } const rolePerms = target.data?.rolePermissions ?? target.data?.role_permissions; if (server && rolePerms) { for (const role of this.orderedRoles) { const rp = rolePerms[role.id]; if (rp) { perms |= BigInt(rp.a ?? 0n); perms &= ~BigInt(rp.d ?? 0n); } } } } else { // target is a Server: compute server-level perms for THIS member perms = BigInt(target.defaultPermissions ?? 0); for (const role of this.orderedRoles) { if (role?.permissions) { perms |= BigInt(role.permissions.a ?? 0n); perms &= ~BigInt(role.permissions.d ?? 0n); } } }
return bitwiseAndEq(perms, ...permission.map((x) => (Permission as any)[x])); }
inferiorTo(target: any) { return target.ranking < this.ranking; }
async edit(data: any) { await this.client.api.patch(`/servers/${this.id.server}/members/${this.id.user}`, data); }
toString() { return `<@${this.id.user}>`; }}