2024-03-03 14:40:37 +00:00
pub mod commands ;
2023-09-16 22:47:26 +01:00
2024-09-30 00:09:29 +01:00
use crate ::commands ::role_adder ::tools ::on_role_change ;
2025-02-27 23:56:48 +00:00
use serenity ::all ::{ ActivityData , Command , CreateMessage , EditInteractionResponse , GuildId , GuildMemberUpdateEvent , Interaction } ;
2024-09-30 00:09:29 +01:00
use serenity ::model ::guild ::Member ;
2023-08-27 17:38:30 +01:00
use serenity ::{
2024-10-28 21:53:04 +00:00
async_trait ,
client ::{ Context , EventHandler } ,
model ::{
gateway ::{ GatewayIntents , Ready } ,
user ::OnlineStatus ,
} ,
Client ,
2023-08-27 17:38:30 +01:00
} ;
2024-10-28 21:53:04 +00:00
use skynet_discord_bot ::common ::database ::{ db_init , get_server_config , get_server_member , DataBase } ;
use skynet_discord_bot ::common ::set_roles ::committee ::update_committees ;
2025-02-18 21:14:05 +00:00
use skynet_discord_bot ::common ::wolves ::committees ::Committees ;
2024-10-28 00:59:04 +00:00
use skynet_discord_bot ::{ get_config , Config } ;
2025-02-18 21:14:05 +00:00
use sqlx ::{ Pool , Sqlite } ;
2024-09-30 00:09:29 +01:00
use std ::sync ::Arc ;
2023-08-27 17:38:30 +01:00
use tokio ::sync ::RwLock ;
2023-08-25 23:36:46 +01:00
2023-09-11 02:25:07 +01:00
struct Handler ;
2023-08-27 15:39:09 +01:00
2023-08-25 23:36:46 +01:00
#[ async_trait ]
impl EventHandler for Handler {
2024-09-29 21:04:08 +01:00
// handles previously linked accounts joining the server
2025-02-19 00:17:02 +00:00
async fn guild_member_addition ( & self , ctx : Context , new_member : Member ) {
2023-09-11 02:25:07 +01:00
let db_lock = {
2023-08-27 17:38:30 +01:00
let data_read = ctx . data . read ( ) . await ;
2023-09-11 02:25:07 +01:00
data_read . get ::< DataBase > ( ) . expect ( " Expected Config in TypeMap. " ) . clone ( )
2023-08-27 17:38:30 +01:00
} ;
2023-09-11 02:25:07 +01:00
let db = db_lock . read ( ) . await ;
2023-08-27 17:38:30 +01:00
2024-11-09 14:55:26 +00:00
let config_lock = {
let data_read = ctx . data . read ( ) . await ;
data_read . get ::< Config > ( ) . expect ( " Expected Config in TypeMap. " ) . clone ( )
} ;
let config_global = config_lock . read ( ) . await ;
2024-10-28 21:40:48 +00:00
// committee server takes priority
2025-04-09 00:06:20 +01:00
let committee_server = GuildId ::new ( 1220150752656363520 ) ;
if new_member . guild_id . get ( ) = = committee_server . get ( ) {
2024-10-28 21:40:48 +00:00
let mut member = vec! [ new_member . clone ( ) ] ;
2024-11-09 14:55:26 +00:00
update_committees ( & db , & ctx , & config_global , & mut member ) . await ;
2024-10-28 21:40:48 +00:00
return ;
}
2024-10-28 21:53:04 +00:00
2024-11-09 14:59:05 +00:00
let config_server = match get_server_config ( & db , & new_member . guild_id ) . await {
None = > return ,
Some ( x ) = > x ,
} ;
2023-09-17 21:17:57 +01:00
if get_server_member ( & db , & new_member . guild_id , & new_member ) . await . is_ok ( ) {
2023-08-27 17:38:30 +01:00
let mut roles = vec! [ ] ;
2024-11-09 14:59:05 +00:00
if let Some ( role ) = & config_server . role_past {
2023-09-11 18:18:59 +01:00
if ! new_member . roles . contains ( role ) {
2023-09-11 02:25:07 +01:00
roles . push ( role . to_owned ( ) ) ;
2023-08-26 15:55:07 +01:00
}
2023-09-11 02:25:07 +01:00
}
2023-08-27 17:38:30 +01:00
2024-11-09 14:59:05 +00:00
if ! new_member . roles . contains ( & config_server . role_current ) {
roles . push ( config_server . role_current . to_owned ( ) ) ;
2023-08-27 17:38:30 +01:00
}
2023-09-11 02:25:07 +01:00
if let Err ( e ) = new_member . add_roles ( & ctx , & roles ) . await {
println! ( " {:?} " , e ) ;
2023-08-27 17:38:30 +01:00
}
2024-09-17 21:41:30 +01:00
} else {
2025-02-24 17:07:26 +00:00
let tmp = get_committee ( & db , config_server . wolves_id ) . await ;
2025-02-18 21:14:05 +00:00
if ! tmp . is_empty ( ) {
let committee = & tmp [ 0 ] ;
let msg = format! (
r #"
2024-09-18 07:15:25 +01:00
Welcome { } to the { } server !
2025-04-23 11:30:22 +00:00
Sign up on [ UL Wolves ] ( { } ) and go to https ://discord.com/channels/{}/{} and use ``/wolves link email_here`` with the email associated with your wolves account, to get full access.
2024-09-17 21:41:30 +01:00
" #,
2025-02-18 21:14:05 +00:00
new_member . display_name ( ) ,
committee . name_full ,
committee . link ,
& config_server . server ,
& config_server . bot_channel_id
) ;
2025-02-19 00:17:02 +00:00
if let Err ( err ) = new_member . user . direct_message ( & ctx , CreateMessage ::new ( ) . content ( & msg ) ) . await {
2025-02-18 21:14:05 +00:00
dbg! ( err ) ;
}
2024-09-16 18:42:18 +01:00
}
2023-08-25 23:36:46 +01:00
}
2023-08-27 17:38:30 +01:00
}
2025-02-18 22:46:58 +00:00
// handles role updates
2025-02-19 00:17:02 +00:00
async fn guild_member_update ( & self , ctx : Context , _old_data : Option < Member > , new_data : Option < Member > , _ : GuildMemberUpdateEvent ) {
2025-02-18 22:46:58 +00:00
// get config/db
let db_lock = {
let data_read = ctx . data . read ( ) . await ;
data_read . get ::< DataBase > ( ) . expect ( " Expected Config in TypeMap. " ) . clone ( )
} ;
let db = db_lock . read ( ) . await ;
// check if the role changed is part of the oens for this server
2025-02-19 00:17:02 +00:00
if let Some ( x ) = new_data {
on_role_change ( & db , & ctx , x ) . await ;
}
2025-02-18 22:46:58 +00:00
}
2023-09-16 22:47:26 +01:00
async fn ready ( & self , ctx : Context , ready : Ready ) {
2023-09-11 02:25:07 +01:00
println! ( " [Main] {} is connected! " , ready . user . name ) ;
2025-02-19 00:17:02 +00:00
ctx . set_presence ( Some ( ActivityData ::playing ( " with humanity's fate " ) ) , OnlineStatus ::Online ) ;
match Command ::set_global_commands (
& ctx . http ,
vec! [
2025-03-06 20:43:36 +00:00
commands ::wolves ::register ( ) ,
2025-03-06 21:35:17 +00:00
commands ::committee ::register ( ) ,
2025-02-19 00:17:02 +00:00
commands ::minecraft ::server ::add ::register ( ) ,
commands ::minecraft ::server ::list ::register ( ) ,
commands ::minecraft ::server ::delete ::register ( ) ,
] ,
)
2023-09-17 00:14:50 +01:00
. await
2023-09-17 19:30:59 +01:00
{
Ok ( _ ) = > { }
Err ( e ) = > {
println! ( " {:?} " , e )
}
}
2025-02-27 03:02:35 +00:00
2025-04-09 00:06:20 +01:00
match GuildId ::new ( 1220150752656363520 )
2025-02-27 23:56:48 +00:00
. set_commands ( & ctx . http , vec! [ commands ::count ::committee ::register ( ) ] )
. await
{
Ok ( _ ) = > { }
Err ( e ) = > {
println! ( " {:?} " , e )
}
}
match GuildId ::new ( 689189992417067052 )
. set_commands ( & ctx . http , vec! [ commands ::count ::servers ::register ( ) ] )
2025-02-27 03:02:35 +00:00
. await
{
Ok ( _ ) = > { }
Err ( e ) = > {
println! ( " {:?} " , e )
}
}
2023-09-16 22:47:26 +01:00
}
async fn interaction_create ( & self , ctx : Context , interaction : Interaction ) {
2025-02-19 00:17:02 +00:00
if let Interaction ::Command ( command ) = interaction {
2023-09-17 15:25:17 +01:00
let _ = command . defer_ephemeral ( & ctx . http ) . await ;
2023-09-16 22:47:26 +01:00
//println!("Received command interaction: {:#?}", command);
let content = match command . data . name . as_str ( ) {
2024-06-03 02:06:35 +01:00
// user commands
2025-03-06 19:21:17 +00:00
" wolves " = > match command . data . options . first ( ) {
None = > " Invalid Command " . to_string ( ) ,
Some ( x ) = > match x . name . as_str ( ) {
2025-03-06 20:43:36 +00:00
" link " = > commands ::wolves ::link ::run ( & command , & ctx ) . await ,
" verify " = > commands ::wolves ::verify ::run ( & command , & ctx ) . await ,
" unlink " = > commands ::wolves ::unlink ::run ( & command , & ctx ) . await ,
2025-03-06 21:42:27 +00:00
" link_minecraft " = > commands ::minecraft ::user ::add ::run ( & command , & ctx ) . await ,
2025-03-06 19:21:17 +00:00
// "link" => commands::count::servers::run(&command, &ctx).await,
& _ = > format! ( " not implemented :( wolves {} " , x . name . as_str ( ) ) ,
} ,
} ,
2024-06-03 02:06:35 +01:00
// admin commands
2025-03-06 21:35:17 +00:00
" committee " = > match command . data . options . first ( ) {
None = > " Invalid Command " . to_string ( ) ,
Some ( x ) = > match x . name . as_str ( ) {
" add " = > commands ::add_server ::run ( & command , & ctx ) . await ,
" roles_adder " = > commands ::role_adder ::edit ::run ( & command , & ctx ) . await ,
// "link" => commands::count::servers::run(&command, &ctx).await,
& _ = > format! ( " not implemented :( committee {} " , x . name . as_str ( ) ) ,
} ,
} ,
2024-06-03 02:21:21 +01:00
" minecraft_add " = > commands ::minecraft ::server ::add ::run ( & command , & ctx ) . await ,
2024-06-03 03:04:12 +01:00
" minecraft_list " = > commands ::minecraft ::server ::list ::run ( & command , & ctx ) . await ,
2024-06-03 03:56:45 +01:00
" minecraft_delete " = > commands ::minecraft ::server ::delete ::run ( & command , & ctx ) . await ,
2025-02-27 23:56:48 +00:00
// sub command
" count " = > match command . data . options . first ( ) {
None = > " Invalid Command " . to_string ( ) ,
Some ( x ) = > match x . name . as_str ( ) {
" committee " = > commands ::count ::committee ::run ( & command , & ctx ) . await ,
" servers " = > commands ::count ::servers ::run ( & command , & ctx ) . await ,
& _ = > format! ( " not implemented :( count {} " , x . name . as_str ( ) ) ,
} ,
} ,
_ = > format! ( " not implemented :( {} " , command . data . name . as_str ( ) ) ,
2023-09-16 22:47:26 +01:00
} ;
2025-02-19 00:17:02 +00:00
if let Err ( why ) = command . edit_response ( & ctx . http , EditInteractionResponse ::new ( ) . content ( content ) ) . await {
2023-09-16 22:47:26 +01:00
println! ( " Cannot respond to slash command: {} " , why ) ;
}
}
2023-08-27 17:38:30 +01:00
}
2023-08-27 15:39:09 +01:00
}
2025-02-24 17:07:26 +00:00
async fn get_committee ( db : & Pool < Sqlite > , wolves_id : i64 ) -> Vec < Committees > {
2025-02-18 21:14:05 +00:00
sqlx ::query_as ::< _ , Committees > (
r #"
SELECT *
FROM committees
2025-02-24 17:07:26 +00:00
WHERE id = ?
2025-02-18 21:14:05 +00:00
" #,
)
2025-02-24 17:07:26 +00:00
. bind ( wolves_id )
2025-02-18 21:14:05 +00:00
. fetch_all ( db )
. await
. unwrap_or_default ( )
}
2023-08-25 23:36:46 +01:00
#[ tokio::main ]
async fn main ( ) {
2023-08-27 17:38:30 +01:00
let config = get_config ( ) ;
2023-09-11 02:25:07 +01:00
let db = match db_init ( & config ) . await {
Ok ( x ) = > x ,
2024-09-17 23:57:46 +01:00
Err ( err ) = > {
dbg! ( err ) ;
2024-09-18 00:03:53 +01:00
return ;
}
2023-09-11 02:25:07 +01:00
} ;
2023-08-27 17:38:30 +01:00
// Intents are a bitflag, bitwise operations can be used to dictate which intents to use
let intents = GatewayIntents ::GUILDS | GatewayIntents ::GUILD_MESSAGES | GatewayIntents ::MESSAGE_CONTENT | GatewayIntents ::GUILD_MEMBERS ;
// Build our client.
let mut client = Client ::builder ( & config . discord_token , intents )
2023-09-11 02:25:07 +01:00
. event_handler ( Handler { } )
2023-08-27 17:38:30 +01:00
. await
. expect ( " Error creating client " ) ;
{
let mut data = client . data . write ( ) . await ;
2023-08-27 17:30:54 +01:00
2023-08-27 17:38:30 +01:00
data . insert ::< Config > ( Arc ::new ( RwLock ::new ( config ) ) ) ;
2023-09-11 02:25:07 +01:00
data . insert ::< DataBase > ( Arc ::new ( RwLock ::new ( db ) ) ) ;
2023-08-27 17:38:30 +01:00
}
// Finally, start a single shard, and start listening to events.
//
// Shards will automatically attempt to reconnect, and will perform
// exponential backoff until it reconnects.
if let Err ( why ) = client . start ( ) . await {
println! ( " Client error: {:?} " , why ) ;
}
}