mirror of
				https://github.com/keanuplayz/TravBot-v3.git
				synced 2024-08-15 02:33:12 +00:00 
			
		
		
		
	Merge pull request #27 from keanuplayz/feature/stream-events
This commit is contained in:
		
						commit
						4978aceec6
					
				
					 5 changed files with 153 additions and 0 deletions
				
			
		|  | @ -164,6 +164,47 @@ export default new Command({ | |||
|                             }) | ||||
|                         }) | ||||
|                     } | ||||
|                 }), | ||||
|                 stream: new Command({ | ||||
|                     description: "Set a channel to send stream notifications. Type `#` to reference the channel.", | ||||
|                     usage: "(<channel mention>)", | ||||
|                     async run($) { | ||||
|                         if ($.guild) { | ||||
|                             const guild = Storage.getGuild($.guild.id); | ||||
| 
 | ||||
|                             if (guild.streamingChannel) { | ||||
|                                 guild.streamingChannel = null; | ||||
|                                 $.channel.send("Removed your server's stream notifications channel."); | ||||
|                             } else { | ||||
|                                 guild.streamingChannel = $.channel.id; | ||||
|                                 $.channel.send(`Set your server's stream notifications channel to ${$.channel}.`); | ||||
|                             } | ||||
| 
 | ||||
|                             Storage.save(); | ||||
|                         } else { | ||||
|                             $.channel.send("You must use this command in a server."); | ||||
|                         } | ||||
|                     }, | ||||
|                     // If/when channel types come out, this will be the perfect candidate to test it.
 | ||||
|                     any: new Command({ | ||||
|                         async run($) { | ||||
|                             if ($.guild) { | ||||
|                                 const match = $.args[0].match(/^<#(\d{17,19})>$/); | ||||
| 
 | ||||
|                                 if (match) { | ||||
|                                     Storage.getGuild($.guild.id).streamingChannel = match[1]; | ||||
|                                     Storage.save(); | ||||
|                                     $.channel.send(`Successfully set this server's welcome channel to ${match[0]}.`); | ||||
|                                 } else { | ||||
|                                     $.channel.send( | ||||
|                                         "You must provide a reference channel. You can do this by typing `#` then searching for the proper channel." | ||||
|                                     ); | ||||
|                                 } | ||||
|                             } else { | ||||
|                                 $.channel.send("You must use this command in a server."); | ||||
|                             } | ||||
|                         } | ||||
|                     }) | ||||
|                 }) | ||||
|             } | ||||
|         }), | ||||
|  |  | |||
							
								
								
									
										18
									
								
								src/commands/utilities/streaminfo.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/commands/utilities/streaminfo.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | |||
| import Command from "../../core/command"; | ||||
| import {streamList} from "../../events/voiceStateUpdate"; | ||||
| 
 | ||||
| export default new Command({ | ||||
|     description: "Sets the description of your stream. You can embed links by writing `[some name](some link)`", | ||||
|     async run($) { | ||||
|         const userID = $.author.id; | ||||
| 
 | ||||
|         if (streamList.has(userID)) { | ||||
|             const stream = streamList.get(userID)!; | ||||
|             stream.description = $.args.join(" ") || "No description set."; | ||||
|             stream.update(); | ||||
|         } else { | ||||
|             // Alternatively, I could make descriptions last outside of just one stream.
 | ||||
|             $.channel.send("You can only use this command when streaming."); | ||||
|         } | ||||
|     } | ||||
| }); | ||||
|  | @ -58,11 +58,13 @@ class Guild { | |||
|     public welcomeType: "none" | "text" | "graphical"; | ||||
|     public welcomeChannel: string | null; | ||||
|     public welcomeMessage: string | null; | ||||
|     public streamingChannel: string | null; | ||||
| 
 | ||||
|     constructor(data?: GenericJSON) { | ||||
|         this.prefix = select(data?.prefix, null, String); | ||||
|         this.welcomeChannel = select(data?.welcomeChannel, null, String); | ||||
|         this.welcomeMessage = select(data?.welcomeMessage, null, String); | ||||
|         this.streamingChannel = select(data?.streamingChannel, null, String); | ||||
| 
 | ||||
|         switch (data?.welcomeType) { | ||||
|             case "text": | ||||
|  |  | |||
							
								
								
									
										14
									
								
								src/events/channelUpdate.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/events/channelUpdate.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| import Event from "../core/event"; | ||||
| import {streamList} from "./voiceStateUpdate"; | ||||
| 
 | ||||
| export default new Event<"channelUpdate">({ | ||||
|     async on(before, after) { | ||||
|         if (before.type === "voice" && after.type === "voice") { | ||||
|             for (const stream of streamList.values()) { | ||||
|                 if (after.id === stream.channel.id) { | ||||
|                     stream.update(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| }); | ||||
							
								
								
									
										78
									
								
								src/events/voiceStateUpdate.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								src/events/voiceStateUpdate.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,78 @@ | |||
| import {GuildMember, VoiceChannel, MessageEmbed, TextChannel, Permissions, Message, Collection} from "discord.js"; | ||||
| import Event from "../core/event"; | ||||
| import $ from "../core/lib"; | ||||
| import {Storage} from "../core/structures"; | ||||
| import {client} from "../index"; | ||||
| 
 | ||||
| type Stream = { | ||||
|     streamer: GuildMember; | ||||
|     channel: VoiceChannel; | ||||
|     description?: string; | ||||
|     message: Message; | ||||
|     update: () => void; | ||||
| }; | ||||
| 
 | ||||
| // A list of user IDs and message embeds.
 | ||||
| export const streamList = new Collection<string, Stream>(); | ||||
| 
 | ||||
| // Probably find a better, DRY way of doing this.
 | ||||
| function getStreamEmbed(streamer: GuildMember, channel: VoiceChannel, description?: string): MessageEmbed { | ||||
|     const user = streamer.user; | ||||
|     const embed = new MessageEmbed() | ||||
|         .setTitle(`Stream: \`#${channel.name}\``) | ||||
|         .setAuthor( | ||||
|             streamer.nickname ?? user.username, | ||||
|             user.avatarURL({ | ||||
|                 dynamic: true, | ||||
|                 format: "png" | ||||
|             }) ?? user.defaultAvatarURL | ||||
|         ) | ||||
|         .setColor(streamer.displayColor); | ||||
| 
 | ||||
|     if (description) { | ||||
|         embed.setDescription(description); | ||||
|     } | ||||
| 
 | ||||
|     return embed; | ||||
| } | ||||
| 
 | ||||
| export default new Event<"voiceStateUpdate">({ | ||||
|     async on(before, after) { | ||||
|         const isStartStreamEvent = !before.streaming && after.streaming; | ||||
|         const isStopStreamEvent = before.streaming && (!after.streaming || !after.channel); // If you were streaming before but now are either not streaming or have left the channel.
 | ||||
|         // Note: isStopStreamEvent can be called twice in a row - If Discord crashes/quits while you're streaming, it'll call once with a null channel and a second time with a channel.
 | ||||
| 
 | ||||
|         if (isStartStreamEvent || isStopStreamEvent) { | ||||
|             const {streamingChannel} = Storage.getGuild(after.guild.id); | ||||
| 
 | ||||
|             if (streamingChannel) { | ||||
|                 const member = after.member!; | ||||
|                 const voiceChannel = after.channel!; | ||||
|                 const textChannel = client.channels.cache.get(streamingChannel); | ||||
| 
 | ||||
|                 if (textChannel instanceof TextChannel) { | ||||
|                     if (isStartStreamEvent) { | ||||
|                         streamList.set(member.id, { | ||||
|                             streamer: member, | ||||
|                             channel: voiceChannel, | ||||
|                             message: await textChannel.send(getStreamEmbed(member, voiceChannel)), | ||||
|                             update(this: Stream) { | ||||
|                                 this.message.edit(getStreamEmbed(this.streamer, this.channel, this.description)); | ||||
|                             } | ||||
|                         }); | ||||
|                     } else if (isStopStreamEvent) { | ||||
|                         if (streamList.has(member.id)) { | ||||
|                             const {message} = streamList.get(member.id)!; | ||||
|                             message.delete(); | ||||
|                             streamList.delete(member.id); | ||||
|                         } | ||||
|                     } | ||||
|                 } else { | ||||
|                     $.error( | ||||
|                         `The streaming notifications channel ${streamingChannel} for guild ${after.guild.id} either doesn't exist or isn't a text channel.` | ||||
|                     ); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| }); | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue