fix(engine,server): safe area clamp, analytics batch, achievement save order, daily rollover, replay validation, leaderboard opt-in (#56, #60, #61, #62, #66, #68)
Build and Deploy / build-and-push (push) Successful in 3m54s
Build and Deploy / build-and-push (push) Successful in 3m54s
- #66: Clamp safe-area insets to 25% of window height with warn!() on excess - #68: Move fire_flush outside per-event loop in analytics (batch flush once) - #56: Persist progress before marking reward_granted to prevent XP loss on crash - #60: Add DateRolloverTimer + check_date_rollover system for midnight seed refresh - #62: Add validate_header() in replay upload with mode/draw_mode allowlists - #61: Restore two-query leaderboard opt-in check (SELECT then UPDATE); original queries already in .sqlx cache; EXISTS variant would require sqlx prepare Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -60,7 +60,6 @@ pub enum SyncBackend {
|
||||
avatar_url: Option<String>,
|
||||
// JWT tokens are stored in the OS keychain — not here.
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
/// Persisted window size (in logical pixels) and screen position
|
||||
@@ -447,8 +446,8 @@ impl Settings {
|
||||
/// to `[TOOLTIP_DELAY_MIN_SECS, TOOLTIP_DELAY_MAX_SECS]`. Returns the
|
||||
/// new value.
|
||||
pub fn adjust_tooltip_delay(&mut self, delta: f32) -> f32 {
|
||||
self.tooltip_delay_secs = (self.tooltip_delay_secs + delta)
|
||||
.clamp(TOOLTIP_DELAY_MIN_SECS, TOOLTIP_DELAY_MAX_SECS);
|
||||
self.tooltip_delay_secs =
|
||||
(self.tooltip_delay_secs + delta).clamp(TOOLTIP_DELAY_MIN_SECS, TOOLTIP_DELAY_MAX_SECS);
|
||||
self.tooltip_delay_secs
|
||||
}
|
||||
|
||||
@@ -522,7 +521,10 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn adjust_sfx_volume_clamps() {
|
||||
let mut s = Settings { sfx_volume: 0.5, ..Default::default() };
|
||||
let mut s = Settings {
|
||||
sfx_volume: 0.5,
|
||||
..Default::default()
|
||||
};
|
||||
assert!((s.adjust_sfx_volume(0.3) - 0.8).abs() < 1e-6);
|
||||
assert!((s.adjust_sfx_volume(0.5) - 1.0).abs() < 1e-6);
|
||||
assert!((s.adjust_sfx_volume(-2.0) - 0.0).abs() < 1e-6);
|
||||
@@ -531,7 +533,10 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn adjust_music_volume_clamps() {
|
||||
let mut s = Settings { music_volume: 0.5, ..Default::default() };
|
||||
let mut s = Settings {
|
||||
music_volume: 0.5,
|
||||
..Default::default()
|
||||
};
|
||||
assert!((s.adjust_music_volume(0.3) - 0.8).abs() < 1e-6);
|
||||
assert!((s.adjust_music_volume(0.5) - 1.0).abs() < 1e-6);
|
||||
assert!((s.adjust_music_volume(-2.0) - 0.0).abs() < 1e-6);
|
||||
@@ -570,7 +575,10 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn adjust_tooltip_delay_clamps_to_range() {
|
||||
let mut s = Settings { tooltip_delay_secs: 0.5, ..Default::default() };
|
||||
let mut s = Settings {
|
||||
tooltip_delay_secs: 0.5,
|
||||
..Default::default()
|
||||
};
|
||||
// Step up to 0.6.
|
||||
assert!((s.adjust_tooltip_delay(0.1) - 0.6).abs() < 1e-6);
|
||||
// Big positive jump clamps to TOOLTIP_DELAY_MAX_SECS.
|
||||
@@ -583,21 +591,23 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn adjust_time_bonus_multiplier_clamps_and_rounds() {
|
||||
let mut s = Settings { time_bonus_multiplier: 1.0, ..Default::default() };
|
||||
let mut s = Settings {
|
||||
time_bonus_multiplier: 1.0,
|
||||
..Default::default()
|
||||
};
|
||||
// Step up to 1.1.
|
||||
assert!((s.adjust_time_bonus_multiplier(0.1) - 1.1).abs() < 1e-6);
|
||||
// Big positive jump clamps to TIME_BONUS_MULTIPLIER_MAX.
|
||||
assert!(
|
||||
(s.adjust_time_bonus_multiplier(99.0) - TIME_BONUS_MULTIPLIER_MAX).abs() < 1e-6
|
||||
);
|
||||
assert!((s.adjust_time_bonus_multiplier(99.0) - TIME_BONUS_MULTIPLIER_MAX).abs() < 1e-6);
|
||||
// Big negative jump clamps to TIME_BONUS_MULTIPLIER_MIN.
|
||||
assert!(
|
||||
(s.adjust_time_bonus_multiplier(-99.0) - TIME_BONUS_MULTIPLIER_MIN).abs() < 1e-6
|
||||
);
|
||||
assert!((s.adjust_time_bonus_multiplier(-99.0) - TIME_BONUS_MULTIPLIER_MIN).abs() < 1e-6);
|
||||
assert_eq!(s.time_bonus_multiplier, 0.0);
|
||||
|
||||
// Repeated incremental adds must not drift past the 0.1 grid.
|
||||
let mut s2 = Settings { time_bonus_multiplier: 0.0, ..Default::default() };
|
||||
let mut s2 = Settings {
|
||||
time_bonus_multiplier: 0.0,
|
||||
..Default::default()
|
||||
};
|
||||
for _ in 0..10 {
|
||||
s2.adjust_time_bonus_multiplier(0.1);
|
||||
}
|
||||
@@ -611,20 +621,24 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn adjust_replay_move_interval_clamps_and_rounds() {
|
||||
let mut s = Settings { replay_move_interval_secs: 0.45, ..Default::default() };
|
||||
let mut s = Settings {
|
||||
replay_move_interval_secs: 0.45,
|
||||
..Default::default()
|
||||
};
|
||||
// Step down to 0.40.
|
||||
assert!((s.adjust_replay_move_interval(-0.05) - 0.40).abs() < 1e-6);
|
||||
// Big positive jump clamps to MAX.
|
||||
assert!(
|
||||
(s.adjust_replay_move_interval(99.0) - REPLAY_MOVE_INTERVAL_MAX_SECS).abs() < 1e-6
|
||||
);
|
||||
assert!((s.adjust_replay_move_interval(99.0) - REPLAY_MOVE_INTERVAL_MAX_SECS).abs() < 1e-6);
|
||||
// Big negative jump clamps to MIN.
|
||||
assert!(
|
||||
(s.adjust_replay_move_interval(-99.0) - REPLAY_MOVE_INTERVAL_MIN_SECS).abs() < 1e-6
|
||||
);
|
||||
|
||||
// Repeated 0.05 steps must not drift past the 0.05 grid.
|
||||
let mut s2 = Settings { replay_move_interval_secs: 0.10, ..Default::default() };
|
||||
let mut s2 = Settings {
|
||||
replay_move_interval_secs: 0.10,
|
||||
..Default::default()
|
||||
};
|
||||
for _ in 0..6 {
|
||||
s2.adjust_replay_move_interval(0.05);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user