From 8aaeae5cf7cea93aaf957d81914d9ead64bc349c Mon Sep 17 00:00:00 2001 From: Steven Wroblewski Date: Thu, 1 Oct 2026 13:19:23 +0200 Subject: [PATCH] Test: volle Spielerliste mit vielen Offline-Spielern wird geladen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Eine Welt kennt bis zu 16 Spieler, von denen höchstens vier online sind. Kein Test lud eine Welt mit mehr als vier bekannten Spielern; ein Fehler, der in check_restorable alle bekannten statt der Online-Spieler zählt, hätte gültige Spielstände zurückgewiesen und blieb unbemerkt. Mit dem Koop-Spiel in M1c sind mehr als vier bekannte Spieler der Normalfall. Der neue Test baut die Welt über Befehle auf: 16 Schlüssel treten in Vierergruppen bei, jede Gruppe außer der letzten geht wieder, bevor die nächste kommt. from_snapshot muss dieselbe Welt liefern, load alle Spieler offline. Mit dem Fehler (alle Spieler gezählt) schlägt der Test mit Invalid("online players") fehl. Co-Authored-By: Claude Sonnet 5.5 --- core/tests/snapshot.rs | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/core/tests/snapshot.rs b/core/tests/snapshot.rs index 2403ebd..a49dbe0 100644 --- a/core/tests/snapshot.rs +++ b/core/tests/snapshot.rs @@ -3,7 +3,7 @@ use grovewright_core::command::Command; use grovewright_core::hash::fnv1a64; use grovewright_core::map::{Map, Pos, Terrain}; use grovewright_core::mapgen::outcrop_origin; -use grovewright_core::player::{Player, PlayerId, MAX_ONLINE_PLAYERS}; +use grovewright_core::player::{Player, PlayerId, MAX_KNOWN_PLAYERS, MAX_ONLINE_PLAYERS}; use grovewright_core::snapshot::{SnapshotError, MAX_RESTORABLE_TICK, SNAPSHOT_VERSION}; use grovewright_core::world::{Event, World, DIG_COOLDOWN_TICKS}; @@ -256,3 +256,43 @@ fn states_right_at_the_limits_are_accepted() { let bytes = snapshot_of(1, MAX_RESTORABLE_TICK, &map, &players); assert!(World::from_snapshot(&bytes).is_ok()); } + +/// A world that knows `MAX_KNOWN_PLAYERS` players, built through commands. +/// They join in groups of `MAX_ONLINE_PLAYERS`, and each group but the last +/// leaves before the next one joins, so only the last group is online. +fn world_with_a_full_roster() -> World { + let mut world = World::new(7); + let groups = MAX_KNOWN_PLAYERS / MAX_ONLINE_PLAYERS; + for group in 0..groups { + let first = group * MAX_ONLINE_PLAYERS; + for index in first..first + MAX_ONLINE_PLAYERS { + world.step(&[Command::Join { + key: [index as u8; 16], + name: format!("P{index}"), + }]); + } + if group + 1 < groups { + for index in first..first + MAX_ONLINE_PLAYERS { + world.step(&[Command::Leave { + player: PlayerId(index as u8), + }]); + } + } + } + world +} + +#[test] +fn a_full_roster_with_most_players_offline_is_accepted() { + let world = world_with_a_full_roster(); + assert_eq!(world.players().len(), MAX_KNOWN_PLAYERS); + let online = world.players().iter().filter(|player| player.online); + assert_eq!(online.count(), MAX_ONLINE_PLAYERS); + + let restored = World::from_snapshot(&world.to_snapshot()).unwrap(); + assert_eq!(restored, world); + + let loaded = World::load(&world.to_snapshot()).unwrap(); + assert_eq!(loaded.players().len(), MAX_KNOWN_PLAYERS); + assert!(loaded.players().iter().all(|player| !player.online)); +}