1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
//! Friend related packets. \[0x18\]
use super::{HelperReadWrite, PacketReadWrite};
use std::time::Duration;
// ----------------------------------------------------------------
// Friend packets
// ----------------------------------------------------------------
/// (0x18, 0x14) Friend List Request.
///
/// (C -> S) Sent when a client wants a friend list.
///
/// Respond with: [`crate::protocol::Packet::FriendList`]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(default))]
#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
#[Id(0x18, 0x14)]
pub struct FriendListRequestPacket {
pub unk: u32,
}
/// (0x18, 0x15) Friend List.
///
/// (S -> C) Sent in response to a request.
///
/// Response to: [`crate::protocol::Packet::FriendListRequest`]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(default))]
#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
#[Id(0x18, 0x15)]
#[Flags(Flags::PACKED)]
#[Magic(0x2E1E, 0x63)]
pub struct FriendListPacket {
pub unk1: u32,
pub unk2: u16,
pub unk3: u16,
/// Players friends.
pub friends: Vec<FriendListEntry>,
/// Player nickname.
pub nickname: String,
}
/// (0x18, 0x18) Send Friend Request.
///
/// (C -> S) Sent when a client has sent a friend request to another player.
///
/// Respond with: [`crate::protocol::Packet::AddedRequest`]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(default))]
#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
#[Id(0x18, 0x18)]
#[Flags(Flags::PACKED)]
#[Magic(0xBF57, 0x44)]
pub struct SendFriendRequestPacket {
/// Target player ID.
pub id: u32,
/// Request message.
#[Seek(4)]
pub msg: String,
}
/// (0x18, 0x1A) Friend Request Sent.
///
/// (S -> C) Sent in response to a request.
///
/// Response to: [`crate::protocol::Packet::SendFriendRequest`]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(default))]
#[derive(Debug, Clone, Default, PartialEq, PacketReadWrite)]
#[Id(0x18, 0x1A)]
pub struct AddedRequestPacket {
pub unk1: u32,
/// Sender player ID.
pub sender_id: u32,
/// Target player ID.
#[Seek(4)]
pub target_id: u32,
/// Sender player nickname.
#[Seek(4)]
#[FixedLen(0x22)]
pub sender_nickname: String,
/// Target player nickname.
#[FixedLen(0x22)]
pub target_nickname: String,
/// Request message.
#[FixedLen(0x80)]
pub msg: String,
/// Request send timestamp.
pub send_time: Duration,
#[Seek(0x88)]
pub unk2: u8,
pub unk3: u8,
#[SeekAfter(0x91)]
pub unk4: u8,
}
// ----------------------------------------------------------------
// Additional structs
// ----------------------------------------------------------------
/// Friend entry in friend list.
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(default))]
#[derive(Debug, Clone, Default, PartialEq, HelperReadWrite)]
pub struct FriendListEntry {
/// Player ID.
pub id: u32,
/// Player nickname.
#[Seek(4)]
#[FixedLen(0x20)]
pub nickname: String,
/// Player character name (if logged in).
#[Seek(4)]
#[FixedLen(0x10)]
pub char_name: String,
/// Friend flags.
#[Seek(4)]
pub flags: FriendFlags,
pub unk2: u8,
pub unk3: u8,
pub unk4: u8,
#[Seek(4)]
pub unk5: u32,
/// Player current block ID.
#[Seek(8)]
pub blockid: u32,
/// Player current location.
pub location: FriendLocation,
pub unk6: u16,
pub unk7: u32,
/// Player alliance name.
#[FixedLen(0x18)]
pub alliance_name: String,
#[Seek(0x8)]
pub unk8: Duration,
pub unk9: Duration,
#[Seek(0x38)]
pub unk10: u32,
#[Seek(4)]
pub unk11: u8,
pub unk12: u8,
#[Seek(2)]
#[SeekAfter(4)]
pub unk13: Duration,
}
bitflags::bitflags! {
/// Friend flags.
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(default))]
#[derive(Debug, Copy, Clone, Default, PartialEq, HelperReadWrite)]
#[BitFlags(u8)]
pub struct FriendFlags: u8 {
/// Is the friend online.
const IS_ONLINE = 1 << 0;
/// Are login notifications enabled for this friend.
const LOGIN_NOTIF = 1 << 3;
/// Did the player not log in for a while.
const NO_RECENT_LOGINS = 1 << 5;
const _ = !0;
}
}
/// Friend map location.
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(u16)]
#[derive(Debug, Copy, Clone, Default, PartialEq, HelperReadWrite)]
pub enum FriendLocation {
/// Player is in the lobby.
#[default]
Lobby,
/// Player is in the quest map.
Quest,
/// Player is in the personal quarters.
PersonalQ,
/// Player is in the alliance quarters.
AllianceQ,
/// Player is in the casino.
Casino,
/// Player is in the challenger lobby.
ChallengerLobby,
/// Player is in the ARKS bridge.
Bridge,
/// Player is in the cafe.
FrancasCafe,
/// Player is in the battle lobby.
BattleLobby,
#[Read_default]
Unknown = 0xFFFF,
}