Add protocol version global mutable to merge Metadata18/19 into one
Cleans up https://github.com/iceiix/steven/pull/57 1.8.9 (47) multiprotocol support which added too much code duplication, Metadata19 vs Metadata18, and different packets for each, the only difference being how it was parsed. Instead, switch back to using only one Metadata implementation, but with parsing conditionalized on a new global mutable: SUPPORTED_PROTOCOL_VERSION. Accessing global mutable state is unsafe but it is only set when initializing the connection, and only read when deep enough in the code where it is not feasible to pass otherwise. More elegant, worth it.
This commit is contained in:
parent
7f2e2033ca
commit
e28946b691
|
@ -38,66 +38,28 @@ impl <T: MetaValue> MetadataKey<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Metadata18 {
|
pub struct Metadata {
|
||||||
map: HashMap<i32, Value>,
|
map: HashMap<i32, Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Metadata19 {
|
impl Metadata {
|
||||||
map: HashMap<i32, Value>,
|
pub fn new() -> Metadata {
|
||||||
}
|
Metadata { map: HashMap::new() }
|
||||||
|
|
||||||
trait MetadataBase: fmt::Debug + Default {
|
|
||||||
fn map(&self) -> &HashMap<i32, Value>;
|
|
||||||
fn map_mut(&mut self) -> &mut HashMap<i32, Value>;
|
|
||||||
|
|
||||||
fn get<T: MetaValue>(&self, key: &MetadataKey<T>) -> Option<&T> {
|
|
||||||
self.map().get(&key.index).map(T::unwrap)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn put<T: MetaValue>(&mut self, key: &MetadataKey<T>, val: T) {
|
pub fn get<T: MetaValue>(&self, key: &MetadataKey<T>) -> Option<&T> {
|
||||||
self.map_mut().insert(key.index, val.wrap());
|
self.map.get(&key.index).map(T::unwrap)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn put<T: MetaValue>(&mut self, key: &MetadataKey<T>, val: T) {
|
||||||
|
self.map.insert(key.index, val.wrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn put_raw<T: MetaValue>(&mut self, index: i32, val: T) {
|
fn put_raw<T: MetaValue>(&mut self, index: i32, val: T) {
|
||||||
self.map_mut().insert(index, val.wrap());
|
self.map.insert(index, val.wrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fmt2(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn read_from18<R: io::Read>(buf: &mut R) -> Result<Self, protocol::Error> {
|
||||||
write!(f, "Metadata[ ")?;
|
|
||||||
for (k, v) in self.map() {
|
|
||||||
write!(f, "{:?}={:?}, ", k, v)?;
|
|
||||||
}
|
|
||||||
write!(f, "]")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MetadataBase for Metadata18 {
|
|
||||||
fn map(&self) -> &HashMap<i32, Value> { &self.map }
|
|
||||||
fn map_mut(&mut self) -> &mut HashMap<i32, Value> { &mut self.map }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MetadataBase for Metadata19 {
|
|
||||||
fn map(&self) -> &HashMap<i32, Value> { &self.map }
|
|
||||||
fn map_mut(&mut self) -> &mut HashMap<i32, Value> { &mut self.map }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Metadata18 {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self { map: HashMap::new() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Metadata19 {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self { map: HashMap::new() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
impl Serializable for Metadata18 {
|
|
||||||
|
|
||||||
fn read_from<R: io::Read>(buf: &mut R) -> Result<Self, protocol::Error> {
|
|
||||||
let mut m = Self::new();
|
let mut m = Self::new();
|
||||||
loop {
|
loop {
|
||||||
let ty_index = u8::read_from(buf)? as i32;
|
let ty_index = u8::read_from(buf)? as i32;
|
||||||
|
@ -128,7 +90,7 @@ impl Serializable for Metadata18 {
|
||||||
Ok(m)
|
Ok(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_to<W: io::Write>(&self, buf: &mut W) -> Result<(), protocol::Error> {
|
fn write_to18<W: io::Write>(&self, buf: &mut W) -> Result<(), protocol::Error> {
|
||||||
for (k, v) in &self.map {
|
for (k, v) in &self.map {
|
||||||
if (*k as u8) > 0x1f {
|
if (*k as u8) > 0x1f {
|
||||||
panic!("write metadata index {:x} > 0x1f", *k as u8);
|
panic!("write metadata index {:x} > 0x1f", *k as u8);
|
||||||
|
@ -177,9 +139,7 @@ impl Serializable for Metadata18 {
|
||||||
val[2].write_to(buf)?;
|
val[2].write_to(buf)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value::FormatComponent(_) | Value::Bool(_) | Value::Position(_) |
|
_ => {
|
||||||
Value::OptionalPosition(_) | Value::Direction(_) | Value::OptionalUUID(_) |
|
|
||||||
Value::Block(_) | Value::NBTTag(_) => {
|
|
||||||
panic!("attempted to write 1.9+ metadata to 1.8");
|
panic!("attempted to write 1.9+ metadata to 1.8");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -187,11 +147,8 @@ impl Serializable for Metadata18 {
|
||||||
u8::write_to(&0x7f, buf)?;
|
u8::write_to(&0x7f, buf)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl Serializable for Metadata19 {
|
fn read_from19<R: io::Read>(buf: &mut R) -> Result<Self, protocol::Error> {
|
||||||
|
|
||||||
fn read_from<R: io::Read>(buf: &mut R) -> Result<Self, protocol::Error> {
|
|
||||||
let mut m = Self::new();
|
let mut m = Self::new();
|
||||||
loop {
|
loop {
|
||||||
let index = u8::read_from(buf)? as i32;
|
let index = u8::read_from(buf)? as i32;
|
||||||
|
@ -243,7 +200,7 @@ impl Serializable for Metadata19 {
|
||||||
Ok(m)
|
Ok(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_to<W: io::Write>(&self, buf: &mut W) -> Result<(), protocol::Error> {
|
fn write_to19<W: io::Write>(&self, buf: &mut W) -> Result<(), protocol::Error> {
|
||||||
for (k, v) in &self.map {
|
for (k, v) in &self.map {
|
||||||
(*k as u8).write_to(buf)?;
|
(*k as u8).write_to(buf)?;
|
||||||
match *v {
|
match *v {
|
||||||
|
@ -316,18 +273,41 @@ impl Serializable for Metadata19 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: is it possible to implement these traits on MetadataBase instead?
|
impl Serializable for Metadata {
|
||||||
impl fmt::Debug for Metadata19 { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt2(f) } }
|
fn read_from<R: io::Read>(buf: &mut R) -> Result<Self, protocol::Error> {
|
||||||
impl fmt::Debug for Metadata18 { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt2(f) } }
|
let protocol_version = unsafe { protocol::CURRENT_PROTOCOL_VERSION };
|
||||||
|
|
||||||
impl Default for Metadata19 {
|
if protocol_version >= 74 {
|
||||||
fn default() -> Self {
|
Metadata::read_from19(buf)
|
||||||
Self::new()
|
} else {
|
||||||
|
Metadata::read_from18(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_to<W: io::Write>(&self, buf: &mut W) -> Result<(), protocol::Error> {
|
||||||
|
let protocol_version = unsafe { protocol::CURRENT_PROTOCOL_VERSION };
|
||||||
|
|
||||||
|
if protocol_version >= 74 {
|
||||||
|
self.write_to19(buf)
|
||||||
|
} else {
|
||||||
|
self.write_to18(buf)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Default for Metadata18 {
|
|
||||||
fn default() -> Self {
|
impl fmt::Debug for Metadata {
|
||||||
Self::new()
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "Metadata[ ")?;
|
||||||
|
for (k, v) in &self.map {
|
||||||
|
write!(f, "{:?}={:?}, ", k, v)?;
|
||||||
|
}
|
||||||
|
write!(f, "]")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Metadata {
|
||||||
|
fn default() -> Metadata {
|
||||||
|
Metadata::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -561,7 +541,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn basic() {
|
fn basic() {
|
||||||
let mut m = Metadata19::new();
|
let mut m = Metadata::new();
|
||||||
|
|
||||||
m.put(&TEST, "Hello world".to_owned());
|
m.put(&TEST, "Hello world".to_owned());
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue