From ee6d50afd9eeaf99916037e4742e1f0e674d90f9 Mon Sep 17 00:00:00 2001 From: HLMC Date: Mon, 6 Jan 2025 14:19:09 +0800 Subject: [PATCH 1/4] feat: judge protect --- prpr/src/bin.rs | 1 + prpr/src/core/chart.rs | 5 ++++- prpr/src/core/note.rs | 1 + prpr/src/judge.rs | 49 ++++++++++++++++++++++++++++++++---------- prpr/src/parse/pec.rs | 1 + prpr/src/parse/pgr.rs | 1 + prpr/src/parse/rpe.rs | 1 + 7 files changed, 47 insertions(+), 12 deletions(-) diff --git a/prpr/src/bin.rs b/prpr/src/bin.rs index 3041107e..6367e6c3 100644 --- a/prpr/src/bin.rs +++ b/prpr/src/bin.rs @@ -339,6 +339,7 @@ impl BinaryData for Note { multiple_hint: false, fake: r.read()?, judge: JudgeStatus::NotJudged, + attr: r.read()?, }) } diff --git a/prpr/src/core/chart.rs b/prpr/src/core/chart.rs index 35fe2bf7..3785acf7 100644 --- a/prpr/src/core/chart.rs +++ b/prpr/src/core/chart.rs @@ -95,7 +95,10 @@ impl Chart { self.lines .iter_mut() .flat_map(|it| it.notes.iter_mut()) - .for_each(|note| note.judge = JudgeStatus::NotJudged); + .for_each(|note| { + note.judge = JudgeStatus::NotJudged; + note.attr = false; + }); for line in &mut self.lines { line.cache.reset(&mut line.notes); } diff --git a/prpr/src/core/note.rs b/prpr/src/core/note.rs index 31f8cbe7..fc90c53e 100644 --- a/prpr/src/core/note.rs +++ b/prpr/src/core/note.rs @@ -41,6 +41,7 @@ pub struct Note { pub multiple_hint: bool, pub fake: bool, pub judge: JudgeStatus, + pub attr: bool, } pub struct RenderConfig<'a> { diff --git a/prpr/src/judge.rs b/prpr/src/judge.rs index 25ca3ef2..ca445a01 100644 --- a/prpr/src/judge.rs +++ b/prpr/src/judge.rs @@ -19,7 +19,7 @@ use tracing::debug; pub const FLICK_SPEED_THRESHOLD: f32 = 0.8; pub const LIMIT_PERFECT: f32 = 0.08; pub const LIMIT_GOOD: f32 = 0.16; -pub const LIMIT_BAD: f32 = 0.22; +pub const LIMIT_BAD: f32 = 0.18; pub const UP_TOLERANCE: f32 = 0.05; pub const DIST_FACTOR: f32 = 0.2; @@ -512,7 +512,7 @@ impl Judge { continue; } let t = time_of(touch); - let mut closest = (None, X_DIFF_MAX, LIMIT_BAD, LIMIT_BAD + (X_DIFF_MAX / NOTE_WIDTH_RATIO_BASE - 1.).max(0.) * DIST_FACTOR); + let mut closest = (None, X_DIFF_MAX, LIMIT_BAD, LIMIT_BAD + (X_DIFF_MAX / NOTE_WIDTH_RATIO_BASE - 1.).max(0.) * DIST_FACTOR, 0.); for (line_id, ((line, pos), (idx, st))) in chart.lines.iter_mut().zip(pos.iter()).zip(self.notes.iter_mut()).enumerate() { let Some(pos) = pos[id] else { continue; @@ -529,16 +529,16 @@ impl Judge { if dt >= closest.3 { break; } - let dt = if dt < 0. { (dt + EARLY_OFFSET).min(0.).abs() } else { dt }; let x = &mut note.object.translation.0; x.set_time(t); - let dist = (x.now() - pos.x).abs(); + let posx = pos.x; + let dist = (x.now() - posx).abs(); if dist > X_DIFF_MAX { continue; } if dt > if matches!(note.kind, NoteKind::Click) { - LIMIT_BAD - LIMIT_PERFECT * (dist - 0.9).max(0.) + LIMIT_BAD } else { LIMIT_GOOD } @@ -546,25 +546,52 @@ impl Judge { continue; } let dt = if matches!(note.kind, NoteKind::Flick | NoteKind::Drag) { - dt + LIMIT_GOOD + dt.abs().max(LIMIT_GOOD) } else { dt }; let key = dt + (dist / NOTE_WIDTH_RATIO_BASE - 1.).max(0.) * DIST_FACTOR; if key < closest.3 { - closest = (Some((line_id, *id)), dist, dt, key); + closest = (Some((line_id, *id)), dist, dt, key, posx); } } } - if let (Some((line_id, id)), _, dt, _) = closest { + if let (Some((line_id, id)), dist, dt, _, posx) = closest { + let unattr_drag = &chart.lines.iter_mut().any(|line| { // Check drag in good range & not flag + line.notes.iter_mut().any(|note| { + let x = &mut note.object.translation.0; + x.set_time(t); + let dist2 = (x.now() - posx).abs(); + let dist = (dist2 - dist).abs(); + let judge_time = t - note.time; + matches!(note.kind, NoteKind::Drag | NoteKind::Flick) && dist <= X_DIFF_MAX && matches!(note.fake, false) && !note.attr && judge_time >= -LIMIT_GOOD && judge_time <= LIMIT_BAD + }) + }); let line = &mut chart.lines[line_id]; if matches!(line.notes[id as usize].kind, NoteKind::Drag) { - debug!("reject by drag"); + // debug!("reject by drag"); continue; } if click { + if *unattr_drag && dt > LIMIT_PERFECT { // flag drag + for line in &mut chart.lines { + for note in &mut line.notes { + let x = &mut note.object.translation.0; + x.set_time(t); + let dist2 = (x.now() - posx).abs(); + let dist = (dist2 - dist).abs(); + let judge_time = t - note.time; + if matches!(note.kind, NoteKind::Drag | NoteKind::Flick) && dist <= X_DIFF_MAX && matches!(note.fake, false) && !note.attr && judge_time >= -LIMIT_GOOD && judge_time <= LIMIT_BAD { //LIMIT_PERFECT * 0.25 + note.attr = true; + // debug!("flag drag"); + } + } + } + continue; + } // click & hold let note = &mut line.notes[id as usize]; + let dt = dt.abs(); if matches!(note.kind, NoteKind::Flick) { continue; // to next loop } @@ -816,7 +843,7 @@ impl Judge { fn auto_play_update(&mut self, res: &mut Resource, chart: &mut Chart) { let t = res.time; - let spd = res.config.speed; + // let spd = res.config.speed; let mut judgements = Vec::new(); for (line_id, (line, (idx, st))) in chart.lines.iter_mut().zip(self.notes.iter_mut()).enumerate() { for id in &idx[*st..] { @@ -839,7 +866,7 @@ impl Judge { note.judge = if matches!(note.kind, NoteKind::Hold { .. }) { note.hitsound.play(res); self.judgements.borrow_mut().push((t, line_id as _, *id, Err(true))); - JudgeStatus::Hold(true, t, (t - note.time) / spd, false, f32::INFINITY) + JudgeStatus::Hold(true, note.time, 0. , false, f32::INFINITY) } else { judgements.push((line_id, *id)); JudgeStatus::Judged diff --git a/prpr/src/parse/pec.rs b/prpr/src/parse/pec.rs index 7161f99c..0a457c6e 100644 --- a/prpr/src/parse/pec.rs +++ b/prpr/src/parse/pec.rs @@ -273,6 +273,7 @@ pub fn parse_pec(source: &str, extra: ChartExtra) -> Result { multiple_hint: false, fake, judge: JudgeStatus::NotJudged, + attr: false, }); if it.next() == Some("#") { last_note!().speed = it.take_f32()?; diff --git a/prpr/src/parse/pgr.rs b/prpr/src/parse/pgr.rs index 0646334f..1880d47e 100644 --- a/prpr/src/parse/pgr.rs +++ b/prpr/src/parse/pgr.rs @@ -192,6 +192,7 @@ fn parse_notes(r: f32, mut pgr: Vec, speed: &mut AnimFloat, height: &mu multiple_hint: false, fake: false, judge: JudgeStatus::NotJudged, + attr: false, }) }) .collect() diff --git a/prpr/src/parse/rpe.rs b/prpr/src/parse/rpe.rs index 3f0320a8..0438607c 100644 --- a/prpr/src/parse/rpe.rs +++ b/prpr/src/parse/rpe.rs @@ -401,6 +401,7 @@ async fn parse_notes( multiple_hint: false, fake: note.is_fake != 0, judge: JudgeStatus::NotJudged, + attr: false, }) } Ok(notes) From 2bbf12bcc909348d36a93efb0e657444722585d8 Mon Sep 17 00:00:00 2001 From: HLMC Date: Fri, 31 Jan 2025 19:17:52 +0800 Subject: [PATCH 2/4] Update bin.rs --- prpr/src/bin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prpr/src/bin.rs b/prpr/src/bin.rs index 6367e6c3..b4f81aeb 100644 --- a/prpr/src/bin.rs +++ b/prpr/src/bin.rs @@ -339,7 +339,7 @@ impl BinaryData for Note { multiple_hint: false, fake: r.read()?, judge: JudgeStatus::NotJudged, - attr: r.read()?, + attr: false, }) } From 6c259835c5bc0d9635ba13822493a2e8c36722ad Mon Sep 17 00:00:00 2001 From: HLMC Date: Sat, 8 Feb 2025 16:44:08 +0800 Subject: [PATCH 3/4] remove shit --- prpr/src/judge.rs | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/prpr/src/judge.rs b/prpr/src/judge.rs index ca445a01..040593a8 100644 --- a/prpr/src/judge.rs +++ b/prpr/src/judge.rs @@ -249,6 +249,7 @@ impl JudgeInner { pub mod inner; #[cfg(feature = "closed")] use inner::*; +use crate::core::Note; #[repr(C)] pub struct Judge { @@ -557,15 +558,21 @@ impl Judge { } } if let (Some((line_id, id)), dist, dt, _, posx) = closest { - let unattr_drag = &chart.lines.iter_mut().any(|line| { // Check drag in good range & not flag - line.notes.iter_mut().any(|note| { - let x = &mut note.object.translation.0; - x.set_time(t); - let dist2 = (x.now() - posx).abs(); - let dist = (dist2 - dist).abs(); - let judge_time = t - note.time; - matches!(note.kind, NoteKind::Drag | NoteKind::Flick) && dist <= X_DIFF_MAX && matches!(note.fake, false) && !note.attr && judge_time >= -LIMIT_GOOD && judge_time <= LIMIT_BAD - }) + let drag_or_flick = |note: &mut Note| { + let x = &mut note.object.translation.0; + x.set_time(t); + let dist2 = (x.now() - posx).abs(); + let dist = (dist2 - dist).abs(); + let judge_time = t - note.time; + matches!(note.kind, NoteKind::Drag | NoteKind::Flick) + && dist <= X_DIFF_MAX + && !note.fake + && !note.attr + && judge_time >= -LIMIT_GOOD + && judge_time <= LIMIT_BAD + }; + let unattr_drag = chart.lines.iter_mut().any(|line| { + line.notes.iter_mut().any(|note| drag_or_flick(note)) }); let line = &mut chart.lines[line_id]; if matches!(line.notes[id as usize].kind, NoteKind::Drag) { @@ -573,15 +580,10 @@ impl Judge { continue; } if click { - if *unattr_drag && dt > LIMIT_PERFECT { // flag drag + if unattr_drag && dt > LIMIT_PERFECT { // flag drag for line in &mut chart.lines { for note in &mut line.notes { - let x = &mut note.object.translation.0; - x.set_time(t); - let dist2 = (x.now() - posx).abs(); - let dist = (dist2 - dist).abs(); - let judge_time = t - note.time; - if matches!(note.kind, NoteKind::Drag | NoteKind::Flick) && dist <= X_DIFF_MAX && matches!(note.fake, false) && !note.attr && judge_time >= -LIMIT_GOOD && judge_time <= LIMIT_BAD { //LIMIT_PERFECT * 0.25 + if drag_or_flick(note) { note.attr = true; // debug!("flag drag"); } From ec5a31684aa4f87b81bb2c82174bdc4d7a19e8c4 Mon Sep 17 00:00:00 2001 From: HLMC Date: Sat, 8 Feb 2025 16:47:21 +0800 Subject: [PATCH 4/4] Update judge.rs --- prpr/src/judge.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/prpr/src/judge.rs b/prpr/src/judge.rs index 040593a8..8172cb5e 100644 --- a/prpr/src/judge.rs +++ b/prpr/src/judge.rs @@ -2,7 +2,7 @@ use crate::{ config::Config, - core::{BadNote, Chart, NoteKind, Point, Resource, Vector, NOTE_WIDTH_RATIO_BASE}, + core::{BadNote, Chart, Note, NoteKind, Point, Resource, Vector, NOTE_WIDTH_RATIO_BASE}, ext::{get_viewport, NotNanExt}, }; use macroquad::prelude::{ @@ -249,7 +249,6 @@ impl JudgeInner { pub mod inner; #[cfg(feature = "closed")] use inner::*; -use crate::core::Note; #[repr(C)] pub struct Judge {