diff --git a/src/packet/messages.rs b/src/packet/messages.rs index d50a5bf..ccdd61a 100644 --- a/src/packet/messages.rs +++ b/src/packet/messages.rs @@ -1,5 +1,6 @@ #![allow(unused_must_use)] use std::io::{SeekFrom}; +use std::convert::TryInto; use psopacket::{pso_message, PSOPacketData}; use crate::{PSOPacketData, PacketParseError}; @@ -684,11 +685,122 @@ pub struct BoxDropRequest { //} + +#[derive(Clone, Debug, PartialEq)] +pub enum TradeRequestInitializeCommand { + Initialize, + Respond, +} + + +#[derive(Clone, Debug, PartialEq)] +pub enum TradeRequestCommand { + Initialize(TradeRequestInitializeCommand, u32), + AddItem(u32, u32), + RemoveItem(u32, u32), + Confirm, + FinalConfirm, + Unknown, +} + +impl PSOPacketData for TradeRequestCommand { + fn from_bytes(cursor: &mut R) -> Result { + let mut bytes = [0u8; 12]; + let len = cursor.read(&mut bytes).map_err(|_| PacketParseError::ReadError)?; + if len != 12 { + return Err(PacketParseError::NotEnoughBytes); + } + + match bytes[0] { + 0 => { + let meseta = u32::from_le_bytes(bytes[8..12].try_into().map_err(|_| PacketParseError::InvalidValue)?); + match bytes[1] { + 0 => Ok(TradeRequestCommand::Initialize(TradeRequestInitializeCommand::Initialize, meseta)), + 2 => Ok(TradeRequestCommand::Initialize(TradeRequestInitializeCommand::Respond, meseta)), + _ => Err(PacketParseError::InvalidValue) + } + }, + 1 => { + Ok(TradeRequestCommand::AddItem( + u32::from_le_bytes(bytes[4..8].try_into().map_err(|_| PacketParseError::InvalidValue)?), + u32::from_le_bytes(bytes[8..12].try_into().map_err(|_| PacketParseError::InvalidValue)?), + )) + }, + 2 => { + Ok(TradeRequestCommand::RemoveItem( + u32::from_le_bytes(bytes[4..8].try_into().map_err(|_| PacketParseError::InvalidValue)?), + u32::from_le_bytes(bytes[8..12].try_into().map_err(|_| PacketParseError::InvalidValue)?), + )) + }, + 3 => { + Ok(TradeRequestCommand::Confirm) + }, + 4 => { + Ok(TradeRequestCommand::FinalConfirm) + }, + 6 => { + Ok(TradeRequestCommand::Unknown) + }, + _ => { + Err(PacketParseError::InvalidValue) + }, + } + + } + + fn as_bytes(&self) -> Vec { + match self { + TradeRequestCommand::Initialize(cmd, meseta) => { + vec![0u8, + match cmd { + TradeRequestInitializeCommand::Initialize => 0, + TradeRequestInitializeCommand::Respond => 2, + }, + 0, 0, + 0, 0, 0, 0] + .into_iter() + .chain(meseta.to_le_bytes().to_vec().into_iter()) + .collect() + }, + TradeRequestCommand::AddItem(item_id, amount) => { + vec![1u8, 0, 0, 0] + .into_iter() + .chain(item_id.to_le_bytes().to_vec().into_iter()) + .chain(amount.to_le_bytes().to_vec().into_iter()) + .collect() + }, + TradeRequestCommand::RemoveItem(item_id, amount) => { + vec![2u8, 0, 0, 0] + .into_iter() + .chain(item_id.to_le_bytes().to_vec().into_iter()) + .chain(amount.to_le_bytes().to_vec().into_iter()) + .collect() + }, + TradeRequestCommand::Confirm => { + vec![3u8] + .into_iter() + .chain(std::iter::repeat(0).take(11)) + .collect() + }, + TradeRequestCommand::FinalConfirm => { + vec![4u8] + .into_iter() + .chain(std::iter::repeat(0).take(11)) + .collect() + }, + TradeRequestCommand::Unknown => { + vec![6u8] + .into_iter() + .chain(std::iter::repeat(0).take(11)) + .collect() + }, + } + } +} + #[pso_message(0xA6)] pub struct TradeRequest { - unknown1: u32, - unknown2: u32, - unknown3: u32, + pub trade: TradeRequestCommand, } //#[pso_message(0xA8)]