From 58d137ccd2420f9f3e72688f32fe39598caa3ceb Mon Sep 17 00:00:00 2001 From: WiseDev <83840010+wisedevik@users.noreply.github.com> Date: Sun, 23 Aug 2026 11:31:50 +0300 Subject: [PATCH] teach the snapshot verifier about decks verify_snapshot still carried the stub from when both decks were always absent, so the first battle that actually carried one was refused before it reached the client. it reads them now: eight presence bits, then a data reference, five vints and two booleans per filled slot. while in there, the six battle booleans were all being discarded, which hid the fact that the two score-change vints are only present when the first of them is set. the verifier tracks it now, same as the encoder. --- crates/logic/src/battle/verify.rs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/crates/logic/src/battle/verify.rs b/crates/logic/src/battle/verify.rs index 34cf61e..21ac7a4 100644 --- a/crates/logic/src/battle/verify.rs +++ b/crates/logic/src/battle/verify.rs @@ -1,6 +1,7 @@ use titan::{ByteStreamReader, Result}; use crate::battle::logic_game_mode::{SECTION_BATTLE, SECTION_TUTORIAL}; use crate::data::{table, LogicDataRef, LogicDataTables}; +use crate::model::DECK_SLOT_COUNT; pub const BUFF_ARRAY_TABLE: i32 = table::DAMAGE_TYPES; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SnapshotReport { @@ -37,6 +38,19 @@ impl<'a, 'b> Verifier<'a, 'b> { } Ok(Some((class_id, self.reader.read_vint()?))) } + fn spell_deck(&mut self) -> Result<()> { + let mut present = [false; DECK_SLOT_COUNT]; + for slot in present.iter_mut() { + *slot = self.reader.read_boolean()?; + } + for _ in present.iter().filter(|slot| **slot) { + self.data_ref()?; + self.vints(5)?; + self.reader.read_boolean()?; + self.reader.read_boolean()?; + } + Ok(()) + } fn vints(&mut self, count: usize) -> Result<()> { for _ in 0..count { self.reader.read_vint()?; @@ -173,7 +187,8 @@ impl<'a, 'b> Verifier<'a, 'b> { self.vints(2)?; self.vints(8)?; self.vints(3)?; - for _ in 0..6 { + let battle_ended_called = self.reader.read_boolean()?; + for _ in 0..5 { self.reader.read_boolean()?; } self.mark("objects"); @@ -224,7 +239,7 @@ impl<'a, 'b> Verifier<'a, 'b> { self.mark("decks"); for _ in 0..2 { if self.reader.read_boolean()? { - return Err(titan::Error::Unsupported("decks are not expected yet")); + self.spell_deck()?; } } self.mark("leaders"); @@ -237,6 +252,9 @@ impl<'a, 'b> Verifier<'a, 'b> { } } self.mark("battle_tail"); + if battle_ended_called { + self.vints(2)?; + } self.vints(6)?; self.mark("avatars"); for _ in 0..2 {