pso2packetlib/protocol/
login.rs

1//! Login related packets. \[0x11\]
2#[cfg(feature = "ngs_packets")]
3use super::models::FunValue;
4use super::{
5    items::Item,
6    items::ItemId,
7    models::{character::Character, SGValue},
8    Flags, HelperReadWrite, ObjectHeader, ObjectType, PacketError, PacketHeader, PacketReadWrite,
9    PacketType,
10};
11use crate::{
12    fixed_types::{Bytes, FixedAsciiString, FixedBytes, FixedString, FixedVec, WinTime},
13    AsciiString,
14};
15use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
16use std::{
17    io::{Read, Seek, Write},
18    net::Ipv4Addr,
19    time::{Duration, SystemTime, UNIX_EPOCH},
20};
21
22// ----------------------------------------------------------------
23// Login packets
24// ----------------------------------------------------------------
25
26/// (0x11, 0x00) Sega ID Login.
27///
28/// (C -> S) Sent when the client wants to auth using Sega ID (JP and deplatformed Global).
29///
30/// Respond with:
31/// [`crate::protocol::Packet::LoginResponse`],
32/// [`crate::protocol::Packet::UserInfo`] (if auth was successful)
33///
34/// Response to: [`crate::protocol::Packet::EncryptionResponse`]
35#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
36#[cfg_attr(feature = "serde", serde(default))]
37#[derive(Debug, Clone, PartialEq, PacketReadWrite)]
38#[Id(0x11, 0x00)]
39#[Flags(Flags::PACKED)]
40#[Magic(0x5E6, 0x6B)]
41pub struct SegaIDLoginPacket {
42    //FIXME: fix data sizes
43    pub unk1: u32,
44    pub unk2: u32,
45    pub unk3: u32,
46    /// Some kind of version ID.
47    pub ver_id: [u8; 0x20],
48    /// Clients active network interfaces.
49    pub interfaces: Vec<NetInterface>,
50    #[Seek(0x14)]
51    pub unk4: FixedBytes<0x90>,
52    #[Seek(0x10)]
53    pub unk5: [u8; 0x10],
54    #[Seek(0x10)]
55    /// Clients text language.
56    pub text_lang: Language,
57    /// Clients voice language.
58    pub voice_lang: Language,
59    /// Clients text language (?).
60    pub text_lang2: Language,
61    /// Clients language.
62    pub lang_lang: Language,
63    /// Language code (in game lang?).
64    #[Seek(0x8)]
65    pub language: FixedString<0x10>,
66    pub unk6: u32,
67    pub unk7: u32,
68    pub magic1: u32,
69    pub unk8: [u8; 0x20],
70    pub unk9: FixedBytes<0x44>,
71    /// Sega ID username.
72    #[Seek(0x104)]
73    pub username: FixedAsciiString<0x40>,
74    /// Sega ID password.
75    #[Seek(0x20)]
76    pub password: FixedAsciiString<0x40>,
77    #[Seek(0x4)]
78    pub unk10: u32,
79    #[SeekAfter(0x4)]
80    pub unk11: AsciiString,
81}
82
83/// (0x11, 0x01) Login Result.
84///
85/// (S -> C) Sent when the client tried to auth.
86///
87/// Respond with (if login was successful):
88/// [`crate::protocol::Packet::SystemInformation`],
89/// [`crate::protocol::Packet::SettingsRequest`]
90///
91/// Response to:
92/// [`crate::protocol::Packet::SegaIDLogin`],
93/// [`crate::protocol::Packet::VitaLogin`],
94/// [`crate::protocol::Packet::BlockLogin`]
95#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
96#[cfg_attr(feature = "serde", serde(default))]
97#[derive(Debug, Clone, PartialEq, PacketReadWrite)]
98#[Id(0x11, 0x01)]
99#[Flags(Flags::PACKED)]
100#[Magic(0x8BA4, 0xB6)]
101pub struct LoginResponsePacket {
102    /// Login status.
103    pub status: LoginStatus,
104    /// Error message (if login failed).
105    pub error: String,
106    /// Player object.
107    pub player: ObjectHeader,
108    /// Current block name.
109    pub blockname: FixedString<0x20>,
110    pub unk1: f32,
111    pub unk2: u32,
112    pub level_cap: u32,
113    pub level_cap2: u32,
114    pub unk5: u32,
115    pub unk6: f32,
116    pub unk7: f32,
117    pub unk8: u32,
118    pub unk9: f32,
119    pub unk10: f32,
120    pub unk11: u32,
121    pub unk12: f32,
122    pub unk13: u32,
123    pub unk14: [f32; 0xA],
124    pub unk15: [f32; 0x15],
125    pub unk16: f32,
126    pub unk17: f32,
127    pub unk18: [f32; 0x9],
128    pub unk19: [u32; 0x2],
129    pub unk20: u32,
130    pub unk21: u32,
131    pub unk22: [f32; 0x3],
132    pub unk23: u32,
133    pub unk24: f32,
134    pub unk25: f32,
135    pub unk26: u32,
136    pub unk27: [u8; 0xC],
137    pub unk28: FixedString<0x20>,
138    pub unk29: u32,
139    pub unk30: String,
140    pub unk31: u32,
141}
142
143/// (0x11, 0x03) Character List.
144///
145/// (S -> C) Sent in response to the request.
146///
147/// Response to:
148/// [`crate::protocol::Packet::CharacterListRequest`]
149#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
150#[cfg_attr(feature = "serde", serde(default))]
151#[derive(Debug, Default, Clone, PartialEq)]
152pub struct CharacterListPacket {
153    /// Available characters.
154    pub characters: Vec<Character>,
155    pub equiped_items: Vec<[Item; 10]>,
156    /// Character play times.
157    pub play_times: [u32; 30],
158    /// Character deletion flags (flag, deletion timestamp).
159    pub deletion_flags: [(u32, u32); 30],
160    /// Character ship transfer flags.
161    pub transfer_flags: [(u32, u32); 30],
162    /// Account accessory flag (?).
163    pub account_accessory: u16,
164    /// Login survey flag.
165    pub login_survey: u32,
166    /// Ad flag (on global 12 star unit ad).
167    pub ad: u32,
168}
169
170/// (0x11, 0x04) Start Game.
171///
172/// (C -> S) Sent when the client has selected the character.
173///
174/// Respond with:
175/// [`crate::protocol::Packet::LoadingScreenTransition`]
176#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
177#[cfg_attr(feature = "serde", serde(default))]
178#[derive(Debug, Default, Clone, PartialEq, PacketReadWrite)]
179#[Id(0x11, 0x04)]
180pub struct StartGamePacket {
181    /// Selected character ID.
182    pub char_id: u32,
183    pub unk1: u32,
184    pub unk2: u32,
185}
186
187/// (0x11, 0x05) Create New Character Request.
188///
189/// (C -> S) Sent when the client has created a new character (i.e. in the end of the character
190/// creation screen).
191///
192/// Respond with: [`crate::protocol::Packet::CharacterCreateResponse`].
193#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
194#[cfg_attr(feature = "serde", serde(default))]
195#[derive(Debug, Default, Clone, PartialEq, PacketReadWrite)]
196#[Id(0x11, 0x05)]
197pub struct CharacterCreatePacket {
198    /// New character data.
199    pub character: Character,
200}
201
202/// (0x11, 0x06) Delete Character Request.
203///
204/// (C -> S) Sent when the client wants to delete an existing character.
205///
206/// Respond with: [`crate::protocol::Packet::CharacterDeletion`]
207#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
208#[cfg_attr(feature = "serde", serde(default))]
209#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
210#[Id(0x11, 0x06)]
211pub struct CharacterDeletionRequestPacket {
212    /// Deleted character ID.
213    pub char_id: u32,
214}
215
216/// (0x11, 0x07) Create New Character Response.
217///
218/// (S -> C) Sent in response to character creation.
219///
220/// Response to: [`crate::protocol::Packet::CharacterCreate`].
221#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
222#[cfg_attr(feature = "serde", serde(default))]
223#[derive(Debug, Default, Clone, PartialEq, PacketReadWrite)]
224#[Id(0x11, 0x07)]
225pub struct CharacterCreateResponsePacket {
226    /// Creation result.
227    pub status: CharacterCreationStatus,
228    /// New character ID.
229    pub char_id: u32,
230}
231
232/// (0x11, 0x08) Delete Character.
233///
234/// (S -> C) Sent in response to the request.
235///
236/// Response to: [`crate::protocol::Packet::CharacterDeletionRequest`]
237#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
238#[cfg_attr(feature = "serde", serde(default))]
239#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
240#[Id(0x11, 0x08)]
241#[Flags(Flags::PACKED)]
242#[Magic(0x33D4, 0xC4)]
243pub struct CharacterDeletionPacket {
244    /// Deletion request status.
245    pub status: DeletionStatus,
246    pub unk1: u32,
247    pub unk2: Vec<ItemId>,
248    pub unk3: Vec<ItemId>,
249    pub unk4: Vec<ItemId>,
250    pub unk5: Vec<ItemId>,
251    pub unk6: Vec<ItemId>,
252}
253
254/// (0x11, 0x0A) Unknown
255///
256/// (S -> C)
257#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
258#[cfg_attr(feature = "serde", serde(default))]
259#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
260#[Id(0x11, 0x0A)]
261pub struct Unk110APacket {
262    pub player_id: u32,
263}
264
265/// (0x11, 0x0B) Encryption Setup Request.
266///
267/// (C -> S) Sent when a client wants to setup encryption.
268///
269/// Respond with: [`crate::protocol::Packet::EncryptionResponse`]
270#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
271#[cfg_attr(feature = "serde", serde(default))]
272#[derive(Debug, Default, Clone, PartialEq)]
273pub struct EncryptionRequestPacket {
274    /// RSA encrypted data (if received using [`crate::connection::Connection`] it will be
275    /// decrypted).
276    pub rsa_data: Bytes,
277}
278
279/// (0x11, 0x0C) Encryption Setup Response.
280///
281/// (S -> C) Sent in response to the request.
282///
283/// Respond with:
284/// [`crate::protocol::Packet::SegaIDLogin`],
285/// [`crate::protocol::Packet::VitaLogin`],
286/// [`crate::protocol::Packet::BlockLogin`]
287///
288/// Response to: [`crate::protocol::Packet::EncryptionRequest`]
289#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
290#[cfg_attr(feature = "serde", serde(default))]
291#[derive(Debug, Default, Clone, PartialEq)]
292pub struct EncryptionResponsePacket {
293    /// Encryption key.
294    pub data: Bytes,
295}
296
297/// (0x11, 0x0D) Client Ping.
298///
299/// (C -> S) Sent periodically by the client.
300///
301/// Respond with:
302/// [`crate::protocol::Packet::ClientPong`],
303#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
304#[cfg_attr(feature = "serde", serde(default))]
305#[derive(Debug, Clone, PartialEq, PacketReadWrite)]
306#[Id(0x11, 0x0D)]
307pub struct ClientPingPacket {
308    /// Ping timestamp.
309    pub time: WinTime,
310}
311
312/// (0x11, 0x0E) Client Pong.
313///
314/// (S -> C) Sent by the server in response to the ping.
315///
316/// Response to:
317/// [`crate::protocol::Packet::ClientPing`]
318#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
319#[cfg_attr(feature = "serde", serde(default))]
320#[derive(Debug, Clone, PartialEq, PacketReadWrite)]
321#[Id(0x11, 0x0E)]
322pub struct ClientPongPacket {
323    /// Ping timestamp.
324    pub client_time: WinTime,
325    /// Pong timestamp.
326    pub server_time: WinTime,
327    pub unk1: u32,
328}
329
330/// (0x11, 0x10) Block List.
331///
332/// (S -> C) Sent in response to the request.
333///
334/// Response to:
335/// [`crate::protocol::Packet::BlockListRequest`]
336#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
337#[cfg_attr(feature = "serde", serde(default))]
338#[derive(Debug, Default, Clone, PartialEq, PacketReadWrite)]
339#[Id(0x11, 0x10)]
340pub struct BlockListPacket {
341    pub blocks: FixedVec<200, BlockInfo>,
342    pub unk: u32,
343}
344
345/// (0x11, 0x11) Block Switch Request.
346///
347/// (C -> S) Sent when the client wants to switch to a different block.
348///
349/// Respond with: [`crate::protocol::Packet::BlockSwitchResponse`]
350#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
351#[cfg_attr(feature = "serde", serde(default))]
352#[derive(Default, Debug, Clone, PartialEq, PacketReadWrite)]
353#[Id(0x11, 0x11)]
354pub struct BlockSwitchRequestPacket {
355    pub unk1: u32,
356    pub unk2: u32,
357    pub unk3: u16,
358    /// Block ID to switch to.
359    pub block_id: u16,
360    pub unk4: u32,
361}
362
363/// (0x11, 0x13) Block Switch Response.
364///
365/// (S -> C) Sent in response to the request.
366///
367/// Response to: [`crate::protocol::Packet::BlockSwitchRequest`]
368#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
369#[cfg_attr(feature = "serde", serde(default))]
370#[derive(Debug, Clone, PartialEq, PacketReadWrite)]
371#[Id(0x11, 0x13)]
372pub struct BlockSwitchResponsePacket {
373    pub unk1: u32,
374    pub unk2: u32,
375    pub unk3: u16,
376    /// Block ID to switch to.
377    pub block_id: u16,
378    /// Block IP.
379    pub ip: Ipv4Addr,
380    /// Block port.
381    pub port: u16,
382    pub unk4: u16,
383    /// Login challenge to use after switching.
384    pub challenge: u32,
385    /// Player ID.
386    pub user_id: u32,
387}
388
389/// (0x11, 0x14) Block Login.
390///
391/// (C -> S) Sent when the client wants to auth after switching blocks.
392///
393/// Response to: [`crate::protocol::Packet::EncryptionRequest`]
394///
395/// Respond with: [`crate::protocol::Packet::LoginResponse`]
396#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
397#[cfg_attr(feature = "serde", serde(default))]
398#[derive(Debug, Clone, PartialEq, Default, PacketReadWrite)]
399#[Id(0x11, 0x14)]
400#[Flags(Flags::PACKED)]
401#[Magic(0x78B8, 0x49)]
402pub struct BlockLoginPacket {
403    /// Player ID.
404    pub player_id: u64,
405    pub unk1: u8,
406    pub unk2: u8,
407    pub unk3: u16,
408    pub unk4: u32,
409    pub unk5: u32,
410    /// Some kind of version ID.
411    pub ver_id: [u8; 0x20],
412    /// Clients active network interfaces.
413    pub interfaces: Vec<NetInterface>,
414    /// Login challenge (from [`crate::protocol::Packet::BlockSwitchResponse`]).
415    pub challenge: u32,
416    pub unk6: FixedBytes<0xC4>,
417    pub unk7: [u8; 0x10],
418}
419
420/// (0x11, 0x1B) User Info.
421///
422/// (S -> C) Sent to notify user about account status after logging in.
423///
424/// Response to: [`crate::protocol::Packet::LoginResponse`]
425#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
426#[cfg_attr(feature = "serde", serde(default))]
427#[derive(Debug, Default, Clone, PartialEq, PacketReadWrite)]
428#[Id(0x11, 0x1B)]
429pub struct UserInfoPacket {
430    pub unk1: u32,
431    pub unk2: u32,
432    pub ac1: u32,
433    pub unk3: u32,
434    pub ac2: u32,
435    pub ac3: u32,
436    pub ac4: u32,
437    pub ac5: u32,
438    pub ac6: u32,
439    pub ac7: u32,
440    pub ac8: [u32; 11],
441    pub fun: u32,
442    pub unk4: u16,
443    pub sg1: SGValue,
444    pub free_sg: SGValue,
445    pub sg2: [SGValue; 18],
446    pub unk5: u16,
447    pub unk6: [u32; 6],
448    /// Premium status expiration timestamp.
449    pub premium_expiration: Duration,
450    pub unk7: u32,
451    /// Personal quarters expiration timestamp.
452    pub pq_expiration: Duration,
453    /// Player shop expiration timestamp.
454    pub pshop_expiration: Duration,
455    pub unk8: [u32; 2],
456    /// Max order expansion expiration timestamp.
457    pub expand_max_orders_expiration: Duration,
458    pub unk9: [u32; 19],
459    /// Material storage expiration timestamp.
460    pub material_storage_expiration: Duration,
461    /// Extended storage 4 expiration timestamp.
462    pub ex_storage4_expiration: Duration,
463    /// Extended storage 5 expiration timestamp.
464    pub ex_storage5_expiration: Duration,
465}
466
467/// (0x11, 0x1B) User Info (NGS).
468///
469/// (S -> C) Sent to notify user about account status after logging in.
470///
471/// Response to: [`crate::protocol::Packet::LoginResponse`]
472#[cfg(feature = "ngs_packets")]
473#[cfg_attr(docsrs, doc(cfg(feature = "ngs_packets")))]
474#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
475#[cfg_attr(feature = "serde", serde(default))]
476#[derive(Debug, Default, Clone, PartialEq, PacketReadWrite)]
477#[Id(0x11, 0x1B)]
478pub struct UserInfoNGSPacket {
479    // i'm unsure about real types, just deriving from base version struct
480    pub unk1: [u32; 22],
481    pub unk2: u16,
482    pub unk3: [u32; 16],
483    pub fun: FunValue,
484    pub unk4: [u32; 2],
485    pub free_sg: SGValue,
486    pub unk5: u16,
487    pub unk6: [u32; 24],
488    /// Premium status expiration timestamp.
489    pub premium_expiration: Duration,
490    pub unk7: u32,
491    /// Personal quarters expiration timestamp.
492    pub pq_expiration: Duration,
493    /// Player shop expiration timestamp.
494    pub pshop_expiration: Duration,
495    pub unk8: [u32; 2],
496    /// Max order expansion expiration timestamp.
497    pub expand_max_orders_expiration: Duration,
498    pub unk9: [u32; 19],
499    /// Material storage expiration timestamp.
500    pub material_storage_expiration: Duration,
501    /// Extended storage 4 expiration timestamp.
502    pub ex_storage4_expiration: Duration,
503    /// Extended storage 5 expiration timestamp.
504    pub ex_storage5_expiration: Duration,
505    pub unk10: [u32; 4],
506}
507
508/// (0x11, 0x1E) Set Nickname Request.
509///
510/// (S -> C) Sent when a player first creates an account (using Sega ID) to set a nickname.
511///
512/// Following: [`crate::protocol::Packet::LoginResponse`]
513///
514/// Respond with: [`crate::protocol::Packet::NicknameResponse`]
515#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
516#[cfg_attr(feature = "serde", serde(default))]
517#[derive(Debug, Default, Clone, PartialEq, PacketReadWrite)]
518#[Id(0x11, 0x1E)]
519pub struct NicknameRequestPacket {
520    /// Error flag.
521    #[SeekAfter(0x42)]
522    pub error: u16,
523}
524
525/// (0x11, 0x1D) Set Nickname Response.
526///
527/// (C -> S) Sent in response to the request
528///
529/// Response to: [`crate::protocol::Packet::NicknameRequest`]
530#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
531#[cfg_attr(feature = "serde", serde(default))]
532#[derive(Debug, Default, Clone, PartialEq, PacketReadWrite)]
533#[Id(0x11, 0x1D)]
534pub struct NicknameResponsePacket {
535    /// Desired nickname.
536    pub nickname: FixedString<0x20>,
537}
538
539/// (0x11, 0x2C) Block Balance.
540///
541/// (S -> C) Sent by the block balancer to transfer a client to a block.
542#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
543#[cfg_attr(feature = "serde", serde(default))]
544#[derive(Debug, Clone, PartialEq, PacketReadWrite)]
545#[Id(0x11, 0x2C)]
546pub struct BlockBalancePacket {
547    pub unk1: [u8; 0x20],
548    /// Target block name.
549    pub blockname: FixedString<0x20>,
550    /// Target block IP.
551    pub ip: Ipv4Addr,
552    /// Target block port.
553    pub port: u16,
554    pub unk2: FixedBytes<0x11A>,
555}
556
557/// (0x11, 0x2D) System Information.
558///
559/// (C -> S) Sent after logging in, contains information about players device.
560#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
561#[cfg_attr(feature = "serde", serde(default))]
562#[derive(Debug, Default, Clone, PartialEq, PacketReadWrite)]
563#[Id(0x11, 0x2D)]
564#[Flags(Flags::PACKED)]
565#[Magic(0x883D, 0x9F)]
566pub struct SystemInformationPacket {
567    /// CPU Model.
568    pub cpu_info: AsciiString,
569    /// GPU Model.
570    pub video_info: AsciiString,
571    /// Video RAM in bytes (if available).
572    pub vram: u64,
573    /// Total system RAM in bytes.
574    pub total_ram: u64,
575    pub unk1: u32,
576    pub unk2: u32,
577    /// OS version and build.
578    pub windows_version: String,
579    /// Game window size and mode.
580    pub window_size: AsciiString,
581    /// Audio device names.
582    pub audio_devices: String,
583    pub unk4: String,
584    /// User video driver and DirectX version.
585    pub video_driver: String,
586    /// Total drive space in bytes.
587    pub total_disk_space: u64,
588    /// Free drive space in bytes.
589    pub free_disk_space: u64,
590}
591
592/// (0x11, 0x3D) Ship List.
593///
594/// (S -> C) Sent by a ship list server when a client connects.
595#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
596#[cfg_attr(feature = "serde", serde(default))]
597#[derive(Debug, Clone, PartialEq, PacketReadWrite)]
598#[Id(0x11, 0x3D)]
599#[Flags(Flags::PACKED)]
600#[Magic(0xE418, 0x51)]
601pub struct ShipListPacket {
602    /// Known ship infos.
603    pub ships: Vec<ShipEntry>,
604    /// Packet timestamp.
605    pub timestamp: Duration,
606    pub unk: u32,
607}
608
609/// (0x11, 0x42) New Character Screen Response.
610///
611/// (S -> C) Sent in response to a request.
612///
613/// Respond with: [`crate::protocol::Packet::CreateCharacter2`]
614///
615/// Response to: [`crate::protocol::Packet::CreateCharacter1`]
616#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
617#[cfg_attr(feature = "serde", serde(default))]
618#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
619#[Id(0x11, 0x42)]
620pub struct CreateCharacter1ResponsePacket {
621    /// Creation status.
622    pub status: u32,
623    pub unk2: u32,
624    pub used_smth: u32,
625    /// Required AC to buy a character creation pass.
626    pub req_ac: u32,
627}
628
629/// (0x11, 0x55) New Player Referral Response.
630///
631/// (S -> C) Sent in response to a request.
632///
633/// Response to: [`crate::protocol::Packet::CreateCharacter2`]
634#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
635#[cfg_attr(feature = "serde", serde(default))]
636#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
637#[Id(0x11, 0x55)]
638pub struct CreateCharacter2ResponsePacket {
639    /// Player already referred flag.
640    pub referral_flag: u32,
641}
642
643/// (0x11, 0x63) Vita Login.
644///
645/// (C -> S) Sent when the client wants to auth using PSN.
646///
647/// Respond with:
648/// [`crate::protocol::Packet::LoginResponse`],
649/// [`crate::protocol::Packet::UserInfo`] (if auth was successful)
650///
651/// Response to: [`crate::protocol::Packet::EncryptionResponse`]
652#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
653#[cfg_attr(feature = "serde", serde(default))]
654#[derive(Debug, Clone, PartialEq, PacketReadWrite)]
655#[Id(0x11, 0x63)]
656#[Flags(Flags::PACKED)]
657#[Magic(0xBE3F, 0x77)]
658pub struct VitaLoginPacket {
659    pub unk1: u8,
660    pub unk2: u8,
661    pub unk3: u16,
662    pub unk4: u32,
663    pub unk5: u32,
664    pub ver_id: [u8; 0x20],
665    /// Client netword interfaces.
666    pub interfaces: Vec<NetInterface>,
667    pub unk6: [u8; 0x10],
668    #[Seek(0x4)]
669    pub unk7: FixedBytes<0x90>,
670    #[Seek(0x10)]
671    pub unk8: [u8; 0x10],
672    #[Seek(0x10)]
673    pub flag1: u32,
674    pub flag2: u32,
675    pub flag3: u32,
676    pub flag4: u32,
677    pub flag5: u32,
678    pub flag6: u32,
679    /// Language code.
680    pub language: FixedString<0x10>,
681    pub unk9: u32,
682    pub unk10: u32,
683    pub magic1: u32,
684    pub unk11: [u8; 0x20],
685    pub unk12: FixedBytes<0x44>,
686    /// PSN username.
687    #[Seek(0xFC)]
688    pub username: FixedAsciiString<0x40>,
689    #[Seek(0x20)]
690    pub password: FixedAsciiString<0x40>,
691    #[Seek(0x4)]
692    pub unk13: u8,
693    pub unk14: u8,
694    pub unk15: u16,
695    pub unk16: AsciiString,
696    pub unk17: Bytes,
697    pub unk18: [u8; 0x10],
698}
699
700/// (0x11, 0x65) Full Block List.
701///
702/// (S -> C) Sent when the client need the information about all blocks (e.g. as part of friend
703/// list).
704///
705/// Response to: [`crate::protocol::Packet::AllBlocksListRequest`]
706#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
707#[cfg_attr(feature = "serde", serde(default))]
708#[derive(Debug, Default, Clone, PartialEq, PacketReadWrite)]
709#[Id(0x11, 0x65)]
710pub struct AllBlocksListPacket {
711    /// All blocks.
712    pub blocks: FixedVec<200, BlockInfo>,
713    pub unk: u32,
714}
715
716/// (0x11, 0x67) Salon Entry Response.
717///
718/// (S -> C) Sent in response to the request.
719///
720/// Response to: [`crate::protocol::Packet::SalonEntryRequest`]
721#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
722#[cfg_attr(feature = "serde", serde(default))]
723#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
724#[Id(0x11, 0x67)]
725#[Flags(Flags::PACKED)]
726#[Magic(0xD536, 0xA4)]
727pub struct SalonResponse {
728    /// Available edit pass time.
729    pub reedit_time: u32,
730    pub unk2: u32,
731    pub unk3: u32,
732    pub unk4: u32,
733    pub unk5: Vec<SalonThing1>,
734    pub unk6: Vec<SalonThing2>,
735    pub unk7: u32,
736}
737
738/// (0x11, 0x68) Anticheat Challenge Request.
739///
740/// (S -> C) Sent periodically by the server to check anticheat status.
741///
742/// Respond with: [`crate::protocol::Packet::ChallengeResponse`]
743#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
744#[cfg_attr(feature = "serde", serde(default))]
745#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
746#[Id(0x11, 0x68)]
747#[Flags(Flags::PACKED)]
748#[Magic(0x5AF4, 0xEF)]
749pub struct ChallengeRequestPacket {
750    /// Challenge data.
751    pub data: Bytes,
752}
753
754/// (0x11, 0x69) Anticheat Challenge Response.
755///
756/// (C -> S) Sent in response to the request.
757///
758/// Response to: [`crate::protocol::Packet::ChallengeRequest`]
759#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
760#[cfg_attr(feature = "serde", serde(default))]
761#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
762#[Id(0x11, 0x69)]
763#[Flags(Flags::PACKED)]
764#[Magic(0xE0B1, 0x3A)]
765pub struct ChallengeResponsePacket {
766    /// Response data.
767    pub data: Bytes,
768}
769
770/// (0x11, 0x6F) Unknown
771///
772/// (S -> C)
773#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
774#[cfg_attr(feature = "serde", serde(default))]
775#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
776#[Id(0x11, 0x6F)]
777#[Flags(Flags::PACKED)]
778#[Magic(0x0323, 0xFD)]
779pub struct Unk116FPacket {
780    pub unk1: String,
781    pub unk2: u32,
782    #[cfg(feature = "ngs_packets")]
783    #[cfg_attr(docsrs, doc(cfg(feature = "ngs_packets")))]
784    #[OnlyOn(PacketType::NGS)]
785    pub unk3: u32,
786}
787
788/// (0x11, 0x71) Notification Status.
789///
790/// (S -> C) Sent when a client has unchecked notifications.
791#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
792#[cfg_attr(feature = "serde", serde(default))]
793#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
794#[Id(0x11, 0x71)]
795pub struct NotificationStatusPacket {
796    /// Number of new mails.
797    pub new_mail: u32,
798    /// Number of unclaimed characted campaigns.
799    pub char_campaigns: u32,
800    /// Number of unclaimed account campaigns.
801    pub campaigns: u32,
802    pub unk3: u32,
803}
804
805/// (0x11, 0x87) Login History.
806///
807/// (S -> C) Sent in response to a request.
808///
809/// Response to: [`crate::protocol::Packet::LoginHistoryRequest`]
810#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
811#[cfg_attr(feature = "serde", serde(default))]
812#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
813#[Id(0x11, 0x87)]
814#[Flags(Flags::PACKED)]
815#[Magic(0x8CEB, 0x8)]
816pub struct LoginHistoryPacket {
817    /// List of login attempts (max 50).
818    pub attempts: Vec<LoginAttempt>,
819}
820
821/// (0x11, 0x8B) 2nd Password Operation Request.
822///
823/// (C -> S) Sent when a client wants to do something with a 2nd password (i.e set a 2nd password
824/// or unlock shops).
825///
826/// Respond with: [`crate::protocol::Packet::SecondPwdOperation`]
827#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
828#[cfg_attr(feature = "serde", serde(default))]
829#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
830#[Id(0x11, 0x8B)]
831pub struct SecondPwdOperationRequestPacket {
832    // 0 - unlock
833    // 1 - set new pwd
834    pub operation_type: u32,
835    pub password: FixedAsciiString<0x10>,
836}
837
838/// (0x11, 0x8C) 2nd Password Operation.
839///
840/// (S -> C) Sent in response to the request.
841///
842/// Response to: [`crate::protocol::Packet::SecondPwdOperationRequest`]
843#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
844#[cfg_attr(feature = "serde", serde(default))]
845#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
846#[Id(0x11, 0x8C)]
847#[Flags(Flags::PACKED)]
848#[Magic(0x29A0, 0x7F)]
849pub struct SecondPwdOperationPacket {
850    pub unk1: u32,
851    pub unk2: u8,
852    /// 2nd password set flag.
853    pub is_set: u8,
854    /// 2nd password entered correctly flag.
855    pub is_unlocked: u16,
856    pub unk5: u32,
857    pub unk: String,
858}
859
860/// (0x11, 0x90) Character Undeletion Request.
861///
862/// (C -> S) Sent when a client wants to cancel a character deletion.
863///
864/// Respond with: [`crate::protocol::Packet::CharacterUndeletion`]
865#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
866#[cfg_attr(feature = "serde", serde(default))]
867#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
868#[Id(0x11, 0x90)]
869pub struct CharacterUndeletionRequestPacket {
870    /// Character ID to cancel deletion.
871    pub char_id: u32,
872}
873
874/// (0x11, 0x91) Character Undeletion.
875///
876/// (S -> C) Sent in response to a request.
877///
878/// Response to: [`crate::protocol::Packet::CharacterUndeletionRequest`]
879#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
880#[cfg_attr(feature = "serde", serde(default))]
881#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
882#[Id(0x11, 0x91)]
883pub struct CharacterUndeletionPacket {
884    /// Undeletion status.
885    pub status: UndeletionStatus,
886}
887
888/// (0x11, 0x97) Character Rename Rights Request.
889///
890/// (C -> S) Sent when a client wants to get character renaming rights (i.e. clicked on "rename character").
891///
892/// Respond with: [`crate::protocol::Packet::CharacterRename`]
893#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
894#[cfg_attr(feature = "serde", serde(default))]
895#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
896#[Id(0x11, 0x97)]
897pub struct CharacterRenameRequestPacket {
898    /// Character ID for renaming.
899    pub char_id: u32,
900}
901
902/// (0x11, 0x98) Character Rename Rights Response.
903///
904/// (S -> C) Sent in response to a request.
905///
906/// Respond with: [`crate::protocol::Packet::CharacterNewNameRequest`] (if permitted)
907///
908/// Response to: [`crate::protocol::Packet::CharacterRenameRequest`]
909#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
910#[cfg_attr(feature = "serde", serde(default))]
911#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
912#[Id(0x11, 0x98)]
913pub struct CharacterRenamePacket {
914    /// Renaming availability status.
915    pub status: RenameRequestStatus,
916    /// AC price for a rename pass.
917    pub ac_price: u32,
918    /// Rename cooldown expiry timestamp (?).
919    pub cooldown_expires: u32,
920    /// Seconds untime rename cooldown expires.
921    pub cooldown_secs: u32,
922}
923
924/// (0x11, 0x9B) Set New Character Name Request.
925///
926/// (C -> S) Sent when a client wants to set a new character name.
927///
928/// Respond with: [`crate::protocol::Packet::CharacterNewName`]
929///
930/// Response to: [`crate::protocol::Packet::CharacterRename`]
931#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
932#[cfg_attr(feature = "serde", serde(default))]
933#[derive(Debug, Default, Clone, PartialEq, PacketReadWrite)]
934#[Id(0x11, 0x9B)]
935pub struct CharacterNewNameRequestPacket {
936    /// Character ID for renaming.
937    pub char_id: u32,
938    /// New character name.
939    pub name: FixedString<0x10>,
940}
941
942/// (0x11, 0x9C) Set New Character Name.
943///
944/// (S -> C) Sent in response to a request.
945///
946/// Response to: [`crate::protocol::Packet::CharacterNewNameRequest`]
947#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
948#[cfg_attr(feature = "serde", serde(default))]
949#[derive(Debug, Default, Clone, PartialEq, PacketReadWrite)]
950#[Id(0x11, 0x9C)]
951pub struct CharacterNewNamePacket {
952    /// Renaming status.
953    pub status: NewNameStatus,
954    /// Character ID for renaming.
955    pub char_id: u32,
956    /// New character name.
957    pub name: FixedString<0x10>,
958}
959
960/// (0x11, 0xAF) Unknown
961///
962/// (S -> C)
963#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
964#[cfg_attr(feature = "serde", serde(default))]
965#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
966#[Id(0x11, 0xAF)]
967pub struct Unk11AFPacket {
968    pub unk1: u32,
969    pub unk2: u32,
970    pub unk3: u32,
971    pub unk4: u32,
972}
973
974/// (0x11, 0xB0) Unknown
975///
976/// (C -> S)
977#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
978#[cfg_attr(feature = "serde", serde(default))]
979#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
980#[Id(0x11, 0xB0)]
981pub struct Unk11B0Packet {
982    pub unk1: u32,
983    pub unk2: u32,
984}
985
986/// (0x11, 0xB8) Character Ship Transfer Rights Request.
987///
988/// (C -> S) Sent when a client wants to get ship transfer rights (i.e. clicked on
989/// "transfer ship").
990///
991/// Respond with: [`crate::protocol::Packet::CharacterMove`]
992#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
993#[cfg_attr(feature = "serde", serde(default))]
994#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
995#[Id(0x11, 0xB8)]
996pub struct CharacterMoveRequestPacket {
997    /// Character ID to move.
998    pub char_id: u32,
999    pub unk1: u32,
1000}
1001
1002/// (0x11, 0xB9) Character Ship Transfer Rights.
1003///
1004/// (S -> C) Sent in response to a request.
1005///
1006/// Respond with: [`crate::protocol::Packet::CharacterMove`]
1007#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1008#[cfg_attr(feature = "serde", serde(default))]
1009#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
1010#[Id(0x11, 0xB9)]
1011pub struct CharacterMovePacket {
1012    pub status: u32,
1013    pub ac_price: u32,
1014    pub unk1: u32,
1015    pub unk2: u32,
1016    pub unk3: u32,
1017    pub unk4: u32,
1018    pub unk5: u32,
1019}
1020
1021/// (0x11, 0xD7) Unknown
1022///
1023/// (S -> C)
1024#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1025#[cfg_attr(feature = "serde", serde(default))]
1026#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
1027#[Id(0x11, 0xD7)]
1028pub struct Unk11D7Packet {
1029    pub unk1: u32,
1030    pub unk2: u32,
1031    pub unk3: u32,
1032    pub unk4: u32,
1033}
1034
1035/// (0x11, 0xDE) Player Report Request
1036///
1037/// (C -> S) Sent when a player has reported other player.
1038#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1039#[cfg_attr(feature = "serde", serde(default))]
1040#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
1041#[Id(0x11, 0xDE)]
1042#[Flags(Flags::PACKED)]
1043#[Magic(0x60, 0x8F)]
1044pub struct PlayerReportedPacket {
1045    /// Reported player ID.
1046    pub targed_id: u32,
1047    /// Report reason.
1048    pub reason: u8,
1049    /// Report message.
1050    #[Seek(3)]
1051    pub msg: String,
1052}
1053
1054/// (0x11, 0xEA) Prohibited Nickname Entered.
1055///
1056/// (C -> S) Sent when a player has entered a prohibited nickname (e.g. "sega").
1057#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1058#[cfg_attr(feature = "serde", serde(default))]
1059#[derive(Debug, Clone, PartialEq, PacketReadWrite)]
1060#[Id(0x11, 0xEA)]
1061#[Flags(Flags::PACKED)]
1062#[Magic(0x4544, 0x14)]
1063pub struct NicknameErrorPacket {
1064    pub unk1: u32,
1065    /// Entered nickname.
1066    pub nickname: String,
1067}
1068
1069/// (0x11, 0xED) Banner List.
1070///
1071/// (S -> C) Sent when a player has logged in.
1072#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1073#[cfg_attr(feature = "serde", serde(default))]
1074#[derive(Debug, Default, Clone, PartialEq, PacketReadWrite)]
1075#[Id(0x11, 0xED)]
1076#[Flags(Flags::PACKED)]
1077#[Magic(0xD67D, 0xF5)]
1078pub struct BannerListPacket {
1079    /// Banner names (semicolon delimited).
1080    pub banners: AsciiString,
1081    #[cfg(feature = "ngs_packets")]
1082    #[cfg_attr(docsrs, doc(cfg(feature = "ngs_packets")))]
1083    #[OnlyOn(PacketType::NGS)]
1084    pub unk1: AsciiString,
1085    /// News URLs (semicolon delimited).
1086    #[cfg(feature = "ngs_packets")]
1087    #[cfg_attr(docsrs, doc(cfg(feature = "ngs_packets")))]
1088    #[OnlyOn(PacketType::NGS)]
1089    pub unk2: AsciiString,
1090}
1091
1092/// (0x11, 0xEE) Email 2FA Code Request.
1093///
1094/// (S -> C) Sent to verify a login when a suspicious one has occured.
1095#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1096#[cfg_attr(feature = "serde", serde(default))]
1097#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
1098#[Id(0x11, 0xEE)]
1099#[Flags(Flags::PACKED)]
1100#[Magic(0x5C3B, 0x40)]
1101pub struct EmailCodeRequestPacket {
1102    pub unk1: u32,
1103    /// Message displayed in the box.
1104    pub message: String,
1105}
1106
1107/// (0x11, 0xFF) Unknown.
1108///
1109/// (? -> ?)
1110#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1111#[cfg_attr(feature = "serde", serde(default))]
1112#[derive(Debug, Default, Clone, PartialEq, PacketReadWrite)]
1113#[Id(0x11, 0xFF)]
1114#[Flags(Flags::PACKED)]
1115#[Magic(0x3DD3, 0x3D)]
1116pub struct Unk11FFPacket {
1117    pub unk1: u8,
1118    pub unk2: u8,
1119    pub unk3: u8,
1120    pub unk4: u8,
1121    pub unk5: String,
1122    pub unk6: [u8; 0xC],
1123    pub unk7: FixedBytes<0x40>,
1124    pub unk8: [u8; 0x20],
1125}
1126
1127// ----------------------------------------------------------------
1128// Additional structs
1129// ----------------------------------------------------------------
1130
1131/// Client network interface.
1132#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1133#[cfg_attr(feature = "serde", serde(default))]
1134#[derive(Debug, Default, Clone, PartialEq, HelperReadWrite)]
1135pub struct NetInterface {
1136    /// Interface status.
1137    pub state: u32,
1138    /// Interface MAC address.
1139    pub mac: FixedAsciiString<0x18>,
1140}
1141
1142/// Ship information.
1143#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1144#[cfg_attr(feature = "serde", serde(default))]
1145#[derive(Debug, Clone, PartialEq, HelperReadWrite)]
1146pub struct ShipEntry {
1147    /// Ship numerical ID.
1148    pub id: u32,
1149    /// Ship string ID (in form of "ShipXX").
1150    pub name: FixedString<0x10>,
1151    /// Ship IP (ignored by the client).
1152    pub ip: Ipv4Addr,
1153    /// Ship status.
1154    #[Seek(4)]
1155    pub status: ShipStatus,
1156    /// Ship order.
1157    #[SeekAfter(4)]
1158    pub order: u16,
1159}
1160
1161/// Ship status.
1162#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1163#[repr(u16)]
1164#[derive(Debug, Default, Clone, Copy, PartialEq, HelperReadWrite)]
1165pub enum ShipStatus {
1166    /// Status unknown or ship is under maintenance.
1167    #[default]
1168    Unknown,
1169    /// Ship is online.
1170    Online,
1171    /// Ship is busy.
1172    Busy,
1173    /// Ship is full.
1174    Full,
1175    /// Ship is offline.
1176    Offline,
1177
1178    #[Read_default]
1179    Undefined = 0xFFFF,
1180}
1181
1182/// Login attempt in login history.
1183#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1184#[cfg_attr(feature = "serde", serde(default))]
1185#[derive(Debug, Clone, PartialEq, HelperReadWrite)]
1186pub struct LoginAttempt {
1187    /// IP of the login.
1188    pub ip: Ipv4Addr,
1189    /// Login status.
1190    pub status: LoginResult,
1191    /// Login timestamp.
1192    pub timestamp: Duration,
1193    pub unk: u32,
1194}
1195
1196/// Login history result.
1197#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1198#[derive(Debug, Default, Clone, Copy, PartialEq, HelperReadWrite)]
1199#[repr(u32)]
1200pub enum LoginResult {
1201    /// Login was successful.
1202    #[default]
1203    Successful,
1204    /// Email 2FA was passed.
1205    EmailConfirmed,
1206    /// Login failed.
1207    LoginError,
1208    /// Email 2FA was failed.
1209    EmailAuthError,
1210    /// Email 2FA was sent.
1211    AuthEmailSent,
1212    /// One time password error.
1213    OTPError,
1214    /// Ship was in maintenance during logon.
1215    InMaintenance,
1216    /// Generic error occured.
1217    GenericError,
1218
1219    #[Read_default]
1220    Undefined = 0xFFFF_FFFF,
1221}
1222
1223/// Login status.
1224#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1225#[derive(Debug, Default, Clone, Copy, PartialEq, HelperReadWrite)]
1226#[repr(u32)]
1227pub enum LoginStatus {
1228    /// Login was successful.
1229    #[default]
1230    Success,
1231    /// Login failed.
1232    Failure,
1233
1234    #[Read_default]
1235    Undefined = 0xFFFF_FFFF,
1236}
1237
1238/// Information about a block.
1239#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1240#[cfg_attr(feature = "serde", serde(default))]
1241#[derive(Debug, Clone, PartialEq, HelperReadWrite)]
1242pub struct BlockInfo {
1243    pub unk1: u32,
1244    pub unk2: u8,
1245    pub unk3: u8,
1246    pub unk4: u8,
1247    pub unk5: u8,
1248    pub unk6: u32,
1249    pub unk7: u32,
1250    pub unk8: u16,
1251    /// Block ID.
1252    pub block_id: u16,
1253    /// Block name.
1254    pub blockname: FixedString<0x20>,
1255    /// Block IP.
1256    pub ip: Ipv4Addr,
1257    /// Block port.
1258    pub port: u16,
1259    pub unk10: u16,
1260    pub unk11: u16,
1261    pub unk12: [u16; 3],
1262    /// Block fullness (between 0 and 1).
1263    pub cur_capacity: f32,
1264}
1265
1266#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1267#[cfg_attr(feature = "serde", serde(default))]
1268#[derive(Debug, Default, Clone, PartialEq, HelperReadWrite)]
1269pub struct SalonThing1 {
1270    pub unk1: u32,
1271    pub unk2: u32,
1272    pub unk3: u32,
1273    pub unk4: u32,
1274}
1275
1276#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1277#[cfg_attr(feature = "serde", serde(default))]
1278#[derive(Debug, Default, Clone, PartialEq, HelperReadWrite)]
1279pub struct SalonThing2 {
1280    pub unk1: u32,
1281    pub unk2: u32,
1282    pub unk3: u32,
1283    pub unk4: u32,
1284    pub unk5: u32,
1285    pub unk6: u32,
1286    pub unk7: u32,
1287    pub unk8: u32,
1288    pub unk9: u32,
1289    pub unk10: u32,
1290    pub unk11: u32,
1291    pub unk12: u32,
1292    pub unk13: u32,
1293    pub unk14: u32,
1294}
1295
1296/// Game languages.
1297#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1298#[derive(Debug, Default, Clone, Copy, PartialEq, HelperReadWrite)]
1299#[repr(u32)]
1300pub enum Language {
1301    #[default]
1302    #[Read_default]
1303    Japanese,
1304    English,
1305}
1306
1307/// Deletion request status.
1308#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1309#[derive(Debug, Default, Clone, Copy, PartialEq, HelperReadWrite)]
1310#[repr(u32)]
1311pub enum DeletionStatus {
1312    /// Character has items which prevent deletion.
1313    #[default]
1314    #[Read_default]
1315    UndeletableItems,
1316    /// Character has been scheduled for deletion.
1317    Success,
1318}
1319
1320/// Undeletion request status.
1321#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1322#[derive(Debug, Default, Clone, Copy, PartialEq, HelperReadWrite)]
1323#[repr(u32)]
1324pub enum UndeletionStatus {
1325    /// Character was already deleted.
1326    #[default]
1327    #[Read_default]
1328    AlreadyDeleted,
1329    /// Character deletion canceled.
1330    Success,
1331}
1332
1333/// Rename rights status.
1334#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1335#[derive(Debug, Default, Clone, Copy, PartialEq, HelperReadWrite)]
1336#[repr(u32)]
1337pub enum RenameRequestStatus {
1338    /// Renaming allowed.
1339    #[default]
1340    Allowed,
1341    /// Renaming permit needed.
1342    PermitNeeded,
1343    /// Renaming privileges suspended.
1344    PrivilegesSuspended,
1345    /// System error has occurred.
1346    #[Read_default]
1347    SystemError,
1348    /// Renaming cooldown hasn't yet expired.
1349    TooEarly,
1350}
1351
1352/// Renaming status.
1353#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1354#[derive(Debug, Default, Clone, Copy, PartialEq, HelperReadWrite)]
1355#[repr(u32)]
1356pub enum NewNameStatus {
1357    /// Renaming was successful.
1358    #[default]
1359    #[Read_default]
1360    Success,
1361    /// Renaming failed.
1362    Failure,
1363}
1364
1365/// Character creation status.
1366#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1367#[derive(Debug, Default, Clone, Copy, PartialEq, HelperReadWrite)]
1368#[repr(u32)]
1369pub enum CharacterCreationStatus {
1370    /// Character has been successfully created.
1371    #[default]
1372    #[Read_default]
1373    Success,
1374    /// Displays an empty error message.
1375    EmptyError,
1376    /// Character limit reached.
1377    LimitReached,
1378    /// Not enough AC to create a character.
1379    NoAC,
1380    /// Generic system error message.
1381    SystemError,
1382}
1383
1384// ----------------------------------------------------------------
1385// Read/Write implementations
1386// ----------------------------------------------------------------
1387
1388impl PacketReadWrite for CharacterListPacket {
1389    fn read(
1390        reader: &mut (impl Read + Seek),
1391        _: &Flags,
1392        packet_type: PacketType,
1393    ) -> Result<Self, PacketError> {
1394        let char_amount = reader
1395            .read_u32::<LittleEndian>()
1396            .map_err(|e| PacketError::FieldLengthError {
1397                packet_name: "CharacterListPacket",
1398                field_name: "characters",
1399                error: e,
1400            })?
1401            .clamp(0, 30);
1402        reader
1403            .seek(std::io::SeekFrom::Current(4))
1404            .map_err(|e| PacketError::PaddingError {
1405                packet_name: "CharacterListPacket",
1406                field_name: "characters",
1407                error: e,
1408            })?;
1409        let mut characters = vec![];
1410        for i in 0..30 {
1411            reader
1412                .seek(std::io::SeekFrom::Current(4))
1413                .map_err(|e| PacketError::PaddingError {
1414                    packet_name: "CharacterListPacket",
1415                    field_name: "vec_characters_value",
1416                    error: e,
1417                })?;
1418            let character = Character::read(reader, packet_type, 0, 0).map_err(|e| {
1419                PacketError::CompositeFieldError {
1420                    packet_name: "CharacterListPacket",
1421                    field_name: "vec_characters_value",
1422                    error: Box::new(e),
1423                }
1424            })?;
1425            if i < char_amount {
1426                characters.push(character);
1427            }
1428        }
1429        // ???
1430        reader
1431            .seek(std::io::SeekFrom::Current(0x4))
1432            .map_err(|e| PacketError::FieldError {
1433                packet_name: "CharacterListPacket",
1434                field_name: "undefined",
1435                error: e,
1436            })?;
1437        let mut equiped_items = vec![];
1438        // items
1439        for i in 0..30 {
1440            let mut items: [Item; 10] = Default::default();
1441            for item in &mut items {
1442                *item = Item::read(reader, packet_type, 0, 0).map_err(|e| {
1443                    PacketError::CompositeFieldError {
1444                        packet_name: "CharacterListPacket",
1445                        field_name: "vec_equiped_items_value",
1446                        error: Box::new(e),
1447                    }
1448                })?;
1449            }
1450            if i < char_amount {
1451                equiped_items.push(items);
1452            }
1453        }
1454        let mut play_times = [0u32; 30];
1455        for item in &mut play_times {
1456            *item = reader
1457                .read_u32::<LittleEndian>()
1458                .map_err(|e| PacketError::FieldError {
1459                    packet_name: "CharacterListPacket",
1460                    field_name: "array_play_times_value",
1461                    error: e,
1462                })?;
1463        }
1464        reader
1465            .seek(std::io::SeekFrom::Current(32))
1466            .map_err(|e| PacketError::PaddingError {
1467                packet_name: "CharacterListPacket",
1468                field_name: "deletion_flags",
1469                error: e,
1470            })?;
1471        let mut deletion_flags = [(0u32, 0u32); 30];
1472        for item in &mut deletion_flags {
1473            item.0 = reader
1474                .read_u32::<LittleEndian>()
1475                .map_err(|e| PacketError::FieldError {
1476                    packet_name: "CharacterListPacket",
1477                    field_name: "array_deletion_flags_0_value",
1478                    error: e,
1479                })?;
1480            item.1 = reader
1481                .read_u32::<LittleEndian>()
1482                .map_err(|e| PacketError::FieldError {
1483                    packet_name: "CharacterListPacket",
1484                    field_name: "array_deletion_flags_1_value",
1485                    error: e,
1486                })?;
1487        }
1488        let mut transfer_flags = [(0u32, 0u32); 30];
1489        for item in &mut transfer_flags {
1490            item.0 = reader
1491                .read_u32::<LittleEndian>()
1492                .map_err(|e| PacketError::FieldError {
1493                    packet_name: "CharacterListPacket",
1494                    field_name: "array_transfer_flags_0_value",
1495                    error: e,
1496                })?;
1497            item.1 = reader
1498                .read_u32::<LittleEndian>()
1499                .map_err(|e| PacketError::FieldError {
1500                    packet_name: "CharacterListPacket",
1501                    field_name: "array_transfer_flags_1_value",
1502                    error: e,
1503                })?;
1504        }
1505        let account_accessory =
1506            reader
1507                .read_u16::<LittleEndian>()
1508                .map_err(|e| PacketError::FieldError {
1509                    packet_name: "CharacterListPacket",
1510                    field_name: "account_accessory",
1511                    error: e,
1512                })?;
1513        reader
1514            .seek(std::io::SeekFrom::Current(6))
1515            .map_err(|e| PacketError::PaddingError {
1516                packet_name: "CharacterListPacket",
1517                field_name: "login_survey",
1518                error: e,
1519            })?;
1520        let login_survey =
1521            reader
1522                .read_u32::<LittleEndian>()
1523                .map_err(|e| PacketError::FieldError {
1524                    packet_name: "CharacterListPacket",
1525                    field_name: "login_survey",
1526                    error: e,
1527                })?;
1528        let ad = reader
1529            .read_u32::<LittleEndian>()
1530            .map_err(|e| PacketError::FieldError {
1531                packet_name: "CharacterListPacket",
1532                field_name: "ad",
1533                error: e,
1534            })?;
1535
1536        Ok(Self {
1537            characters,
1538            equiped_items,
1539            play_times,
1540            deletion_flags,
1541            transfer_flags,
1542            account_accessory,
1543            login_survey,
1544            ad,
1545        })
1546    }
1547    fn write(&self, packet_type: PacketType) -> Result<Vec<u8>, PacketError> {
1548        let mut buf = PacketHeader::new(0x11, 0x03, Flags::default()).write(packet_type);
1549        buf.write_u32::<LittleEndian>((self.characters.len() as u32).clamp(0, 30))
1550            .map_err(|e| PacketError::FieldLengthError {
1551                packet_name: "CharacterListPacket",
1552                field_name: "characters",
1553                error: e,
1554            })?;
1555        buf.write_u32::<LittleEndian>(0)
1556            .map_err(|e| PacketError::PaddingError {
1557                packet_name: "CharacterListPacket",
1558                field_name: "characters",
1559                error: e,
1560            })?;
1561
1562        let characters = &self.characters;
1563
1564        for character in characters
1565            .iter()
1566            .chain([Character::default()].iter())
1567            .cycle()
1568            .take(30)
1569        {
1570            buf.write_u32::<LittleEndian>(0)
1571                .map_err(|e| PacketError::PaddingError {
1572                    packet_name: "CharacterListPacket",
1573                    field_name: "vec_characters_value",
1574                    error: e,
1575                })?;
1576            character.write(&mut buf, packet_type, 0, 0).map_err(|e| {
1577                PacketError::CompositeFieldError {
1578                    packet_name: "CharacterListPacket",
1579                    field_name: "vec_characters_value",
1580                    error: Box::new(e),
1581                }
1582            })?;
1583        }
1584        // ???
1585        buf.write_u32::<LittleEndian>(0)
1586            .map_err(|e| PacketError::FieldError {
1587                packet_name: "CharacterListPacket",
1588                field_name: "undefined",
1589                error: e,
1590            })?;
1591        for equiped_items in self
1592            .equiped_items
1593            .iter()
1594            .chain([Default::default()].iter())
1595            .cycle()
1596            .take(30)
1597        {
1598            for item in equiped_items {
1599                item.write(&mut buf, packet_type, 0, 0).map_err(|e| {
1600                    PacketError::CompositeFieldError {
1601                        packet_name: "CharacterListPacket",
1602                        field_name: "vec_equiped_items_value",
1603                        error: Box::new(e),
1604                    }
1605                })?;
1606            }
1607        }
1608        for i in 0..30 {
1609            buf.write_u32::<LittleEndian>(self.play_times[i])
1610                .map_err(|e| PacketError::FieldError {
1611                    packet_name: "CharacterListPacket",
1612                    field_name: "array_play_times_value",
1613                    error: e,
1614                })?;
1615        }
1616        // ???
1617        for _ in 0..32 {
1618            buf.write_u8(0).map_err(|e| PacketError::PaddingError {
1619                packet_name: "CharacterListPacket",
1620                field_name: "deletion_flags",
1621                error: e,
1622            })?;
1623        }
1624        for i in 0..30 {
1625            // deletion flag
1626            buf.write_u32::<LittleEndian>(self.deletion_flags[i].0)
1627                .map_err(|e| PacketError::FieldError {
1628                    packet_name: "CharacterListPacket",
1629                    field_name: "array_deletion_flags_0_value",
1630                    error: e,
1631                })?;
1632            // timestamp
1633            buf.write_u32::<LittleEndian>(self.deletion_flags[i].1)
1634                .map_err(|e| PacketError::FieldError {
1635                    packet_name: "CharacterListPacket",
1636                    field_name: "array_deletion_flags_1_value",
1637                    error: e,
1638                })?;
1639        }
1640        for i in 0..30 {
1641            // transfer flag
1642            buf.write_u32::<LittleEndian>(self.transfer_flags[i].0)
1643                .map_err(|e| PacketError::FieldError {
1644                    packet_name: "CharacterListPacket",
1645                    field_name: "array_transfer_flags_0_value",
1646                    error: e,
1647                })?;
1648            // ??? prob target ship
1649            buf.write_u32::<LittleEndian>(self.transfer_flags[i].1)
1650                .map_err(|e| PacketError::FieldError {
1651                    packet_name: "CharacterListPacket",
1652                    field_name: "array_transfer_flags_1_value",
1653                    error: e,
1654                })?;
1655        }
1656        buf.write_u16::<LittleEndian>(self.account_accessory)
1657            .map_err(|e| PacketError::FieldError {
1658                packet_name: "CharacterListPacket",
1659                field_name: "account_accessory",
1660                error: e,
1661            })?;
1662        // ???
1663        buf.write_all(&[0u8; 6])
1664            .map_err(|e| PacketError::PaddingError {
1665                packet_name: "CharacterListPacket",
1666                field_name: "login_survey",
1667                error: e,
1668            })?;
1669        buf.write_u32::<LittleEndian>(self.login_survey)
1670            .map_err(|e| PacketError::FieldError {
1671                packet_name: "CharacterListPacket",
1672                field_name: "login_survey",
1673                error: e,
1674            })?;
1675        buf.write_u32::<LittleEndian>(self.ad)
1676            .map_err(|e| PacketError::FieldError {
1677                packet_name: "CharacterListPacket",
1678                field_name: "ad",
1679                error: e,
1680            })?;
1681        // ???
1682        buf.write_u32::<LittleEndian>(0x00_00_00_00)
1683            .map_err(|e| PacketError::FieldError {
1684                packet_name: "CharacterListPacket",
1685                field_name: "undefined",
1686                error: e,
1687            })?;
1688
1689        // ???
1690        buf.write_u32::<LittleEndian>(0x00_00_00_00)
1691            .map_err(|e| PacketError::FieldError {
1692                packet_name: "CharacterListPacket",
1693                field_name: "undefined",
1694                error: e,
1695            })?;
1696
1697        Ok(buf)
1698    }
1699}
1700
1701impl PacketReadWrite for EncryptionRequestPacket {
1702    fn read(reader: &mut impl Read, _: &Flags, _: PacketType) -> Result<Self, PacketError> {
1703        let mut rsa_data = vec![];
1704        reader
1705            .read_to_end(&mut rsa_data)
1706            .map_err(|e| PacketError::FieldError {
1707                packet_name: "EncryptionRequestPacket",
1708                field_name: "rsa_data",
1709                error: e,
1710            })?;
1711        let mut tmp_data = vec![];
1712        let mut iter = rsa_data.into_iter().rev().skip(4);
1713        if let Some(x) = iter.find(|x| *x != 0x00) {
1714            tmp_data.push(x);
1715            tmp_data.extend(iter);
1716        }
1717        Ok(Self {
1718            rsa_data: tmp_data.into(),
1719        })
1720    }
1721    fn write(&self, packet_type: PacketType) -> Result<Vec<u8>, PacketError> {
1722        let mut buf = PacketHeader::new(0x11, 0x0B, Flags::default()).write(packet_type);
1723        let mut data = self.rsa_data.clone();
1724        data.reverse();
1725        data.resize(0x104, 0);
1726        buf.extend(data.iter());
1727        Ok(buf)
1728    }
1729}
1730
1731impl PacketReadWrite for EncryptionResponsePacket {
1732    fn read(reader: &mut impl Read, _: &Flags, _: PacketType) -> Result<Self, PacketError> {
1733        let mut data = vec![];
1734        reader
1735            .read_to_end(&mut data)
1736            .map_err(|e| PacketError::FieldError {
1737                packet_name: "EncryptionResponsePacket",
1738                field_name: "data",
1739                error: e,
1740            })?;
1741
1742        Ok(Self { data: data.into() })
1743    }
1744    fn write(&self, packet_type: PacketType) -> Result<Vec<u8>, PacketError> {
1745        let mut buf = PacketHeader::new(0x11, 0x0C, Flags::default()).write(packet_type);
1746        buf.extend(self.data.iter());
1747        Ok(buf)
1748    }
1749}
1750
1751// ----------------------------------------------------------------
1752// Default implementations
1753// ----------------------------------------------------------------
1754
1755impl Default for SegaIDLoginPacket {
1756    fn default() -> Self {
1757        Self {
1758            unk1: 0,
1759            unk2: 9,
1760            unk3: 0,
1761            ver_id: [0u8; 0x20],
1762            interfaces: vec![],
1763            unk4: Default::default(),
1764            unk5: [0u8; 0x10],
1765            text_lang: Language::Japanese,
1766            voice_lang: Language::Japanese,
1767            text_lang2: Language::Japanese,
1768            lang_lang: Language::Japanese,
1769            language: Default::default(),
1770            unk6: 7,
1771            unk7: 7,
1772            magic1: 0x0419,
1773            unk8: [0u8; 0x20],
1774            unk9: Default::default(),
1775            username: Default::default(),
1776            password: Default::default(),
1777            unk10: 512,
1778            unk11: Default::default(),
1779        }
1780    }
1781}
1782
1783impl Default for LoginResponsePacket {
1784    fn default() -> Self {
1785        Self {
1786            status: LoginStatus::Success,
1787            error: String::new(),
1788            player: ObjectHeader {
1789                id: 0,
1790                unk: 0,
1791                map_id: 0,
1792                entity_type: ObjectType::Player,
1793            },
1794            blockname: Default::default(),
1795            unk1: 70.0,
1796            unk2: 32767,
1797            level_cap: 100,
1798            level_cap2: 100,
1799            unk5: 1,
1800            unk6: 10.0,
1801            unk7: 5.0,
1802            unk8: 0,
1803            unk9: 2.0,
1804            unk10: 75.0,
1805            unk11: 70,
1806            unk12: 25.0,
1807            unk13: 1,
1808            unk14: [100.0; 0xA],
1809            unk15: [100.0; 0x15],
1810            unk16: 450.0,
1811            unk17: 100.0,
1812            unk18: [100.0; 0x9],
1813            unk19: [0; 0x2],
1814            unk20: 15,
1815            unk21: 5,
1816            unk22: [15.0; 0x3],
1817            unk23: 0,
1818            unk24: 3000.0,
1819            unk25: 1000.0,
1820            unk26: 0,
1821            unk27: [0; 0xC],
1822            unk28: Default::default(),
1823            unk29: 0,
1824            unk30: String::new(),
1825            unk31: 0,
1826        }
1827    }
1828}
1829
1830impl Default for ClientPingPacket {
1831    fn default() -> Self {
1832        Self {
1833            time: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().into(),
1834        }
1835    }
1836}
1837
1838impl Default for ClientPongPacket {
1839    fn default() -> Self {
1840        Self {
1841            client_time: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().into(),
1842            server_time: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().into(),
1843            unk1: 0,
1844        }
1845    }
1846}
1847
1848impl Default for BlockBalancePacket {
1849    fn default() -> Self {
1850        Self {
1851            unk1: [0u8; 0x20],
1852            blockname: Default::default(),
1853            ip: Ipv4Addr::UNSPECIFIED,
1854            port: 0,
1855            unk2: Default::default(),
1856        }
1857    }
1858}
1859
1860impl Default for ShipListPacket {
1861    fn default() -> Self {
1862        Self {
1863            ships: vec![],
1864            timestamp: SystemTime::now().duration_since(UNIX_EPOCH).unwrap(),
1865            unk: 0,
1866        }
1867    }
1868}
1869
1870impl Default for VitaLoginPacket {
1871    fn default() -> Self {
1872        Self {
1873            unk1: 0,
1874            unk2: 0,
1875            unk3: 0,
1876            unk4: 9,
1877            unk5: 0,
1878            ver_id: [0u8; 0x20],
1879            interfaces: vec![],
1880            unk6: [0u8; 0x10],
1881            unk7: Default::default(),
1882            unk8: [0u8; 0x10],
1883            flag1: 0,
1884            flag2: 0,
1885            flag3: 0,
1886            flag4: 0,
1887            flag5: 0,
1888            flag6: 0,
1889            language: Default::default(),
1890            unk9: 0,
1891            unk10: 0,
1892            magic1: 0,
1893            unk11: [0u8; 0x20],
1894            unk12: Default::default(),
1895            username: Default::default(),
1896            password: Default::default(),
1897            unk13: 0,
1898            unk14: 2,
1899            unk15: 0,
1900            unk16: Default::default(),
1901            unk17: Default::default(),
1902            unk18: [0u8; 0x10],
1903        }
1904    }
1905}
1906
1907impl Default for NicknameErrorPacket {
1908    fn default() -> Self {
1909        Self {
1910            unk1: 2,
1911            nickname: String::new(),
1912        }
1913    }
1914}
1915
1916impl Default for ShipEntry {
1917    fn default() -> Self {
1918        Self {
1919            id: 0,
1920            name: Default::default(),
1921            ip: Ipv4Addr::UNSPECIFIED,
1922            status: ShipStatus::Unknown,
1923            order: 0,
1924        }
1925    }
1926}
1927
1928impl Default for LoginAttempt {
1929    fn default() -> Self {
1930        Self {
1931            ip: Ipv4Addr::UNSPECIFIED,
1932            status: LoginResult::Successful,
1933            timestamp: Duration::new(0, 0),
1934            unk: 9,
1935        }
1936    }
1937}
1938
1939impl Default for BlockInfo {
1940    fn default() -> Self {
1941        Self {
1942            unk1: 0,
1943            unk2: 0,
1944            unk3: 0,
1945            unk4: 0,
1946            unk5: 0,
1947            unk6: 0,
1948            unk7: 0,
1949            unk8: 0,
1950            block_id: 0,
1951            blockname: Default::default(),
1952            ip: Ipv4Addr::UNSPECIFIED,
1953            port: 0,
1954            unk10: 0,
1955            unk11: 0,
1956            unk12: [0; 3],
1957            cur_capacity: 0.0,
1958        }
1959    }
1960}
1961impl Default for BlockSwitchResponsePacket {
1962    fn default() -> Self {
1963        Self {
1964            unk1: 0,
1965            unk2: 0,
1966            unk3: 0,
1967            block_id: 0,
1968            ip: Ipv4Addr::UNSPECIFIED,
1969            port: 0,
1970            unk4: 0,
1971            challenge: 0,
1972            user_id: 0,
1973        }
1974    }
1975}