quectocraft2/src/protocol/v1_17_1.rs

146 lines
5.5 KiB
Rust
Raw Normal View History

2023-07-24 00:50:20 -04:00
use std::io::{Write, Read};
2023-08-01 00:56:38 -04:00
use log::trace;
2023-07-24 00:50:20 -04:00
2023-08-07 22:24:28 -04:00
use crate::{ser::{Serializable, Deserializable}, varint::VarInt, command::Commands};
2023-07-24 00:50:20 -04:00
use super::{ServerPacket, ClientPacket, Protocol, ProtocolState, common::COMMON};
2023-08-02 00:44:57 -04:00
pub const NAME: &str = "1.17.1";
2023-08-01 00:56:38 -04:00
pub const VERSION: i32 = 756;
2023-07-24 00:50:20 -04:00
pub const PROTOCOL: Protocol = Protocol {
2023-08-02 00:44:57 -04:00
name: NAME,
2023-07-24 00:50:20 -04:00
version: VERSION,
encode,
decode,
};
fn encode(mut w: Box<&mut dyn Write>, state: ProtocolState, ev: ServerPacket) -> anyhow::Result<()> {
2023-08-02 00:44:57 -04:00
trace!("{NAME} encoding {ev:?}");
2023-07-24 00:50:20 -04:00
match ev {
ServerPacket::LoginSuccess { name, uuid } => {
VarInt(0x02).serialize(&mut w)?;
uuid.serialize(&mut w)?;
name.serialize(&mut w)?;
},
2023-08-01 00:56:38 -04:00
ServerPacket::ChatMessage(msg, _) => {
VarInt(0x0F).serialize(&mut w)?;
msg.serialize(&mut w)?;
0u8.serialize(&mut w)?; // chat
0u128.serialize(&mut w)?; // null uuid
2023-07-24 00:50:20 -04:00
},
2023-08-01 00:56:38 -04:00
ServerPacket::SystemMessage(msg, overlay) => {
VarInt(0x0F).serialize(&mut w)?;
2023-07-24 00:50:20 -04:00
msg.serialize(&mut w)?;
2023-08-01 00:56:38 -04:00
if overlay { 2u8 } else { 1u8 } // system or overlay
.serialize(&mut w)?;
0u128.serialize(&mut w)?; // null uuid
2023-07-24 00:50:20 -04:00
},
2023-08-07 22:24:28 -04:00
ServerPacket::CommandData(commands) => {
VarInt(0x12).serialize(&mut w)?;
VarInt(commands.len()).serialize(&mut w)?;
commands.serialize(&mut w, false)?;
VarInt(Commands::root()).serialize(&mut w)?;
},
2023-07-26 00:53:51 -04:00
ServerPacket::PluginMessage { channel, data } => {
2023-08-01 00:56:38 -04:00
VarInt(0x18).serialize(&mut w)?;
2023-07-24 00:50:20 -04:00
channel.serialize(&mut w)?;
2023-07-26 00:53:51 -04:00
w.write_all(&data)?;
2023-07-24 00:50:20 -04:00
},
2023-08-01 00:56:38 -04:00
ServerPacket::PlayDisconnect(msg) => {
VarInt(0x1A).serialize(&mut w)?;
msg.serialize(&mut w)?;
},
ServerPacket::KeepAlive(data) => {
VarInt(0x21).serialize(&mut w)?;
data.serialize(&mut w)?;
},
2023-07-24 00:50:20 -04:00
ServerPacket::ChunkData { x, z } => {
2023-08-01 00:56:38 -04:00
VarInt(0x22).serialize(&mut w)?;
2023-07-24 00:50:20 -04:00
// chunk x
x.serialize(&mut w)?;
// chunk z
z.serialize(&mut w)?;
2023-08-01 00:56:38 -04:00
// bit mask
2023-07-24 00:50:20 -04:00
VarInt(0).serialize(&mut w)?;
2023-08-01 00:56:38 -04:00
// heightmap
include_bytes!("../resources/heightmap.nbt").serialize(&mut w)?;
// biomes
VarInt(1024).serialize(&mut w)?;
[VarInt(127); 1024].serialize(&mut w)?;
// chunk data size and chunk data
2023-07-24 00:50:20 -04:00
VarInt(0).serialize(&mut w)?;
2023-08-01 00:56:38 -04:00
// block entities
2023-07-24 00:50:20 -04:00
VarInt(0).serialize(&mut w)?;
},
2023-08-01 00:56:38 -04:00
ServerPacket::JoinGame { eid, gamemode, hardcode } => {
VarInt(0x26).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!("../resources/dimcodec_1.17.1.nbt").serialize(&mut w)?; // dimension codec
include_bytes!("../resources/dimension_1.17.1.nbt").serialize(&mut w)?; // dimension data
"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
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
},
ServerPacket::PositionAndLook { pos, look, flags } => {
VarInt(0x38).serialize(&mut w)?;
pos.serialize(&mut w)?;
look.serialize(&mut w)?;
flags.serialize(&mut w)?;
VarInt(0).serialize(&mut w)?; // teleport id
false.serialize(&mut w)?; // dismount
}
2023-07-24 00:50:20 -04:00
ServerPacket::SetDefaultSpawn { pos, angle } => {
2023-08-01 00:56:38 -04:00
VarInt(0x4B).serialize(&mut w)?;
2023-07-24 00:50:20 -04:00
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>> {
2023-08-02 00:44:57 -04:00
trace!("{NAME} decoding {state:?} {id}");
2023-07-24 00:50:20 -04:00
type Ps = ProtocolState;
match (state, id) {
(Ps::Login, 0x00) => {
let name = String::deserialize(&mut r)?;
2023-08-01 00:56:38 -04:00
Ok(Some(ClientPacket::LoginStart { name, uuid: None }))
2023-07-24 00:50:20 -04:00
}
(Ps::Login, 0x01 | 0x02) => Ok(None), // unsupported
2023-08-01 00:56:38 -04:00
(Ps::Play, 0x03) => {
let mut msg = String::deserialize(&mut r)?;
if msg.starts_with('/') {
msg.remove(0);
Ok(Some(ClientPacket::Command(msg)))
} else {
Ok(Some(ClientPacket::ChatMessage(msg)))
}
},
(Ps::Play, 0x0A) => {
2023-07-24 00:50:20 -04:00
let channel = String::deserialize(&mut r)?;
let mut data = Vec::new();
r.read_to_end(&mut data)?;
Ok(Some(ClientPacket::PluginMessage { channel, data }))
}
2023-08-01 00:56:38 -04:00
(Ps::Play, 0x0F) => {
2023-07-24 00:50:20 -04:00
let data = i64::deserialize(&mut r)?;
Ok(Some(ClientPacket::KeepAlive(data)))
}
2023-08-01 00:56:38 -04:00
(Ps::Play, 0x11 | 0x12 | 0x13) => Ok(None), // position & rotation
2023-07-24 00:50:20 -04:00
_ => (COMMON.decode)(r, state, len, id)
}
}