Gruß-Anfang und Ablehnung festschreiben

Ein Test hält fest, dass ein Gruß mit Kennung und Version beginnt und
eine Ablehnung aus Kennung und Grund besteht. Beides bleibt auch bei
einer neuen Protokollversion gleich, damit sich Spiele verschiedener
Versionen weiter sagen können, dass sie nicht zusammenpassen. Die
Meldung des festgeschriebenen Nachrichtenformats weist darauf hin.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Steven Wroblewski
2026-10-01 18:29:32 +02:00
parent a0cb6b12b7
commit b7d5383650
2 changed files with 48 additions and 4 deletions
+41 -2
View File
@@ -12,7 +12,7 @@ use grovewright_core::command::Command;
use grovewright_core::hash::fnv1a64;
use grovewright_core::map::{Map, Pos, Terrain, Tile};
use grovewright_core::player::PlayerId;
use grovewright_core::protocol::{Action, Refusal, ToGuest, ToHost};
use grovewright_core::protocol::{Action, Refusal, ToGuest, ToHost, PROTOCOL_VERSION};
use grovewright_core::replay::Recording;
use grovewright_core::rules::{
end_hash, frozen_offline_script, frozen_script, rules_id, RULES_SEED,
@@ -162,6 +162,45 @@ fn the_protocol_format_is_unchanged() {
fnv1a64(&bytes),
0xc263_69c0_f892_247b,
"the messages between host and guests changed; raise \
PROTOCOL_VERSION in core/src/protocol.rs; then update this value"
PROTOCOL_VERSION in core/src/protocol.rs; then update this value. \
The start of a greeting and the refusal must never change, see \
the_greeting_start_and_the_refusal_never_change"
);
}
/// Covers the promise that games of every version can still tell each other
/// that they do not fit: a greeting starts with its tag and the version, and
/// a refusal is its tag and the code of its reason. Unlike every other part
/// of the messages, these stay the same when PROTOCOL_VERSION is raised.
#[test]
fn the_greeting_start_and_the_refusal_never_change() {
let hello = ToHost::Hello {
rules: 1,
key: [3; 16],
name: "Ada".to_owned(),
}
.encode();
let mut start = vec![1];
start.extend(PROTOCOL_VERSION.to_le_bytes());
assert_eq!(
hello[..start.len()],
start[..],
"a greeting starts with the tag 1 and the version; this never \
changes, not even with a new PROTOCOL_VERSION"
);
let refusals = [
(Refusal::OtherProtocol, 1),
(Refusal::OtherRules, 2),
(Refusal::WorldFull, 3),
(Refusal::TooManyPlayers, 4),
(Refusal::AlreadyPlaying, 5),
];
for (refusal, code) in refusals {
assert_eq!(
ToGuest::Refused(refusal).encode(),
vec![2, code],
"a refusal is the tag 2 and the code of its reason; this never \
changes, not even with a new PROTOCOL_VERSION"
);
}
}