quectocraft2/src/protocol/v1_20_1/mod.rs

137 lines
5.2 KiB
Rust
Raw Normal View History

2023-07-24 00:50:20 -04:00
use std::io::{Write, Read};
use uuid::Uuid;
use crate::{ser::{Serializable, Deserializable}, varint::VarInt};
use super::{ServerPacket, ClientPacket, Protocol, ProtocolState, common::COMMON};
pub const VERSION: i32 = 763;
pub const PROTOCOL: Protocol = Protocol {
name: "1.20.1",
version: VERSION,
encode,
decode,
};
fn encode(mut w: Box<&mut dyn Write>, state: ProtocolState, ev: ServerPacket) -> anyhow::Result<()> {
match ev {
ServerPacket::LoginSuccess { name, uuid } => {
VarInt(0x02).serialize(&mut w)?;
uuid.serialize(&mut w)?;
name.serialize(&mut w)?;
// number of properties (0)
VarInt(0x00).serialize(&mut w)?;
},
ServerPacket::JoinGame { eid, gamemode, hardcode } => {
VarInt(0x28).serialize(&mut w)?;
eid.serialize(&mut w)?;
hardcode.serialize(&mut w)?;
gamemode.serialize(&mut w)?;
(-1i8).serialize(&mut w)?; // prev gamemode undefined
VarInt(1).serialize(&mut w)?; // dimension count
"qc:world".serialize(&mut w)?; // register one dimension
include_bytes!("registry.nbt").serialize(&mut w)?; // registry codec
"minecraft:the_end".serialize(&mut w)?; // dimension type
"qc:world".serialize(&mut w)?; // dimension name
0i64.serialize(&mut w)?; // seed
VarInt(65535).serialize(&mut w)?; // max players
VarInt(8).serialize(&mut w)?; // view dist
VarInt(0).serialize(&mut w)?; // sim dist
false.serialize(&mut w)?; // reduce debug info
false.serialize(&mut w)?; // respawn screen
false.serialize(&mut w)?; // is debug
false.serialize(&mut w)?; // is flat
false.serialize(&mut w)?; // has death location
VarInt(1).serialize(&mut w)?; // portal cooldown
},
ServerPacket::KeepAlive(data) => {
VarInt(0x23).serialize(&mut w)?;
data.serialize(&mut w)?;
},
ServerPacket::PlayDisconnect(msg) => {
VarInt(0x1A).serialize(&mut w)?;
msg.serialize(&mut w)?;
},
2023-07-26 00:53:51 -04:00
ServerPacket::PluginMessage { channel, data } => {
2023-07-24 00:50:20 -04:00
VarInt(0x17).serialize(&mut w)?;
channel.serialize(&mut w)?;
2023-07-26 00:53:51 -04:00
w.write_all(&data)?;
2023-07-24 00:50:20 -04:00
},
ServerPacket::ChunkData { x, z } => {
VarInt(0x24).serialize(&mut w)?;
// chunk x
x.serialize(&mut w)?;
// chunk z
z.serialize(&mut w)?;
// heightmap
let hmdata = [0i64; 37];
let mut heightmap = nbt::Blob::new();
heightmap.insert("MOTION_BLOCKING", hmdata.as_ref()).unwrap();
heightmap.serialize(&mut w)?;
// chunk data
let mut chunk_data: Vec<u8> = Vec::new();
for _ in 0..(384 / 16) {
// number of non-air blocks
(0i16).serialize(&mut chunk_data)?;
// block states
(0u8).serialize(&mut chunk_data)?;
VarInt(0).serialize(&mut chunk_data)?;
VarInt(0).serialize(&mut chunk_data)?;
// biomes
(0u8).serialize(&mut chunk_data)?;
VarInt(0).serialize(&mut chunk_data)?;
VarInt(0).serialize(&mut chunk_data)?;
}
VarInt(chunk_data.len() as i32).serialize(&mut w)?;
w.write_all(&chunk_data)?;
// block entities
VarInt(0).serialize(&mut w)?;
// light masks
VarInt(0).serialize(&mut w)?;
VarInt(0).serialize(&mut w)?;
VarInt(0).serialize(&mut w)?;
VarInt(0).serialize(&mut w)?;
// sky light array len
VarInt(0).serialize(&mut w)?;
// block light array len
VarInt(0).serialize(&mut w)?;
},
ServerPacket::SetDefaultSpawn { pos, angle } => {
VarInt(0x50).serialize(&mut w)?;
pos.serialize(&mut w)?;
angle.serialize(&mut w)?;
},
_ => { (COMMON.encode)(w, state, ev)?; }
}
Ok(())
}
fn decode(mut r: Box<&mut dyn Read>, state: ProtocolState, len: i32, id: i32) -> anyhow::Result<Option<ClientPacket>> {
type Ps = ProtocolState;
match (state, id) {
(Ps::Login, 0x00) => {
let name = String::deserialize(&mut r)?;
let has_uuid = bool::deserialize(&mut r)?;
let uuid = if has_uuid {
Some(Uuid::deserialize(&mut r)?)
} else { None };
Ok(Some(ClientPacket::LoginStart { name, uuid }))
}
(Ps::Login, 0x01 | 0x02) => Ok(None), // unsupported
(Ps::Play, 0x0D) => {
let channel = String::deserialize(&mut r)?;
let mut data = Vec::new();
r.read_to_end(&mut data)?;
Ok(Some(ClientPacket::PluginMessage { channel, data }))
}
(Ps::Play, 0x12) => {
let data = i64::deserialize(&mut r)?;
Ok(Some(ClientPacket::KeepAlive(data)))
}
(Ps::Play, 0x14 | 0x15 | 0x16) => Ok(None), // position & rotation
_ => (COMMON.decode)(r, state, len, id)
}
}