74 lines
2.6 KiB
TypeScript
74 lines
2.6 KiB
TypeScript
import { WS } from '@acrd/types';
|
|
import { Socket } from 'socket.io';
|
|
import { GuildDocument } from '../../data/models/guild';
|
|
import { GuildMember } from '../../data/models/guild-member';
|
|
import { SelfUserDocument } from '../../data/models/user';
|
|
import { WebSocket } from '../websocket';
|
|
import { WSEvent, } from './ws-event';
|
|
|
|
export default class implements WSEvent<'GUILD_MEMBER_REMOVE'> {
|
|
public on = 'GUILD_MEMBER_REMOVE' as const;
|
|
|
|
public async invoke(ws: WebSocket, client: Socket, { guildId, userId }: WS.Params.GuildMemberRemove) {
|
|
const guild = await deps.guilds.get(guildId);
|
|
const members = await deps.guilds.getMembers(guildId);
|
|
const member = members.find(m => m.userId === userId);
|
|
if (!member)
|
|
throw new TypeError('Member does not exist');
|
|
|
|
const selfUserId = ws.sessions.get(client.id);
|
|
if (guild.ownerId === member.userId)
|
|
throw new TypeError('You cannot leave a guild you own, check guild settings to delete guild');
|
|
|
|
else if (selfUserId !== member.userId)
|
|
await deps.wsGuard.validateCan(client, guildId, 'KICK_MEMBERS');
|
|
|
|
// TODO: validate user is higher before kicking them
|
|
|
|
const user = await deps.users.getSelf(member.userId);
|
|
const index = user.guildIds.indexOf(guildId);
|
|
user.guildIds.splice(index, 1);
|
|
await user.save();
|
|
|
|
await GuildMember.deleteOne({ guildId, userId });
|
|
|
|
const targetClientId = ws.sessions.getClientIdFromUserId(userId);
|
|
if (targetClientId) {
|
|
const memberClient = ws.io.sockets.sockets.get(targetClientId);
|
|
memberClient?.emit('GUILD_DELETE', { guildId } as WS.Args.GuildDelete);
|
|
await client.leave(guildId);
|
|
}
|
|
|
|
await this.leaveGuildRooms(client, guild);
|
|
|
|
return [await this.leaveGuildMessage(guild, user), {
|
|
emit: this.on,
|
|
to: [guildId],
|
|
send: { memberId: member.id },
|
|
}, {
|
|
emit: 'GUILD_DELETE' as const,
|
|
to: [userId],
|
|
send: { guildId },
|
|
}];
|
|
}
|
|
|
|
private async leaveGuildMessage(guild: GuildDocument, user: SelfUserDocument) {
|
|
try {
|
|
const sysMessage = await deps.messages.createSystem(guild.id, `<@${user.id}> left the guild.`, 'GUILD_MEMBER_LEAVE');
|
|
|
|
return {
|
|
emit: 'MESSAGE_CREATE' as const,
|
|
to: [guild.systemChannelId!],
|
|
send: { message: sysMessage },
|
|
};
|
|
} catch { }
|
|
}
|
|
|
|
private async leaveGuildRooms(client: Socket, guild: GuildDocument) {
|
|
await client.leave(guild.id);
|
|
const guildChannels = await deps.guilds.getChannels(guild.id);
|
|
for (const channel of guildChannels)
|
|
await client.leave(channel.id);
|
|
}
|
|
}
|