aboutsummaryrefslogtreecommitdiff
path: root/src/game.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/game.rs')
-rw-r--r--src/game.rs176
1 files changed, 107 insertions, 69 deletions
diff --git a/src/game.rs b/src/game.rs
index 0f6637e..362e304 100644
--- a/src/game.rs
+++ b/src/game.rs
@@ -2,12 +2,12 @@ use std::{
convert::Infallible,
fs,
iter,
+ path::PathBuf,
result::Result as StdResult,
str::{
self,
FromStr,
},
- path::PathBuf,
};
use fnv::{
@@ -44,27 +44,20 @@ use anyhow::{
Error,
};
use lazy_static::lazy_static;
+use serenity::framework::standard::CommandResult;
use crate::{
- util::CtxExt,
+ util,
Result,
CONFIG,
};
-pub use self::GAME_GROUP as GROUP;
+pub use self::Game as GROUP;
-group!({
- name: "game",
- options: {
- only_in: "guild",
- },
- commands: [
- game,
- installedgame,
- ownedgame,
- updategaem,
- ],
-});
+#[group]
+#[prefix = "game"]
+#[commands(game, installedgame, ownedgame, updategaem)]
+pub struct Game;
lazy_static! {
static ref SPREADSHEET_URL: Url = Url::parse(&format!(
@@ -101,7 +94,8 @@ lazy_static! {
static ref USER_INFO_MAP: FnvHashMap<String, ProfileInfo> = {
let v: Vec<UserInfo> = serde_json::from_str(&USER_MAP_STR).unwrap();
- let result = v.into_iter()
+ let result = v
+ .into_iter()
.map(|ui| {
let UserInfo {
name,
@@ -112,7 +106,11 @@ lazy_static! {
})
.collect::<FnvHashMap<_, _>>();
- log::info!("loaded user info for {} users ({:#?})", result.len(), result.keys().collect::<Vec<_>>());
+ log::info!(
+ "loaded user info for {} users ({:#?})",
+ result.len(),
+ result.keys().collect::<Vec<_>>()
+ );
result
};
@@ -120,14 +118,16 @@ lazy_static! {
USER_INFO_MAP
.clone()
.into_iter()
- .map(|(name, profile)| (UserId(profile.discord_user_id), name))
+ .map(|(name, profile)| (UserId::new(profile.discord_user_id), name))
.collect::<FnvHashMap<_, _>>()
};
static ref STEAM_MAP: FnvHashMap<UserId, u64> = {
USER_INFO_MAP
.clone()
.into_iter()
- .filter_map(|(_, profile)| profile.steam_id.map(|sid| (UserId(profile.discord_user_id), sid)))
+ .filter_map(|(_, profile)| {
+ profile.steam_id.map(|sid| (UserId::new(profile.discord_user_id), sid))
+ })
.collect::<FnvHashMap<_, _>>()
};
static ref ALPHABET: Vec<char> = (0..26).map(|x| (x + b'a') as char).collect();
@@ -163,13 +163,13 @@ impl FromStr for GameStatus {
#[command]
#[aliases("installedgaem")]
-pub fn installedgame(ctx: &mut Context, msg: &Message, args: Args) -> Result<()> {
+pub async fn installedgame(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
_game(ctx, msg, args, GameStatus::Installed)
}
#[command]
#[aliases("ownedgaem")]
-pub fn ownedgame(ctx: &mut Context, msg: &Message, args: Args) -> Result<()> {
+pub async fn ownedgame(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
_game(ctx, msg, args, GameStatus::NotInstalled)
}
@@ -186,30 +186,34 @@ pub fn get_user_id<S: AsRef<str>>(g: &Guild, s: S) -> StdResult<UserId, UserLook
let s = s.as_ref().trim_start_matches("@").to_lowercase();
if let Some(info) = USER_INFO_MAP.get(&s) {
- return Ok(UserId(info.discord_user_id));
+ return Ok(UserId::new(info.discord_user_id));
}
let nicks = g.members_nick_containing(&s, false, false);
{
- let exact_match = nicks.iter().find(|m| m.user.read().name.to_lowercase() == s);
+ let exact_match = nicks.iter().find(|(m, _)| m.display_name().to_lowercase() == s);
- if let Some(m) = exact_match {
- return Ok(m.user_id());
+ if let Some((m, _)) = exact_match {
+ return Ok(m.user.id);
}
}
let usernames = g.members_username_containing(&s, false, false);
{
- let exact_match = usernames.iter().find(|m| m.user.read().name.to_lowercase() == s);
+ let exact_match = usernames.iter().find(|(m, _)| m.user.name.to_lowercase() == s);
- if let Some(m) = exact_match {
- return Ok(m.user_id());
+ if let Some((m, _)) = exact_match {
+ return Ok(m.user.id);
}
}
- let opts = nicks.into_iter().chain(usernames.into_iter()).map(|member| member.user_id()).collect::<FnvHashSet<_>>();
+ let opts = nicks
+ .into_iter()
+ .chain(usernames.into_iter())
+ .map(|(member, _)| member.user.id)
+ .collect::<FnvHashSet<_>>();
match opts.len() {
0 => Err(UserLookupError::NotFound),
@@ -220,16 +224,19 @@ pub fn get_user_id<S: AsRef<str>>(g: &Guild, s: S) -> StdResult<UserId, UserLook
#[command]
#[aliases("gaem")]
-fn game(ctx: &mut Context, msg: &Message, args: Args) -> Result<()> {
- _game(ctx, msg, args, GameStatus::Installed)
+async fn game(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
+ _game(ctx, msg, args, GameStatus::Installed).await
}
-fn _game(ctx: &mut Context, msg: &Message, mut args: Args, min_status: GameStatus) -> Result<()> {
- let guild = msg.channel_id.to_channel(&ctx)?.guild().ok_or(anyhow!("couldn't find guild"))?;
-
- let guild = guild.read().guild(&ctx).ok_or(anyhow!("couldn't find guild"))?;
-
- let guild = guild.read();
+async fn _game(
+ ctx: &Context,
+ msg: &Message,
+ mut args: Args,
+ min_status: GameStatus,
+) -> CommandResult {
+ let guild =
+ msg.channel_id.to_channel(&ctx).await?.guild().ok_or(anyhow!("couldn't find guild"))?;
+ let guild = guild.guild(&ctx).ok_or_else(|| anyhow!("couldn't find guild"))?;
let user_args: Vec<String> = if args.rest().is_empty() {
Vec::new()
@@ -248,12 +255,22 @@ fn _game(ctx: &mut Context, msg: &Message, mut args: Args, min_status: GameStatu
match possible {
Err(UserLookupError::NotFound) => {
- let _ = ctx.send(msg.channel_id, &format!("didn't recognize {}", &u), msg.tts);
+ let _ = util::send(
+ ctx,
+ msg.channel_id,
+ &format!("didn't recognize {}", &u),
+ msg.tts,
+ );
None
},
Ok(x) => Some(x),
Err(UserLookupError::Ambiguous(x)) => {
- let _ = ctx.send(msg.channel_id, &format!("too many matches ({}) for {}", x, &u), msg.tts);
+ let _ = util::send(
+ ctx,
+ msg.channel_id,
+ &format!("too many matches ({}) for {}", x, &u),
+ msg.tts,
+ );
None
},
}
@@ -294,11 +311,11 @@ fn _game(ctx: &mut Context, msg: &Message, mut args: Args, min_status: GameStatu
if inferred && users.len() < 2 || !inferred && users.len() < 1 {
info!("too few known users to make game comparison");
- ctx.send(msg.channel_id, "yer too lonely", msg.tts)?;
+ util::send(ctx, msg.channel_id, "yer too lonely", msg.tts).await?;
return Ok(());
}
- let data = load_spreadsheet()?;
+ let data = load_spreadsheet().await?;
let user_indexes = (0..data.len())
.filter_map(|i| {
@@ -328,7 +345,8 @@ fn _game(ctx: &mut Context, msg: &Message, mut args: Args, min_status: GameStatu
.collect::<FnvHashMap<_, _>>();
(1..data[*col].len()).for_each(|i| {
- let status = &data_ref[*col][i].parse::<GameStatus>().unwrap_or(GameStatus::Unknown);
+ let status =
+ &data_ref[*col][i].parse::<GameStatus>().unwrap_or(GameStatus::Unknown);
let game = &data_ref[0][i];
game_map.get_mut(status).unwrap().insert(game);
@@ -338,23 +356,29 @@ fn _game(ctx: &mut Context, msg: &Message, mut args: Args, min_status: GameStatu
})
.collect::<FnvHashMap<_, _>>();
- let statuses = vec![GameStatus::Installed, GameStatus::NotOwned, GameStatus::NotInstalled, GameStatus::Unknown]
- .into_iter()
- .filter(|s| s <= &min_status)
- .collect::<Vec<_>>();
+ let statuses = vec![
+ GameStatus::Installed,
+ GameStatus::NotOwned,
+ GameStatus::NotInstalled,
+ GameStatus::Unknown,
+ ]
+ .into_iter()
+ .filter(|s| s <= &min_status)
+ .collect::<Vec<_>>();
let mut games_in_common = {
let game_map = user_games.values().nth(0).unwrap();
- statuses
- .iter()
- .fold(iter::empty().collect::<FnvHashSet<_>>(), |acc, s| acc.union(&game_map[s]).cloned().collect())
+ statuses.iter().fold(iter::empty().collect::<FnvHashSet<_>>(), |acc, s| {
+ acc.union(&game_map[s]).cloned().collect()
+ })
};
for (_user, game_map) in user_games.iter() {
- let relevant_games = statuses
- .iter()
- .fold(iter::empty().collect::<FnvHashSet<_>>(), |acc, s| acc.union(&game_map[s]).cloned().collect());
+ let relevant_games =
+ statuses.iter().fold(iter::empty().collect::<FnvHashSet<_>>(), |acc, s| {
+ acc.union(&game_map[s]).cloned().collect()
+ });
games_in_common = games_in_common.intersection(&relevant_games).cloned().collect();
}
@@ -366,12 +390,12 @@ fn _game(ctx: &mut Context, msg: &Message, mut args: Args, min_status: GameStatu
games_formatted = "**LITERALLY NOTHING**".to_owned();
}
- ctx.send(msg.channel_id, &games_formatted, msg.tts)?;
+ util::send(ctx, msg.channel_id, &games_formatted, msg.tts).await?;
Ok(())
}
-fn load_spreadsheet() -> Result<Vec<Vec<String>>> {
+async fn load_spreadsheet() -> Result<Vec<Vec<String>>> {
let mut u = SPREADSHEET_URL.clone();
u.query_pairs_mut()
@@ -382,7 +406,7 @@ fn load_spreadsheet() -> Result<Vec<Vec<String>>> {
let req = reqwest::Request::new(reqwest::Method::GET, u);
let client = reqwest::Client::new();
- let mut resp = client.execute(req)?;
+ let resp = client.execute(req).await?;
#[derive(Deserialize)]
struct Resp {
@@ -395,14 +419,14 @@ fn load_spreadsheet() -> Result<Vec<Vec<String>>> {
values: Vec<Vec<String>>,
}
- let resp = resp.json::<Resp>()?;
+ let resp = resp.json::<Resp>().await?;
Ok(resp.value_ranges.into_iter().next().unwrap().values)
}
#[command]
#[aliases("updategame")]
-pub fn updategaem(ctx: &mut Context, msg: &Message, mut args: Args) -> Result<()> {
+pub async fn updategaem(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
use regex::Regex;
let arg_user = args.single_quoted::<String>();
@@ -412,7 +436,8 @@ pub fn updategaem(ctx: &mut Context, msg: &Message, mut args: Args) -> Result<()
} else {
use std::borrow::Borrow;
- let guild = msg.channel_id.to_channel(&ctx)?.guild().ok_or(anyhow!("couldn't find guild"))?;
+ let guild =
+ msg.channel_id.to_channel(&ctx)?.guild().ok_or(anyhow!("couldn't find guild"))?;
let guild = guild.read().guild(&ctx).ok_or(anyhow!("couldn't find guild"))?;
@@ -425,21 +450,24 @@ pub fn updategaem(ctx: &mut Context, msg: &Message, mut args: Args) -> Result<()
let username = match DISCORD_MAP.get(&user) {
Some(s) => s,
- None => return ctx.send(msg.channel_id, "WHO THE FUCK ARE YE", msg.tts),
+ None => return util::send(ctx, msg.channel_id, "WHO THE FUCK ARE YE", msg.tts).await,
};
let steam_id = match STEAM_MAP.get(&user) {
Some(u) => u,
- None => return ctx.send(msg.channel_id, "WHO ARE YE ON STEAM", msg.tts),
+ None => return util::send(ctx, msg.channel_id, "WHO ARE YE ON STEAM", msg.tts).await,
};
- let spreadsheet = load_spreadsheet()?;
+ let spreadsheet = load_spreadsheet().await?;
- let user_column = (0..spreadsheet.len()).find(|x| spreadsheet[*x][0].to_lowercase() == username.to_lowercase());
+ let user_column = (0..spreadsheet.len())
+ .find(|x| spreadsheet[*x][0].to_lowercase() == username.to_lowercase());
let user_column = match user_column {
Some(c) => &spreadsheet[c][1..],
- None => return ctx.send(msg.channel_id, "YER NOT IN THE SPREADSHEET", msg.tts),
+ None => {
+ return util::send(ctx, msg.channel_id, "YER NOT IN THE SPREADSHEET", msg.tts).await;
+ },
};
lazy_static! {
@@ -452,14 +480,16 @@ pub fn updategaem(ctx: &mut Context, msg: &Message, mut args: Args) -> Result<()
Some(c) => &spreadsheet[c][1..],
None => {
error!("didn't find an appid column in the spreadsheet");
- return ctx.send(msg.channel_id, "SPREADSHEET BROKE", msg.tts);
+ return util::send(ctx, msg.channel_id, "SPREADSHEET BROKE", msg.tts).await;
},
};
let missing_appids = (0..user_column.len())
.filter_map(|x| user_column[x].parse::<GameStatus>().ok().map(|s| (x, s)))
.filter(|(_, s)| *s == GameStatus::Unknown || *s == GameStatus::NotOwned)
- .filter_map(|(x, _)| appid_column.get(x).and_then(|s| s.parse::<u64>().ok().map(|appid| (appid, x))));
+ .filter_map(|(x, _)| {
+ appid_column.get(x).and_then(|s| s.parse::<u64>().ok().map(|appid| (appid, x)))
+ });
let mut u = Url::parse("https://api.steampowered.com/IPlayerService/GetOwnedGames/v1")?;
@@ -487,8 +517,15 @@ pub fn updategaem(ctx: &mut Context, msg: &Message, mut args: Args) -> Result<()
play_time: u64,
}
- let games_owned =
- reqwest::get(u)?.json::<SteamResp>()?.response.games.into_iter().map(|ge| ge.app_id).collect::<FnvHashSet<_>>();
+ let games_owned = reqwest::get(u)
+ .await?
+ .json::<SteamResp>()
+ .await?
+ .response
+ .games
+ .into_iter()
+ .map(|ge| ge.app_id)
+ .collect::<FnvHashSet<_>>();
let found_games = missing_appids
.filter_map(|(ai, x)| {
@@ -501,7 +538,8 @@ pub fn updategaem(ctx: &mut Context, msg: &Message, mut args: Args) -> Result<()
.join("\n");
if found_games.len() > 0 {
- ctx.send(
+ util::send(
+ ctx,
msg.channel_id,
&format!(
"{} games owned on steam that are missing from the list:\n{}",
@@ -511,6 +549,6 @@ pub fn updategaem(ctx: &mut Context, msg: &Message, mut args: Args) -> Result<()
msg.tts,
)
} else {
- ctx.send(msg.channel_id, "up to date", msg.tts)
+ util::send(ctx, msg.channel_id, "up to date", msg.tts)
}
}