commit 9f713a6463cd1e5a1c1798f4c711a8e548eb4da6 Author: kageru Date: Wed May 6 19:11:04 2020 +0200 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..6e7ab90 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "vcrole" +version = "0.1.0" +authors = ["kageru "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +lazy_static = "1.4" + +[dependencies.serenity] +default-features = false +# i.e. everything except the bot framework stuff +features = ["builder", "cache", "client", "gateway", "http", "model", "utils", "rustls_backend"] +version = "0.8" diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..b8d4dc9 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,82 @@ +use serenity::model::id::{GuildId, RoleId}; +use serenity::model::prelude::*; +use serenity::prelude::*; +use serenity::Client; +use std::collections::HashMap; +use std::fs::File; +use std::io::{self, BufRead, BufReader}; +#[macro_use] +extern crate lazy_static; + +struct Handler; + +impl EventHandler for Handler { + fn voice_state_update( + &self, + ctx: Context, + guild_id: Option, + old: Option, + new: VoiceState, + ) { + if let Some(gid) = guild_id { + if let Some(rid) = ROLES_BY_SERVER.get(&gid) { + if let Ok(guild) = PartialGuild::get(&ctx.http, gid) { + let mut roles = guild + .member(&ctx.http, new.user_id) + .expect("could not retrieve member") + .roles; + // user just joined the VC -> add the role + if old.is_none() { + roles.push(*rid); + // user is no longer in VC -> remove the role + } else if new.channel_id.is_none() { + roles.retain(|r| r != rid); + } + if let Err(e) = guild.edit_member(&ctx.http, new.user_id, |m| m.roles(roles)) { + println!( + "Could not edit member {} of guild {}, {}", + new.user_id, gid, e + ); + } + } + } + } + } +} + +lazy_static! { + static ref ROLES_BY_SERVER: HashMap = { + std::env::args() + .nth(1) + .expect( + " + Please specify at least one guild-role tuple like + `./bot 'guild_id:role_id;guild_id2:role_id2'`", + ) + .split(';') + .map(|s| s.splitn(2, ':')) + .map(|mut s| { + ( + GuildId { + 0: s.next().unwrap().parse().unwrap(), + }, + RoleId { + 0: s.next().unwrap().parse().unwrap(), + }, + ) + }) + .collect() + }; +} + +fn main() { + println!("Running with config for {} servers", ROLES_BY_SERVER.len()); + let mut client = Client::new(read_token().expect("Could not read secret"), Handler) + .expect("Could not create new client."); + client.start().expect("Could not start client."); +} + +fn read_token() -> io::Result { + let reader = BufReader::new(File::open("secret")?); + reader.lines().next().unwrap() +}