@@ -7,12 +7,13 @@ use crate::prelude::modules::*;
77use crate :: prelude:: types:: * ;
88use crate :: prelude:: utils:: * ;
99use crate :: wrap_command;
10- use serenity:: all:: { GuildId , MessageId , UserId } ;
10+ use serenity:: all:: { GuildId , MessageId , Permissions , UserId } ;
1111use serenity:: {
1212 all:: { ChannelId , Context , EventHandler , Message , MessageUpdateEvent } ,
1313 async_trait,
1414} ;
1515use std:: collections:: HashSet ;
16+ use std:: sync:: atomic:: { AtomicBool , Ordering } ;
1617use std:: sync:: { LazyLock , Mutex } ;
1718use std:: { collections:: HashMap , future:: Future , pin:: Pin , sync:: Arc } ;
1819use tokio:: sync:: Mutex as AsyncMutex ;
@@ -39,6 +40,7 @@ pub struct GuildMessagesHandler {
3940 pub registry : Arc < CommandRegistry > ,
4041 pub shutdown : Arc < Receiver < bool > > ,
4142 pub pagination : PaginationStore ,
43+ pub maintenance_mode : Arc < AtomicBool > ,
4244}
4345
4446impl GuildMessagesHandler {
@@ -47,13 +49,15 @@ impl GuildMessagesHandler {
4749 registry : Arc < CommandRegistry > ,
4850 shutdown : Receiver < bool > ,
4951 pagination : PaginationStore ,
52+ maintenance_mode : Arc < AtomicBool > ,
5053 ) -> Self {
5154 let h = Self {
5255 config : Arc :: new ( config. clone ( ) ) ,
5356 commands : Arc :: new ( AsyncMutex :: new ( HashMap :: new ( ) ) ) ,
5457 registry,
5558 shutdown : Arc :: new ( shutdown) ,
5659 pagination,
60+ maintenance_mode,
5761 } ;
5862
5963 let mut lock = h. commands . lock ( ) . await ;
@@ -198,10 +202,68 @@ async fn manage_incoming_message(
198202 Ok ( ( ) )
199203}
200204
205+ async fn is_user_maintenance_exempt ( ctx : & Context , msg : & Message , config : & Config ) -> bool {
206+ let user_id = msg. author . id . get ( ) ;
207+
208+ if config. bot . panel_super_admin_users . contains ( & user_id) {
209+ return true ;
210+ }
211+
212+ let guild_id = match msg. guild_id {
213+ Some ( id) => id,
214+ None => return false ,
215+ } ;
216+
217+ let member = match guild_id. member ( & ctx. http , msg. author . id ) . await {
218+ Ok ( m) => m,
219+ Err ( _) => return false ,
220+ } ;
221+
222+ if !config. bot . panel_super_admin_roles . is_empty ( ) {
223+ for role_id in & member. roles {
224+ if config. bot . panel_super_admin_roles . contains ( & role_id. get ( ) ) {
225+ return true ;
226+ }
227+ }
228+ }
229+
230+ let guild = match guild_id. to_partial_guild ( & ctx. http ) . await {
231+ Ok ( g) => g,
232+ Err ( _) => return false ,
233+ } ;
234+
235+ if guild. owner_id == msg. author . id {
236+ return true ;
237+ }
238+
239+ member. roles . iter ( ) . any ( |role_id| {
240+ guild
241+ . roles
242+ . get ( role_id)
243+ . map ( |role| role. permissions . contains ( Permissions :: ADMINISTRATOR ) )
244+ . unwrap_or ( false )
245+ } )
246+ }
247+
201248#[ async_trait]
202249impl EventHandler for GuildMessagesHandler {
203250 async fn message ( & self , ctx : Context , msg : Message ) {
204251 if msg. guild_id . is_none ( ) {
252+ if self . maintenance_mode . load ( Ordering :: Relaxed ) {
253+ let _ = MessageBuilder :: system_message ( & ctx, & self . config )
254+ . translated_content (
255+ "status.maintenance_mode_active_user" ,
256+ None ,
257+ Some ( msg. author . id ) ,
258+ None ,
259+ )
260+ . await
261+ . to_user ( msg. author . id )
262+ . send ( true )
263+ . await ;
264+ return ;
265+ }
266+
205267 if let Err ( error) = manage_incoming_message ( & ctx, & msg, & self . config ) . await {
206268 if let Some ( error_handler) = & self . config . error_handler {
207269 let _ = error_handler
@@ -222,6 +284,18 @@ impl EventHandler for GuildMessagesHandler {
222284 command_name = & message_content[ self . config . command . prefix . len ( ) ..i] ;
223285 }
224286
287+ if self . maintenance_mode . load ( Ordering :: Relaxed ) {
288+ if !is_user_maintenance_exempt ( & ctx, & msg, & self . config ) . await {
289+ let _ = MessageBuilder :: system_message ( & ctx, & self . config )
290+ . translated_content ( "status.maintenance_mode_active" , None , None , None )
291+ . await
292+ . to_channel ( msg. channel_id )
293+ . send ( true )
294+ . await ;
295+ return ;
296+ }
297+ }
298+
225299 let commands_lock = self . commands . lock ( ) . await ;
226300
227301 if let Some ( command_func) = commands_lock. get ( command_name)
0 commit comments