1use bevy_app::{App, Plugin, Startup, Update};
36use bevy_ecs::prelude::*;
37use serenity::all::*;
38
39use crate::messages::{MessageCollectionBot, bot::*, send_events_bot};
40use event_handlers::*;
41
42use crate::DiscordSystems;
43use crate::bot::handle::Handle;
44use crate::channel::ChannelRes;
45use crate::runtime::tokio_runtime;
46
47pub(crate) mod event_handlers;
48mod handle;
49
50#[derive(Debug, Clone)]
91pub struct DiscordBotPlugin(crate::config::DiscordBotConfig);
92
93impl DiscordBotPlugin {
94 pub fn new(configuration: crate::config::DiscordBotConfig) -> Self {
100 Self(configuration)
101 }
102}
103
104impl Plugin for DiscordBotPlugin {
105 fn build(&self, app: &mut App) {
106 let (tx, rx) = flume::unbounded::<MessageCollectionBot>();
107 let channel_res = ChannelRes { tx, rx };
108 app.insert_resource(channel_res);
109
110 #[cfg(feature = "bot_cache")]
111 app.add_message::<CacheReadMessage>()
112 .add_message::<ShardsReadyMessage>();
113
114 app.insert_resource(self.0.clone())
115 .add_message::<BotReadyMessage>()
116 .add_message::<CommandPermissionsUpdateMessage>()
117 .add_message::<AutoModerationRuleCreateMessage>()
118 .add_message::<AutoModerationRuleUpdateMessage>()
119 .add_message::<AutoModerationRuleDeleteMessage>()
120 .add_message::<AutoModerationActionExecutionMessage>()
121 .add_message::<ChannelCreateMessage>()
122 .add_message::<CategoryCreateMessage>()
123 .add_message::<CategoryDeleteMessage>()
124 .add_message::<ChannelDeleteMessage>()
125 .add_message::<ChannelPinUpdateMessage>()
126 .add_message::<ChannelUpdateMessage>()
127 .add_message::<GuildAuditLogEntryCreateMessage>()
128 .add_message::<GuildBanAdditionMessage>()
129 .add_message::<GuildBanRemovalMessage>()
130 .add_message::<GuildCreateMessage>()
131 .add_message::<GuildDeleteMessage>()
132 .add_message::<GuildEmojisUpdateMessage>()
133 .add_message::<GuildIntegrationsUpdateMessage>()
134 .add_message::<GuildMemberAdditionMessage>()
135 .add_message::<GuildMemberRemovalMessage>()
136 .add_message::<GuildMemberUpdateMessage>()
137 .add_message::<GuildMembersChunkMessage>()
138 .add_message::<GuildRoleCreateMessage>()
139 .add_message::<GuildRoleDeleteMessage>()
140 .add_message::<GuildRoleUpdateMessage>()
141 .add_message::<GuildStickersUpdateMessage>()
142 .add_message::<GuildUpdateMessage>()
143 .add_message::<InviteCreateMessage>()
144 .add_message::<InviteDeleteMessage>()
145 .add_message::<DiscordMessage>()
146 .add_message::<DiscordMessageDeleteMessage>()
147 .add_message::<DiscordMessageDeleteBulkMessage>()
148 .add_message::<DiscordMessageUpdateMessage>()
149 .add_message::<ReactionAddMessage>()
150 .add_message::<ReactionRemoveMessage>()
151 .add_message::<ReactionRemoveAllMessage>()
152 .add_message::<ReactionRemoveEmojiMessage>()
153 .add_message::<PresenceUpdateMessage>()
154 .add_message::<ResumeMessage>()
155 .add_message::<ShardStageUpdateMessage>()
156 .add_message::<TypingStartMessage>()
157 .add_message::<UserUpdateMessage>()
158 .add_message::<VoiceServerUpdateMessage>()
159 .add_message::<VoiceStateUpdateMessage>()
160 .add_message::<VoiceChannelStatusUpdateMessage>()
161 .add_message::<WebhookUpdateMessage>()
162 .add_message::<InteractionCreateMessage>()
163 .add_message::<IntegrationCreateMessage>()
164 .add_message::<IntegrationUpdateMessage>()
165 .add_message::<StageInstanceCreateMessage>()
166 .add_message::<StageInstanceUpdateMessage>()
167 .add_message::<StageInstanceDeleteMessage>()
168 .add_message::<ThreadCreateMessage>()
169 .add_message::<ThreadUpdateMessage>()
170 .add_message::<ThreadDeleteMessage>()
171 .add_message::<ThreadListSyncMessage>()
172 .add_message::<ThreadMemberUpdateMessage>()
173 .add_message::<ThreadMembersUpdateMessage>()
174 .add_message::<GuildScheduledEventCreateMessage>()
175 .add_message::<GuildScheduledEventUpdateMessage>()
176 .add_message::<GuildScheduledEventDeleteMessage>()
177 .add_message::<GuildScheduledEventUserAddMessage>()
178 .add_message::<GuildScheduledEventUserRemoveMessage>()
179 .add_message::<EntitlementCreateMessage>()
180 .add_message::<EntitlementUpdateMessage>()
181 .add_message::<EntitlementDeleteMessage>()
182 .add_message::<PollVoteAddMessage>()
183 .add_message::<PollVoteRemoveMessage>()
184 .add_message::<RateLimitMessage>()
185 .add_systems(Startup, setup_bot.in_set(DiscordSystems))
186 .add_systems(
187 Update,
188 (handle_b_ready_message, send_events_bot)
189 .chain()
190 .in_set(DiscordSystems),
191 );
192 }
193}
194
195fn setup_bot(
196 discord_bot_config: Res<crate::config::DiscordBotConfig>,
197 channel_res: Res<ChannelRes<MessageCollectionBot>>,
198) {
199 let tx = channel_res.tx.clone();
200
201 let mut client_builder = Client::builder(
202 &discord_bot_config.token,
203 discord_bot_config.gateway_intents,
204 )
205 .event_handler(Handle { tx });
206
207 let discord_bot_res_clone = discord_bot_config.clone();
208
209 if let Some(status) = discord_bot_res_clone.status {
210 client_builder = client_builder.status(status);
211 }
212
213 if let Some(activity) = discord_bot_res_clone.activity {
214 client_builder = client_builder.activity(activity);
215 }
216
217 let discord_bot_config_clone = discord_bot_config.clone();
218
219 tokio_runtime().spawn(async move {
220 let mut client = client_builder
221 .await
222 .expect("Unable to build discord Client");
223
224 if discord_bot_config_clone.shards == 0 {
225 client
226 .start()
227 .await
228 .expect("Unable to run the discord Client");
229 } else {
230 client
231 .start_shards(discord_bot_config_clone.shards)
232 .await
233 .expect("Unable to run the discord Client with multiple shards.")
234 }
235 });
236}