use crate::{
errors::ParseError,
packet::{
header::{Header, PacketFrequency},
packet::{Packet, PacketData},
packet_types::PacketType,
},
};
use byteorder::{LittleEndian, ReadBytesExt};
use serde::{Deserialize, Serialize};
use std::io::Cursor;
use std::io::Read;
use uuid::Uuid;
use super::ChatType;
impl Packet {
pub fn new_chat_from_viewer(chat_from_viewer: ChatFromViewer) -> Self {
Packet {
header: Header {
id: 80,
frequency: PacketFrequency::Low,
reliable: true,
zerocoded: false,
..Default::default()
},
body: PacketType::ChatFromViewer(Box::new(chat_from_viewer)),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChatFromViewer {
pub agent_id: Uuid,
pub session_id: Uuid,
pub message: String,
pub message_type: ChatType,
pub channel: i32,
}
impl PacketData for ChatFromViewer {
fn from_bytes(bytes: &[u8]) -> Result<Self, ParseError> {
let mut cursor = Cursor::new(bytes);
let mut agent_id_bytes = [0u8; 16];
cursor.read_exact(&mut agent_id_bytes)?;
let agent_id = Uuid::from_bytes(agent_id_bytes);
let mut session_id_bytes = [0u8; 16];
cursor.read_exact(&mut session_id_bytes)?;
let session_id = Uuid::from_bytes(session_id_bytes);
let message_length = cursor.read_u16::<LittleEndian>()? as usize;
let mut message_bytes = vec![0u8; message_length];
cursor.read_exact(&mut message_bytes)?;
if let Some(&0) = message_bytes.last() {
message_bytes.pop();
}
let message = String::from_utf8(message_bytes)?;
let message_type_byte = cursor.read_u8()?;
let message_type = ChatType::from_bytes(message_type_byte);
let channel = cursor.read_i32::<LittleEndian>()?;
Ok(ChatFromViewer {
agent_id,
session_id,
message,
message_type,
channel,
})
}
fn to_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.extend_from_slice(self.agent_id.as_bytes());
bytes.extend_from_slice(self.session_id.as_bytes());
let mut message_bytes = self.message.as_bytes().to_vec();
message_bytes.push(0); bytes.extend_from_slice(&(message_bytes.len() as u16).to_le_bytes());
bytes.extend_from_slice(&message_bytes);
bytes.push(self.message_type.to_bytes());
bytes.extend_from_slice(&self.channel.to_le_bytes());
bytes
}
}