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

- #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:
funman300
2026-05-28 13:07:22 -07:00
parent 8cb4c9808e
commit 6e407a3ea7
104 changed files with 6356 additions and 3092 deletions
+178 -48
View File
@@ -13,12 +13,12 @@ use crate::font_plugin::FontResource;
use crate::hud_plugin::ANDROID_HINT_LABEL;
use crate::platform::SHOW_KEYBOARD_ACCELERATORS;
use crate::ui_modal::{
spawn_modal, spawn_modal_actions, spawn_modal_button, spawn_modal_header, ButtonVariant,
ModalScrim, ScrimDismissible,
ButtonVariant, ModalScrim, ScrimDismissible, spawn_modal, spawn_modal_actions,
spawn_modal_button, spawn_modal_header,
};
use crate::ui_theme::{
BORDER_SUBTLE, HighContrastBorder, RADIUS_SM, SPACE_2, TEXT_PRIMARY, TEXT_SECONDARY,
TYPE_BODY, TYPE_CAPTION, VAL_SPACE_1, VAL_SPACE_2, VAL_SPACE_3, Z_MODAL_PANEL,
BORDER_SUBTLE, HighContrastBorder, RADIUS_SM, SPACE_2, TEXT_PRIMARY, TEXT_SECONDARY, TYPE_BODY,
TYPE_CAPTION, VAL_SPACE_1, VAL_SPACE_2, VAL_SPACE_3, Z_MODAL_PANEL,
};
/// Marker on the help overlay root node.
@@ -145,26 +145,56 @@ const CONTROL_SECTIONS: &[ControlSection] = &[
ControlSection {
title: "Touch",
rows: &[
ControlRow { keys: "Tap stock", description: "Draw from stock" },
ControlRow { keys: "Drag card", description: "Move cards between piles" },
ControlRow { keys: "Tap foundation area", description: "Auto-move top card to foundation" },
ControlRow {
keys: "Tap stock",
description: "Draw from stock",
},
ControlRow {
keys: "Drag card",
description: "Move cards between piles",
},
ControlRow {
keys: "Tap foundation area",
description: "Auto-move top card to foundation",
},
],
},
ControlSection {
title: "New Game",
rows: &[
ControlRow { keys: "New+", description: "Start a new Classic game" },
ControlRow { keys: "Modes↓", description: "Pick Daily, Zen, Challenge, or Time Attack" },
ControlRow {
keys: "New+",
description: "Start a new Classic game",
},
ControlRow {
keys: "Modes↓",
description: "Pick Daily, Zen, Challenge, or Time Attack",
},
],
},
ControlSection {
title: "HUD buttons",
rows: &[
ControlRow { keys: "", description: "Undo last move" },
ControlRow { keys: "||", description: "Pause / resume" },
ControlRow { keys: "?", description: "This help screen" },
ControlRow { keys: ANDROID_HINT_LABEL, description: "Show a hint" },
ControlRow { keys: "", description: "Open menu (Stats, Settings, Profile...)" },
ControlRow {
keys: "",
description: "Undo last move",
},
ControlRow {
keys: "||",
description: "Pause / resume",
},
ControlRow {
keys: "?",
description: "This help screen",
},
ControlRow {
keys: ANDROID_HINT_LABEL,
description: "Show a hint",
},
ControlRow {
keys: "",
description: "Open menu (Stats, Settings, Profile...)",
},
],
},
];
@@ -174,17 +204,35 @@ const CONTROL_SECTIONS: &[ControlSection] = &[
ControlSection {
title: "Gameplay",
rows: &[
ControlRow { keys: "Drag", description: "Move cards between piles" },
ControlRow { keys: "D / Space", description: "Draw from stock" },
ControlRow { keys: "U", description: "Undo last move" },
ControlRow { keys: "Click stock", description: "Draw" },
ControlRow {
keys: "Drag",
description: "Move cards between piles",
},
ControlRow {
keys: "D / Space",
description: "Draw from stock",
},
ControlRow {
keys: "U",
description: "Undo last move",
},
ControlRow {
keys: "Click stock",
description: "Draw",
},
],
},
ControlSection {
title: "Mouse",
rows: &[
ControlRow { keys: "Double-click", description: "Auto-move card to its best destination" },
ControlRow { keys: "Right-click", description: "Highlight legal destinations briefly" },
ControlRow {
keys: "Double-click",
description: "Auto-move card to its best destination",
},
ControlRow {
keys: "Right-click",
description: "Highlight legal destinations briefly",
},
ControlRow {
keys: "Hold RMB",
description: "Open radial menu — release over an icon to quick-drop",
@@ -194,48 +242,129 @@ const CONTROL_SECTIONS: &[ControlSection] = &[
ControlSection {
title: "Keyboard drag",
rows: &[
ControlRow { keys: "Tab", description: "Focus next draggable card" },
ControlRow { keys: "Enter", description: "Lift focused card (then arrows pick where)" },
ControlRow { keys: "Arrows / Tab", description: "Cycle legal destinations while lifted" },
ControlRow { keys: "Enter", description: "Drop the lifted cards on the focused pile" },
ControlRow { keys: "Esc", description: "Cancel lift (Esc again clears focus)" },
ControlRow { keys: "Space", description: "Auto-move focused card (foundation first)" },
ControlRow {
keys: "Tab",
description: "Focus next draggable card",
},
ControlRow {
keys: "Enter",
description: "Lift focused card (then arrows pick where)",
},
ControlRow {
keys: "Arrows / Tab",
description: "Cycle legal destinations while lifted",
},
ControlRow {
keys: "Enter",
description: "Drop the lifted cards on the focused pile",
},
ControlRow {
keys: "Esc",
description: "Cancel lift (Esc again clears focus)",
},
ControlRow {
keys: "Space",
description: "Auto-move focused card (foundation first)",
},
],
},
ControlSection {
title: "New Game",
rows: &[
ControlRow { keys: "N", description: "New Classic game (N twice if in progress)" },
ControlRow { keys: "C", description: "Start today's daily challenge" },
ControlRow { keys: "Z", description: "Start a Zen game (level 5+)" },
ControlRow { keys: "X", description: "Start the next Challenge (level 5+)" },
ControlRow { keys: "T", description: "Start a Time Attack session (level 5+)" },
ControlRow {
keys: "N",
description: "New Classic game (N twice if in progress)",
},
ControlRow {
keys: "C",
description: "Start today's daily challenge",
},
ControlRow {
keys: "Z",
description: "Start a Zen game (level 5+)",
},
ControlRow {
keys: "X",
description: "Start the next Challenge (level 5+)",
},
ControlRow {
keys: "T",
description: "Start a Time Attack session (level 5+)",
},
],
},
ControlSection {
title: "Mode Launcher (M)",
rows: &[
ControlRow { keys: "1", description: "Launch Classic" },
ControlRow { keys: "2", description: "Launch Daily Challenge" },
ControlRow { keys: "3", description: "Launch Zen (level 5+)" },
ControlRow { keys: "4", description: "Launch Challenge (level 5+)" },
ControlRow { keys: "5", description: "Launch Time Attack (level 5+)" },
ControlRow {
keys: "1",
description: "Launch Classic",
},
ControlRow {
keys: "2",
description: "Launch Daily Challenge",
},
ControlRow {
keys: "3",
description: "Launch Zen (level 5+)",
},
ControlRow {
keys: "4",
description: "Launch Challenge (level 5+)",
},
ControlRow {
keys: "5",
description: "Launch Time Attack (level 5+)",
},
],
},
ControlSection {
title: "Overlays",
rows: &[
ControlRow { keys: "M", description: "Mode launcher (Home)" },
ControlRow { keys: "P", description: "Profile" },
ControlRow { keys: "S", description: "Stats & progression" },
ControlRow { keys: "A", description: "Achievements" },
ControlRow { keys: "L", description: "Leaderboard" },
ControlRow { keys: "O", description: "Settings" },
ControlRow { keys: "F1", description: "This help screen" },
ControlRow { keys: "F11", description: "Toggle fullscreen" },
ControlRow { keys: "Esc", description: "Pause / resume" },
ControlRow { keys: "[ / ]", description: "SFX volume down / up" },
ControlRow { keys: "Enter", description: "Play Again (on the Win Summary)" },
ControlRow {
keys: "M",
description: "Mode launcher (Home)",
},
ControlRow {
keys: "P",
description: "Profile",
},
ControlRow {
keys: "S",
description: "Stats & progression",
},
ControlRow {
keys: "A",
description: "Achievements",
},
ControlRow {
keys: "L",
description: "Leaderboard",
},
ControlRow {
keys: "O",
description: "Settings",
},
ControlRow {
keys: "F1",
description: "This help screen",
},
ControlRow {
keys: "F11",
description: "Toggle fullscreen",
},
ControlRow {
keys: "Esc",
description: "Pause / resume",
},
ControlRow {
keys: "[ / ]",
description: "SFX volume down / up",
},
ControlRow {
keys: "Enter",
description: "Play Again (on the Win Summary)",
},
],
},
];
@@ -315,7 +444,8 @@ fn spawn_help_screen(commands: &mut Commands, font_res: Option<&FontResource>) {
});
}
line.spawn(( Text::new(row.description),
line.spawn((
Text::new(row.description),
font_row.clone(),
TextColor(TEXT_PRIMARY),
));