Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions late-core/src/models/quest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,9 +396,13 @@ async fn ensure_period_assignments(
if existing_slots.contains(slot) {
continue;
}
let Some(template) =
choose_template(&templates, cadence, period_start, *slot, &selected_templates)
else {
let Some(template) = choose_template(
&templates,
cadence,
period_start,
*slot,
&selected_templates,
) else {
continue;
};

Expand Down Expand Up @@ -1041,7 +1045,12 @@ mod tests {
template("easy_sudoku", "easy", "puzzle", "daily_puzzle_win"),
template("medium_sudoku", "medium", "puzzle", "daily_puzzle_win"),
template("medium_2048", "medium", "arcade", "arcade_score"),
template("solve_rubiks_cube", "medium", "arcade", "arcade_puzzle_solved"),
template(
"solve_rubiks_cube",
"medium",
"arcade",
"arcade_puzzle_solved",
),
];
let easy_pick = templates[0].id;

Expand Down
6 changes: 1 addition & 5 deletions late-ssh/src/app/door/hub/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,7 @@ pub fn draw_games_hub(frame: &mut Frame, area: Rect, view: &HubView) {
crate::app::door::dcss::render::draw_landing(frame, layout[3], view.dcss_enabled);
}
HubGame::Usurper => {
crate::app::door::usurper::render::draw_landing(
frame,
layout[3],
view.usurper_enabled,
);
crate::app::door::usurper::render::draw_landing(frame, layout[3], view.usurper_enabled);
}
HubGame::GreenDragon => {
crate::app::door::greendragon::screen::draw_landing(
Expand Down
30 changes: 25 additions & 5 deletions late-ssh/src/app/door/usurper/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,26 @@ fn render_landing(frame: &mut Frame, area: Rect, launch: Vec<Line<'static>>) {
)),
legend_credentials(),
Line::from(""),
landing::stat("world", "one shared realm; every player walks the same town", 8),
landing::stat("daily", "turns refresh each day; a session is a quick visit", 8),
landing::stat("gangs", "form teams, brawl rivals, hold the town together", 8),
landing::stat("throne", "dethrone the king, or reach the darkest dungeon", 8),
landing::stat(
"world",
"one shared realm; every player walks the same town",
8,
),
landing::stat(
"daily",
"turns refresh each day; a session is a quick visit",
8,
),
landing::stat(
"gangs",
"form teams, brawl rivals, hold the town together",
8,
),
landing::stat(
"throne",
"dethrone the king, or reach the darkest dungeon",
8,
),
Line::from(""),
flavor_headline(),
flavor_quote(),
Expand All @@ -92,7 +108,11 @@ fn render_landing(frame: &mut Frame, area: Rect, launch: Vec<Line<'static>>) {
lines.extend([
Line::from(""),
landing::heading("Once Inside"),
landing::hint("menus", "every screen lists its own keys; letters choose", 8),
landing::hint(
"menus",
"every screen lists its own keys; letters choose",
8,
),
landing::hint("Q", "quit to the hub from the main menus", 8),
landing::hint("size", "a classic 80x25 screen; keep the window roomy", 8),
Line::from(""),
Expand Down
4 changes: 1 addition & 3 deletions late-ssh/src/app/door/usurper/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,9 +281,7 @@ pub(super) fn strip_input_noise(data: &[u8]) -> Vec<u8> {
continue;
}
// Linux-console F1-F5: ESC [ [ A..E
if rest.first() == Some(&b'[')
&& rest.len() >= 2
&& matches!(rest[1], b'A'..=b'E')
if rest.first() == Some(&b'[') && rest.len() >= 2 && matches!(rest[1], b'A'..=b'E')
{
i += 4;
continue;
Expand Down
3 changes: 2 additions & 1 deletion late-usurper/src/cp437.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ const HIGH: [char; 128] = [
'└', '┴', '┬', '├', '─', '┼', '╞', '╟', '╚', '╔', '╩', '╦', '╠', '═', '╬', '╧', // 0xC0
'╨', '╤', '╥', '╙', '╘', '╒', '╓', '╫', '╪', '┘', '┌', '█', '▄', '▌', '▐', '▀', // 0xD0
'α', 'ß', 'Γ', 'π', 'Σ', 'σ', 'µ', 'τ', 'Φ', 'Θ', 'Ω', 'δ', '∞', 'φ', 'ε', '∩', // 0xE0
'≡', '±', '≥', '≤', '⌠', '⌡', '÷', '≈', '°', '∙', '·', '√', 'ⁿ', '²', '■', '\u{a0}', // 0xF0
'≡', '±', '≥', '≤', '⌠', '⌡', '÷', '≈', '°', '∙', '·', '√', 'ⁿ', '²', '■',
'\u{a0}', // 0xF0
];

/// Transcode a chunk of raw CP437 terminal output into UTF-8 bytes.
Expand Down
3 changes: 2 additions & 1 deletion late-usurper/src/dropfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ pub fn write_door32(game_dir: &str, node: u16, playname: &str) -> Result<String>
// node number. The game keys the player record on the uppercased real
// name; time is per-session and generous (the game's own daily turn
// limits are what actually bound play).
let contents = format!("0\n0\n38400\nlate.sh\n1\n{playname}\n{playname}\n100\n999\n1\n{node}\n");
let contents =
format!("0\n0\n38400\nlate.sh\n1\n{playname}\n{playname}\n100\n999\n1\n{node}\n");
let path = dir.join("door32.sys");
fs::write(&path, contents).with_context(|| format!("writing {}", path.display()))?;
Ok(rel)
Expand Down
5 changes: 4 additions & 1 deletion late-usurper/src/dropfile_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ fn writes_local_mode_dropfile_with_identity() {
assert_eq!(rel, "DROP/3/");
let written = fs::read_to_string(root.join("DROP/3/door32.sys")).unwrap();
let lines: Vec<&str> = written.lines().collect();
assert_eq!(lines[0], "0", "comm type must be 0 = local (PTY, no socket)");
assert_eq!(
lines[0], "0",
"comm type must be 0 = local (PTY, no socket)"
);
assert_eq!(lines[5], "Gnoll_Fan", "real name carries the identity");
assert_eq!(lines[6], "Gnoll_Fan");
assert_eq!(lines[9], "1", "ANSI emulation");
Expand Down
5 changes: 4 additions & 1 deletion late-usurper/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,10 @@ async fn run_bridge(

match stop {
StopReason::ChildExited => {
tracing::debug!(node = cfg.node.number(), "usurper child exited; closing channel");
tracing::debug!(
node = cfg.node.number(),
"usurper child exited; closing channel"
);
}
StopReason::Teardown => {
// Client hung up or the host is shutting down with the game still
Expand Down
32 changes: 16 additions & 16 deletions late-usurper/src/input_filter_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,22 @@ fn assert_every_split(input: &[u8], expected: &[u8]) {
// The load-bearing sysop keys DDPlus binds in local mode: F2 chat, F7/F8 time
// credit, F10 terminate. Each must vanish at every split.
const PROTECTED: &[&[u8]] = &[
b"\x1bOP", // F1 (SS3)
b"\x1bOQ", // F2 (SS3)
b"\x1bOR", // F3 (SS3)
b"\x1bOS", // F4 (SS3)
b"\x1b[11~", // F1 (CSI)
b"\x1b[12~", // F2
b"\x1b[15~", // F5
b"\x1b[17~", // F6
b"\x1b[18~", // F7
b"\x1b[19~", // F8
b"\x1b[20~", // F9
b"\x1b[21~", // F10 -> HosedMessage; halt
b"\x1b[23~", // F11
b"\x1b[24~", // F12
b"\x1b[[A", // F1 (linux console)
b"\x1b[[E", // F5 (linux console)
b"\x1bOP", // F1 (SS3)
b"\x1bOQ", // F2 (SS3)
b"\x1bOR", // F3 (SS3)
b"\x1bOS", // F4 (SS3)
b"\x1b[11~", // F1 (CSI)
b"\x1b[12~", // F2
b"\x1b[15~", // F5
b"\x1b[17~", // F6
b"\x1b[18~", // F7
b"\x1b[19~", // F8
b"\x1b[20~", // F9
b"\x1b[21~", // F10 -> HosedMessage; halt
b"\x1b[23~", // F11
b"\x1b[24~", // F12
b"\x1b[[A", // F1 (linux console)
b"\x1b[[E", // F5 (linux console)
];

#[test]
Expand Down
11 changes: 7 additions & 4 deletions late-usurper/src/seed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ pub fn prepare_game_dir(seed_dir: &str, game_dir: &str) -> Result<()> {
match fs::remove_file(&path) {
Ok(()) => tracing::info!(file = %path.display(), "swept stale lock file at boot"),
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {}
Err(e) => tracing::warn!(file = %path.display(), error = ?e, "could not sweep stale lock file"),
Err(e) => {
tracing::warn!(file = %path.display(), error = ?e, "could not sweep stale lock file")
}
}
}
Ok(())
Expand Down Expand Up @@ -71,9 +73,10 @@ fn copy_atomic(from: &Path, to: &Path) -> Result<()> {
tmp_name.push(".seedtmp");
let tmp = to.with_file_name(tmp_name);
{
let mut src = fs::File::open(from).with_context(|| format!("opening {}", from.display()))?;
let mut dst = fs::File::create(&tmp)
.with_context(|| format!("creating temp {}", tmp.display()))?;
let mut src =
fs::File::open(from).with_context(|| format!("opening {}", from.display()))?;
let mut dst =
fs::File::create(&tmp).with_context(|| format!("creating temp {}", tmp.display()))?;
std::io::copy(&mut src, &mut dst)
.with_context(|| format!("streaming {} -> {}", from.display(), tmp.display()))?;
dst.flush().ok();
Expand Down
5 changes: 4 additions & 1 deletion late-usurper/src/seed_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ fn seeds_missing_files_but_never_overwrites() {
prepare_game_dir(seed.to_str().unwrap(), game.to_str().unwrap()).unwrap();

// Missing file arrived; existing world data untouched.
assert_eq!(fs::read_to_string(game.join("USURPER.CFG")).unwrap(), "seed-cfg");
assert_eq!(
fs::read_to_string(game.join("USURPER.CFG")).unwrap(),
"seed-cfg"
);
assert_eq!(
fs::read_to_string(game.join("DATA/MONSTER.DAT")).unwrap(),
"live-world"
Expand Down
Loading