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)
|
|
|
|
}
|
|
|
|
}
|