From 84a114b3395cdb4cd94f2df239e3b230d3381568 Mon Sep 17 00:00:00 2001 From: Sakuhl <2012collector@gmail.com> Date: Sat, 13 Jan 2018 11:24:53 +0100 Subject: [PATCH] Split code up --- src/commands/feed.rs | 168 +++++++++++++++++++ src/commands/guild.rs | 86 ++++++++++ src/commands/mod.rs | 78 +++++++++ src/commands/player.rs | 33 ++++ src/main.rs | 360 +++-------------------------------------- 5 files changed, 384 insertions(+), 341 deletions(-) create mode 100644 src/commands/feed.rs create mode 100644 src/commands/guild.rs create mode 100644 src/commands/mod.rs create mode 100644 src/commands/player.rs diff --git a/src/commands/feed.rs b/src/commands/feed.rs new file mode 100644 index 0000000..7e82b73 --- /dev/null +++ b/src/commands/feed.rs @@ -0,0 +1,168 @@ +use ::wynncraft; + +use serenity::model::*; + +use ::diesel; +use ::diesel::prelude::*; +use ::diesel::pg::PgConnection; + +use ::serde_json; +use ::serde_json::Value; + +use ::reqwest; + +use ::std::{env, thread}; + +pub fn territory_livefeed() { + use models::LivefeedListener; + use schema::livefeedlisteners::dsl::*; + + let connection = establish_connection(); + + let resp = reqwest::get("https://api.wynncraft.com/public_api.php?action=territoryList").unwrap(); + + let mut territories: Value = serde_json::from_reader(resp).unwrap(); + + loop { + thread::sleep_ms(10_000); // 10 seconds + let resp = reqwest::get("https://api.wynncraft.com/public_api.php?action=territoryList").unwrap(); + + let new_territories: Value = serde_json::from_reader(resp).unwrap(); + + for key in territories.get("territories").unwrap().as_object().unwrap().keys() { + let value = territories.get("territories").unwrap().as_object().unwrap().get(key).unwrap(); + let new_value = new_territories.get("territories").unwrap().as_object().unwrap().get(key).unwrap(); + if value.get("guild").unwrap().as_str().unwrap() != new_value.get("guild").unwrap().as_str().unwrap() { + for listener in livefeedlisteners + .load::(&connection) + .expect("Error loading listeners") { + let _ = ChannelId(listener.id as u64).say(format!("{}: ~~{}~~ -> **{}**", + value.get("territory").unwrap().as_str().unwrap(), + value.get("guild").unwrap().as_str().unwrap(), + new_value.get("guild").unwrap().as_str().unwrap() + )); + } + } + } + + territories = new_territories; + } +} + +pub fn war_livefeed() { + use models::WarfeedListener; + use schema::warfeedlisteners::dsl::*; + + let connection = establish_connection(); + + let resp = reqwest::get("https://api.wynncraft.com/public_api.php?action=onlinePlayers").unwrap(); + + let mut players: Value = serde_json::from_reader(resp).unwrap(); + + loop { + thread::sleep_ms(50_000); // 50 seconds + let resp = reqwest::get("https://api.wynncraft.com/public_api.php?action=onlinePlayers").unwrap(); + + let new_players: Value = serde_json::from_reader(resp).unwrap(); + + for key in new_players.as_object().unwrap().keys() { + if key == "request" { + continue; + } + if !key.starts_with("WAR") { + continue; + } + let war_players = new_players.get(key).unwrap().as_array().unwrap(); + for player in war_players.into_iter() { + let old_server = players.as_object().unwrap().iter().map(|(server, players)| { + if server == "request" { + (&**server, false) + } else { + (&**server, players.as_array().unwrap().contains(player)) + } + }).filter(|&(_, is_in_it)| is_in_it).next().unwrap_or(("WC?", true)).0; + if old_server != key { + let player = player.as_str().unwrap(); + let guild = wynncraft::player(player).unwrap().guild.name; + for listener in warfeedlisteners + .load::(&connection) + .expect("Error loading listeners") { + let _ = ChannelId(listener.id as u64).say(format!("{} ({}): ~~{}~~ -> **{}**", + player.replace('_', "\\_"), + guild, + old_server, + key + )); + } + } + } + } + + players = new_players; + } +} + +pub fn wc_livefeed(msg: Message) { + use models::LivefeedListener; + use schema::livefeedlisteners; + + let connection = establish_connection(); + + diesel::insert_into(livefeedlisteners::table) + .values(&LivefeedListener { + id: msg.channel_id.0 as i64 + }) + .execute(&connection) + .expect("Error saving new listener"); + + msg.channel_id.say("Success!").unwrap(); +} + +pub fn wc_unlivefeed(msg: Message) { + use schema::livefeedlisteners::dsl::*; + + let connection = establish_connection(); + + let channel_id = msg.channel_id.0 as i64; + diesel::delete(livefeedlisteners.filter(id.eq(channel_id))) + .execute(&connection) + .expect("Error deleting listener"); + + msg.channel_id.say("Success!").unwrap(); +} + +pub fn wc_warfeed(msg: Message) { + use models::WarfeedListener; + use schema::warfeedlisteners; + + let connection = establish_connection(); + + diesel::insert_into(warfeedlisteners::table) + .values(&WarfeedListener { + id: msg.channel_id.0 as i64 + }) + .execute(&connection) + .expect("Error saving new listener"); + + msg.channel_id.say("Success!").unwrap(); +} + +pub fn wc_unwarfeed(msg: Message) { + use schema::warfeedlisteners::dsl::*; + + let connection = establish_connection(); + + let channel_id = msg.channel_id.0 as i64; + diesel::delete(warfeedlisteners.filter(id.eq(channel_id))) + .execute(&connection) + .expect("Error deleting listener"); + + msg.channel_id.say("Success!").unwrap(); +} + +fn establish_connection() -> PgConnection { + let database_url = env::var("DATABASE_URL") + .expect("DATABASE_URL must be set"); + PgConnection::establish(&database_url) + .expect(&format!("Error connecting to {}", database_url)) +} \ No newline at end of file diff --git a/src/commands/guild.rs b/src/commands/guild.rs new file mode 100644 index 0000000..cad3600 --- /dev/null +++ b/src/commands/guild.rs @@ -0,0 +1,86 @@ +use ::wynncraft; + +use serenity::model::*; + +use ::reqwest; + +use ::serde_json; +use ::serde_json::Value; + +pub fn wc_guild(msg: Message) { + let guild = &msg.content[9..]; + + let guild = if guild.len() <= 3 { + let guild = wynncraft::guild_by_prefix(guild).unwrap().unwrap(); + wynncraft::guild(&guild.name).unwrap() + } else { + wynncraft::guild(guild).unwrap() + }; + + let resp = reqwest::get("https://api.wynncraft.com/public_api.php?action=territoryList").unwrap(); + assert!(resp.status().is_success()); + + let territories: Value = serde_json::from_reader(resp).unwrap(); + + let mut message = String::new(); + let mut territories_count = 0; + for value in territories.get("territories").unwrap().as_object().unwrap().values() { + if value.get("guild").unwrap().as_str().unwrap() == guild.name { + message.push_str(&format!(" +**Territory**: {}", + value.get("territory").unwrap().as_str().unwrap() + )); + territories_count += 1; + } + } + + if let Err(_) = msg.channel_id.say( + format!( +"**Guild**: {} +**prefix**: {} +**Created**: {} +**Level**: {} +**Members**: {}", + guild.name, + guild.prefix, + guild.created_friendly, + guild.level, + guild.members.len() + ) + &message + ) { + msg.channel_id.say( + format!( +"**Guild**: {} +**prefix**: {} +**Created**: {} +**Level**: {} +**Members**: {} +**Territories**: {}", + guild.name, + guild.prefix, + guild.created_friendly, + guild.level, + guild.members.len(), + territories_count + ) + ).unwrap(); + }; +} + +pub fn wc_topguilds(msg: Message) { + let limit: usize = msg.content[13..].parse().unwrap(); + + wc_topguilds_limit(msg, limit); +} + +pub fn wc_topguilds_limit(msg: Message, limit: usize) { + let leaderboard = wynncraft::guild_leaderboard().unwrap(); + + let mut text = "```".to_owned(); + for guild in leaderboard.data[..limit].into_iter() { + text += &format!("#{:02}: {:18} [{:3}] - {:2} territories\n", guild.num, guild.name, guild.prefix, guild.territories) + } + text += "```"; + + msg.channel_id.say(text).unwrap(); +} \ No newline at end of file diff --git a/src/commands/mod.rs b/src/commands/mod.rs new file mode 100644 index 0000000..c58174f --- /dev/null +++ b/src/commands/mod.rs @@ -0,0 +1,78 @@ +use ::serenity; +use ::serenity::model::*; + +use ::reqwest; + +use ::serde_json; +use ::serde_json::Value; + +pub mod player; +pub mod guild; +pub mod feed; + +pub use player::*; +pub use guild::*; +pub use feed::{wc_livefeed, wc_unlivefeed, wc_warfeed, wc_unwarfeed}; + +pub fn wc_status(msg: Message) { + let resp = reqwest::get("https://api.wynncraft.com/public_api.php?action=onlinePlayersSum").unwrap(); + + let value: Value = serde_json::from_reader(resp).unwrap(); + + msg.channel_id.say( + format!("{} players online", value.get("players_online").unwrap().as_u64().unwrap()) + ).unwrap(); +} + +pub fn wc_territory(msg: Message) { + let territory = &msg.content[13..]; + + let resp = reqwest::get("https://api.wynncraft.com/public_api.php?action=territoryList").unwrap(); + assert!(resp.status().is_success()); + + let territories: Value = serde_json::from_reader(resp).unwrap(); + + let mut message = String::new(); + for value in territories.get("territories").unwrap().as_object().unwrap().values() { + if value.get("territory").unwrap().as_str().unwrap().contains(territory) { + message.push_str(&format!(" +**Territory**: {} +**Owner**: {} +**Acquired at**: {} +", + value.get("territory").unwrap().as_str().unwrap(), + value.get("guild").unwrap().as_str().unwrap(), + value.get("acquired").unwrap().as_str().unwrap() + )) + } + } + + if !message.is_empty() { + msg.channel_id.say( + message + ).unwrap(); + } +} + +pub fn wc_info(msg: Message) { + let guilds = serenity::http::get_current_user().unwrap().guilds().unwrap().len(); + msg.channel_id.say(format!("Developer: Wurst#1783 +Forum thread: https://forums.wynncraft.com/threads/discord-bot.212142/ +Version: {} +Servers: {}", env!("CARGO_PKG_VERSION"), guilds)).unwrap(); +} + +pub fn wc_crop(msg: Message) { + let url = &msg.content[8..]; + let new_url = reqwest::get(&format!("https://wynncraft-autocrop.herokuapp.com/crop?url={}", url)).unwrap().text().unwrap(); + msg.channel_id.say(&new_url).unwrap(); +} + +pub fn wc_crop_discord_upload(msg: Message) { + let last = &msg.channel_id.messages(|g| g.before(msg.id).limit(1)).unwrap()[0]; + for attachment in &last.attachments { + let url = &attachment.url; + let new_url = reqwest::get(&format!("https://wynncraft-autocrop.herokuapp.com/crop?url={}", url)).unwrap().text().unwrap(); + msg.channel_id.say(&new_url).unwrap(); + } +} \ No newline at end of file diff --git a/src/commands/player.rs b/src/commands/player.rs new file mode 100644 index 0000000..a4d19a3 --- /dev/null +++ b/src/commands/player.rs @@ -0,0 +1,33 @@ +use ::wynncraft; + +use serenity::model::*; + +pub fn wc_player(msg: Message) { + let player = &msg.content[10..]; + + let player = wynncraft::player(player).unwrap(); + + let current_server_msg = if player.current_server != "null" { + format!("\n**Currently online on**: {}", player.current_server) + } else { + String::new() + }; + + msg.channel_id.say( + format!( +"**Player name**: {} +**Guild**: {} +**Playtime**: {} hours +**Kills**: {} mobs & {} players +**Chests looted**: {} +**Total level**: {}{}", + player.username, + player.guild.name, + player.playtime / 60, + player.global.mobs_killed, player.global.pvp_kills, + player.global.chests_found, + player.classes.iter().map(|(_, x)| x.level).sum::(), + current_server_msg + ) + ).unwrap(); +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 9eac6a0..564ce72 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,12 +7,9 @@ use serenity::model::*; extern crate reqwest; extern crate serde_json; -use serde_json::Value; #[macro_use] extern crate diesel; -use diesel::prelude::*; -use diesel::pg::PgConnection; use std::env; use std::panic; @@ -20,6 +17,8 @@ use std::thread; mod models; mod schema; +mod commands; +use commands::*; struct Handler; @@ -70,345 +69,13 @@ impl EventHandler for Handler { } } -fn wc_guild(msg: Message) { - let guild = &msg.content[9..]; - - let guild = if guild.len() <= 3 { - let guild = wynncraft::guild_by_prefix(guild).unwrap().unwrap(); - wynncraft::guild(&guild.name).unwrap() - } else { - wynncraft::guild(guild).unwrap() - }; - - let resp = reqwest::get("https://api.wynncraft.com/public_api.php?action=territoryList").unwrap(); - assert!(resp.status().is_success()); - - let territories: Value = serde_json::from_reader(resp).unwrap(); - - let mut message = String::new(); - let mut territories_count = 0; - for value in territories.get("territories").unwrap().as_object().unwrap().values() { - if value.get("guild").unwrap().as_str().unwrap() == guild.name { - message.push_str(&format!(" -**Territory**: {}", - value.get("territory").unwrap().as_str().unwrap() - )); - territories_count += 1; - } - } - - if let Err(_) = msg.channel_id.say( - format!( -"**Guild**: {} -**prefix**: {} -**Created**: {} -**Level**: {} -**Members**: {}", - guild.name, - guild.prefix, - guild.created_friendly, - guild.level, - guild.members.len() - ) + &message - ) { - msg.channel_id.say( - format!( -"**Guild**: {} -**prefix**: {} -**Created**: {} -**Level**: {} -**Members**: {} -**Territories**: {}", - guild.name, - guild.prefix, - guild.created_friendly, - guild.level, - guild.members.len(), - territories_count - ) - ).unwrap(); - }; -} - -fn wc_topguilds(msg: Message) { - let limit: usize = msg.content[13..].parse().unwrap(); - - wc_topguilds_limit(msg, limit); -} - -fn wc_topguilds_limit(msg: Message, limit: usize) { - let leaderboard = wynncraft::guild_leaderboard().unwrap(); - - let mut text = "```".to_owned(); - for guild in leaderboard.data[..limit].into_iter() { - text += &format!("#{:02}: {:18} [{:3}] - {:2} territories\n", guild.num, guild.name, guild.prefix, guild.territories) - } - text += "```"; - - msg.channel_id.say(text).unwrap(); -} - -fn wc_status(msg: Message) { - let resp = reqwest::get("https://api.wynncraft.com/public_api.php?action=onlinePlayersSum").unwrap(); - - let value: Value = serde_json::from_reader(resp).unwrap(); - - msg.channel_id.say( - format!("{} players online", value.get("players_online").unwrap().as_u64().unwrap()) - ).unwrap(); -} - -fn wc_territory(msg: Message) { - let territory = &msg.content[13..]; - - let resp = reqwest::get("https://api.wynncraft.com/public_api.php?action=territoryList").unwrap(); - assert!(resp.status().is_success()); - - let territories: Value = serde_json::from_reader(resp).unwrap(); - - let mut message = String::new(); - for value in territories.get("territories").unwrap().as_object().unwrap().values() { - if value.get("territory").unwrap().as_str().unwrap().contains(territory) { - message.push_str(&format!(" -**Territory**: {} -**Owner**: {} -**Acquired at**: {} -", - value.get("territory").unwrap().as_str().unwrap(), - value.get("guild").unwrap().as_str().unwrap(), - value.get("acquired").unwrap().as_str().unwrap() - )) - } - } - - if !message.is_empty() { - msg.channel_id.say( - message - ).unwrap(); - } -} - -fn wc_player(msg: Message) { - let player = &msg.content[10..]; - - let player = wynncraft::player(player).unwrap(); - - let current_server_msg = if player.current_server != "null" { - format!("\n**Currently online on**: {}", player.current_server) - } else { - String::new() - }; - - msg.channel_id.say( - format!( -"**Player name**: {} -**Guild**: {} -**Playtime**: {} hours -**Kills**: {} mobs & {} players -**Chests looted**: {} -**Total level**: {}{}", - player.username, - player.guild.name, - player.playtime / 60, - player.global.mobs_killed, player.global.pvp_kills, - player.global.chests_found, - player.classes.iter().map(|(_, x)| x.level).sum::(), - current_server_msg - ) - ).unwrap(); -} - -fn wc_livefeed(msg: Message) { - use models::LivefeedListener; - use schema::livefeedlisteners; - - let connection = establish_connection(); - - diesel::insert_into(livefeedlisteners::table) - .values(&LivefeedListener { - id: msg.channel_id.0 as i64 - }) - .execute(&connection) - .expect("Error saving new listener"); - - msg.channel_id.say("Success!").unwrap(); -} - -fn wc_unlivefeed(msg: Message) { - use schema::livefeedlisteners::dsl::*; - - let connection = establish_connection(); - - let channel_id = msg.channel_id.0 as i64; - diesel::delete(livefeedlisteners.filter(id.eq(channel_id))) - .execute(&connection) - .expect("Error deleting listener"); - - msg.channel_id.say("Success!").unwrap(); -} - -fn wc_warfeed(msg: Message) { - use models::WarfeedListener; - use schema::warfeedlisteners; - - let connection = establish_connection(); - - diesel::insert_into(warfeedlisteners::table) - .values(&WarfeedListener { - id: msg.channel_id.0 as i64 - }) - .execute(&connection) - .expect("Error saving new listener"); - - msg.channel_id.say("Success!").unwrap(); -} - -fn wc_unwarfeed(msg: Message) { - use schema::warfeedlisteners::dsl::*; - - let connection = establish_connection(); - - let channel_id = msg.channel_id.0 as i64; - diesel::delete(warfeedlisteners.filter(id.eq(channel_id))) - .execute(&connection) - .expect("Error deleting listener"); - - msg.channel_id.say("Success!").unwrap(); -} - -fn wc_info(msg: Message) { - let guilds = serenity::http::get_current_user().unwrap().guilds().unwrap().len(); - msg.channel_id.say(format!("Developer: Wurst#1783 -Forum thread: https://forums.wynncraft.com/threads/discord-bot.212142/ -Version: {} -Servers: {}", env!("CARGO_PKG_VERSION"), guilds)).unwrap(); -} - -fn wc_crop(msg: Message) { - let url = &msg.content[8..]; - let new_url = reqwest::get(&format!("https://wynncraft-autocrop.herokuapp.com/crop?url={}", url)).unwrap().text().unwrap(); - msg.channel_id.say(&new_url).unwrap(); -} - -fn wc_crop_discord_upload(msg: Message) { - let last = &msg.channel_id.messages(|g| g.before(msg.id).limit(1)).unwrap()[0]; - for attachment in &last.attachments { - let url = &attachment.url; - let new_url = reqwest::get(&format!("https://wynncraft-autocrop.herokuapp.com/crop?url={}", url)).unwrap().text().unwrap(); - msg.channel_id.say(&new_url).unwrap(); - } -} - -fn territory_livefeed() { - use models::LivefeedListener; - use schema::livefeedlisteners::dsl::*; - - let connection = establish_connection(); - - let resp = reqwest::get("https://api.wynncraft.com/public_api.php?action=territoryList").unwrap(); - - let mut territories: Value = serde_json::from_reader(resp).unwrap(); - - loop { - thread::sleep_ms(10_000); // 10 seconds - let resp = reqwest::get("https://api.wynncraft.com/public_api.php?action=territoryList").unwrap(); - - let new_territories: Value = serde_json::from_reader(resp).unwrap(); - - for key in territories.get("territories").unwrap().as_object().unwrap().keys() { - let value = territories.get("territories").unwrap().as_object().unwrap().get(key).unwrap(); - let new_value = new_territories.get("territories").unwrap().as_object().unwrap().get(key).unwrap(); - if value.get("guild").unwrap().as_str().unwrap() != new_value.get("guild").unwrap().as_str().unwrap() { - for listener in livefeedlisteners - .load::(&connection) - .expect("Error loading listeners") { - let _ = ChannelId(listener.id as u64).say(format!("{}: ~~{}~~ -> **{}**", - value.get("territory").unwrap().as_str().unwrap(), - value.get("guild").unwrap().as_str().unwrap(), - new_value.get("guild").unwrap().as_str().unwrap() - )); - } - } - } - - territories = new_territories; - } -} - -fn war_livefeed() { - use models::WarfeedListener; - use schema::warfeedlisteners::dsl::*; - - let connection = establish_connection(); - - let resp = reqwest::get("https://api.wynncraft.com/public_api.php?action=onlinePlayers").unwrap(); - - let mut players: Value = serde_json::from_reader(resp).unwrap(); - - loop { - thread::sleep_ms(50_000); // 50 seconds - let resp = reqwest::get("https://api.wynncraft.com/public_api.php?action=onlinePlayers").unwrap(); - - let new_players: Value = serde_json::from_reader(resp).unwrap(); - - for key in new_players.as_object().unwrap().keys() { - if key == "request" { - continue; - } - if !key.starts_with("WAR") { - continue; - } - let war_players = new_players.get(key).unwrap().as_array().unwrap(); - for player in war_players.into_iter() { - let old_server = players.as_object().unwrap().iter().map(|(server, players)| { - if server == "request" { - (&**server, false) - } else { - (&**server, players.as_array().unwrap().contains(player)) - } - }).filter(|&(_, is_in_it)| is_in_it).next().unwrap_or(("WC?", true)).0; - if old_server != key { - let player = player.as_str().unwrap(); - let guild = wynncraft::player(player).unwrap().guild.name; - for listener in warfeedlisteners - .load::(&connection) - .expect("Error loading listeners") { - let _ = ChannelId(listener.id as u64).say(format!("{} ({}): ~~{}~~ -> **{}**", - player.replace('_', "\\_"), - guild, - old_server, - key - )); - } - } - } - } - - players = new_players; - } -} - fn main() { // Configure the client with your Discord bot token in the environment. let token = env::var("DISCORD_TOKEN").expect("DISCORD_TOKEN must be set"); env::var("DATABASE_URL") .expect("DATABASE_URL must be set"); - thread::Builder::new() - .spawn(|| { - loop { - println!("{:?}", panic::catch_unwind(|| territory_livefeed())); - } - }) - .unwrap(); - - thread::Builder::new() - .spawn(|| { - loop { - println!("{:?}", panic::catch_unwind(|| war_livefeed())); - } - }) - .unwrap(); + start_daemons(); loop { // Create a new instance of the Client, logging in as a bot. This will @@ -426,9 +93,20 @@ fn main() { } } -pub fn establish_connection() -> PgConnection { - let database_url = env::var("DATABASE_URL") - .expect("DATABASE_URL must be set"); - PgConnection::establish(&database_url) - .expect(&format!("Error connecting to {}", database_url)) +fn start_daemons() { + thread::Builder::new() + .spawn(|| { + loop { + println!("{:?}", panic::catch_unwind(|| commands::feed::territory_livefeed())); + } + }) + .unwrap(); + + thread::Builder::new() + .spawn(|| { + loop { + println!("{:?}", panic::catch_unwind(|| commands::feed::war_livefeed())); + } + }) + .unwrap(); } \ No newline at end of file