134 Zeilen
3.5 KiB
Rust
134 Zeilen
3.5 KiB
Rust
|
use std::ops::{Deref, DerefMut};
|
||
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||
|
use serde::de::Error;
|
||
|
use lixcraft_derive::Wrapper;
|
||
|
|
||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Wrapper)]
|
||
|
pub struct VarInt(pub i32);
|
||
|
|
||
|
impl From<VarInt> for usize {
|
||
|
fn from(v: VarInt) -> Self {
|
||
|
v.0 as usize
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl From<usize> for VarInt {
|
||
|
fn from(v: usize) -> Self {
|
||
|
VarInt(v as i32)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl Serialize for VarInt {
|
||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
|
||
|
let mut v = self.0 as u32;
|
||
|
loop {
|
||
|
if v & 0x80 == 0 {
|
||
|
return serializer.serialize_u8(v as u8);
|
||
|
}
|
||
|
|
||
|
serializer.serialize_u8((v as u8 & 0x7f) | 0x80)?;
|
||
|
v >>= 7;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl<'de> Deserialize<'de> for VarInt {
|
||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
|
||
|
let mut num_read = 0;
|
||
|
let mut result = 0;
|
||
|
loop {
|
||
|
let read = u8::deserialize(deserializer)?;
|
||
|
let value = i32::from(read & 0b0111_1111);
|
||
|
result |= value.overflowing_shl(7 * num_read).0;
|
||
|
|
||
|
num_read += 1;
|
||
|
|
||
|
if num_read > 5 {
|
||
|
return Err(D::Error::custom("VarInt too large"));
|
||
|
}
|
||
|
if read & 0b1000_0000 == 0 {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
Ok(VarInt(result))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Debug)]
|
||
|
pub enum NextState {
|
||
|
Status,
|
||
|
Login
|
||
|
}
|
||
|
|
||
|
impl Serialize for NextState {
|
||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
|
||
|
VarInt::from(match self {
|
||
|
NextState::Status => 1,
|
||
|
NextState::Login => 2
|
||
|
}).serialize(serializer)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl<'de> Deserialize<'de> for NextState {
|
||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
|
||
|
match VarInt::deserialize(deserializer)? {
|
||
|
VarInt(1) => Ok(NextState::Status),
|
||
|
VarInt(2) => Ok(NextState::Login),
|
||
|
_ => Err(D::Error::custom("Invalid NextState"))
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Serialize, Deserialize)]
|
||
|
pub struct StatusResponseVersion {
|
||
|
name: String,
|
||
|
protocol: i32
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Serialize, Deserialize)]
|
||
|
pub struct StatusResponseSample {
|
||
|
name: String,
|
||
|
id: String
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Serialize, Deserialize)]
|
||
|
pub struct StatusResponsePlayers {
|
||
|
max: i32,
|
||
|
online: i32,
|
||
|
sample: Vec<StatusResponseSample>
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Serialize, Deserialize)]
|
||
|
pub struct StatusResponseDescription {
|
||
|
text: String
|
||
|
}
|
||
|
|
||
|
#[derive(Debug)]
|
||
|
pub struct StatusResponse {
|
||
|
version: StatusResponseVersion,
|
||
|
players: StatusResponsePlayers,
|
||
|
description: StatusResponseDescription,
|
||
|
//#[serde(skip_serializing_if = "Option::is_none")]
|
||
|
favicon: Option<String>
|
||
|
}
|
||
|
|
||
|
impl Serialize for StatusResponse {
|
||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
|
||
|
serializer.serialize_str(&match serde_json::to_string(self) {
|
||
|
Ok(v) => v,
|
||
|
Err(_) => return Err(serde::ser::Error::custom("Could not serialize status response"))
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl<'de> Deserialize<'de> for StatusResponse {
|
||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
|
||
|
match String::deserialize(deserializer) {
|
||
|
Ok(json) => match serde_json::from_str(&json) {
|
||
|
Ok(v) => Ok(v),
|
||
|
Err(_) => Err(D::Error::custom("Could not parse json status response"))
|
||
|
},
|
||
|
Err(err) => Err(err)
|
||
|
}
|
||
|
}
|
||
|
}
|