use crate::{
errors::ParseError,
packet::{
header::{Header, PacketFrequency},
message::UIMessage,
packet::{Packet, PacketData},
packet_types::PacketType,
},
};
use byteorder::ReadBytesExt;
use glam::Vec3;
use serde::{Deserialize, Serialize};
use std::io::Read;
use std::io::{self, Cursor};
use uuid::Uuid;
use super::ChatType;
impl Packet {
pub fn new_chat_from_simulator(chat_from_simulator: ChatFromSimulator) -> Self {
Packet {
header: Header {
id: 139,
frequency: PacketFrequency::Low,
reliable: true,
zerocoded: false,
..Default::default()
},
body: PacketType::ChatFromSimulator(Box::new(chat_from_simulator)),
}
}
}
impl UIMessage {
pub fn new_chat_from_simulator(data: ChatFromSimulator) -> Self {
UIMessage::ChatFromSimulator(data)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChatFromSimulator {
pub from_name: String,
pub source_id: Uuid,
pub owner_id: Uuid,
pub source_type: SourceType,
pub chat_type: ChatType,
pub audible: Audible,
pub position: Vec3,
pub message: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SourceType {
System,
Agent,
Object,
Unknown,
}
impl SourceType {
fn from_bytes(bytes: u8) -> Self {
match bytes {
0 => SourceType::System,
1 => SourceType::Agent,
2 => SourceType::Object,
_ => SourceType::Unknown,
}
}
fn to_bytes(&self) -> u8 {
match self {
SourceType::System => 0,
SourceType::Agent => 1,
SourceType::Object => 2,
SourceType::Unknown => 3,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Audible {
Not,
Barely,
Fully,
Unknown,
}
impl Audible {
fn from_bytes(bytes: u8) -> Self {
match bytes {
255 => Audible::Not,
0 => Audible::Barely,
1 => Audible::Fully,
_ => Audible::Unknown,
}
}
fn to_bytes(&self) -> u8 {
match self {
Audible::Not => 255,
Audible::Barely => 0,
Audible::Fully => 1,
Audible::Unknown => 2,
}
}
}
impl PacketData for ChatFromSimulator {
fn from_bytes(bytes: &[u8]) -> Result<Self, ParseError> {
let mut cursor = Cursor::new(bytes);
let name_len = cursor.read_u8()?;
let mut from_name_bytes = vec![0u8; name_len as usize];
cursor.read_exact(&mut from_name_bytes)?;
if let Some(&0) = from_name_bytes.last() {
from_name_bytes.pop();
}
let from_name = String::from_utf8(from_name_bytes)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
let source_id = Uuid::from_slice(
&cursor.get_ref()[cursor.position() as usize..cursor.position() as usize + 16],
)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
cursor.set_position(cursor.position() + 16);
let owner_id = Uuid::from_slice(
&cursor.get_ref()[cursor.position() as usize..cursor.position() as usize + 16],
)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
cursor.set_position(cursor.position() + 16);
let source_type_byte = cursor.read_u8()?;
let source_type = SourceType::from_bytes(source_type_byte);
let chat_type_byte = cursor.read_u8()?;
let chat_type = ChatType::from_bytes(chat_type_byte);
let audible_byte = cursor.read_u8()?;
let audible = Audible::from_bytes(audible_byte);
let position = Vec3 {
x: cursor.read_f32::<byteorder::LittleEndian>()?,
y: cursor.read_f32::<byteorder::LittleEndian>()?,
z: cursor.read_f32::<byteorder::LittleEndian>()?,
};
let message_len = cursor.read_u16::<byteorder::LittleEndian>()?;
let mut message_bytes = vec![0u8; message_len as usize];
cursor.read_exact(&mut message_bytes)?;
if let Some(&0) = message_bytes.last() {
message_bytes.pop();
}
let message = String::from_utf8(message_bytes)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
Ok(Self {
from_name,
source_id,
owner_id,
source_type,
chat_type,
audible,
position,
message,
})
}
fn to_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
let mut name_bytes = self.from_name.as_bytes().to_vec();
name_bytes.push(0); bytes.push(name_bytes.len() as u8);
bytes.extend_from_slice(&name_bytes);
bytes.extend_from_slice(self.source_id.as_bytes());
bytes.extend_from_slice(self.owner_id.as_bytes());
bytes.push(self.source_type.to_bytes());
bytes.push(self.chat_type.to_bytes());
bytes.push(self.audible.to_bytes());
bytes.extend_from_slice(&self.position.x.to_le_bytes());
bytes.extend_from_slice(&self.position.y.to_le_bytes());
bytes.extend_from_slice(&self.position.z.to_le_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
}
}