2023-09-11 02:25:07 +01:00
|
|
|
use serenity::{
|
2024-10-28 00:59:04 +00:00
|
|
|
async_trait,
|
|
|
|
client::{Context, EventHandler},
|
|
|
|
model::gateway::{GatewayIntents, Ready},
|
|
|
|
Client,
|
2023-09-11 02:25:07 +01:00
|
|
|
};
|
2024-10-28 00:59:04 +00:00
|
|
|
use skynet_discord_bot::{get_config, set_roles, Config};
|
2023-09-11 18:18:59 +01:00
|
|
|
use std::{process, sync::Arc};
|
2024-10-28 21:17:44 +00:00
|
|
|
use std::collections::HashMap;
|
|
|
|
use serenity::builder::EditRole;
|
|
|
|
use serenity::model::guild::{Member, Role};
|
|
|
|
use serenity::model::id::{GuildId, RoleId, UserId};
|
|
|
|
use sqlx::{Pool, Sqlite};
|
2023-09-11 02:25:07 +01:00
|
|
|
use tokio::sync::RwLock;
|
2024-10-28 21:17:44 +00:00
|
|
|
use skynet_discord_bot::common::database::{db_init, get_server_config_bulk, DataBase, Servers, Wolves};
|
|
|
|
use skynet_discord_bot::common::wolves::committees::Committees;
|
2023-09-11 02:25:07 +01:00
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
async fn main() {
|
|
|
|
let config = get_config();
|
|
|
|
let db = match db_init(&config).await {
|
|
|
|
Ok(x) => x,
|
|
|
|
Err(_) => return,
|
|
|
|
};
|
|
|
|
|
|
|
|
// 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)
|
|
|
|
.event_handler(Handler {})
|
|
|
|
.await
|
|
|
|
.expect("Error creating client");
|
|
|
|
|
|
|
|
{
|
|
|
|
let mut data = client.data.write().await;
|
|
|
|
|
|
|
|
data.insert::<Config>(Arc::new(RwLock::new(config)));
|
|
|
|
data.insert::<DataBase>(Arc::new(RwLock::new(db)));
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Err(why) = client.start().await {
|
|
|
|
println!("Client error: {:?}", why);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Handler;
|
|
|
|
#[async_trait]
|
|
|
|
impl EventHandler for Handler {
|
|
|
|
async fn ready(&self, ctx: Context, ready: Ready) {
|
|
|
|
let ctx = Arc::new(ctx);
|
|
|
|
println!("{} is connected!", ready.user.name);
|
|
|
|
|
2024-10-28 21:17:44 +00:00
|
|
|
// this goes into each server and sets roles for each wolves member
|
|
|
|
check_bulk(Arc::clone(&ctx)).await;
|
|
|
|
|
|
|
|
// u[date committee server
|
|
|
|
committee::check_committee(Arc::clone(&ctx)).await;
|
2023-09-11 02:25:07 +01:00
|
|
|
|
|
|
|
// finish up
|
|
|
|
process::exit(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-28 21:17:44 +00:00
|
|
|
async fn check_bulk(ctx: Arc<Context>) {
|
2023-09-11 02:25:07 +01:00
|
|
|
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;
|
|
|
|
|
|
|
|
for server_config in get_server_config_bulk(&db).await {
|
2024-05-06 02:12:26 +01:00
|
|
|
set_roles::update_server(&ctx, &server_config, &[], &[]).await;
|
2023-09-11 02:25:07 +01:00
|
|
|
}
|
|
|
|
}
|
2024-10-28 21:17:44 +00:00
|
|
|
|
|
|
|
// for updating committee members
|
|
|
|
pub mod committee {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
pub(crate) async fn check_committee(ctx: Arc<Context>) {
|
|
|
|
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;
|
|
|
|
|
|
|
|
let server = GuildId(1220150752656363520);
|
|
|
|
let mut members = server.members(&ctx, None, None).await.unwrap_or_default();
|
|
|
|
|
|
|
|
update_committees(&db, &ctx, &mut members).await;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn update_committees(db: &Pool<Sqlite>, ctx: &Context, members: &mut Vec<Member>){
|
|
|
|
let server = GuildId(1220150752656363520);
|
|
|
|
let committee_member = RoleId(1226602779968274573);
|
|
|
|
let committees = get_committees(db).await;
|
|
|
|
|
|
|
|
// information about the server
|
|
|
|
let roles = server.roles(&ctx).await.unwrap_or_default();
|
|
|
|
|
|
|
|
// make a hashmap of the nameof roles to quickly get them out again
|
|
|
|
let mut roles_name = HashMap::new();
|
|
|
|
for role in roles.values() {
|
|
|
|
roles_name.insert(role.name.to_owned(), role.to_owned());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// a map of users and the roles they are goign to be getting
|
|
|
|
let mut users_roles = HashMap::new();
|
|
|
|
|
|
|
|
// a list of all the roles that can be removed from folks who should have them
|
|
|
|
let mut committee_roles = vec![
|
|
|
|
committee_member
|
|
|
|
];
|
|
|
|
|
|
|
|
for committee in &committees {
|
|
|
|
// get the role for this committee/club/soc
|
|
|
|
let role = match roles_name.get(&committee.name) {
|
|
|
|
Some(x) => {Some(x.to_owned())}
|
|
|
|
None => {
|
|
|
|
// create teh role if it does not exist
|
|
|
|
match server.create_role(&ctx, |r| r.hoist(false).mentionable(true).name(&committee.name)).await{
|
|
|
|
Ok(x) => { Some(x) }
|
|
|
|
Err(_) => {None}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// so if the role exists
|
|
|
|
if let Some(r) = role {
|
|
|
|
committee_roles.push(r.id);
|
|
|
|
|
|
|
|
for id_wolves in &committee.committee {
|
|
|
|
// ID in this is the wolves ID, so we need to get a matching discord ID (if one exists)
|
|
|
|
if let Some(x) = get_server_member_discord(&db, id_wolves).await {
|
|
|
|
if let Some(member_tmp) = x.discord {
|
|
|
|
let values = users_roles.entry(member_tmp).or_insert(vec![]);
|
|
|
|
values.push(r.id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// now we have a map of all users that should get roles time to go through all the folks on teh server
|
|
|
|
for member in members {
|
|
|
|
let roles_required = match users_roles.get(&member.user.id) {
|
|
|
|
None => {
|
|
|
|
vec![]
|
|
|
|
}
|
|
|
|
Some(x) => {
|
|
|
|
let mut combined = x.to_owned();
|
|
|
|
// this is the main role, since it provides access to everything.
|
|
|
|
combined.push(committee_member);
|
|
|
|
combined
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// get a list of all the roles to remove from someone
|
|
|
|
let mut roles_rem = vec![];
|
|
|
|
for role in &committee_roles {
|
|
|
|
if !roles_required.contains(role) {
|
|
|
|
roles_rem.push(role.to_owned());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !roles_rem.is_empty() {
|
|
|
|
member.remove_roles(&ctx, &roles_rem).await.unwrap_or_default();
|
|
|
|
}
|
|
|
|
|
|
|
|
if !roles_required.is_empty() {
|
|
|
|
// these roles are flavor roles, only there to make folks mentionable
|
|
|
|
member.add_roles(&ctx, &roles_required).await.unwrap_or_default();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn get_committees(db: &Pool<Sqlite>) -> Vec<Committees> {
|
|
|
|
sqlx::query_as::<_, Committees>(
|
|
|
|
r#"
|
|
|
|
SELECT *
|
|
|
|
FROM committees
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.fetch_all(db)
|
|
|
|
.await
|
|
|
|
.unwrap_or_default()
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn get_server_member_discord(db: &Pool<Sqlite>, user: &i64) -> Option<Wolves> {
|
|
|
|
sqlx::query_as::<_, Wolves>(
|
|
|
|
r#"
|
|
|
|
SELECT *
|
|
|
|
FROM wolves
|
|
|
|
WHERE id_wolves = ?
|
|
|
|
"#,
|
|
|
|
)
|
|
|
|
.bind(user)
|
|
|
|
.fetch_one(db)
|
|
|
|
.await
|
|
|
|
.ok()
|
|
|
|
}
|
|
|
|
}
|