1use crate::fixed_types::FixedString;
3
4use super::{HelperReadWrite, PacketReadWrite};
5use std::time::Duration;
6
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
17#[cfg_attr(feature = "serde", serde(default))]
18#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
19#[Id(0x18, 0x14)]
20pub struct FriendListRequestPacket {
21 pub unk: u32,
22}
23
24#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
30#[cfg_attr(feature = "serde", serde(default))]
31#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
32#[Id(0x18, 0x15)]
33#[Flags(Flags::PACKED)]
34#[Magic(0x2E1E, 0x63)]
35pub struct FriendListPacket {
36 pub unk1: u32,
37 pub unk2: u16,
38 pub unk3: u16,
39 pub friends: Vec<FriendListEntry>,
41 pub nickname: String,
43}
44
45#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
51#[cfg_attr(feature = "serde", serde(default))]
52#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
53#[Id(0x18, 0x18)]
54#[Flags(Flags::PACKED)]
55#[Magic(0xBF57, 0x44)]
56pub struct SendFriendRequestPacket {
57 pub id: u32,
59 #[Seek(4)]
61 pub msg: String,
62}
63
64#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
70#[cfg_attr(feature = "serde", serde(default))]
71#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
72#[Id(0x18, 0x1A)]
73pub struct AddedRequestPacket {
74 pub unk1: u32,
75 pub sender_id: u32,
77 #[Seek(4)]
79 pub target_id: u32,
80 #[Seek(4)]
82 pub sender_nickname: FixedString<0x22>,
83 pub target_nickname: FixedString<0x22>,
85 pub msg: FixedString<0x80>,
87 pub send_time: Duration,
89 #[Seek(0x88)]
90 pub unk2: u8,
91 pub unk3: u8,
92 #[SeekAfter(0x91)]
93 pub unk4: u8,
94}
95
96#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
102#[cfg_attr(feature = "serde", serde(default))]
103#[derive(Debug, Clone, Default, PartialEq, HelperReadWrite)]
104pub struct FriendListEntry {
105 pub id: u32,
107 #[Seek(4)]
109 pub nickname: FixedString<0x20>,
110 #[Seek(4)]
112 pub char_name: FixedString<0x10>,
113 #[Seek(4)]
115 pub flags: FriendFlags,
116 pub unk2: u8,
117 pub unk3: u8,
118 pub unk4: u8,
119 #[Seek(4)]
120 pub unk5: u32,
121 #[Seek(8)]
123 pub blockid: u32,
124 pub location: FriendLocation,
126 pub unk6: u16,
127 pub unk7: u32,
128 pub alliance_name: FixedString<0x18>,
130 #[Seek(0x8)]
131 pub unk8: Duration,
132 pub unk9: Duration,
133 #[Seek(0x38)]
134 pub unk10: u32,
135 #[Seek(4)]
136 pub unk11: u8,
137 pub unk12: u8,
138 #[Seek(2)]
139 #[SeekAfter(4)]
140 pub unk13: Duration,
141}
142
143bitflags::bitflags! {
144 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
146 #[cfg_attr(feature = "serde", serde(default))]
147 #[derive(Debug, Copy, Clone, Default, PartialEq, HelperReadWrite)]
148 #[BitFlags(u8)]
149 pub struct FriendFlags: u8 {
150 const IS_ONLINE = 1 << 0;
152 const LOGIN_NOTIF = 1 << 3;
154 const NO_RECENT_LOGINS = 1 << 5;
156
157 const _ = !0;
158 }
159}
160
161#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
163#[repr(u16)]
164#[derive(Debug, Copy, Clone, Default, PartialEq, HelperReadWrite)]
165pub enum FriendLocation {
166 #[default]
168 Lobby,
169 Quest,
171 PersonalQ,
173 AllianceQ,
175 Casino,
177 ChallengerLobby,
179 Bridge,
181 FrancasCafe,
183 BattleLobby,
185
186 #[Read_default]
187 Unknown = 0xFFFF,
188}