take the checksum from before the closing checkpoint

LogicGameMode::encode reads its return value out of getCheckSum() and
only then writes it:

  v15 = ChecksumEncoder::getCheckSum(a2);
  (...vptr+88)(a2, v15);        // the checkpoint vint
  return v15;

we were reading ours after that write, so the closing checkpoint was
folded into the number we compared. the two could never match, whatever
the simulation did - which is why tick 41 disagreed with six untouched
towers on the field.

write() now hands back the value it wrote, the way encode() does.
This commit is contained in:
WiseDev 2026-08-23 15:04:51 +03:00
parent 252277ec8d
commit 81d6fe3922
2 changed files with 8 additions and 7 deletions

View file

@ -23,7 +23,7 @@ impl LogicGameMode {
} }
} }
impl LogicGameMode { impl LogicGameMode {
pub fn write(&self, writer: &mut ByteStreamWriter, with_commands: bool) -> Result<()> { pub fn write(&self, writer: &mut ByteStreamWriter, with_commands: bool) -> Result<i32> {
writer.write_vint(self.time.tick); writer.write_vint(self.time.tick);
writer.write_checksum_checkpoint(); writer.write_checksum_checkpoint();
writer.write_vint(SECTION_BATTLE); writer.write_vint(SECTION_BATTLE);
@ -36,21 +36,21 @@ impl LogicGameMode {
} }
writer.write_vint(SECTION_TUTORIAL); writer.write_vint(SECTION_TUTORIAL);
self.tutorial_manager.encode(writer)?; self.tutorial_manager.encode(writer)?;
writer.write_checksum_checkpoint(); let checksum = writer.write_checksum_checkpoint();
if with_commands { if with_commands {
writer.write_vint(0); writer.write_vint(0);
} }
Ok(()) Ok(checksum)
} }
pub fn calculate_checksum(&self) -> Result<i32> { pub fn calculate_checksum(&self) -> Result<i32> {
let mut writer = ByteStreamWriter::new(); let mut writer = ByteStreamWriter::new();
self.write(&mut writer, false)?; self.write(&mut writer, false)
Ok(writer.checksum() as i32)
} }
} }
impl Payload for LogicGameMode { impl Payload for LogicGameMode {
fn encode(&self, writer: &mut ByteStreamWriter) -> Result<()> { fn encode(&self, writer: &mut ByteStreamWriter) -> Result<()> {
self.write(writer, true) self.write(writer, true)?;
Ok(())
} }
fn decode(_reader: &mut titan::ByteStreamReader<'_>) -> Result<Self> { fn decode(_reader: &mut titan::ByteStreamReader<'_>) -> Result<Self> {
Err(titan::Error::Unsupported("LogicGameMode is encode only")) Err(titan::Error::Unsupported("LogicGameMode is encode only"))

View file

@ -33,9 +33,10 @@ impl ByteStreamWriter {
pub fn checksum(&self) -> u32 { pub fn checksum(&self) -> u32 {
self.checksum.value() self.checksum.value()
} }
pub fn write_checksum_checkpoint(&mut self) { pub fn write_checksum_checkpoint(&mut self) -> i32 {
let running = self.checksum.value() as i32; let running = self.checksum.value() as i32;
self.write_vint(running); self.write_vint(running);
running
} }
pub fn write_byte(&mut self, value: u8) { pub fn write_byte(&mut self, value: u8) {
self.checksum.write_byte(value as i8); self.checksum.write_byte(value as i8);