Skip to content

Commit

Permalink
fix: voice lobby now handles multiple guilds (#77)
Browse files Browse the repository at this point in the history
  • Loading branch information
neolectron authored and potb committed Jan 5, 2024
1 parent 82ef0fa commit 23e7c98
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 36 deletions.
2 changes: 1 addition & 1 deletion src/core/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ interface Cache<Entries extends Record<string, any>> {
}

interface CacheEntries {
lobbyId: string;
lobbyIds: string[];
channels: string[];
quoiFeurChannels: string[];
recurringMessages: { id: string; channelId: string; frequency: Frequency; message: string }[];
Expand Down
6 changes: 1 addition & 5 deletions src/modules/voiceOnDemand/voiceOnDemand.helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@ export const isJoinState = (newState: VoiceState): newState is CheckedVoiceState
export const isLeaveState = (oldDate: VoiceState): oldDate is CheckedVoiceState =>
oldDate.channel !== null && oldDate.channelId !== null && oldDate.member !== null;

export const handleJoin = async (state: CheckedVoiceState, lobbyId: string): Promise<void> => {
if (state.channelId !== lobbyId) {
return;
}

export const handleJoin = async (state: CheckedVoiceState): Promise<void> => {
const channel = await createUserVoiceChannel(state.channel.parent, state.member);
await state.member.voice.setChannel(channel);
};
Expand Down
65 changes: 35 additions & 30 deletions src/modules/voiceOnDemand/voiceOnDemand.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,24 @@ export const voiceOnDemand: BotModule = {
.toJSON(),
handler: {
create: async (interaction): Promise<void> => {
const guild = interaction.guild as Guild;
const { guild } = interaction;

const lobbyId = await cache.get('lobbyId');
if (!(guild instanceof Guild)) {
await interaction.reply({
content: 'This command is only available in guilds',
ephemeral: true,
});

if (lobbyId !== undefined && guild.channels.cache.has(lobbyId)) {
guild.channels.cache.delete(lobbyId);
return;
}
const lobbyIds = await cache.get('lobbyIds', []);
const lobbyId = lobbyIds.find((lobbyId) => guild.channels.cache.has(lobbyId));

const channel =
lobbyId === undefined ? null : await guild.channels.fetch(lobbyId).catch(() => null);

if (channel !== null) {
if (lobbyId !== undefined) {
await interaction.reply({
content: 'Voice on demand voice lobby already exists.',
ephemeral: true,
});

return;
}

Expand All @@ -41,7 +42,8 @@ export const voiceOnDemand: BotModule = {
type: ChannelType.GuildVoice,
});

await cache.set('lobbyId', id);
//NOTES: this is a potential race condition.
await cache.set('lobbyIds', [...lobbyIds, id]);

await interaction.reply({
content: 'Created voice on demand voice channel.',
Expand All @@ -53,7 +55,9 @@ export const voiceOnDemand: BotModule = {
],
eventHandlers: {
voiceStateUpdate: async (oldState, newState) => {
const lobbyId = await cache.get('lobbyId');
const lobbyIds = await cache.get('lobbyIds', []);
const lobbyId = lobbyIds.find((lobbyId) => newState.channelId === lobbyId);

if (lobbyId === undefined) {
return;
}
Expand All @@ -63,34 +67,35 @@ export const voiceOnDemand: BotModule = {
}

if (isJoinState(newState)) {
await handleJoin(newState, lobbyId);
await handleJoin(newState);
}
},
channelDelete: async (channel) => {
if (channel.type !== ChannelType.GuildVoice) {
return;
}

const lobbyId = await cache.get('lobbyId');

const lobbyIds = await cache.get('lobbyIds', []);
const { guild, id } = channel;

if (id === lobbyId) {
await cache.delete('lobbyId');
guild.channels.cache.delete(lobbyId);

const channels = await cache.get('channels', []);

await Promise.all(
channels.map(async (id) => {
const channel = await guild.channels.fetch(id).catch(() => null);
if (channel !== null) {
await guild.channels.delete(id);
guild.channels.cache.delete(id);
}
}),
);
}
if (lobbyIds.includes(id)) return;

await cache.set(
'lobbyIds',
lobbyIds.filter((lobbyId) => lobbyId !== id),
);

const channels = await cache.get('channels', []);

await Promise.all(
channels.map(async (id) => {
const channel = await guild.channels.fetch(id).catch(() => null);
if (channel !== null) {
await guild.channels.delete(id);
guild.channels.cache.delete(id);
}
}),
);
},
},
intents: ['GuildVoiceStates', 'GuildMembers'],
Expand Down

0 comments on commit 23e7c98

Please sign in to comment.