more things

This commit is contained in:
TriMill 2022-12-05 11:31:45 -05:00
parent e1ccb6ec7d
commit 162d337769
12 changed files with 407 additions and 110 deletions

226
Cargo.lock generated
View file

@ -17,6 +17,15 @@ dependencies = [
"memchr",
]
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "autocfg"
version = "1.1.0"
@ -38,6 +47,12 @@ dependencies = [
"memchr",
]
[[package]]
name = "bumpalo"
version = "3.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
[[package]]
name = "byteorder"
version = "1.4.3"
@ -62,6 +77,37 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f"
dependencies = [
"iana-time-zone",
"js-sys",
"num-integer",
"num-traits",
"time",
"wasm-bindgen",
"winapi",
]
[[package]]
name = "codespan-reporting"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
dependencies = [
"termcolor",
"unicode-width",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
[[package]]
name = "crc32fast"
version = "1.3.2"
@ -71,6 +117,50 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "cxx"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdf07d07d6531bfcdbe9b8b739b104610c6508dcc4d63b410585faf338241daf"
dependencies = [
"cc",
"cxxbridge-flags",
"cxxbridge-macro",
"link-cplusplus",
]
[[package]]
name = "cxx-build"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2eb5b96ecdc99f72657332953d4d9c50135af1bac34277801cc3937906ebd39"
dependencies = [
"cc",
"codespan-reporting",
"once_cell",
"proc-macro2",
"quote",
"scratch",
"syn",
]
[[package]]
name = "cxxbridge-flags"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac040a39517fd1674e0f32177648334b0f4074625b5588a64519804ba0553b12"
[[package]]
name = "cxxbridge-macro"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1362b0ddcfc4eb0a1f57b68bd77dd99f0e826958a96abd0ae9bd092e114ffed6"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "either"
version = "1.8.0"
@ -157,6 +247,30 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "iana-time-zone"
version = "0.1.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
"winapi",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"
dependencies = [
"cxx",
"cxx-build",
]
[[package]]
name = "io-lifetimes"
version = "1.0.3"
@ -194,12 +308,30 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
[[package]]
name = "js-sys"
version = "0.3.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "libc"
version = "0.2.138"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
[[package]]
name = "link-cplusplus"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369"
dependencies = [
"cc",
]
[[package]]
name = "linux-raw-sys"
version = "0.1.3"
@ -262,6 +394,16 @@ dependencies = [
"syn",
]
[[package]]
name = "num-integer"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.15"
@ -320,6 +462,7 @@ dependencies = [
name = "quectocraft"
version = "0.1.0"
dependencies = [
"chrono",
"env_logger",
"hematite-nbt",
"log",
@ -381,6 +524,12 @@ version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
[[package]]
name = "scratch"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898"
[[package]]
name = "serde"
version = "1.0.148"
@ -432,12 +581,29 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "time"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
dependencies = [
"libc",
"wasi",
"winapi",
]
[[package]]
name = "unicode-ident"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
[[package]]
name = "unicode-width"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
[[package]]
name = "uuid"
version = "1.2.2"
@ -450,6 +616,66 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasi"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]]
name = "wasm-bindgen"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
[[package]]
name = "winapi"
version = "0.3.9"

View file

@ -13,3 +13,4 @@ mlua = { version = "0.8", features = ["lua54", "macros", "serialize"] }
uuid = "1.2"
log = "0.4.0"
env_logger = "0.10.0"
chrono = "0.4"

View file

@ -1,6 +1,6 @@
local plugin = {
id = "chat",
name = "Chat",
id = "mcchat",
name = "MCChat",
description = "Provides Minecraft-style chat. Messages sent by one client will be broadcasted to every client.",
authors = { "trimill" },
version = "0.1.0",
@ -10,7 +10,7 @@ local logger = nil
function plugin.init()
logger = server.initLogger(plugin)
logger.info("Loaded chat")
logger.info("MCChat version " .. plugin.version)
end
function plugin.playerJoin(name)

View file

@ -1,5 +1,8 @@
use std::time::{Duration, SystemTime};
use std::borrow::Cow;
use std::time::Duration;
use std::io::Write;
use chrono::Utc;
use env_logger::Env;
use log::info;
use mlua::Lua;
@ -13,16 +16,34 @@ mod network;
pub const VERSION: &'static str = std::env!("CARGO_PKG_VERSION");
fn main() {
env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
env_logger::Builder::from_env(
Env::default().default_filter_or("info")
).format(|buf, record| {
info!("quectocraft version {}", VERSION);
let now = Utc::now().format("%Y-%m-%d %H:%M:%S");
let mut target = Cow::Borrowed(record.target());
if target.starts_with("quectocraft") {
target = Cow::Owned(record.target().replacen("quectocraft", "qc", 1));
}
let color = match record.level() {
log::Level::Error => "\x1b[31m",
log::Level::Warn => "\x1b[33m",
log::Level::Info => "\x1b[32m",
log::Level::Debug => "\x1b[37m",
log::Level::Trace => "\x1b[37m",
};
writeln!(buf, "\x1b[90m[\x1b[37m{} {color}{}\x1b[37m {}\x1b[90m]\x1b[0m {}", now, record.level(), target, record.args())
}).init();
info!("Starting Quectocraft version {}", VERSION);
let lua = Lua::new();
let mut plugins = Plugins::new(&lua).expect("Error initializing lua environment");
std::fs::create_dir_all("plugins").expect("couldn't create the plugins directory");
std::fs::create_dir_all("plugins").expect("Couldn't create the plugins directory");
plugins.load_plugins();
info!("{} plugins loaded", plugins.count());
let mut server = NetworkServer::new("127.0.0.1:25565".to_owned(), plugins);
let sleep_dur = Duration::from_millis(5);

View file

@ -1,6 +1,6 @@
use std::{net::{TcpStream, Shutdown}, thread, io::Write, sync::mpsc::{Receiver, Sender, TryRecvError}, time::Duration};
use log::info;
use log::debug;
use crate::{protocol::{data::{PacketDecoder}, serverbound::*, clientbound::*, NetworkState}};
@ -49,7 +49,7 @@ impl NetworkClient {
}
pub fn close(&mut self) {
info!("closed connection id {}", self.id);
debug!("Closed connection id {}", self.id);
let _ = self.stream.shutdown(Shutdown::Both);
self.closed = true;
}

View file

@ -1,6 +1,7 @@
use std::{net::TcpListener, thread, sync::mpsc::{Receiver, Sender, channel}, collections::HashSet};
use log::{info, warn, trace, debug, error};
use log::{info, warn, debug};
use serde_json::json;
use crate::{protocol::{data::PacketEncoder, serverbound::*, clientbound::*}, plugins::{Plugins, Response}, VERSION};
@ -15,7 +16,7 @@ pub struct NetworkServer<'lua> {
impl <'lua> NetworkServer<'lua> {
pub fn new(addr: String, plugins: Plugins<'lua>) -> Self {
let (send, recv) = channel();
info!("initializing plugins");
info!("Initializing plugins");
plugins.init();
thread::spawn(move || Self::listen(&addr, send));
Self {
@ -26,11 +27,11 @@ impl <'lua> NetworkServer<'lua> {
}
fn listen(addr: &str, send_clients: Sender<NetworkClient>) {
info!("listening on {}", addr);
info!("Listening on {}", addr);
let listener = TcpListener::bind(addr).unwrap();
for (id, stream) in listener.incoming().enumerate() {
let stream = stream.unwrap();
info!("connection from {} (id {})", stream.peer_addr().unwrap(), id);
debug!("Connection from {} (id {})", stream.peer_addr().unwrap(), id);
let stream_2 = stream.try_clone().unwrap();
let (send, recv) = channel();
thread::spawn(|| NetworkClient::listen(stream_2, send));
@ -97,16 +98,6 @@ impl <'lua> NetworkServer<'lua> {
fn handle_plugin_response(&mut self, response: Response) -> std::io::Result<()> {
match response {
Response::Log { level, origin, message } => {
match level {
0 => trace!(target: &origin, "{}", message),
1 => debug!(target: &origin, "{}", message),
2 => info!(target: &origin, "{}", message),
3 => warn!(target: &origin, "{}", message),
4 => error!(target: &origin, "{}", message),
_ => warn!("unknown log level: {}", level)
}
},
Response::Message { player, message } => {
for client in self.clients.iter_mut() {
if let Some(p) = &client.player {
@ -124,6 +115,15 @@ impl <'lua> NetworkServer<'lua> {
}
}
},
Response::Disconnect { player, reason } => {
for client in self.clients.iter_mut() {
if let Some(pl) = &client.player {
if pl.name == player || pl.uuid.to_string() == player {
client.send_packet(ClientBoundPacket::Disconnect(reason.clone()))?;
}
}
}
}
}
Ok(())
}
@ -131,7 +131,7 @@ impl <'lua> NetworkServer<'lua> {
fn handle_packet(&mut self, client: &mut NetworkClient, packet: ServerBoundPacket) -> std::io::Result<()> {
match packet {
ServerBoundPacket::Ignored(_) => (),
ServerBoundPacket::Unknown(id) => warn!("unknown: {}", id),
ServerBoundPacket::Unknown(id) => warn!("Unknown packet: {}", id),
ServerBoundPacket::Handshake(_) => (),
ServerBoundPacket::StatusRequest()
=> client.send_packet(ClientBoundPacket::StatusResponse(
@ -142,17 +142,22 @@ impl <'lua> NetworkServer<'lua> {
client.close();
}
ServerBoundPacket::LoginStart(login_start) => {
client.player = Some(Player {
name: login_start.name.clone(),
uuid: login_start.uuid.unwrap(),
});
client.play = true;
client.send_packet(ClientBoundPacket::LoginSuccess(LoginSuccess {
name: login_start.name,
uuid: login_start.uuid.unwrap(),
}))?;
self.plugins.player_join(client.player.as_ref().unwrap());
self.post_login(client)?;
if self.clients.iter().filter_map(|x| x.player.as_ref()).any(|x| x.uuid == login_start.uuid) {
client.send_packet(ClientBoundPacket::LoginDisconnect(json!({"translate": "multiplayer.disconnect.duplicate_login"})))?;
client.close();
} else {
client.player = Some(Player {
name: login_start.name.clone(),
uuid: login_start.uuid,
});
client.play = true;
client.send_packet(ClientBoundPacket::LoginSuccess(LoginSuccess {
name: login_start.name,
uuid: login_start.uuid,
}))?;
self.plugins.player_join(client.player.as_ref().unwrap());
self.post_login(client)?;
}
}
ServerBoundPacket::ChatMessage(msg) => {
self.plugins.chat_message(client.player.as_ref().unwrap(), &msg.message);
@ -187,11 +192,10 @@ impl <'lua> NetworkServer<'lua> {
channel: "minecraft:brand".to_owned(),
data: {
let mut data = Vec::new();
data.write_string(32767, &format!("quectocraft {}", VERSION));
data.write_string(32767, &format!("Quectocraft {}", VERSION));
data
}
}))?;
client.send_packet(ClientBoundPacket::PlayerAbilities(0x0d, 0.05, 0.1))?;
let mut chunk_data: Vec<u8> = Vec::new();
for _ in 0..(384 / 16) {
// number of non-air blocks
@ -224,6 +228,8 @@ impl <'lua> NetworkServer<'lua> {
teleport_id: 0,
dismount: false
}))?;
// TODO why doesn't this work with quilt?
// client.send_packet(ClientBoundPacket::PlayerAbilities(0x0f, 0.05, 0.1))?;
Ok(())
}

70
src/plugins/init_lua.rs Normal file
View file

@ -0,0 +1,70 @@
use log::{info, warn, trace, error, debug};
use mlua::{Lua, chunk};
pub fn init<'lua>(lua: &'lua Lua) -> Result<(), mlua::Error> {
macro_rules! log_any {
($level:tt) => {
lua.create_function(|_, args: (String, String)| {
$level!(target: &args.0, "{}", args.1);
Ok(())
})
}
}
let log_trace = log_any!(trace)?;
let log_debug = log_any!(debug)?;
let log_info = log_any!(info)?;
let log_warn = log_any!(warn)?;
let log_error = log_any!(error)?;
lua.load(chunk!{
server = { players = {} }
_qc = { responses = {} }
function server.initLogger(plugin)
local id = "pl::" .. assert(plugin["id"])
return {
trace = function(msg) $log_trace(id, msg) end,
debug = function(msg) $log_debug(id, msg) end,
info = function(msg) $log_info(id, msg) end,
warn = function(msg) $log_warn(id, msg) end,
error = function(msg) $log_error(id, msg) end,
}
end
local function to_chat(message, default)
if message == nil then
if default ~= nil then
return default
else
error("message must be a string or table")
end
elseif type(message) == "table" then
return message
elseif type(message) == "string" then
return { text = message }
elseif default == nil then
error("message must be a string or table")
else
error("message must be a string, table, or nil for the default message")
end
end
function server.sendMessage(player, message)
if type(player) ~= "string" then
error("player must be a string")
end
local message = assert(to_chat(message))
table.insert(_qc.responses, {type = "message", player = player, message = message})
end
function server.broadcast(message)
local message = assert(to_chat(message))
table.insert(_qc.responses, { type = "broadcast", message = message })
end
function server.disconnect(player, reason)
local reason = assert(to_chat(reason, { translate = "multiplayer.disconnect.generic" }))
table.insert(_qc.responses, { type = "disconnect", player = player, reason = reason })
end
}).exec()?;
Ok(())
}

View file

@ -1,7 +1,7 @@
use std::{path::Path, fs::{self, read_dir}};
use std::fs::read_dir;
use log::warn;
use mlua::{Lua, Table, chunk, LuaSerdeExt};
use log::{warn, info};
use mlua::{Lua, Table, LuaSerdeExt};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
@ -9,8 +9,21 @@ use crate::network::Player;
use self::plugin::Plugin;
mod init_lua;
mod plugin;
#[derive(Serialize, Deserialize)]
#[serde(tag="type")]
pub enum Response {
#[serde(rename = "message")]
Message { player: String, message: serde_json::Value },
#[serde(rename = "broadcast")]
Broadcast { message: serde_json::Value },
#[serde(rename = "disconnect")]
Disconnect { player: String, reason: serde_json::Value },
}
pub struct Plugins<'lua> {
lua: &'lua Lua,
plugins: Vec<Plugin<'lua>>
@ -18,47 +31,7 @@ pub struct Plugins<'lua> {
impl <'lua> Plugins<'lua> {
pub fn new(lua: &'lua Lua) -> Result<Self, mlua::Error> {
lua.load(chunk!{
server = { players = {} }
_qc = { responses = {} }
function server.sendMessage(player, message)
if type(player) ~= "string" then
error("player must be a string")
end
if type(message) == "table" then
table.insert(_qc.responses, {type = "message", player = player, message = message})
elseif type(message) == "string" then
table.insert(_qc.responses, {type = "message", player = player, message = { text = message}})
else
error("message must be a string or table")
end
end
function server.broadcast(message)
if type(message) == "table" then
table.insert(_qc.responses, { type = "broadcast", message = message })
elseif type(message) == "string" then
table.insert(_qc.responses, { type = "broadcast", message = { text = message } })
else
error("message must be a string or table")
end
end
function server.initLogger(plugin)
local function log_for(level)
return function(message)
table.insert(_qc.responses, {
type = "log", origin = plugin.id, message = message, level = level
})
end
end
return {
trace = log_for(0),
debug = log_for(1),
info = log_for(2),
warn = log_for(3),
error = log_for(4),
}
end
}).exec()?;
init_lua::init(lua)?;
Ok(Self {
lua,
plugins: Vec::new(),
@ -78,18 +51,15 @@ impl <'lua> Plugins<'lua> {
};
let pl = Plugin::load(&path, &self.lua).expect("error loading plugin");
self.plugins.push(pl);
info!("Loaded plugin '{}'", file.file_name().to_string_lossy());
}
}
pub fn count(&self) -> usize {
self.plugins.len()
}
pub fn get_responses(&self) -> Vec<Response> {
match self.get_responses_inner() {
Ok(x) => x,
Err(e) => {
warn!("error getting responses: {}", e);
warn!("Error getting responses: {}", e);
Vec::new()
}
}
@ -164,14 +134,3 @@ impl <'lua> Plugins<'lua> {
}
}
}
#[derive(Serialize, Deserialize)]
#[serde(tag="type")]
pub enum Response {
#[serde(rename = "log")]
Log { level: i32, origin: String, message: String },
#[serde(rename = "message")]
Message { player: String, message: serde_json::Value },
#[serde(rename = "broadcast")]
Broadcast { message: serde_json::Value },
}

View file

@ -1,4 +1,4 @@
use std::{path::{PathBuf, Path}, str::FromStr};
use std::path::Path;
use mlua::{Function, Table, Lua};

View file

@ -135,6 +135,7 @@ impl ChunkData {
}
}
#[allow(unused)]
#[derive(Debug)]
pub enum ClientBoundPacket {
// status
@ -142,6 +143,7 @@ pub enum ClientBoundPacket {
PingResponse(i64),
// login
LoginSuccess(LoginSuccess),
LoginDisconnect(serde_json::Value),
// play
LoginPlay(LoginPlay),
PluginMessage(PluginMessage),
@ -149,6 +151,7 @@ pub enum ClientBoundPacket {
ChunkData(ChunkData),
KeepAlive(i64),
PlayerAbilities(i8, f32, f32),
Disconnect(serde_json::Value),
SystemChatMessage(serde_json::Value, bool),
}
@ -156,6 +159,7 @@ impl ClientBoundPacket {
pub fn encode(self) -> Vec<u8> {
let mut packet = Vec::new();
match self {
// Status
Self::StatusResponse(status) => {
packet.write_string(32767, &status);
finalize_packet(packet, 0)
@ -164,10 +168,24 @@ impl ClientBoundPacket {
packet.write_long(n);
finalize_packet(packet, 1)
},
// Login
Self::LoginDisconnect(message) => {
packet.write_string(262144, &message.to_string());
finalize_packet(packet, 0)
}
Self::LoginSuccess(login_success) => {
login_success.encode(&mut packet);
finalize_packet(packet, 2)
}
// Play
Self::Disconnect(message) => {
packet.write_string(262144, &message.to_string());
finalize_packet(packet, 25)
}
Self::LoginPlay(login_play) => {
login_play.encode(&mut packet);
finalize_packet(packet, 37)
}
Self::PluginMessage(plugin_message) => {
plugin_message.encode(&mut packet);
finalize_packet(packet, 22)
@ -176,10 +194,6 @@ impl ClientBoundPacket {
sync_player_position.encode(&mut packet);
finalize_packet(packet, 57)
}
Self::LoginPlay(login_play) => {
login_play.encode(&mut packet);
finalize_packet(packet, 37)
}
Self::ChunkData(chunk_data) => {
chunk_data.encode(&mut packet);
finalize_packet(packet, 33)

View file

@ -136,6 +136,7 @@ pub struct PacketDecoder {
packet_id: i32,
}
#[allow(unused)]
impl PacketDecoder {
pub fn decode(read: &mut impl Read) -> Result<PacketDecoder, std::io::Error> {
let size = read_varint(read)? as usize;

View file

@ -31,7 +31,7 @@ pub struct SigData {
pub struct LoginStart {
pub name: String,
pub sig_data: Option<SigData>,
pub uuid: Option<Uuid>,
pub uuid: Uuid,
}
impl LoginStart {
@ -49,11 +49,10 @@ impl LoginStart {
None
};
let has_uuid = decoder.read_bool();
let uuid = if has_uuid {
Some(decoder.read_uuid())
} else {
None
};
if !has_uuid {
panic!("Client didn't supply UUID");
}
let uuid = decoder.read_uuid();
Self { name, sig_data, uuid }
}
}