Improving the packet mapping

pull/5/head
Wyatt Herkamp 2 years ago
parent 497552c730
commit 4d1353afd2

@ -1,3 +1,5 @@
use std::collections::HashMap;
use std::convert::TryInto;
use crate::api::protocol::Protocol;
use crate::api::tests::get_test_versions;
use crate::models::protocol::{PacketDataType};

@ -1,6 +1,7 @@
pub mod types;
pub mod packet_mapper;
use std::borrow::Cow;
use std::fmt;
use serde::{de, Deserialize, Deserializer};
use serde::de::{MapAccess, Visitor};
@ -8,7 +9,7 @@ use serde_json::Value;
pub use packet_mapper::{PacketMapper, PacketSwitch, PacketMapperSwitch};
pub use types::{BitField, NativeType, PacketDataType, PacketDataTypes};
#[derive(Deserialize, Debug)]
#[derive(Deserialize, Debug, Clone)]
pub struct Protocol {
pub types: PacketDataTypes,
pub handshaking: PacketGrouping,
@ -17,7 +18,7 @@ pub struct Protocol {
pub play: PacketGrouping,
}
#[derive(Deserialize, Debug)]
#[derive(Deserialize, Debug, Clone)]
pub struct PacketGrouping {
#[serde(rename = "toServer")]
pub to_server: PacketTypes,
@ -25,7 +26,7 @@ pub struct PacketGrouping {
pub to_client: PacketTypes,
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum DataTypeReference {
Simple(String),
Complex {
@ -34,13 +35,38 @@ pub enum DataTypeReference {
},
}
#[derive(Debug)]
impl Into<PacketDataType> for DataTypeReference {
fn into(self) -> PacketDataType {
let (name, properties) = match self {
DataTypeReference::Simple(simple) => {
(simple, Value::Null)
}
DataTypeReference::Complex { name, properties } => {
(name, properties)
}
};
PacketDataType::new(name.as_str(), Cow::Borrowed(&properties)).
or_else(|| {
let option = NativeType::new(name.as_str(), Cow::Borrowed(&properties));
option.map(PacketDataType::Native)
})
.unwrap_or_else(|| {
PacketDataType::Other {
name: Some(name.into()),
value: properties,
}
})
}
}
#[derive(Debug, Clone)]
pub struct Packet {
pub name: String,
pub data: Vec<(String, DataTypeReference)>,
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct PacketTypes {
pub packet_mapper: PacketMapperSwitch,
pub types: Vec<Packet>,
@ -89,7 +115,7 @@ impl<'de> Deserialize<'de> for PacketTypes {
let name = obj.remove("name");
let name = if let Some(name) = name {
name.to_string()
}else{
} else {
"anon".to_string()
};
let value = obj.remove("type").ok_or_else(|| de::Error::custom(format!("Packet ID {} missing type", key)))?;

@ -1,26 +1,45 @@
use std::collections::HashMap;
use std::convert::TryInto;
use std::fmt;
use std::iter::Map;
use std::num::ParseIntError;
use serde::de::{SeqAccess, Visitor};
use serde::{de, Deserialize, Deserializer};
use serde_json::Value;
#[derive(Deserialize, Debug)]
#[derive(Deserialize, Debug, Clone)]
pub struct PacketMapper {
/// A Type
#[serde(rename = "type")]
pub map_type: String,
/// The first Value is a Hex value of the packet id. That is a string in the JSON. You can convert the map with the `i32::from_str_radix` (The ids do start with 0x) function. You can also just do try_into::<HashMap<i32, String>() on the PacketMapper
/// The second Value is the name of the packet
pub mappings: HashMap<String, String>,
}
#[derive(Deserialize, Debug)]
impl TryInto<HashMap<i32, String>> for PacketMapper {
type Error = ParseIntError;
fn try_into(self) -> Result<HashMap<i32, String>, Self::Error> {
let mut map = HashMap::with_capacity(self.mappings.len());
for (key, value) in self.mappings.into_iter() {
let key = i32::from_str_radix(key.trim_start_matches("0x"), 16)?;
map.insert(key, value);
}
Ok(map)
}
}
#[derive(Deserialize, Debug, Clone)]
pub struct PacketSwitch {
#[serde(rename = "compareTo")]
pub compare_to: String,
/// First value is the name of the packet. Second is the name of the JSON object for the packet.
pub fields: HashMap<String, String>,
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct PacketMapperSwitch {
pub mapper: PacketMapper,
pub switch: PacketSwitch,
@ -59,10 +78,10 @@ impl<'de> Deserialize<'de> for PacketMapperSwitch {
} else if key.eq("switch") {
let value: PacketSwitch = serde_json::from_value(value).map_err(de::Error::custom)?;
switch = Some(value);
}else{
} else {
return Err(de::Error::custom("unknown key"));
}
}else{
} else {
return Err(de::Error::custom("unknown key"));
}
} else {

@ -435,6 +435,9 @@ pub enum PacketDataType {
},
/// A Type that could not be built or parsed. This is a fallback for when we don't know what the type is
/// This type is usually a reference to a built type
///
/// If this is a reference you you will want to push any data within Value to the reference.
/// For example the Packet type references another type called "PacketData" that has a variable within it for the compareTo value. You will want to take the value from the Value and push it to the PacketData type.
Other {
// The name of the type if found
name: Option<TypeName>,
@ -492,7 +495,7 @@ impl PacketDataType {
}
}
#[derive(Debug)]
#[derive(Debug,Clone)]
pub struct PacketDataTypes {
pub types: Vec<PacketDataType>,
}

Loading…
Cancel
Save