Improve osu (#10)

* Add rank event parsing

* Refactor osu announcer

* Increase api limits

* Register user is locked
This commit is contained in:
Natsu Kagami 2021-01-22 21:54:01 +09:00 committed by GitHub
parent 145cb01bd0
commit f05afb2b80
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 509 additions and 197 deletions

View file

@ -23,6 +23,7 @@ mod db;
pub(crate) mod embeds;
mod hook;
pub(crate) mod oppai_cache;
mod register_user;
mod server_rank;
use db::OsuUser;
@ -95,6 +96,7 @@ pub fn setup(
catch,
mania,
save,
forcesave,
recent,
last,
check,
@ -168,14 +170,32 @@ pub async fn save(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult
let user: Option<User> = osu.user(UserID::Auto(user), |f| f).await?;
match user {
Some(u) => {
OsuSavedUsers::open(&*data).borrow_mut()?.insert(
msg.author.id,
OsuUser {
id: u.id,
last_update: chrono::Utc::now(),
pp: vec![],
},
);
let check_beatmap_id = register_user::user_register_beatmap_id(&u);
let check = osu
.user_recent(UserID::ID(u.id), |f| f.mode(Mode::Std).limit(1))
.await?
.into_iter()
.take(1)
.any(|s| s.beatmap_id == check_beatmap_id);
if !check {
let msg = msg.reply(&ctx, format!("To set your osu username, please make your most recent play be the following map: `/b/{}` in **osu! standard** mode! It does **not** have to be a pass.", check_beatmap_id));
let beatmap = osu
.beatmaps(
crate::request::BeatmapRequestKind::Beatmap(check_beatmap_id),
|f| f,
)
.await?
.into_iter()
.next()
.unwrap();
msg.await?
.edit(&ctx, |f| {
f.embed(|e| beatmap_embed(&beatmap, Mode::Std, Mods::NOMOD, None, e))
})
.await?;
return Ok(());
}
add_user(msg.author.id, u.id, &*data)?;
msg.reply(
&ctx,
MessageBuilder::new()
@ -192,6 +212,55 @@ pub async fn save(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult
Ok(())
}
#[command]
#[description = "Save the given username as someone's username."]
#[owners_only]
#[usage = "[ping user]/[username or user_id]"]
#[num_args(2)]
pub async fn forcesave(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
let data = ctx.data.read().await;
let osu = data.get::<OsuClient>().unwrap();
let target = args.single::<serenity::model::id::UserId>()?;
let user = args.single::<String>()?;
let user: Option<User> = osu.user(UserID::Auto(user), |f| f).await?;
match user {
Some(u) => {
add_user(target, u.id, &*data)?;
msg.reply(
&ctx,
MessageBuilder::new()
.push("user has been set to ")
.push_mono_safe(u.username)
.build(),
)
.await?;
}
None => {
msg.reply(&ctx, "user not found...").await?;
}
}
Ok(())
}
fn add_user(target: serenity::model::id::UserId, user_id: u64, data: &TypeMap) -> Result<()> {
OsuSavedUsers::open(data).borrow_mut()?.insert(
target,
OsuUser {
id: user_id,
last_update: chrono::Utc::now(),
pp: vec![],
},
);
OsuUserBests::open(data)
.borrow_mut()?
.iter_mut()
.for_each(|(_, r)| {
r.remove(&target);
});
Ok(())
}
struct ModeArg(Mode);
impl FromStr for ModeArg {
@ -438,7 +507,7 @@ pub async fn recent(ctx: &Context, msg: &Message, mut args: Args) -> CommandResu
"{}: here is the play that you requested",
msg.author
))
.embed(|m| score_embed(&recent_play, &beatmap_mode, &content, &user, None, m))
.embed(|m| score_embed(&recent_play, &beatmap_mode, &content, &user).build(m))
})
.await?;
@ -537,7 +606,7 @@ pub async fn check(ctx: &Context, msg: &Message, mut args: Args) -> CommandResul
for score in scores.iter() {
msg.channel_id
.send_message(&ctx, |c| {
c.embed(|m| score_embed(&score, &bm, &content, &user, None, m))
c.embed(|m| score_embed(&score, &bm, &content, &user).build(m))
})
.await?;
}
@ -601,7 +670,11 @@ pub async fn top(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult
"{}: here is the play that you requested",
msg.author
))
.embed(|m| score_embed(&top_play, &beatmap, &content, &user, Some(rank), m))
.embed(|m| {
score_embed(&top_play, &beatmap, &content, &user)
.top_record(rank)
.build(m)
})
})
.await?;