1use std::cmp::min;
2use std::fmt::Debug;
3use crate::spec::reader::Reader;
4use crate::spec::writer::Writer;
5
6macro_rules! impl_from_packet {
7 ($($name:ident)*) => ($(
8 impl From<$name> for Packet {
9 fn from(value: $name) -> Self {
10 Self::$name(value)
11 }
12 }
13 )*)
14}
15
16pub const KEY_CONSOLE_TYPE: &[u8] = &[0x00, 0x01];
17pub const KEY_CONSOLE_REGION: &[u8] = &[0x00, 0x02];
18pub const KEY_GAME_TITLE: &[u8] = &[0x00, 0x03];
19pub const KEY_ROM_NAME: &[u8] = &[0x00, 0x04];
20pub const KEY_ATTRIBUTION: &[u8] = &[0x00, 0x05];
21pub const KEY_CATEGORY: &[u8] = &[0x00, 0x06];
22pub const KEY_EMULATOR_NAME: &[u8] = &[0x00, 0x07];
23pub const KEY_EMULATOR_VERSION: &[u8] = &[0x00, 0x08];
24pub const KEY_EMULATOR_CORE: &[u8] = &[0x00, 0x09];
25pub const KEY_TAS_LAST_MODIFIED: &[u8] = &[0x00, 0x0A];
26pub const KEY_DUMP_CREATED: &[u8] = &[0x00, 0x0B];
27pub const KEY_DUMP_LAST_MODIFIED: &[u8] = &[0x00, 0x0C];
28pub const KEY_TOTAL_FRAMES: &[u8] = &[0x00, 0x0D];
29pub const KEY_RERECORDS: &[u8] = &[0x00, 0x0E];
30pub const KEY_SOURCE_LINK: &[u8] = &[0x00, 0x0F];
31pub const KEY_BLANK_FRAMES: &[u8] = &[0x00, 0x10];
32pub const KEY_VERIFIED: &[u8] = &[0x00, 0x11];
33pub const KEY_MEMORY_INIT: &[u8] = &[0x00, 0x12];
34pub const KEY_GAME_IDENTIFIER: &[u8] = &[0x00, 0x13];
35pub const KEY_MOVIE_LICENSE: &[u8] = &[0x00, 0x14];
36pub const KEY_MOVIE_FILE: &[u8] = &[0x00, 0x15];
37
38pub const KEY_PORT_CONTROLLER: &[u8] = &[0x00, 0xF0];
39pub const KEY_PORT_OVERREAD: &[u8] = &[0x00, 0xF1];
40
41pub const KEY_NES_LATCH_FILTER: &[u8] = &[0x01, 0x01];
42pub const KEY_NES_CLOCK_FILTER: &[u8] = &[0x01, 0x02];
43
44pub const KEY_NES_GAME_GENIE_CODE: &[u8] = &[0x01, 0x04];
45
46pub const KEY_SNES_LATCH_FILTER: &[u8] = &[0x02, 0x01];
47pub const KEY_SNES_CLOCK_FILTER: &[u8] = &[0x02, 0x02];
48
49pub const KEY_SNES_GAME_GENIE_CODE: &[u8] = &[0x02, 0x04];
50pub const KEY_SNES_LATCH_TRAIN: &[u8] = &[0x02, 0x05];
51
52pub const KEY_GENESIS_GAME_GENIE_CODE: &[u8] = &[0x08, 0x04];
53
54pub const KEY_INPUT_CHUNK: &[u8] = &[0xFE, 0x01];
55pub const KEY_INPUT_MOMENT: &[u8] = &[0xFE, 0x02];
56pub const KEY_TRANSITION: &[u8] = &[0xFE, 0x03];
57pub const KEY_LAG_FRAME_CHUNK: &[u8] = &[0xFE, 0x04];
58pub const KEY_MOVIE_TRANSITION: &[u8] = &[0xFE, 0x05];
59
60pub const KEY_COMMENT: &[u8] = &[0xFF, 0x01];
61pub const KEY_EXPERIMENTAL: &[u8] = &[0xFF, 0xFE];
62pub const KEY_UNSPECIFIED: &[u8] = &[0xFF, 0xFF];
63
64#[derive(Debug)]
65pub enum PacketError {
66 MissingKey,
67 MismatchedKey,
68 MissingPayloadLength,
69 UnsupportedExponent(u8),
70 InvalidPayload {
71 key: Vec<u8>,
72 payload: Vec<u8>,
73 },
74}
75impl PacketError {
76 pub(crate) fn invalid(key: &[u8], payload: Reader) -> Self {
77 Self::InvalidPayload {
78 key: key.to_vec(),
79 payload: payload.to_vec(),
80 }
81 }
82}
83
84
85pub trait Decode: Sized + Debug + Clone + PartialEq {
86 fn decode(key: &[u8], payload: Reader) -> Result<Self, PacketError>;
87
88 fn kind(&self) -> PacketKind;
89 fn name(&self) -> String {
90 self.kind().to_string()
91 }
92}
93
94pub trait Encode: Debug + Clone + PartialEq {
95 fn encode(&self, keylen: u8) -> Vec<u8>;
96
97 fn key(&self) -> Vec<u8>;
98}
99
100
101#[derive(Debug, Clone, PartialEq)]
102#[non_exhaustive]
103pub enum Packet {
104 ConsoleType(ConsoleType),
105 ConsoleRegion(ConsoleRegion),
106 GameTitle(GameTitle),
107 RomName(RomName),
108 Attribution(Attribution),
109 Category(Category),
110 EmulatorName(EmulatorName),
111 EmulatorVersion(EmulatorVersion),
112 EmulatorCore(EmulatorCore),
113 TasLastModified(TasLastModified),
114 DumpCreated(DumpCreated),
115 DumpLastModified(DumpLastModified),
116 TotalFrames(TotalFrames),
117 Rerecords(Rerecords),
118 SourceLink(SourceLink),
119 BlankFrames(BlankFrames),
120 Verified(Verified),
121 MemoryInit(MemoryInit),
122 GameIdentifier(GameIdentifier),
123 MovieLicense(MovieLicense),
124 MovieFile(MovieFile),
125 PortController(PortController),
126 PortOverread(PortOverread),
127 NesLatchFilter(NesLatchFilter),
128 NesClockFilter(NesClockFilter),
129 NesGameGenieCode(NesGameGenieCode),
130 SnesLatchFilter(SnesLatchFilter),
131 SnesClockFilter(SnesClockFilter),
132 SnesGameGenieCode(SnesGameGenieCode),
133 SnesLatchTrain(SnesLatchTrain),
134 GenesisGameGenieCode(GenesisGameGenieCode),
135 InputChunk(InputChunk),
136 InputMoment(InputMoment),
137 Transition(Transition),
138 LagFrameChunk(LagFrameChunk),
139 MovieTransition(MovieTransition),
140 Comment(Comment),
141 Experimental(Experimental),
142 Unspecified(Unspecified),
143 Unsupported(Unsupported),
144}
145impl Packet {
146 pub fn with_reader(r: &mut Reader, keylen: u8) -> Result<Packet, PacketError> {
147 if r.remaining() < keylen as usize {
148 return Err(PacketError::MissingKey);
149 }
150 let key = r.read_len(keylen as usize).to_vec();
151
152 if r.remaining() < 1 {
153 return Err(PacketError::MissingPayloadLength);
154 }
155 let exp = r.read_u8() as usize;
156
157 if r.remaining() < exp {
158 return Err(PacketError::MissingPayloadLength);
159 }
160 if exp > 8 {
161 return Err(PacketError::UnsupportedExponent(exp as u8));
162 }
163
164 let mut plen = [0u8; 8];
165 for i in (0..exp).rev() {
166 plen[plen.len() - i - 1] = r.read_u8();
167 }
168 let plen = u64::from_be_bytes(plen);
169
170 let payload = r.read_len(plen as usize);
171 let payload = Reader::new(&payload);
172
173 let key = key.as_slice();
174 Ok(match key {
175 KEY_CONSOLE_TYPE => Packet::ConsoleType(ConsoleType::decode(key, payload)?),
176 KEY_CONSOLE_REGION => Packet::ConsoleRegion(ConsoleRegion::decode(key, payload)?),
177 KEY_GAME_TITLE => Packet::GameTitle(GameTitle::decode(key, payload)?),
178 KEY_ROM_NAME => Packet::RomName(RomName::decode(key, payload)?),
179 KEY_ATTRIBUTION => Packet::Attribution(Attribution::decode(key, payload)?),
180 KEY_CATEGORY => Packet::Category(Category::decode(key, payload)?),
181 KEY_EMULATOR_NAME => Packet::EmulatorName(EmulatorName::decode(key, payload)?),
182 KEY_EMULATOR_VERSION => Packet::EmulatorVersion(EmulatorVersion::decode(key, payload)?),
183 KEY_EMULATOR_CORE => Packet::EmulatorCore(EmulatorCore::decode(key, payload)?),
184 KEY_TAS_LAST_MODIFIED => Packet::TasLastModified(TasLastModified::decode(key, payload)?),
185 KEY_DUMP_CREATED => Packet::DumpCreated(DumpCreated::decode(key, payload)?),
186 KEY_DUMP_LAST_MODIFIED => Packet::DumpLastModified(DumpLastModified::decode(key, payload)?),
187 KEY_TOTAL_FRAMES => Packet::TotalFrames(TotalFrames::decode(key, payload)?),
188 KEY_RERECORDS => Packet::Rerecords(Rerecords::decode(key, payload)?),
189 KEY_SOURCE_LINK => Packet::SourceLink(SourceLink::decode(key, payload)?),
190 KEY_BLANK_FRAMES => Packet::BlankFrames(BlankFrames::decode(key, payload)?),
191 KEY_VERIFIED => Packet::Verified(Verified::decode(key, payload)?),
192 KEY_MEMORY_INIT => Packet::MemoryInit(MemoryInit::decode(key, payload)?),
193 KEY_GAME_IDENTIFIER => Packet::GameIdentifier(GameIdentifier::decode(key, payload)?),
194 KEY_MOVIE_LICENSE => Packet::MovieLicense(MovieLicense::decode(key, payload)?),
195 KEY_MOVIE_FILE => Packet::MovieFile(MovieFile::decode(key, payload)?),
196 KEY_PORT_CONTROLLER => Packet::PortController(PortController::decode(key, payload)?),
197 KEY_PORT_OVERREAD => Packet::PortOverread(PortOverread::decode(key, payload)?),
198 KEY_NES_LATCH_FILTER => Packet::NesLatchFilter(NesLatchFilter::decode(key, payload)?),
199 KEY_NES_CLOCK_FILTER => Packet::NesClockFilter(NesClockFilter::decode(key, payload)?),
200 KEY_NES_GAME_GENIE_CODE => Packet::NesGameGenieCode(NesGameGenieCode::decode(key, payload)?),
201 KEY_SNES_LATCH_FILTER => Packet::SnesLatchFilter(SnesLatchFilter::decode(key, payload)?),
202 KEY_SNES_CLOCK_FILTER => Packet::SnesClockFilter(SnesClockFilter::decode(key, payload)?),
203 KEY_SNES_GAME_GENIE_CODE => Packet::SnesGameGenieCode(SnesGameGenieCode::decode(key, payload)?),
204 KEY_SNES_LATCH_TRAIN => Packet::SnesLatchTrain(SnesLatchTrain::decode(key, payload)?),
205 KEY_GENESIS_GAME_GENIE_CODE => Packet::GenesisGameGenieCode(GenesisGameGenieCode::decode(key, payload)?),
206 KEY_INPUT_CHUNK => Packet::InputChunk(InputChunk::decode(key, payload)?),
207 KEY_INPUT_MOMENT => Packet::InputMoment(InputMoment::decode(key, payload)?),
208 KEY_TRANSITION => Packet::Transition(Transition::decode(key, payload)?),
209 KEY_LAG_FRAME_CHUNK => Packet::LagFrameChunk(LagFrameChunk::decode(key, payload)?),
210 KEY_MOVIE_TRANSITION => Packet::MovieTransition(MovieTransition::decode(key, payload)?),
211 KEY_COMMENT => Packet::Comment(Comment::decode(key, payload)?),
212 KEY_EXPERIMENTAL => Packet::Experimental(Experimental::decode(key, payload)?),
213 KEY_UNSPECIFIED => Packet::Unspecified(Unspecified::decode(key, payload)?),
214
215 _ => Packet::Unsupported(Unsupported::decode(key, payload)?)
216 })
217 }
218
219 pub fn kind(&self) -> PacketKind {
220 match self {
221 Self::ConsoleType(packet) => packet.kind(),
222 Self::ConsoleRegion(packet) => packet.kind(),
223 Self::GameTitle(packet) => packet.kind(),
224 Self::RomName(packet) => packet.kind(),
225 Self::Attribution(packet) => packet.kind(),
226 Self::Category(packet) => packet.kind(),
227 Self::EmulatorName(packet) => packet.kind(),
228 Self::EmulatorVersion(packet) => packet.kind(),
229 Self::EmulatorCore(packet) => packet.kind(),
230 Self::TasLastModified(packet) => packet.kind(),
231 Self::DumpCreated(packet) => packet.kind(),
232 Self::DumpLastModified(packet) => packet.kind(),
233 Self::TotalFrames(packet) => packet.kind(),
234 Self::Rerecords(packet) => packet.kind(),
235 Self::SourceLink(packet) => packet.kind(),
236 Self::BlankFrames(packet) => packet.kind(),
237 Self::Verified(packet) => packet.kind(),
238 Self::MemoryInit(packet) => packet.kind(),
239 Self::GameIdentifier(packet) => packet.kind(),
240 Self::MovieLicense(packet) => packet.kind(),
241 Self::MovieFile(packet) => packet.kind(),
242 Self::PortController(packet) => packet.kind(),
243 Self::PortOverread(packet) => packet.kind(),
244 Self::NesLatchFilter(packet) => packet.kind(),
245 Self::NesClockFilter(packet) => packet.kind(),
246 Self::NesGameGenieCode(packet) => packet.kind(),
247 Self::SnesLatchFilter(packet) => packet.kind(),
248 Self::SnesClockFilter(packet) => packet.kind(),
249 Self::SnesGameGenieCode(packet) => packet.kind(),
250 Self::SnesLatchTrain(packet) => packet.kind(),
251 Self::GenesisGameGenieCode(packet) => packet.kind(),
252 Self::InputChunk(packet) => packet.kind(),
253 Self::InputMoment(packet) => packet.kind(),
254 Self::Transition(packet) => packet.kind(),
255 Self::LagFrameChunk(packet) => packet.kind(),
256 Self::MovieTransition(packet) => packet.kind(),
257 Self::Comment(packet) => packet.kind(),
258 Self::Experimental(packet) => packet.kind(),
259 Self::Unspecified(packet) => packet.kind(),
260 Self::Unsupported(packet) => packet.kind(),
261 }
262 }
263}
264impl Encode for Packet {
265 fn encode(&self, keylen: u8) -> Vec<u8> {
266 match self {
267 Self::ConsoleType(packet) => packet.encode(keylen),
268 Self::ConsoleRegion(packet) => packet.encode(keylen),
269 Self::GameTitle(packet) => packet.encode(keylen),
270 Self::RomName(packet) => packet.encode(keylen),
271 Self::Attribution(packet) => packet.encode(keylen),
272 Self::Category(packet) => packet.encode(keylen),
273 Self::EmulatorName(packet) => packet.encode(keylen),
274 Self::EmulatorVersion(packet) => packet.encode(keylen),
275 Self::EmulatorCore(packet) => packet.encode(keylen),
276 Self::TasLastModified(packet) => packet.encode(keylen),
277 Self::DumpCreated(packet) => packet.encode(keylen),
278 Self::DumpLastModified(packet) => packet.encode(keylen),
279 Self::TotalFrames(packet) => packet.encode(keylen),
280 Self::Rerecords(packet) => packet.encode(keylen),
281 Self::SourceLink(packet) => packet.encode(keylen),
282 Self::BlankFrames(packet) => packet.encode(keylen),
283 Self::Verified(packet) => packet.encode(keylen),
284 Self::MemoryInit(packet) => packet.encode(keylen),
285 Self::GameIdentifier(packet) => packet.encode(keylen),
286 Self::MovieLicense(packet) => packet.encode(keylen),
287 Self::MovieFile(packet) => packet.encode(keylen),
288 Self::PortController(packet) => packet.encode(keylen),
289 Self::PortOverread(packet) => packet.encode(keylen),
290 Self::NesLatchFilter(packet) => packet.encode(keylen),
291 Self::NesClockFilter(packet) => packet.encode(keylen),
292 Self::NesGameGenieCode(packet) => packet.encode(keylen),
293 Self::SnesLatchFilter(packet) => packet.encode(keylen),
294 Self::SnesClockFilter(packet) => packet.encode(keylen),
295 Self::SnesGameGenieCode(packet) => packet.encode(keylen),
296 Self::SnesLatchTrain(packet) => packet.encode(keylen),
297 Self::GenesisGameGenieCode(packet) => packet.encode(keylen),
298 Self::InputChunk(packet) => packet.encode(keylen),
299 Self::InputMoment(packet) => packet.encode(keylen),
300 Self::Transition(packet) => packet.encode(keylen),
301 Self::LagFrameChunk(packet) => packet.encode(keylen),
302 Self::MovieTransition(packet) => packet.encode(keylen),
303 Self::Comment(packet) => packet.encode(keylen),
304 Self::Experimental(packet) => packet.encode(keylen),
305 Self::Unspecified(packet) => packet.encode(keylen),
306 Self::Unsupported(packet) => packet.encode(keylen),
307 }
308 }
309
310 fn key(&self) -> Vec<u8> {
311 match self {
312 Self::ConsoleType(packet) => packet.key(),
313 Self::ConsoleRegion(packet) => packet.key(),
314 Self::GameTitle(packet) => packet.key(),
315 Self::RomName(packet) => packet.key(),
316 Self::Attribution(packet) => packet.key(),
317 Self::Category(packet) => packet.key(),
318 Self::EmulatorName(packet) => packet.key(),
319 Self::EmulatorVersion(packet) => packet.key(),
320 Self::EmulatorCore(packet) => packet.key(),
321 Self::TasLastModified(packet) => packet.key(),
322 Self::DumpCreated(packet) => packet.key(),
323 Self::DumpLastModified(packet) => packet.key(),
324 Self::TotalFrames(packet) => packet.key(),
325 Self::Rerecords(packet) => packet.key(),
326 Self::SourceLink(packet) => packet.key(),
327 Self::BlankFrames(packet) => packet.key(),
328 Self::Verified(packet) => packet.key(),
329 Self::MemoryInit(packet) => packet.key(),
330 Self::GameIdentifier(packet) => packet.key(),
331 Self::MovieLicense(packet) => packet.key(),
332 Self::MovieFile(packet) => packet.key(),
333 Self::PortController(packet) => packet.key(),
334 Self::PortOverread(packet) => packet.key(),
335 Self::NesLatchFilter(packet) => packet.key(),
336 Self::NesClockFilter(packet) => packet.key(),
337 Self::NesGameGenieCode(packet) => packet.key(),
338 Self::SnesLatchFilter(packet) => packet.key(),
339 Self::SnesClockFilter(packet) => packet.key(),
340 Self::SnesGameGenieCode(packet) => packet.key(),
341 Self::SnesLatchTrain(packet) => packet.key(),
342 Self::GenesisGameGenieCode(packet) => packet.key(),
343 Self::InputChunk(packet) => packet.key(),
344 Self::InputMoment(packet) => packet.key(),
345 Self::Transition(packet) => packet.key(),
346 Self::LagFrameChunk(packet) => packet.key(),
347 Self::MovieTransition(packet) => packet.key(),
348 Self::Comment(packet) => packet.key(),
349 Self::Experimental(packet) => packet.key(),
350 Self::Unspecified(packet) => packet.key(),
351 Self::Unsupported(packet) => packet.key(),
352 }
353 }
354}
355impl_from_packet!(
356 ConsoleType
357 ConsoleRegion
358 GameTitle
359 RomName
360 Attribution
361 Category
362 EmulatorName
363 EmulatorVersion
364 EmulatorCore
365 TasLastModified
366 DumpCreated
367 DumpLastModified
368 TotalFrames
369 Rerecords
370 SourceLink
371 BlankFrames
372 Verified
373 MemoryInit
374 GameIdentifier
375 MovieLicense
376 MovieFile
377 PortController
378 PortOverread
379 NesLatchFilter
380 NesClockFilter
381 NesGameGenieCode
382 SnesLatchFilter
383 SnesClockFilter
384 SnesGameGenieCode
385 SnesLatchTrain
386 GenesisGameGenieCode
387 InputChunk
388 InputMoment
389 Transition
390 LagFrameChunk
391 MovieTransition
392 Comment
393 Experimental
394 Unspecified
395 Unsupported
396);
397
398#[derive(Debug, Copy, Clone, PartialEq, strum_macros::Display, strum_macros::EnumString)]
399#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
400pub enum PacketKind {
401 ConsoleType,
402 ConsoleRegion,
403 GameTitle,
404 RomName,
405 Attribution,
406 Category,
407 EmulatorName,
408 EmulatorVersion,
409 EmulatorCore,
410 TasLastModified,
411 DumpCreated,
412 DumpLastModified,
413 TotalFrames,
414 Rerecords,
415 SourceLink,
416 BlankFrames,
417 Verified,
418 MemoryInit,
419 GameIdentifier,
420 MovieLicense,
421 MovieFile,
422 PortController,
423 PortOverread,
424 NesLatchFilter,
425 NesClockFilter,
426 NesGameGenieCode,
427 SnesLatchFilter,
428 SnesClockFilter,
429 SnesGameGenieCode,
430 SnesLatchTrain,
431 GenesisGameGenieCode,
432 InputChunk,
433 InputMoment,
434 Transition,
435 LagFrameChunk,
436 MovieTransition,
437 Comment,
438 Experimental,
439 Unspecified,
440 Unsupported,
441}
442
443
444
445#[derive(Debug, Clone, PartialEq)]
447pub struct Unsupported {
448 pub key: Vec<u8>,
449 pub payload: Vec<u8>,
450}
451impl Decode for Unsupported {
452 fn decode(key: &[u8], payload: Reader) -> Result<Self, PacketError> {
453 Ok(Self {
454 key: key.to_vec(),
455 payload: payload.to_vec(),
456 })
457 }
458
459 fn kind(&self) -> PacketKind {
460 PacketKind::Unsupported
461 }
462}
463impl Encode for Unsupported {
464 fn encode(&self, keylen: u8) -> Vec<u8> {
465 let mut w = Writer::new();
466
467 w.write_slice(&self.payload);
468
469 w.into_packet(&self.key, keylen)
470 }
471
472 fn key(&self) -> Vec<u8> {
473 self.key.clone()
474 }
475}
476
477
478#[derive(Debug, Clone, PartialEq)]
480pub struct ConsoleType {
481 pub kind: u8,
482 pub custom: Option<String>,
483}
484impl Decode for ConsoleType {
485 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
486 if payload.remaining() < 1 {
487 return Err(PacketError::invalid(key, payload));
488 }
489 let kind = payload.read_u8();
490
491 let custom = payload.read_remaining();
492 let custom = if custom.is_empty() {
493 None
494 } else {
495 Some(String::from_utf8_lossy(custom).to_string())
496 };
497
498 Ok(Self {
499 kind,
500 custom,
501 })
502 }
503
504 fn kind(&self) -> PacketKind {
505 PacketKind::ConsoleType
506 }
507}
508impl Encode for ConsoleType {
509 fn encode(&self, keylen: u8) -> Vec<u8> {
510 let mut w = Writer::new();
511
512 w.write_u8(self.kind);
513 w.write_option_string(&self.custom);
514
515 w.into_packet(&self.key(), keylen)
516 }
517
518 fn key(&self) -> Vec<u8> {
519 KEY_CONSOLE_TYPE.to_vec()
520 }
521}
522
523
524#[derive(Debug, Clone, PartialEq)]
526pub struct ConsoleRegion {
527 pub region: u8,
528}
529impl Decode for ConsoleRegion {
530 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
531 if payload.remaining() != 1 {
532 return Err(PacketError::invalid(key, payload));
533 }
534
535 Ok(Self {
536 region: payload.read_u8(),
537 })
538 }
539
540 fn kind(&self) -> PacketKind {
541 PacketKind::ConsoleRegion
542 }
543}
544impl Encode for ConsoleRegion {
545 fn encode(&self, keylen: u8) -> Vec<u8> {
546 let mut w = Writer::new();
547
548 w.write_u8(self.region);
549
550 w.into_packet(&self.key(), keylen)
551 }
552
553 fn key(&self) -> Vec<u8> {
554 KEY_CONSOLE_REGION.to_vec()
555 }
556}
557
558
559#[derive(Debug, Clone, PartialEq)]
561pub struct GameTitle {
562 pub title: String,
563}
564impl Decode for GameTitle {
565 fn decode(_key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
566 Ok(Self {
567 title: payload.read_string(payload.remaining())
568 })
569 }
570
571 fn kind(&self) -> PacketKind {
572 PacketKind::GameTitle
573 }
574}
575impl Encode for GameTitle {
576 fn encode(&self, keylen: u8) -> Vec<u8> {
577 let mut w = Writer::new();
578
579 w.write_str(&self.title);
580
581 w.into_packet(&self.key(), keylen)
582 }
583
584 fn key(&self) -> Vec<u8> {
585 KEY_GAME_TITLE.to_vec()
586 }
587}
588
589
590#[derive(Debug, Clone, PartialEq)]
592pub struct RomName {
593 pub name: String,
594}
595impl Decode for RomName {
596 fn decode(_key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
597 Ok(Self {
598 name: payload.read_string(payload.remaining())
599 })
600 }
601
602 fn kind(&self) -> PacketKind {
603 PacketKind::RomName
604 }
605}
606impl Encode for RomName {
607 fn encode(&self, keylen: u8) -> Vec<u8> {
608 let mut w = Writer::new();
609
610 w.write_str(&self.name);
611
612 w.into_packet(&self.key(), keylen)
613 }
614
615 fn key(&self) -> Vec<u8> {
616 KEY_ROM_NAME.to_vec()
617 }
618}
619
620
621#[derive(Debug, Clone, PartialEq)]
623pub struct Attribution {
624 pub kind: u8,
625 pub name: String,
626}
627impl Decode for Attribution {
628 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
629 if payload.remaining() < 1 {
630 return Err(PacketError::invalid(key, payload));
631 }
632
633 Ok(Self {
634 kind: payload.read_u8(),
635 name: payload.read_string(payload.remaining()),
636 })
637 }
638
639 fn kind(&self) -> PacketKind {
640 PacketKind::Attribution
641 }
642}
643impl Encode for Attribution {
644 fn encode(&self, keylen: u8) -> Vec<u8> {
645 let mut w = Writer::new();
646
647 w.write_u8(self.kind);
648 w.write_str(&self.name);
649
650 w.into_packet(&self.key(), keylen)
651 }
652
653 fn key(&self) -> Vec<u8> {
654 KEY_ATTRIBUTION.to_vec()
655 }
656}
657
658
659#[derive(Debug, Clone, PartialEq)]
661pub struct Category {
662 pub category: String,
663}
664impl Decode for Category {
665 fn decode(_key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
666 Ok(Self {
667 category: payload.read_string(payload.remaining())
668 })
669 }
670
671 fn kind(&self) -> PacketKind {
672 PacketKind::Category
673 }
674}
675impl Encode for Category {
676 fn encode(&self, keylen: u8) -> Vec<u8> {
677 let mut w = Writer::new();
678
679 w.write_str(&self.category);
680
681 w.into_packet(&self.key(), keylen)
682 }
683
684 fn key(&self) -> Vec<u8> {
685 KEY_CATEGORY.to_vec()
686 }
687}
688
689
690#[derive(Debug, Clone, PartialEq)]
692pub struct EmulatorName {
693 pub name: String,
694}
695impl Decode for EmulatorName {
696 fn decode(_key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
697 Ok(Self {
698 name: payload.read_string(payload.remaining())
699 })
700 }
701
702 fn kind(&self) -> PacketKind {
703 PacketKind::EmulatorName
704 }
705}
706impl Encode for EmulatorName {
707 fn encode(&self, keylen: u8) -> Vec<u8> {
708 let mut w = Writer::new();
709
710 w.write_str(&self.name);
711
712 w.into_packet(&self.key(), keylen)
713 }
714
715 fn key(&self) -> Vec<u8> {
716 KEY_EMULATOR_NAME.to_vec()
717 }
718}
719
720
721#[derive(Debug, Clone, PartialEq)]
723pub struct EmulatorVersion {
724 pub version: String,
725}
726impl Decode for EmulatorVersion {
727 fn decode(_key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
728 Ok(Self {
729 version: payload.read_string(payload.remaining())
730 })
731 }
732
733 fn kind(&self) -> PacketKind {
734 PacketKind::EmulatorVersion
735 }
736}
737impl Encode for EmulatorVersion {
738 fn encode(&self, keylen: u8) -> Vec<u8> {
739 let mut w = Writer::new();
740
741 w.write_str(&self.version);
742
743 w.into_packet(&self.key(), keylen)
744 }
745
746 fn key(&self) -> Vec<u8> {
747 KEY_EMULATOR_VERSION.to_vec()
748 }
749}
750
751
752#[derive(Debug, Clone, PartialEq)]
754pub struct EmulatorCore {
755 pub core: String,
756}
757impl Decode for EmulatorCore {
758 fn decode(_key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
759 Ok(Self {
760 core: payload.read_string(payload.remaining())
761 })
762 }
763
764 fn kind(&self) -> PacketKind {
765 PacketKind::EmulatorCore
766 }
767}
768impl Encode for EmulatorCore {
769 fn encode(&self, keylen: u8) -> Vec<u8> {
770 let mut w = Writer::new();
771
772 w.write_str(&self.core);
773
774 w.into_packet(&self.key(), keylen)
775 }
776
777 fn key(&self) -> Vec<u8> {
778 KEY_EMULATOR_CORE.to_vec()
779 }
780}
781
782
783#[derive(Debug, Clone, PartialEq)]
785pub struct TasLastModified {
786 pub epoch: i64,
787}
788impl Decode for TasLastModified {
789 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
790 if payload.remaining() != 8 {
791 return Err(PacketError::invalid(key, payload));
792 }
793
794 Ok(Self {
795 epoch: payload.read_i64(),
796 })
797 }
798
799 fn kind(&self) -> PacketKind {
800 PacketKind::TasLastModified
801 }
802}
803impl Encode for TasLastModified {
804 fn encode(&self, keylen: u8) -> Vec<u8> {
805 let mut w = Writer::new();
806
807 w.write_i64(self.epoch);
808
809 w.into_packet(&self.key(), keylen)
810 }
811
812 fn key(&self) -> Vec<u8> {
813 KEY_TAS_LAST_MODIFIED.to_vec()
814 }
815}
816
817
818#[derive(Debug, Clone, PartialEq)]
820pub struct DumpCreated {
821 pub epoch: i64,
822}
823impl Decode for DumpCreated {
824 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
825 if payload.remaining() != 8 {
826 return Err(PacketError::invalid(key, payload));
827 }
828
829 Ok(Self {
830 epoch: payload.read_i64(),
831 })
832 }
833
834 fn kind(&self) -> PacketKind {
835 PacketKind::DumpCreated
836 }
837}
838impl Encode for DumpCreated {
839 fn encode(&self, keylen: u8) -> Vec<u8> {
840 let mut w = Writer::new();
841
842 w.write_i64(self.epoch);
843
844 w.into_packet(&self.key(), keylen)
845 }
846
847 fn key(&self) -> Vec<u8> {
848 KEY_DUMP_CREATED.to_vec()
849 }
850}
851
852
853#[derive(Debug, Clone, PartialEq)]
855pub struct DumpLastModified {
856 pub epoch: i64,
857}
858impl Decode for DumpLastModified {
859 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
860 if payload.remaining() != 8 {
861 return Err(PacketError::invalid(key, payload));
862 }
863
864 Ok(Self {
865 epoch: payload.read_i64(),
866 })
867 }
868
869 fn kind(&self) -> PacketKind {
870 PacketKind::DumpLastModified
871 }
872}
873impl Encode for DumpLastModified {
874 fn encode(&self, keylen: u8) -> Vec<u8> {
875 let mut w = Writer::new();
876
877 w.write_i64(self.epoch);
878
879 w.into_packet(&self.key(), keylen)
880 }
881
882 fn key(&self) -> Vec<u8> {
883 KEY_DUMP_LAST_MODIFIED.to_vec()
884 }
885}
886
887
888#[derive(Debug, Clone, PartialEq)]
890pub struct TotalFrames {
891 pub frames: u32,
892}
893impl Decode for TotalFrames {
894 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
895 if payload.remaining() != 4 {
896 return Err(PacketError::invalid(key, payload));
897 }
898
899 Ok(Self {
900 frames: payload.read_u32(),
901 })
902 }
903
904 fn kind(&self) -> PacketKind {
905 PacketKind::TotalFrames
906 }
907}
908impl Encode for TotalFrames {
909 fn encode(&self, keylen: u8) -> Vec<u8> {
910 let mut w = Writer::new();
911
912 w.write_u32(self.frames);
913
914 w.into_packet(&self.key(), keylen)
915 }
916
917 fn key(&self) -> Vec<u8> {
918 KEY_TOTAL_FRAMES.to_vec()
919 }
920}
921
922
923#[derive(Debug, Clone, PartialEq)]
925pub struct Rerecords {
926 pub rerecords: u32,
927}
928impl Decode for Rerecords {
929 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
930 if payload.remaining() != 4 {
931 return Err(PacketError::invalid(key, payload));
932 }
933
934 Ok(Self {
935 rerecords: payload.read_u32(),
936 })
937 }
938
939 fn kind(&self) -> PacketKind {
940 PacketKind::Rerecords
941 }
942}
943impl Encode for Rerecords {
944 fn encode(&self, keylen: u8) -> Vec<u8> {
945 let mut w = Writer::new();
946
947 w.write_u32(self.rerecords);
948
949 w.into_packet(&self.key(), keylen)
950 }
951
952 fn key(&self) -> Vec<u8> {
953 KEY_RERECORDS.to_vec()
954 }
955}
956
957
958#[derive(Debug, Clone, PartialEq)]
960pub struct SourceLink {
961 pub link: String,
962}
963impl Decode for SourceLink {
964 fn decode(_key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
965 Ok(Self {
966 link: payload.read_string(payload.remaining())
967 })
968 }
969
970 fn kind(&self) -> PacketKind {
971 PacketKind::SourceLink
972 }
973}
974impl Encode for SourceLink {
975 fn encode(&self, keylen: u8) -> Vec<u8> {
976 let mut w = Writer::new();
977
978 w.write_str(&self.link);
979
980 w.into_packet(&self.key(), keylen)
981 }
982
983 fn key(&self) -> Vec<u8> {
984 KEY_SOURCE_LINK.to_vec()
985 }
986}
987
988
989#[derive(Debug, Clone, PartialEq)]
991pub struct BlankFrames {
992 pub frames: i16,
993}
994impl Decode for BlankFrames {
995 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
996 if payload.remaining() != 2 {
997 return Err(PacketError::invalid(key, payload));
998 }
999
1000 Ok(Self {
1001 frames: payload.read_i16(),
1002 })
1003 }
1004
1005 fn kind(&self) -> PacketKind {
1006 PacketKind::BlankFrames
1007 }
1008}
1009impl Encode for BlankFrames {
1010 fn encode(&self, keylen: u8) -> Vec<u8> {
1011 let mut w = Writer::new();
1012
1013 w.write_i16(self.frames);
1014
1015 w.into_packet(&self.key(), keylen)
1016 }
1017
1018 fn key(&self) -> Vec<u8> {
1019 KEY_BLANK_FRAMES.to_vec()
1020 }
1021}
1022
1023
1024#[derive(Debug, Clone, PartialEq)]
1026pub struct Verified {
1027 pub verified: bool,
1028}
1029impl Decode for Verified {
1030 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
1031 if payload.remaining() != 1 {
1032 return Err(PacketError::invalid(key, payload));
1033 }
1034
1035 Ok(Self {
1036 verified: payload.read_bool(),
1037 })
1038 }
1039
1040 fn kind(&self) -> PacketKind {
1041 PacketKind::Verified
1042 }
1043}
1044impl Encode for Verified {
1045 fn encode(&self, keylen: u8) -> Vec<u8> {
1046 let mut w = Writer::new();
1047
1048 w.write_bool(self.verified);
1049
1050 w.into_packet(&self.key(), keylen)
1051 }
1052
1053 fn key(&self) -> Vec<u8> {
1054 KEY_VERIFIED.to_vec()
1055 }
1056}
1057
1058
1059#[derive(Debug, Clone, PartialEq)]
1061pub struct MemoryInit {
1062 pub data_type: u8,
1063 pub device: u16,
1064 pub required: bool,
1065 pub name: String,
1066 pub data: Option<Vec<u8>>,
1067}
1068impl Decode for MemoryInit {
1069 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
1070 if payload.remaining() < 5 {
1071 return Err(PacketError::invalid(key, payload));
1072 }
1073 let data_type = payload.read_u8();
1074 let device = payload.read_u16();
1075 let required = payload.read_bool();
1076
1077 let nlen = payload.read_u8();
1078 if payload.remaining() < nlen as usize {
1079 return Err(PacketError::invalid(key, payload));
1080 }
1081 let name = payload.read_string(nlen as usize);
1082
1083 Ok(Self {
1084 data_type,
1085 device,
1086 required,
1087 name,
1088 data: if data_type == 0xFF { Some(payload.read_remaining().to_vec()) } else { None },
1089 })
1090 }
1091
1092 fn kind(&self) -> PacketKind {
1093 PacketKind::MemoryInit
1094 }
1095}
1096impl Encode for MemoryInit {
1097 fn encode(&self, keylen: u8) -> Vec<u8> {
1098 let mut w = Writer::new();
1099
1100 w.write_u8(self.data_type);
1101 w.write_u16(self.device);
1102 w.write_bool(self.required);
1103 w.write_u8_str(&self.name);
1104
1105 w.into_packet(&self.key(), keylen)
1106 }
1107
1108 fn key(&self) -> Vec<u8> {
1109 KEY_MEMORY_INIT.to_vec()
1110 }
1111}
1112
1113
1114#[derive(Debug, Clone, PartialEq)]
1116pub struct GameIdentifier {
1117 pub kind: u8,
1118 pub encoding: u8,
1119 pub name: String,
1120 pub identifier: Vec<u8>,
1121}
1122impl Decode for GameIdentifier {
1123 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
1124 if payload.remaining() < 3 {
1125 return Err(PacketError::invalid(key, payload));
1126 }
1127
1128 let kind = payload.read_u8();
1129 let encoding = payload.read_u8();
1130
1131 let nlen = payload.read_u8();
1132 if payload.remaining() < nlen as usize {
1133 return Err(PacketError::invalid(key, payload));
1134 }
1135 let name = payload.read_string(nlen as usize);
1136
1137 let identifier = payload.read_remaining().to_vec();
1138
1139 Ok(Self {
1140 kind,
1141 encoding,
1142 name,
1143 identifier,
1144 })
1145 }
1146
1147 fn kind(&self) -> PacketKind {
1148 PacketKind::GameIdentifier
1149 }
1150}
1151impl Encode for GameIdentifier {
1152 fn encode(&self, keylen: u8) -> Vec<u8> {
1153 let mut w = Writer::new();
1154
1155 w.write_u8(self.kind);
1156 w.write_u8(self.encoding);
1157 w.write_u8_str(&self.name);
1158 w.write_slice(&self.identifier);
1159
1160 w.into_packet(&self.key(), keylen)
1161 }
1162
1163 fn key(&self) -> Vec<u8> {
1164 KEY_GAME_IDENTIFIER.to_vec()
1165 }
1166}
1167
1168
1169#[derive(Debug, Clone, PartialEq)]
1171pub struct MovieLicense {
1172 pub license: String,
1173}
1174impl Decode for MovieLicense {
1175 fn decode(_key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
1176 Ok(Self {
1177 license: payload.read_string(payload.remaining())
1178 })
1179 }
1180
1181 fn kind(&self) -> PacketKind {
1182 PacketKind::MovieLicense
1183 }
1184}
1185impl Encode for MovieLicense {
1186 fn encode(&self, keylen: u8) -> Vec<u8> {
1187 let mut w = Writer::new();
1188
1189 w.write_str(&self.license);
1190
1191 w.into_packet(&self.key(), keylen)
1192 }
1193
1194 fn key(&self) -> Vec<u8> {
1195 KEY_MOVIE_LICENSE.to_vec()
1196 }
1197}
1198
1199
1200#[derive(Debug, Clone, PartialEq)]
1202pub struct MovieFile {
1203 pub name: String,
1204 pub data: Vec<u8>,
1205}
1206impl Decode for MovieFile {
1207 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
1208 if payload.remaining() < 1 {
1209 return Err(PacketError::invalid(key, payload));
1210 }
1211 let nlen = payload.read_u8();
1212 if payload.remaining() < nlen as usize {
1213 return Err(PacketError::invalid(key, payload));
1214 }
1215 let name = payload.read_string(nlen as usize);
1216
1217 Ok(Self {
1218 name,
1219 data: payload.read_remaining().to_vec(),
1220 })
1221 }
1222
1223 fn kind(&self) -> PacketKind {
1224 PacketKind::MovieFile
1225 }
1226}
1227impl Encode for MovieFile {
1228 fn encode(&self, keylen: u8) -> Vec<u8> {
1229 let mut w = Writer::new();
1230
1231 w.write_u8_str(&self.name);
1232 w.write_slice(&self.data);
1233
1234 w.into_packet(&self.key(), keylen)
1235 }
1236
1237 fn key(&self) -> Vec<u8> {
1238 KEY_MOVIE_FILE.to_vec()
1239 }
1240}
1241
1242
1243#[derive(Debug, Clone, PartialEq)]
1245pub struct PortController {
1246 pub port: u8,
1247 pub kind: u16,
1248}
1249impl Decode for PortController {
1250 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
1251 if payload.remaining() != 3 {
1252 return Err(PacketError::invalid(key, payload));
1253 }
1254
1255 Ok(Self {
1256 port: payload.read_u8(),
1257 kind: payload.read_u16(),
1258 })
1259 }
1260
1261 fn kind(&self) -> PacketKind {
1262 PacketKind::PortController
1263 }
1264}
1265impl Encode for PortController {
1266 fn encode(&self, keylen: u8) -> Vec<u8> {
1267 let mut w = Writer::new();
1268
1269 w.write_u8(self.port);
1270 w.write_u16(self.kind);
1271
1272 w.into_packet(&self.key(), keylen)
1273 }
1274
1275 fn key(&self) -> Vec<u8> {
1276 KEY_PORT_CONTROLLER.to_vec()
1277 }
1278}
1279
1280
1281#[derive(Debug, Clone, PartialEq)]
1283pub struct PortOverread {
1284 pub port: u8,
1285 pub overread: bool,
1286}
1287impl Decode for PortOverread {
1288 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
1289 if payload.remaining() != 2 {
1290 return Err(PacketError::invalid(key, payload));
1291 }
1292
1293 Ok(Self {
1294 port: payload.read_u8(),
1295 overread: payload.read_bool(),
1296 })
1297 }
1298
1299 fn kind(&self) -> PacketKind {
1300 PacketKind::PortOverread
1301 }
1302}
1303impl Encode for PortOverread {
1304 fn encode(&self, keylen: u8) -> Vec<u8> {
1305 let mut w = Writer::new();
1306
1307 w.write_u8(self.port);
1308 w.write_bool(self.overread);
1309
1310 w.into_packet(&self.key(), keylen)
1311 }
1312
1313 fn key(&self) -> Vec<u8> {
1314 KEY_PORT_OVERREAD.to_vec()
1315 }
1316}
1317
1318
1319#[derive(Debug, Clone, PartialEq)]
1321pub struct NesLatchFilter {
1322 pub time: u16,
1323}
1324impl Decode for NesLatchFilter {
1325 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
1326 if payload.remaining() != 2 {
1327 return Err(PacketError::invalid(key, payload));
1328 }
1329
1330 Ok(Self {
1331 time: payload.read_u16(),
1332 })
1333 }
1334
1335 fn kind(&self) -> PacketKind {
1336 PacketKind::NesLatchFilter
1337 }
1338}
1339impl Encode for NesLatchFilter {
1340 fn encode(&self, keylen: u8) -> Vec<u8> {
1341 let mut w = Writer::new();
1342
1343 w.write_u16(self.time);
1344
1345 w.into_packet(&self.key(), keylen)
1346 }
1347
1348 fn key(&self) -> Vec<u8> {
1349 KEY_NES_LATCH_FILTER.to_vec()
1350 }
1351}
1352
1353
1354#[derive(Debug, Clone, PartialEq)]
1356pub struct NesClockFilter {
1357 pub time: u8,
1358}
1359impl Decode for NesClockFilter {
1360 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
1361 if payload.remaining() != 1 {
1362 return Err(PacketError::invalid(key, payload));
1363 }
1364
1365 Ok(Self {
1366 time: payload.read_u8(),
1367 })
1368 }
1369
1370 fn kind(&self) -> PacketKind {
1371 PacketKind::NesClockFilter
1372 }
1373}
1374impl Encode for NesClockFilter {
1375 fn encode(&self, keylen: u8) -> Vec<u8> {
1376 let mut w = Writer::new();
1377
1378 w.write_u8(self.time);
1379
1380 w.into_packet(&self.key(), keylen)
1381 }
1382
1383 fn key(&self) -> Vec<u8> {
1384 KEY_NES_CLOCK_FILTER.to_vec()
1385 }
1386}
1387
1388
1389#[derive(Debug, Clone, PartialEq)]
1391pub struct NesGameGenieCode {
1392 pub code: String,
1393}
1394impl Decode for NesGameGenieCode {
1395 fn decode(_key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
1396 Ok(Self {
1397 code: payload.read_string(payload.remaining())
1398 })
1399 }
1400
1401 fn kind(&self) -> PacketKind {
1402 PacketKind::NesGameGenieCode
1403 }
1404}
1405impl Encode for NesGameGenieCode {
1406 fn encode(&self, keylen: u8) -> Vec<u8> {
1407 let mut w = Writer::new();
1408
1409 w.write_str(&self.code);
1410
1411 w.into_packet(&self.key(), keylen)
1412 }
1413
1414 fn key(&self) -> Vec<u8> {
1415 KEY_NES_GAME_GENIE_CODE.to_vec()
1416 }
1417}
1418
1419
1420#[derive(Debug, Clone, PartialEq)]
1422pub struct SnesLatchFilter {
1423 pub time: u16,
1424}
1425impl Decode for SnesLatchFilter {
1426 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
1427 if payload.remaining() != 2 {
1428 return Err(PacketError::invalid(key, payload));
1429 }
1430
1431 Ok(Self {
1432 time: payload.read_u16(),
1433 })
1434 }
1435
1436 fn kind(&self) -> PacketKind {
1437 PacketKind::SnesLatchFilter
1438 }
1439}
1440impl Encode for SnesLatchFilter {
1441 fn encode(&self, keylen: u8) -> Vec<u8> {
1442 let mut w = Writer::new();
1443
1444 w.write_u16(self.time);
1445
1446 w.into_packet(&self.key(), keylen)
1447 }
1448
1449 fn key(&self) -> Vec<u8> {
1450 KEY_SNES_LATCH_FILTER.to_vec()
1451 }
1452}
1453
1454
1455#[derive(Debug, Clone, PartialEq)]
1457pub struct SnesClockFilter {
1458 pub time: u8,
1459}
1460impl Decode for SnesClockFilter {
1461 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
1462 if payload.remaining() != 1 {
1463 return Err(PacketError::invalid(key, payload));
1464 }
1465
1466 Ok(Self {
1467 time: payload.read_u8(),
1468 })
1469 }
1470
1471 fn kind(&self) -> PacketKind {
1472 PacketKind::SnesClockFilter
1473 }
1474}
1475impl Encode for SnesClockFilter {
1476 fn encode(&self, keylen: u8) -> Vec<u8> {
1477 let mut w = Writer::new();
1478
1479 w.write_u8(self.time);
1480
1481 w.into_packet(&self.key(), keylen)
1482 }
1483
1484 fn key(&self) -> Vec<u8> {
1485 KEY_SNES_CLOCK_FILTER.to_vec()
1486 }
1487}
1488
1489
1490#[derive(Debug, Clone, PartialEq)]
1492pub struct SnesGameGenieCode {
1493 pub code: String,
1494}
1495impl Decode for SnesGameGenieCode {
1496 fn decode(_key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
1497 Ok(Self {
1498 code: payload.read_string(payload.remaining())
1499 })
1500 }
1501
1502 fn kind(&self) -> PacketKind {
1503 PacketKind::SnesGameGenieCode
1504 }
1505}
1506impl Encode for SnesGameGenieCode {
1507 fn encode(&self, keylen: u8) -> Vec<u8> {
1508 let mut w = Writer::new();
1509
1510 w.write_str(&self.code);
1511
1512 w.into_packet(&self.key(), keylen)
1513 }
1514
1515 fn key(&self) -> Vec<u8> {
1516 KEY_SNES_GAME_GENIE_CODE.to_vec()
1517 }
1518}
1519
1520
1521#[derive(Debug, Clone, PartialEq)]
1523pub struct SnesLatchTrain {
1524 pub points: Vec<u64>,
1525}
1526impl Decode for SnesLatchTrain {
1527 fn decode(_key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
1528 Ok(Self {
1529 points: payload.read_remaining()
1530 .chunks_exact(8)
1531 .map(|chunk| u64::from_be_bytes(chunk.try_into().unwrap()))
1532 .collect()
1533 })
1534 }
1535
1536 fn kind(&self) -> PacketKind {
1537 PacketKind::SnesLatchTrain
1538 }
1539}
1540impl Encode for SnesLatchTrain {
1541 fn encode(&self, keylen: u8) -> Vec<u8> {
1542 let mut w = Writer::new();
1543
1544 w.write_slice(&self.points.iter()
1545 .map(|point| point.to_be_bytes())
1546 .flatten()
1547 .collect::<Vec<u8>>());
1548
1549 w.into_packet(&self.key(), keylen)
1550 }
1551
1552 fn key(&self) -> Vec<u8> {
1553 KEY_SNES_LATCH_TRAIN.to_vec()
1554 }
1555}
1556
1557
1558#[derive(Debug, Clone, PartialEq)]
1560pub struct GenesisGameGenieCode {
1561 pub code: String,
1562}
1563impl Decode for GenesisGameGenieCode {
1564 fn decode(_key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
1565 Ok(Self {
1566 code: payload.read_string(payload.remaining())
1567 })
1568 }
1569
1570 fn kind(&self) -> PacketKind {
1571 PacketKind::GenesisGameGenieCode
1572 }
1573}
1574impl Encode for GenesisGameGenieCode {
1575 fn encode(&self, keylen: u8) -> Vec<u8> {
1576 let mut w = Writer::new();
1577
1578 w.write_str(&self.code);
1579
1580 w.into_packet(&self.key(), keylen)
1581 }
1582
1583 fn key(&self) -> Vec<u8> {
1584 KEY_GENESIS_GAME_GENIE_CODE.to_vec()
1585 }
1586}
1587
1588
1589#[derive(Debug, Clone, PartialEq)]
1591pub struct InputChunk {
1592 pub port: u8,
1593 pub inputs: Vec<u8>,
1594}
1595impl Decode for InputChunk {
1596 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
1597 if payload.remaining() < 1 {
1598 return Err(PacketError::invalid(key, payload));
1599 }
1600
1601 Ok(Self {
1602 port: payload.read_u8(),
1603 inputs: payload.read_remaining().to_vec(),
1604 })
1605 }
1606
1607 fn kind(&self) -> PacketKind {
1608 PacketKind::InputChunk
1609 }
1610}
1611impl Encode for InputChunk {
1612 fn encode(&self, keylen: u8) -> Vec<u8> {
1613 let mut w = Writer::new();
1614
1615 w.write_u8(self.port);
1616 w.write_slice(&self.inputs);
1617
1618 w.into_packet(&self.key(), keylen)
1619 }
1620
1621 fn key(&self) -> Vec<u8> {
1622 KEY_INPUT_CHUNK.to_vec()
1623 }
1624}
1625
1626
1627#[derive(Debug, Clone, PartialEq)]
1629pub struct InputMoment {
1630 pub port: u8,
1631 pub index_type: u8,
1632 pub index: u64,
1633 pub inputs: Vec<u8>,
1634}
1635impl Decode for InputMoment {
1636 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
1637 if payload.remaining() < 10 {
1638 return Err(PacketError::invalid(key, payload));
1639 }
1640
1641 Ok(Self {
1642 port: payload.read_u8(),
1643 index_type: payload.read_u8(),
1644 index: payload.read_u64(),
1645 inputs: payload.read_remaining().to_vec(),
1646 })
1647 }
1648
1649 fn kind(&self) -> PacketKind {
1650 PacketKind::InputMoment
1651 }
1652}
1653impl Encode for InputMoment {
1654 fn encode(&self, keylen: u8) -> Vec<u8> {
1655 let mut w = Writer::new();
1656
1657 w.write_u8(self.port);
1658 w.write_u8(self.index_type);
1659 w.write_u64(self.index);
1660 w.write_slice(&self.inputs);
1661
1662 w.into_packet(&self.key(), keylen)
1663 }
1664
1665 fn key(&self) -> Vec<u8> {
1666 KEY_INPUT_MOMENT.to_vec()
1667 }
1668}
1669
1670
1671#[derive(Debug, Clone, PartialEq)]
1673pub struct Transition {
1674 pub index_type: u8,
1675 pub port: u8,
1676 pub index: u64,
1677 pub transition_type: u8,
1678 pub packet: Option<Box<Packet>>,
1679}
1680impl Decode for Transition {
1681 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
1682 if payload.remaining() < 10 {
1683 return Err(PacketError::invalid(key, payload));
1684 }
1685 let index_type = payload.read_u8();
1686 let port = payload.read_u8();
1687 let index = payload.read_u64();
1688 let transition_type = payload.read_u8();
1689 let packet_data = payload.read_remaining();
1690 let mut packet_reader = Reader::new(&packet_data);
1691
1692 Ok(Self {
1693 index_type,
1694 port,
1695 index,
1696 transition_type,
1697 packet: if transition_type == 0xFF { Some(Box::new(Packet::with_reader(&mut packet_reader, key.len() as u8)?)) } else { None }
1698 })
1699 }
1700
1701 fn kind(&self) -> PacketKind {
1702 PacketKind::Transition
1703 }
1704}
1705impl Encode for Transition {
1706 fn encode(&self, keylen: u8) -> Vec<u8> {
1707 let mut w = Writer::new();
1708
1709 w.write_u8(self.index_type);
1710 w.write_u8(self.port);
1711 w.write_u64(self.index);
1712 w.write_u8(self.transition_type);
1713 if let Some(packet) = self.packet.as_ref() {
1714 w.write_slice(&packet.encode(keylen));
1715 }
1716
1717 w.into_packet(&self.key(), keylen)
1718 }
1719
1720 fn key(&self) -> Vec<u8> {
1721 KEY_TRANSITION.to_vec()
1722 }
1723}
1724
1725
1726#[derive(Debug, Clone, PartialEq)]
1728pub struct LagFrameChunk {
1729 pub movie_frame: u32,
1730 pub count: u32,
1731}
1732impl Decode for LagFrameChunk {
1733 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
1734 if payload.remaining() != 8 {
1735 return Err(PacketError::invalid(key, payload));
1736 }
1737
1738 Ok(Self {
1739 movie_frame: payload.read_u32(),
1740 count: payload.read_u32(),
1741 })
1742 }
1743
1744 fn kind(&self) -> PacketKind {
1745 PacketKind::LagFrameChunk
1746 }
1747}
1748impl Encode for LagFrameChunk {
1749 fn encode(&self, keylen: u8) -> Vec<u8> {
1750 let mut w = Writer::new();
1751
1752 w.write_u32(self.movie_frame);
1753 w.write_u32(self.count);
1754
1755 w.into_packet(&self.key(), keylen)
1756 }
1757
1758 fn key(&self) -> Vec<u8> {
1759 KEY_LAG_FRAME_CHUNK.to_vec()
1760 }
1761}
1762
1763
1764#[derive(Debug, Clone, PartialEq)]
1766pub struct MovieTransition {
1767 pub movie_frame: u32,
1768 pub transition_type: u8,
1769 pub packet: Option<Box<Packet>>,
1770}
1771impl Decode for MovieTransition {
1772 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
1773 if payload.remaining() < 5 {
1774 return Err(PacketError::invalid(key, payload));
1775 }
1776 let movie_frame = payload.read_u32();
1777 let transition_type = payload.read_u8();
1778 let packet_data = payload.read_remaining();
1779 let mut packet_reader = Reader::new(&packet_data);
1780
1781 Ok(Self {
1782 movie_frame,
1783 transition_type,
1784 packet: if transition_type == 0xFF { Some(Box::new(Packet::with_reader(&mut packet_reader, key.len() as u8)?)) } else { None }
1785 })
1786 }
1787
1788 fn kind(&self) -> PacketKind {
1789 PacketKind::MovieTransition
1790 }
1791}
1792impl Encode for MovieTransition {
1793 fn encode(&self, keylen: u8) -> Vec<u8> {
1794 let mut w = Writer::new();
1795
1796 w.write_u32(self.movie_frame);
1797 w.write_u8(self.transition_type);
1798 if let Some(packet) = self.packet.as_ref() {
1799 w.write_slice(&packet.encode(keylen));
1800 }
1801
1802 w.into_packet(&self.key(), keylen)
1803 }
1804
1805 fn key(&self) -> Vec<u8> {
1806 KEY_MOVIE_TRANSITION.to_vec()
1807 }
1808}
1809
1810
1811#[derive(Debug, Clone, PartialEq)]
1813pub struct Comment {
1814 pub comment: String,
1815}
1816impl Decode for Comment {
1817 fn decode(_key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
1818 Ok(Self {
1819 comment: payload.read_string(payload.remaining())
1820 })
1821 }
1822
1823 fn kind(&self) -> PacketKind {
1824 PacketKind::Comment
1825 }
1826}
1827impl Encode for Comment {
1828 fn encode(&self, keylen: u8) -> Vec<u8> {
1829 let mut w = Writer::new();
1830
1831 w.write_str(&self.comment);
1832
1833 w.into_packet(&self.key(), keylen)
1834 }
1835
1836 fn key(&self) -> Vec<u8> {
1837 KEY_COMMENT.to_vec()
1838 }
1839}
1840
1841
1842#[derive(Debug, Clone, PartialEq)]
1844pub struct Experimental {
1845 pub experimental: bool,
1846}
1847impl Decode for Experimental {
1848 fn decode(key: &[u8], mut payload: Reader) -> Result<Self, PacketError> {
1849 if payload.remaining() != 1 {
1850 return Err(PacketError::invalid(key, payload));
1851 }
1852
1853 Ok(Self {
1854 experimental: payload.read_bool(),
1855 })
1856 }
1857
1858 fn kind(&self) -> PacketKind {
1859 PacketKind::Experimental
1860 }
1861}
1862impl Encode for Experimental {
1863 fn encode(&self, keylen: u8) -> Vec<u8> {
1864 let mut w = Writer::new();
1865
1866 w.write_bool(self.experimental);
1867
1868 w.into_packet(&self.key(), keylen)
1869 }
1870
1871 fn key(&self) -> Vec<u8> {
1872 KEY_EXPERIMENTAL.to_vec()
1873 }
1874}
1875
1876
1877#[derive(Debug, Clone, PartialEq)]
1879pub struct Unspecified {
1880 pub payload: Vec<u8>,
1881}
1882impl Decode for Unspecified {
1883 fn decode(_key: &[u8], payload: Reader) -> Result<Self, PacketError> {
1884 Ok(Self {
1885 payload: payload.to_vec(),
1886 })
1887 }
1888
1889 fn kind(&self) -> PacketKind {
1890 PacketKind::Unspecified
1891 }
1892}
1893impl Encode for Unspecified {
1894 fn encode(&self, keylen: u8) -> Vec<u8> {
1895 let mut w = Writer::new();
1896
1897 w.write_slice(&self.payload);
1898
1899 w.into_packet(&self.key(), keylen)
1900 }
1901
1902 fn key(&self) -> Vec<u8> {
1903 KEY_UNSPECIFIED.to_vec()
1904 }
1905}