Add server-sent chat packets

This commit is contained in:
lcdr
2020-11-12 17:30:07 +01:00
parent b65efbd426
commit f11fdd7d50
38 changed files with 360 additions and 196 deletions
+2 -2
View File
@@ -70,7 +70,7 @@ fn parse(path: &Path) -> Res<usize> {
dbg!(msg);
};
packet_count += 1;
} else if file.name().contains("[53-05-")
} else if file.name().contains("[53-02-") || (file.name().contains("[53-05-")
&& !file.name().contains("[53-05-00-00]")
&& !file.name().contains("[53-05-00-06]")
&& !file.name().contains("[53-05-00-15]")
@@ -121,7 +121,7 @@ fn parse(path: &Path) -> Res<usize> {
&& !file.name().contains("[1558]")
&& !file.name().contains("[1564]")
&& !file.name().contains("[1647]")
&& !file.name().contains("[1648]")
&& !file.name().contains("[1648]"))
{
let msg: WorldClientMessage = file.read().expect(&format!("Zip: {}, Filename: {}, {} bytes", path.to_str().unwrap(), file.name(), file.size()));
if unsafe { PRINT_PACKETS } {
+27 -8
View File
@@ -5,21 +5,40 @@ use endio::{LEWrite, Serialize};
use endio::LittleEndian as LE;
use lu_packets_derive::FromVariants;
use crate::common::{LuString33, LuVarWString, LuWString33};
use crate::common::{LuString33, LuVarWString, LuWString33, ServiceId};
use crate::general::client::{DisconnectNotify, Handshake, GeneralMessage};
/// All LU messages that can be received by a client from an auth server.
pub type LuMessage = crate::general::client::LuMessage<ClientMessage>;
/// All messages that can be received by a client from an auth server.
pub type Message = crate::raknet::client::Message<LuMessage>;
impl From<ClientMessage> for Message {
fn from(msg: ClientMessage) -> Self {
LuMessage::Client(msg).into()
/// All LU messages that can be received by a client from an auth server.
#[derive(Debug, FromVariants, PartialEq, Serialize)]
#[repr(u16)]
pub enum LuMessage {
General(GeneralMessage) = ServiceId::General as u16,
Client(ClientMessage) = ServiceId::Client as u16,
}
impl From<LuMessage> for Message {
fn from(msg: LuMessage) -> Self {
Message::UserMessage(msg)
}
}
impl From<Handshake> for Message {
fn from(msg: Handshake) -> Self {
GeneralMessage::Handshake(msg).into()
}
}
impl From<DisconnectNotify> for Message {
fn from(msg: DisconnectNotify) -> Self {
GeneralMessage::DisconnectNotify(msg).into()
}
}
/// All client-received auth messages.
#[derive(Debug, FromVariants, Serialize)]
#[derive(Debug, FromVariants, PartialEq, Serialize)]
#[post_disc_padding=1]
#[repr(u32)]
pub enum ClientMessage {
@@ -45,7 +64,7 @@ pub enum ClientMessage {
### Notes
Expect the connection to be closed soon after this message is received, if you're not closing it yourself already.
*/
#[derive(Debug)]
#[derive(Debug, PartialEq)]
#[non_exhaustive]
#[repr(u8)]
pub enum LoginResponse {

Before

Width:  |  Height:  |  Size: 15 B

After

Width:  |  Height:  |  Size: 15 B

+5
View File
@@ -0,0 +1,5 @@
LuMessage::General(
GeneralMessage::DisconnectNotify(
crate::general::client::DisconnectNotify::WrongGameVersion(0),
),
)
-1
View File
@@ -1 +0,0 @@
+30
View File
@@ -0,0 +1,30 @@
use endio::{Deserialize, Serialize};
use lu_packets_derive::{FromVariants, VariantTests};
use crate::common::{LuWString33, ObjId};
use crate::world::client::Message;
use super::{GeneralChatMessage, PrivateChatMessage};
#[derive(Debug, Deserialize, PartialEq, Serialize, FromVariants, VariantTests)]
#[non_exhaustive]
#[post_disc_padding=9]
#[repr(u32)]
pub enum ChatMessage {
GeneralChatMessage(GeneralChatMessage) = 1,
PrivateChatMessage(PrivateChatMessage) = 2,
AchievementNotify(AchievementNotify) = 59,
}
#[derive(Debug, Deserialize, PartialEq, Serialize)]
pub struct AchievementNotify {
#[padding=5]
pub sender_name: LuWString33,
pub sender: ObjId,
pub source_id: u16,
pub sender_gm_level: u8,
pub target_group: u32, // todo: type?
pub mission_message_key: u32, // todo: type?
pub requesting_player: ObjId,
pub recipient_name: LuWString33,
pub recipient_gm_level: u8,
}
Binary file not shown.
@@ -0,0 +1,13 @@
ChatMessage::AchievementNotify(
AchievementNotify {
sender_name: lu!("BreezyFlyingNinja"),
sender: 491736784313516311,
source_id: 23,
sender_gm_level: 0,
target_group: 1,
mission_message_key: 132,
requesting_player: 1152921507960010807,
recipient_name: lu!("CheekyMonkey"),
recipient_gm_level: 0,
},
)
Binary file not shown.
@@ -0,0 +1,10 @@
ChatMessage::GeneralChatMessage(
GeneralChatMessage {
chat_channel: crate::chat::ChatChannel::Team,
sender_name: lu!("GruntMonkey"),
sender: 1152921510436607007,
source_id: 23,
sender_gm_level: 0,
message: lu!("thanks."),
},
)
Binary file not shown.
@@ -0,0 +1,13 @@
ChatMessage::PrivateChatMessage(
PrivateChatMessage {
chat_channel: crate::chat::ChatChannel::Private,
sender_name: lu!("CheekyMonkey"),
sender: 1152921507004579166,
source_id: 0,
sender_gm_level: 0,
recipient_name: lu!("BreezyFlyingNinja"),
recipient_gm_level: 0,
response_code: crate::chat::PrivateChatMessageResponseCode::Sent,
message: lu!("Hey, what\'s up?"),
},
)
+162
View File
@@ -1,3 +1,165 @@
//! Chat messages.
pub mod client;
pub mod server;
use std::io::{Read, Write};
use std::io::Result as Res;
use endio::{Deserialize, LERead, LEWrite, Serialize};
use endio::LittleEndian as LE;
use crate::common::{LuVarWString, LuWString33, ObjId};
#[derive(Debug, Deserialize, PartialEq, Serialize)]
#[repr(u8)]
pub enum ChatChannel {
SystemNotify,
SystemWarning,
SystemError,
Broadcast,
Local,
LocalNoanim,
Emote,
Private,
Team,
TeamLocal,
Guild,
GuildNotify,
Property,
Admin,
CombatDamage,
CombatHealing,
CombatLoot,
CombatExp,
CombatDeath,
General,
Trade,
Lfg,
User,
}
#[derive(Debug, PartialEq)]
pub struct GeneralChatMessage {
pub chat_channel: ChatChannel,
pub sender_name: LuWString33,
pub sender: ObjId,
pub source_id: u16,
pub sender_gm_level: u8,
pub message: LuVarWString<u32>,
}
impl<R: Read+LERead> Deserialize<LE, R> for GeneralChatMessage
where u8: Deserialize<LE, R>,
u16: Deserialize<LE, R>,
u32: Deserialize<LE, R>,
LuWString33: Deserialize<LE, R>,
ObjId: Deserialize<LE, R> {
fn deserialize(reader: &mut R) -> Res<Self> {
let chat_channel = LERead::read(reader)?;
let mut str_len: u32 = LERead::read(reader)?;
if chat_channel == ChatChannel::Team {
str_len -= 1;
}
let sender_name = LERead::read(reader)?;
let sender = LERead::read(reader)?;
let source_id = LERead::read(reader)?;
let sender_gm_level = LERead::read(reader)?;
let message = LuVarWString::deser_content(reader, str_len)?;
let _: u16 = LERead::read(reader)?;
Ok(Self { chat_channel, sender_name, sender, source_id, sender_gm_level, message })
}
}
impl<'a, W: Write+LEWrite> Serialize<LE, W> for &'a GeneralChatMessage
where u8: Serialize<LE, W>,
u16: Serialize<LE, W>,
u32: Serialize<LE, W>,
&'a LuWString33: Serialize<LE, W>,
ObjId: Serialize<LE, W> {
fn serialize(self, writer: &mut W) -> Res<()> {
LEWrite::write(writer, &self.chat_channel)?;
let mut str_len = self.message.len();
if self.chat_channel == ChatChannel::Team {
str_len += 1;
}
LEWrite::write(writer, str_len as u32)?;
LEWrite::write(writer, &self.sender_name)?;
LEWrite::write(writer, self.sender)?;
LEWrite::write(writer, self.source_id)?;
LEWrite::write(writer, self.sender_gm_level)?;
self.message.ser_content(writer)?;
LEWrite::write(writer, 0u16)
}
}
#[derive(Debug, Deserialize, PartialEq, Serialize)]
#[repr(u8)]
pub enum PrivateChatMessageResponseCode {
Sent,
NotOnline,
GeneralError,
ReceivedNewWhisper,
NotFriends,
SenderFreeTrial,
ReceiverFreeTrial,
}
#[derive(Debug, PartialEq)]
pub struct PrivateChatMessage {
pub chat_channel: ChatChannel,
pub sender_name: LuWString33,
pub sender: ObjId,
pub source_id: u16,
pub sender_gm_level: u8,
pub recipient_name: LuWString33,
pub recipient_gm_level: u8,
pub response_code: PrivateChatMessageResponseCode,
pub message: LuVarWString<u32>,
}
impl<R: Read+LERead> Deserialize<LE, R> for PrivateChatMessage
where u8: Deserialize<LE, R>,
u16: Deserialize<LE, R>,
u32: Deserialize<LE, R>,
LuWString33: Deserialize<LE, R>,
ObjId: Deserialize<LE, R>,
PrivateChatMessageResponseCode: Deserialize<LE, R> {
fn deserialize(reader: &mut R) -> Res<Self> {
let chat_channel = LERead::read(reader)?;
let mut str_len: u32 = LERead::read(reader)?;
str_len -= 1;
let sender_name = LERead::read(reader)?;
let sender = LERead::read(reader)?;
let source_id = LERead::read(reader)?;
let sender_gm_level = LERead::read(reader)?;
let recipient_name = LERead::read(reader)?;
let recipient_gm_level = LERead::read(reader)?;
let response_code = LERead::read(reader)?;
let message = LuVarWString::deser_content(reader, str_len)?;
let _: u16 = LERead::read(reader)?;
Ok(Self { chat_channel, sender_name, sender, source_id, sender_gm_level, recipient_name, recipient_gm_level, response_code, message })
}
}
impl<'a, W: Write+LEWrite> Serialize<LE, W> for &'a PrivateChatMessage
where u8: Serialize<LE, W>,
u16: Serialize<LE, W>,
u32: Serialize<LE, W>,
&'a LuWString33: Serialize<LE, W>,
ObjId: Serialize<LE, W>,
&'a PrivateChatMessageResponseCode: Serialize<LE, W> {
fn serialize(self, writer: &mut W) -> Res<()> {
LEWrite::write(writer, &self.chat_channel)?;
let mut str_len = self.message.len();
str_len += 1;
LEWrite::write(writer, str_len as u32)?;
LEWrite::write(writer, &self.sender_name)?;
LEWrite::write(writer, self.sender)?;
LEWrite::write(writer, self.source_id)?;
LEWrite::write(writer, self.sender_gm_level)?;
LEWrite::write(writer, &self.recipient_name)?;
LEWrite::write(writer, self.recipient_gm_level)?;
LEWrite::write(writer, &self.response_code)?;
self.message.ser_content(writer)?;
LEWrite::write(writer, 0u16)
}
}
+5 -122
View File
@@ -1,11 +1,8 @@
use std::io::{Read, Write};
use std::io::Result as Res;
use endio::{Deserialize, LERead, LEWrite, Serialize};
use endio::LittleEndian as LE;
use endio::{Deserialize, Serialize};
use lu_packets_derive::VariantTests;
use crate::common::{LuVarWString, LuWString33, ObjId};
use crate::common::{LuWString33, ObjId};
use super::{ChatChannel, GeneralChatMessage, PrivateChatMessage};
#[derive(Debug, Deserialize, PartialEq, Serialize, VariantTests)]
#[post_disc_padding=9]
@@ -23,120 +20,6 @@ pub enum ChatMessage {
RequestMinimumChatModePrivate(RequestMinimumChatModePrivate) = 51,
}
#[derive(Debug, PartialEq)]
pub struct GeneralChatMessage {
pub chat_channel: u8, // todo: type?
pub sender_name: LuWString33,
pub sender: ObjId,
pub source_id: u16,
pub sender_gm_level: u8,
pub message: LuVarWString<u32>,
}
impl<R: Read+LERead> Deserialize<LE, R> for GeneralChatMessage
where u8: Deserialize<LE, R>,
u16: Deserialize<LE, R>,
u32: Deserialize<LE, R>,
LuWString33: Deserialize<LE, R>,
ObjId: Deserialize<LE, R> {
fn deserialize(reader: &mut R) -> Res<Self> {
let chat_channel = LERead::read(reader)?;
let str_len: u32 = LERead::read(reader)?;
let sender_name = LERead::read(reader)?;
let sender = LERead::read(reader)?;
let source_id = LERead::read(reader)?;
let sender_gm_level = LERead::read(reader)?;
let message = LuVarWString::deser_content(reader, str_len)?;
Ok(Self { chat_channel, sender_name, sender, source_id, sender_gm_level, message })
}
}
impl<'a, W: Write+LEWrite> Serialize<LE, W> for &'a GeneralChatMessage
where u8: Serialize<LE, W>,
u16: Serialize<LE, W>,
u32: Serialize<LE, W>,
&'a LuWString33: Serialize<LE, W>,
ObjId: Serialize<LE, W> {
fn serialize(self, writer: &mut W) -> Res<()> {
LEWrite::write(writer, self.chat_channel)?;
self.message.ser_len(writer)?;
LEWrite::write(writer, &self.sender_name)?;
LEWrite::write(writer, self.sender)?;
LEWrite::write(writer, self.source_id)?;
LEWrite::write(writer, self.sender_gm_level)?;
self.message.ser_content(writer)
}
}
#[derive(Debug, Deserialize, PartialEq, Serialize)]
#[repr(u8)]
pub enum PrivateChatMessageResponseCode {
Sent,
NotOnline,
GeneralError,
ReceivedNewWhisper,
NotFriends,
SenderFreeTrial,
ReceiverFreeTrial,
}
#[derive(Debug, PartialEq)]
pub struct PrivateChatMessage {
pub chat_channel: u8, // todo: type?
pub sender_name: LuWString33,
pub sender: ObjId,
pub source_id: u16,
pub sender_gm_level: u8,
pub recipient_name: LuWString33,
pub recipient_gm_level: u8,
pub response_code: PrivateChatMessageResponseCode,
pub message: LuVarWString<u32>,
}
impl<R: Read+LERead> Deserialize<LE, R> for PrivateChatMessage
where u8: Deserialize<LE, R>,
u16: Deserialize<LE, R>,
u32: Deserialize<LE, R>,
LuWString33: Deserialize<LE, R>,
ObjId: Deserialize<LE, R>,
PrivateChatMessageResponseCode: Deserialize<LE, R> {
fn deserialize(reader: &mut R) -> Res<Self> {
let chat_channel = LERead::read(reader)?;
let str_len: u32 = LERead::read(reader)?;
let sender_name = LERead::read(reader)?;
let sender = LERead::read(reader)?;
let source_id = LERead::read(reader)?;
let sender_gm_level = LERead::read(reader)?;
let recipient_name = LERead::read(reader)?;
let recipient_gm_level = LERead::read(reader)?;
let response_code = LERead::read(reader)?;
let message = LuVarWString::deser_content(reader, str_len)?;
Ok(Self { chat_channel, sender_name, sender, source_id, sender_gm_level, recipient_name, recipient_gm_level, response_code, message })
}
}
impl<'a, W: Write+LEWrite> Serialize<LE, W> for &'a PrivateChatMessage
where u8: Serialize<LE, W>,
u16: Serialize<LE, W>,
u32: Serialize<LE, W>,
&'a LuWString33: Serialize<LE, W>,
ObjId: Serialize<LE, W>,
&'a PrivateChatMessageResponseCode: Serialize<LE, W> {
fn serialize(self, writer: &mut W) -> Res<()> {
LEWrite::write(writer, self.chat_channel)?;
self.message.ser_len(writer)?;
LEWrite::write(writer, &self.sender_name)?;
LEWrite::write(writer, self.sender)?;
LEWrite::write(writer, self.source_id)?;
LEWrite::write(writer, self.sender_gm_level)?;
LEWrite::write(writer, &self.recipient_name)?;
LEWrite::write(writer, self.recipient_gm_level)?;
LEWrite::write(writer, &self.response_code)?;
self.message.ser_content(writer)
}
}
#[derive(Debug, Deserialize, PartialEq, Serialize)]
#[repr(u8)]
pub enum AddFriendResponseCode {
@@ -173,11 +56,11 @@ pub struct TeamLeave {
#[derive(Debug, Deserialize, PartialEq, Serialize)]
pub struct RequestMinimumChatMode {
pub chat_channel: u8, // todo: separate type?
pub chat_channel: ChatChannel,
}
#[derive(Debug, Deserialize, PartialEq, Serialize)]
pub struct RequestMinimumChatModePrivate {
pub chat_channel: u8, // todo: separate type?
pub chat_channel: ChatChannel,
pub recipient_name: LuWString33,
}
+2 -2
View File
@@ -1,10 +1,10 @@
ChatMessage::GeneralChatMessage(
GeneralChatMessage {
chat_channel: 8,
chat_channel: crate::chat::ChatChannel::Team,
sender_name: lu!("mission for computer"),
sender: 0,
source_id: 0,
sender_gm_level: 0,
message: lu!("thanks.\u{0}"),
message: lu!("thanks."),
},
)
+3 -3
View File
@@ -1,13 +1,13 @@
ChatMessage::PrivateChatMessage(
PrivateChatMessage {
chat_channel: 7,
chat_channel: ChatChannel::Private,
sender_name: lu!("nks quab"),
sender: 0,
source_id: 0,
sender_gm_level: 0,
recipient_name: lu!("BreezyFlyingNinja"),
recipient_gm_level: 0,
response_code: PrivateChatMessageResponseCode::Sent,
message: lu!("Hey, what\'s up?\u{0}"),
response_code: crate::chat::PrivateChatMessageResponseCode::Sent,
message: lu!("Hey, what\'s up?"),
},
)
@@ -1,5 +1,5 @@
ChatMessage::RequestMinimumChatMode(
RequestMinimumChatMode {
chat_channel: 8,
chat_channel: ChatChannel::Team,
},
)
@@ -1,6 +1,6 @@
ChatMessage::RequestMinimumChatModePrivate(
RequestMinimumChatModePrivate {
chat_channel: 7,
chat_channel: ChatChannel::Private,
recipient_name: lu!("RockVonViper"),
},
)
-36
View File
@@ -4,30 +4,6 @@ use lu_packets_derive::VariantTests;
use crate::common::ServiceId;
/// All client-received messages from a specific server type, including Raknet messages.
pub type Message<C> = crate::raknet::client::Message<LuMessage<C>>;
/// All client-received LU messages from a specific server type.
#[derive(Debug, Deserialize, PartialEq, Serialize, VariantTests)]
#[test_params(crate::world::client::ClientMessage)]
#[repr(u16)]
pub enum LuMessage<C> {
General(GeneralMessage) = ServiceId::General as u16,
Client(C) = ServiceId::Client as u16,
}
impl<C> From<LuMessage<C>> for Message<C> {
fn from(msg: LuMessage<C>) -> Self {
Message::UserMessage(msg)
}
}
impl<C> From<GeneralMessage> for Message<C> {
fn from(msg: GeneralMessage) -> Self {
LuMessage::General(msg).into()
}
}
/// Client-received general messages.
#[derive(Debug, Deserialize, PartialEq, Serialize, VariantTests)]
#[post_disc_padding=1]
@@ -37,18 +13,6 @@ pub enum GeneralMessage {
DisconnectNotify(DisconnectNotify),
}
impl<C> From<Handshake> for Message<C> {
fn from(msg: Handshake) -> Self {
GeneralMessage::Handshake(msg).into()
}
}
impl<C> From<DisconnectNotify> for Message<C> {
fn from(msg: DisconnectNotify) -> Self {
GeneralMessage::DisconnectNotify(msg).into()
}
}
/**
Completes a version handshake initiated by the client.
-5
View File
@@ -1,5 +0,0 @@
LuMessage::General(
GeneralMessage::DisconnectNotify(
DisconnectNotify::WrongGameVersion(0),
),
)
+30 -8
View File
@@ -5,18 +5,40 @@ use endio::{Deserialize, LERead, LEWrite, Serialize};
use endio::LittleEndian as LE;
use lu_packets_derive::{FromVariants, VariantTests};
use crate::common::{ObjId, LuString33, LuWString33, LVec};
use crate::chat::ChatChannel;
use crate::chat::client::ChatMessage;
use crate::common::{ObjId, LuString33, LuWString33, LVec, ServiceId};
use crate::general::client::{DisconnectNotify, Handshake, GeneralMessage};
use super::{Lot, lnv::LuNameValue, Vector3, ZoneId};
use super::gm::client::SubjectGameMessage;
/// All LU messages that can be received by a client from a world server.
pub type LuMessage = crate::general::client::LuMessage<ClientMessage>;
/// All messages that can be received by a client from a world server.
pub type Message = crate::raknet::client::Message<LuMessage>;
impl From<ClientMessage> for Message {
fn from(msg: ClientMessage) -> Self {
LuMessage::Client(msg).into()
/// All client-received LU messages from a world server.
#[derive(Debug, Deserialize, FromVariants, PartialEq, Serialize, VariantTests)]
#[repr(u16)]
pub enum LuMessage {
General(GeneralMessage) = ServiceId::General as u16,
Chat(ChatMessage) = ServiceId::Chat as u16,
Client(ClientMessage) = ServiceId::Client as u16,
}
impl From<LuMessage> for Message {
fn from(msg: LuMessage) -> Self {
Message::UserMessage(msg)
}
}
impl From<Handshake> for Message {
fn from(msg: Handshake) -> Self {
GeneralMessage::Handshake(msg).into()
}
}
impl From<DisconnectNotify> for Message {
fn from(msg: DisconnectNotify) -> Self {
GeneralMessage::DisconnectNotify(msg).into()
}
}
@@ -280,13 +302,13 @@ pub struct TeamInvite {
#[derive(Debug, Deserialize, PartialEq, Serialize)]
pub struct MinimumChatModeResponse {
pub chat_mode: u8, // todo: type?
pub chat_channel: u8, // todo: type?
pub chat_channel: ChatChannel,
}
#[derive(Debug, Deserialize, PartialEq, Serialize)]
pub struct MinimumChatModeResponsePrivate {
pub chat_mode: u8, // todo: type?
pub chat_channel: u8, // todo: type?
pub chat_channel: ChatChannel,
pub recipient_name: LuWString33,
pub recipient_gm_level: u8,
}
Binary file not shown.
+12
View File
@@ -0,0 +1,12 @@
LuMessage::Chat(
crate::chat::client::ChatMessage::GeneralChatMessage(
crate::chat::GeneralChatMessage {
chat_channel: crate::chat::ChatChannel::Local,
sender_name: lu!("srgjktrjehfkyjghfkgestei"),
sender: 1152921506625600874,
source_id: 0,
sender_gm_level: 0,
message: lu!("selling imagination pack dagger and jet pack for gold hamer or shield need one for my brother"),
},
),
)
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 B

+5
View File
@@ -0,0 +1,5 @@
LuMessage::General(
GeneralMessage::DisconnectNotify(
crate::general::client::DisconnectNotify::WrongGameVersion(0),
),
)
@@ -1,6 +1,6 @@
ClientMessage::MinimumChatModeResponse(
MinimumChatModeResponse {
chat_mode: 0,
chat_channel: 8,
chat_channel: ChatChannel::Team,
},
)
@@ -1,7 +1,7 @@
ClientMessage::MinimumChatModeResponsePrivate(
MinimumChatModeResponsePrivate {
chat_mode: 0,
chat_channel: 7,
chat_channel: ChatChannel::Private,
recipient_name: lu!("RockVonViper"),
recipient_gm_level: 0,
},
+35 -3
View File
@@ -7,6 +7,7 @@ use endio::LittleEndian as LE;
use lu_packets_derive::VariantTests;
use crate::common::{ObjId, LuVarWString, LuWString33, LuWString42, ServiceId};
use crate::chat::ChatChannel;
use crate::chat::server::ChatMessage;
use super::ZoneId;
use super::gm::server::SubjectGameMessage;
@@ -182,13 +183,44 @@ pub struct CharacterDeleteRequest {
pub char_id: ObjId,
}
#[derive(Debug, Deserialize, PartialEq, Serialize)]
#[derive(Debug, PartialEq)]
pub struct GeneralChatMessage {
pub chat_channel: u8, // todo: type?
pub chat_channel: ChatChannel,
pub source_id: u16,
pub message: LuVarWString<u32>,
}
impl<R: Read+LERead> Deserialize<LE, R> for GeneralChatMessage
where u8: Deserialize<LE, R>,
LuWString33: Deserialize<LE, R> {
fn deserialize(reader: &mut R) -> Res<Self> {
let chat_channel = LERead::read(reader)?;
let source_id = LERead::read(reader)?;
let mut str_len: u32 = LERead::read(reader)?;
str_len -= 1;
let message = LuVarWString::deser_content(reader, str_len)?;
let _: u16 = LERead::read(reader)?;
Ok(Self {
chat_channel,
source_id,
message,
})
}
}
impl<'a, W: Write+LEWrite> Serialize<LE, W> for &'a GeneralChatMessage {
fn serialize(self, writer: &mut W) -> Res<()> {
LEWrite::write(writer, &self.chat_channel)?;
LEWrite::write(writer, self.source_id)?;
let mut str_len = self.message.len();
str_len += 1;
LEWrite::write(writer, str_len as u32)?;
self.message.ser_content(writer)?;
LEWrite::write(writer, 0u16)
}
}
/**
Reports to the server that client-side loading has finished.
@@ -229,7 +261,7 @@ pub enum RouteMessage {
#[derive(Debug, Deserialize, PartialEq, Serialize)]
pub struct StringCheck {
pub chat_mode: u8, // todo: type?
pub chat_channel: u8, // todo: type?
pub chat_channel: u8,
pub recipient_name: LuWString42,
/// The string to be checked.
pub string: LuVarWString<u16>,
+2 -2
View File
@@ -1,7 +1,7 @@
WorldMessage::GeneralChatMessage(
GeneralChatMessage {
chat_channel: 9,
chat_channel: ChatChannel::TeamLocal,
source_id: 0,
message: lu!("how long are you going to stay there?\u{0}"),
message: lu!("how long are you going to stay there?"),
},
)