Split code up

This commit is contained in:
Sakuhl 2018-01-13 11:24:53 +01:00
parent c4ecfdd67b
commit 84a114b339
5 changed files with 384 additions and 341 deletions

168
src/commands/feed.rs Normal file
View File

@ -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::<LivefeedListener>(&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::<WarfeedListener>(&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))
}

86
src/commands/guild.rs Normal file
View File

@ -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();
}

78
src/commands/mod.rs Normal file
View File

@ -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();
}
}

33
src/commands/player.rs Normal file
View File

@ -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::<u64>(),
current_server_msg
)
).unwrap();
}

View File

@ -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::<u64>(),
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::<LivefeedListener>(&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::<WarfeedListener>(&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();
}