mirror of
https://github.com/lcdr/lu_packets.git
synced 2026-01-07 16:30:42 -06:00
Add GetFriendsListResponse message
This commit is contained in:
@@ -73,7 +73,6 @@ fn parse(path: &Path) -> Res<usize> {
|
||||
&& !file.name().contains("[53-05-00-06]")
|
||||
&& !file.name().contains("[53-05-00-15]")
|
||||
&& !file.name().contains("[53-05-00-1c]")
|
||||
&& !file.name().contains("[53-05-00-1e]")
|
||||
&& !file.name().contains("[53-05-00-1f]")
|
||||
&& !file.name().contains("[53-05-00-22]")
|
||||
&& !file.name().contains("[53-05-00-31]")
|
||||
|
||||
@@ -16,9 +16,9 @@ pub use self::str::*;
|
||||
Note: the length type is not checked and the `Vec` still uses `usize` internally. Handle with care.
|
||||
*/
|
||||
#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
pub struct LVec<T, L>(Vec<T>, PhantomData<L>);
|
||||
pub struct LVec<L, T>(Vec<T>, PhantomData<L>);
|
||||
|
||||
impl<T, L> LVec<T, L> {
|
||||
impl<L, T> LVec<L, T> {
|
||||
pub fn new() -> Self {
|
||||
Self(Vec::new(), PhantomData)
|
||||
}
|
||||
@@ -31,46 +31,48 @@ impl<T, L> LVec<T, L> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub(crate) fn deser_content<R: Read>(reader: &mut R, str_len: L) -> Res<Self> where L: TryInto<usize> {
|
||||
let str_len = match str_len.try_into() {
|
||||
pub(crate) fn deser_content<R: Read>(reader: &mut R, len: L) -> Res<Self> where L: TryInto<usize>, T: Deserialize<LE, R> {
|
||||
let len = match len.try_into() {
|
||||
Ok(x) => x,
|
||||
_ => panic!(),
|
||||
};
|
||||
let mut vec = Vec::<T>::with_capacity(str_len);
|
||||
unsafe {
|
||||
vec.set_len(str_len);
|
||||
let mut ucs2_str_slice = std::slice::from_raw_parts_mut(vec.as_mut_ptr() as *mut u8, str_len*std::mem::size_of::<T>());
|
||||
Read::read(reader, &mut ucs2_str_slice)?;
|
||||
let mut vec = Vec::<T>::with_capacity(len);
|
||||
for _ in 0..len {
|
||||
vec.push(LERead::read(reader)?);
|
||||
}
|
||||
Ok(Self(vec, PhantomData))
|
||||
}
|
||||
|
||||
pub(crate) fn ser_len<W: LEWrite>(&self, writer: &mut W) -> Res<()> where L: TryFrom<usize> + Serialize<LE, W> {
|
||||
let str_len = self.0.len();
|
||||
let l_len = match L::try_from(str_len) {
|
||||
let len = self.0.len();
|
||||
let l_len = match L::try_from(len) {
|
||||
Ok(x) => x,
|
||||
_ => panic!(),
|
||||
};
|
||||
writer.write(l_len)
|
||||
}
|
||||
|
||||
pub(crate) fn ser_content<W: Write>(&self, writer: &mut W) -> Res<()> {
|
||||
let u8_slice = unsafe { std::slice::from_raw_parts(self.0.as_ptr() as *const u8, self.0.len()*std::mem::size_of::<T>()) };
|
||||
writer.write_all(u8_slice)
|
||||
pub(crate) fn ser_content<W: Write>(&self, writer: &mut W) -> Res<()> where for<'a> &'a T: Serialize<LE, W> {
|
||||
for e in &self.0 {
|
||||
LEWrite::write(writer, e)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, L, R: Read> Deserialize<LE, R> for LVec<T, L>
|
||||
where L: TryInto<usize> + Deserialize<LE, R> {
|
||||
impl<T, L, R: Read> Deserialize<LE, R> for LVec<L, T>
|
||||
where L: TryInto<usize> + Deserialize<LE, R>,
|
||||
T: Deserialize<LE, R> {
|
||||
|
||||
fn deserialize(reader: &mut R) -> Res<Self> {
|
||||
let str_len: L = LERead::read(reader)?;
|
||||
Self::deser_content(reader, str_len)
|
||||
let len: L = LERead::read(reader)?;
|
||||
Self::deser_content(reader, len)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T, L, W: Write> Serialize<LE, W> for &'a LVec<T, L>
|
||||
where L: TryFrom<usize> + Serialize<LE, W> {
|
||||
impl<'a, T, L, W: Write> Serialize<LE, W> for &'a LVec<L, T>
|
||||
where L: TryFrom<usize> + Serialize<LE, W>,
|
||||
for<'b> &'b T: Serialize<LE, W> {
|
||||
|
||||
fn serialize(self, writer: &mut W) -> Res<()> {
|
||||
self.ser_len(writer)?;
|
||||
@@ -78,7 +80,7 @@ impl<'a, T, L, W: Write> Serialize<LE, W> for &'a LVec<T, L>
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, L> std::ops::Deref for LVec<T, L> {
|
||||
impl<L, T> std::ops::Deref for LVec<L, T> {
|
||||
type Target = Vec<T>;
|
||||
|
||||
#[inline]
|
||||
@@ -87,14 +89,14 @@ impl<T, L> std::ops::Deref for LVec<T, L> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, L> std::ops::DerefMut for LVec<T, L> {
|
||||
impl<L, T> std::ops::DerefMut for LVec<L, T> {
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, L> From<Vec<T>> for LVec<T, L> {
|
||||
impl<L, T> From<Vec<T>> for LVec<L, T> {
|
||||
fn from(vec: Vec<T>) -> Self {
|
||||
Self(vec, PhantomData)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
mod fixed;
|
||||
mod variable;
|
||||
|
||||
use endio::{Deserialize, Serialize};
|
||||
|
||||
pub use self::fixed::*;
|
||||
pub use self::variable::*;
|
||||
|
||||
@@ -15,9 +17,9 @@ pub struct AsciiError;
|
||||
#[derive(Debug)]
|
||||
pub struct Ucs2Error;
|
||||
|
||||
#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
#[derive(Clone, Copy, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
|
||||
pub struct AsciiChar(u8);
|
||||
#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
#[derive(Clone, Copy, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
|
||||
pub struct Ucs2Char(u16);
|
||||
|
||||
impl LuChar for AsciiChar {
|
||||
|
||||
@@ -4,8 +4,8 @@ use std::marker::PhantomData;
|
||||
use crate::common::LVec;
|
||||
use super::{AsciiChar, AsciiError, LuStrExt, LuWStr, Ucs2Char, Ucs2Error};
|
||||
|
||||
pub type LuVarString<L> = LVec<AsciiChar, L>;
|
||||
pub type LuVarWString<L> = LVec<Ucs2Char, L>;
|
||||
pub type LuVarString<L> = LVec<L, AsciiChar>;
|
||||
pub type LuVarWString<L> = LVec<L, Ucs2Char>;
|
||||
|
||||
impl<L> std::fmt::Debug for LuVarString<L> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
||||
|
||||
@@ -58,6 +58,7 @@ pub enum ClientMessage {
|
||||
TransferToWorld(TransferToWorld) = 14,
|
||||
BlueprintLoadItemResponse(BlueprintLoadItemResponse) = 23,
|
||||
AddFriendRequest(AddFriendRequest) = 27,
|
||||
GetFriendsListResponse(GetFriendsListResponse) = 30,
|
||||
TeamInvite(TeamInvite) = 35,
|
||||
MinimumChatModeResponse(MinimumChatModeResponse) = 57,
|
||||
MinimumChatModeResponsePrivate(MinimumChatModeResponsePrivate) = 58,
|
||||
@@ -187,7 +188,7 @@ pub struct CharListChar {
|
||||
#[padding=4]
|
||||
pub last_location: ZoneId,
|
||||
#[padding=8]
|
||||
pub equipped_items: LVec<Lot, u16>,
|
||||
pub equipped_items: LVec<u16, Lot>,
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -281,6 +282,26 @@ pub struct AddFriendRequest {
|
||||
pub is_best_friend_request: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||
#[trailing_padding=6]
|
||||
pub struct FriendState {
|
||||
is_online: bool,
|
||||
is_best_friend: bool,
|
||||
is_free_trial: bool,
|
||||
#[padding=5]
|
||||
location: ZoneId,
|
||||
object_id: ObjId,
|
||||
char_name: LuWString33,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||
#[repr(u8)]
|
||||
#[post_disc_padding=2]
|
||||
pub enum GetFriendsListResponse {
|
||||
Ok(LVec<u16, FriendState>),
|
||||
GeneralError,
|
||||
}
|
||||
|
||||
/**
|
||||
Informs the client that another player has asked them to be their friend.
|
||||
|
||||
|
||||
BIN
src/world/client/tests/GetFriendsListResponse.bin
Normal file
BIN
src/world/client/tests/GetFriendsListResponse.bin
Normal file
Binary file not shown.
138
src/world/client/tests/GetFriendsListResponse.rs
Normal file
138
src/world/client/tests/GetFriendsListResponse.rs
Normal file
@@ -0,0 +1,138 @@
|
||||
ClientMessage::GetFriendsListResponse(
|
||||
GetFriendsListResponse::Ok(
|
||||
vec![
|
||||
FriendState {
|
||||
is_online: false,
|
||||
is_best_friend: false,
|
||||
is_free_trial: false,
|
||||
location: ZoneId {
|
||||
map_id: 0,
|
||||
instance_id: 0,
|
||||
clone_id: 0,
|
||||
},
|
||||
object_id: 1152921508123877941,
|
||||
char_name: lu!("Stingrod"),
|
||||
},
|
||||
FriendState {
|
||||
is_online: false,
|
||||
is_best_friend: false,
|
||||
is_free_trial: false,
|
||||
location: ZoneId {
|
||||
map_id: 0,
|
||||
instance_id: 0,
|
||||
clone_id: 0,
|
||||
},
|
||||
object_id: 1152921508691197351,
|
||||
char_name: lu!("scaredycat12"),
|
||||
},
|
||||
FriendState {
|
||||
is_online: false,
|
||||
is_best_friend: false,
|
||||
is_free_trial: true,
|
||||
location: ZoneId {
|
||||
map_id: 0,
|
||||
instance_id: 0,
|
||||
clone_id: 0,
|
||||
},
|
||||
object_id: 1152921507861167019,
|
||||
char_name: lu!("DivineDinoKing"),
|
||||
},
|
||||
FriendState {
|
||||
is_online: false,
|
||||
is_best_friend: false,
|
||||
is_free_trial: false,
|
||||
location: ZoneId {
|
||||
map_id: 0,
|
||||
instance_id: 0,
|
||||
clone_id: 0,
|
||||
},
|
||||
object_id: 1152921507552150810,
|
||||
char_name: lu!("ScottishBeast"),
|
||||
},
|
||||
FriendState {
|
||||
is_online: false,
|
||||
is_best_friend: false,
|
||||
is_free_trial: false,
|
||||
location: ZoneId {
|
||||
map_id: 0,
|
||||
instance_id: 0,
|
||||
clone_id: 0,
|
||||
},
|
||||
object_id: 1152921507612937007,
|
||||
char_name: lu!("Forkstealer"),
|
||||
},
|
||||
FriendState {
|
||||
is_online: false,
|
||||
is_best_friend: false,
|
||||
is_free_trial: false,
|
||||
location:ZoneId {
|
||||
map_id: 0,
|
||||
instance_id: 0,
|
||||
clone_id: 0,
|
||||
},
|
||||
object_id: 1152921507702853643,
|
||||
char_name: lu!("princebrick")
|
||||
},
|
||||
FriendState {
|
||||
is_online: false,
|
||||
is_best_friend: false,
|
||||
is_free_trial: true,
|
||||
location: ZoneId {
|
||||
map_id: 0,
|
||||
instance_id: 0,
|
||||
clone_id: 0,
|
||||
},
|
||||
object_id: 1152921507778387642,
|
||||
char_name: lu!("CosmicFinestHerder"),
|
||||
},
|
||||
FriendState {
|
||||
is_online: false,
|
||||
is_best_friend: false,
|
||||
is_free_trial: false,
|
||||
location: ZoneId {
|
||||
map_id: 0,
|
||||
instance_id: 0,
|
||||
clone_id: 0,
|
||||
},
|
||||
object_id: 1152921508146466976,
|
||||
char_name: lu!("felito"),
|
||||
},
|
||||
FriendState {
|
||||
is_online: false,
|
||||
is_best_friend: false,
|
||||
is_free_trial: false,
|
||||
location: ZoneId {
|
||||
map_id: 0,
|
||||
instance_id: 0,
|
||||
clone_id: 0,
|
||||
},
|
||||
object_id: 1152921509260170524,
|
||||
char_name: lu!("FrecklyCrunchEarlobe"),
|
||||
},
|
||||
FriendState {
|
||||
is_online: false,
|
||||
is_best_friend: false,
|
||||
is_free_trial: false,
|
||||
location: ZoneId {
|
||||
map_id: 0,
|
||||
instance_id: 0,
|
||||
clone_id: 0,
|
||||
},
|
||||
object_id: 1152921507960010807,
|
||||
char_name: lu!("BreezyFlyingNinja"),
|
||||
},
|
||||
FriendState {
|
||||
is_online: false,
|
||||
is_best_friend: false,
|
||||
is_free_trial: false,
|
||||
location: ZoneId {
|
||||
map_id: 0,
|
||||
instance_id: 0,
|
||||
clone_id: 0,
|
||||
},
|
||||
object_id: 1152921509697915304,
|
||||
char_name: lu!("PikachuThunder"),
|
||||
},
|
||||
].into(),
|
||||
),
|
||||
)
|
||||
Reference in New Issue
Block a user