From af6c1ef3b826ee265d05af996db86ab123376561 Mon Sep 17 00:00:00 2001 From: MeexReay Date: Sat, 3 May 2025 16:42:55 +0300 Subject: [PATCH] packet id constants remake --- .gitignore | 5 +- parse_ids.py | 99 +++++++ shell.nix | 15 + src/server/mod.rs | 2 +- src/server/player/protocol.rs | 30 +- .../{protocol.rs => protocol/handler.rs} | 68 +---- src/server/protocol/id.rs | 275 ++++++++++++++++++ src/server/protocol/mod.rs | 14 + src/server/protocol/play.rs | 16 + 9 files changed, 454 insertions(+), 70 deletions(-) create mode 100644 parse_ids.py create mode 100644 shell.nix rename src/server/{protocol.rs => protocol/handler.rs} (71%) create mode 100644 src/server/protocol/id.rs create mode 100644 src/server/protocol/mod.rs create mode 100644 src/server/protocol/play.rs diff --git a/.gitignore b/.gitignore index c46d3d6..153bca6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ -/target -server.toml \ No newline at end of file +target/ +server.toml +Packets.html \ No newline at end of file diff --git a/parse_ids.py b/parse_ids.py new file mode 100644 index 0000000..b3770de --- /dev/null +++ b/parse_ids.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python + +# Использование: +# +# ./parse_ids.py < Packets.html > src/server/protocol/id.rs + +import sys +from bs4 import BeautifulSoup +import re + +BOUNDS = ["clientbound", "serverbound"] +MODES = { + "#Handshaking": "handshake", + "#Status": "status", + "#Login": "login", + "#Play": "play", + "#Configuration": "configuration" +} + +def sanitize_name(name, bound, mode): + name = (" " + name.lower() + " ").replace(" " + bound.lower() + " ", "").replace(" " + mode.lower() + " ", "") \ + if name.lower() != bound.lower() and name.lower() != mode.lower() else name + name = re.sub(r'\(.*?\)', '', name) + name = name.strip() + name = name.upper() + name = name.replace(' ', '_') + return name + +def parse_packet_id_table(span): + table = span.parent.find_next_sibling("table") + if not table: + return None + rows = table.find_all("tr") + if len(rows) < 2: + return None + code_tag = rows[1].find("td").find("code") + if not code_tag: + return None + return code_tag.text.strip() + +def main(): + soup = BeautifulSoup(sys.stdin.read(), "html.parser") + + print("/*\n") + print(" Generated with parse_ids.py \n") + print(" */\n") + + toc = soup.select_one("#toc") + + for bound_type in BOUNDS: + print(f"pub mod {bound_type} {{") + + for li in toc.find("ul").find_all("li", recursive=False): + a = li.find("a", href=True) + if not a or a["href"] not in MODES: + continue + + mode = MODES[a["href"]] + ul = li.find("ul", recursive=False) + if not ul: + continue + lis = ul.find_all("li", recursive=False) + + mode_size = 0 + + try: + bound_list = lis[BOUNDS.index(bound_type)].find_all("li") + except KeyError: + continue + + for item in bound_list: + packet_a = item.find("a", href=True) + if not packet_a or not packet_a["href"].startswith("#"): + continue + + href = packet_a["href"].lstrip("#") + span = soup.find("span", id=href) + if not span: + continue + + packet_id = parse_packet_id_table(span) + if not packet_id: + continue + + name = sanitize_name(" ".join(packet_a.text.split(" ")[1:]), bound_type, mode) + if len(name) > 0: + mode_size += 1 + + if mode_size == 1: + print(f" pub mod {mode} {{") + print(f" pub const {name}: u8 = {packet_id};") + + if mode_size > 0: + print(" }\n") + + print("}\n") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..d4ddaeb --- /dev/null +++ b/shell.nix @@ -0,0 +1,15 @@ + +with import { }; + +mkShell { + nativeBuildInputs = [ + direnv + rustc + cargo + python3 + python3Packages.beautifulsoup4 + python3Packages.requests + ]; + + NIX_ENFORCE_PURITY = true; +} \ No newline at end of file diff --git a/src/server/mod.rs b/src/server/mod.rs index b8d427d..9aec631 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -4,7 +4,7 @@ use context::ServerContext; use ignore_result::Ignore; use log::{error, info}; use player::context::ClientContext; -use protocol::handle_connection; +use protocol::handler::handle_connection; use rust_mc_proto::{MinecraftConnection, ProtocolError}; pub mod config; diff --git a/src/server/player/protocol.rs b/src/server/player/protocol.rs index 1fdfcf1..b73d826 100644 --- a/src/server/player/protocol.rs +++ b/src/server/player/protocol.rs @@ -2,7 +2,7 @@ use std::{io::Read, sync::Arc, time::{Duration, SystemTime}}; use rust_mc_proto::{DataReader, DataWriter, Packet}; -use crate::server::{data::text_component::TextComponent, data::ReadWriteNBT, protocol::ConnectionState, ServerError}; +use crate::server::{data::{text_component::TextComponent, ReadWriteNBT}, protocol::{id::{clientbound, serverbound}, *}, ServerError}; use super::context::ClientContext; @@ -31,8 +31,8 @@ impl ProtocolHelper { pub fn leave_configuration(&self) -> Result<(), ServerError> { match self.state { ConnectionState::Configuration => { - self.client.write_packet(&Packet::empty(0x03))?; - self.client.read_packet()?; + self.client.write_packet(&Packet::empty(clientbound::configuration::FINISH))?; + self.client.read_packet(serverbound::configuration::ACKNOWLEDGE_FINISH)?; self.client.set_state(ConnectionState::Play)?; Ok(()) }, @@ -44,8 +44,8 @@ impl ProtocolHelper { pub fn enter_configuration(&self) -> Result<(), ServerError> { match self.state { ConnectionState::Play => { - self.client.write_packet(&Packet::empty(0x6F))?; - self.client.read_packet()?; + self.client.write_packet(&Packet::empty(clientbound::play::START_CONFIGURATION))?; + self.client.read_packet(serverbound::play::ACKNOWLEDGE_CONFIGURATION)?; self.client.set_state(ConnectionState::Configuration)?; Ok(()) }, @@ -58,14 +58,14 @@ impl ProtocolHelper { match self.state { ConnectionState::Play => { let time = SystemTime::now(); - self.client.write_packet(&Packet::empty(0x36))?; - self.client.read_packet()?; + self.client.write_packet(&Packet::empty(clientbound::play::PING))?; + self.client.read_packet(serverbound::play::PONG)?; Ok(SystemTime::now().duration_since(time).unwrap()) }, ConnectionState::Configuration => { let time = SystemTime::now(); - self.client.write_packet(&Packet::empty(0x05))?; - self.client.read_packet()?; + self.client.write_packet(&Packet::empty(clientbound::configuration::PING))?; + self.client.read_packet(serverbound::configuration::PONG)?; Ok(SystemTime::now().duration_since(time).unwrap()) }, _ => Err(ServerError::UnexpectedState) @@ -101,11 +101,11 @@ impl ProtocolHelper { pub fn request_cookie(&self, id: &str) -> Result>, ServerError> { match self.state { ConnectionState::Configuration => { - let mut packet = Packet::empty(0x00); + let mut packet = Packet::empty(clientbound::configuration::COOKIE_REQUEST); packet.write_string(id)?; self.client.write_packet(&packet)?; - let mut packet = self.client.read_packet()?; + let mut packet = self.client.read_packet(serverbound::configuration::COOKIE_RESPONSE)?; packet.read_string()?; let data = if packet.read_boolean()? { let n = packet.read_usize_varint()?; @@ -124,13 +124,13 @@ impl ProtocolHelper { pub fn send_login_plugin_request(&self, id: i32, channel: &str, data: &[u8]) -> Result<(i32, Option>), ServerError> { match self.state { ConnectionState::Login => { - let mut packet = Packet::empty(0x04); + let mut packet = Packet::empty(clientbound::login::PLUGIN_REQUEST); packet.write_varint(id)?; packet.write_string(channel)?; packet.write_bytes(data)?; self.client.write_packet(&packet)?; - let mut packet = self.client.read_packet()?; + let mut packet = self.client.read_packet(serverbound::login::PLUGIN_RESPONSE)?; let identifier = packet.read_varint()?; let data = if packet.read_boolean()? { let mut data = Vec::new(); @@ -148,8 +148,8 @@ impl ProtocolHelper { pub fn send_plugin_message(&self, channel: &str, data: &[u8]) -> Result<(), ServerError> { let mut packet = match self.state { - ConnectionState::Configuration => Packet::empty(0x01), - ConnectionState::Play => Packet::empty(0x18), + ConnectionState::Configuration => Packet::empty(clientbound::configuration::PLUGIN_MESSAGE), + ConnectionState::Play => Packet::empty(clientbound::play::PLUGIN_MESSAGE), _ => return Err(ServerError::UnexpectedState) }; packet.write_string(channel)?; diff --git a/src/server/protocol.rs b/src/server/protocol/handler.rs similarity index 71% rename from src/server/protocol.rs rename to src/server/protocol/handler.rs index a5a75ce..336ad22 100644 --- a/src/server/protocol.rs +++ b/src/server/protocol/handler.rs @@ -1,35 +1,12 @@ use std::{io::Read, sync::Arc}; -use super::{player::context::{ClientContext, ClientInfo, Handshake, PlayerInfo}, ServerError}; +use crate::server::{player::context::{ClientContext, ClientInfo, Handshake, PlayerInfo}, ServerError}; use rust_mc_proto::{DataReader, DataWriter, Packet}; -use crate::{server::data::text_component::TextComponent, trigger_event}; +use crate::trigger_event; -// Тут будут все айди пакетов +use super::{id::*, play::handle_play_state, ConnectionState}; -pub const HANDSHAKE_ID: u8 = 0x00; -pub const STATUS_REQUEST_ID: u8 = 0x00; -pub const STATUS_RESPONSE_ID: u8 = 0x00; -pub const STATUS_PING_REQUEST_ID: u8 = 0x01; -pub const STATUS_PING_RESPONSE_ID: u8 = 0x01; -pub const LOGIN_START_ID: u8 = 0x00; -pub const LOGIN_SET_COMPRESSION_ID: u8 = 0x03; -pub const LOGIN_SUCCESS_ID: u8 = 0x02; -pub const LOGIN_ACKNOWLEDGED_ID: u8 = 0x03; -pub const CONFIGURATION_SERVERBOUND_PLUGIN_MESSAGE_ID: u8 = 0x02; -pub const CONFIGURATION_CLIENT_INFORMATION_ID: u8 = 0x00; -pub const CONFIGURATION_FINISH_ID: u8 = 0x03; -pub const CONFIGURATION_ACKNOWLEDGE_FINISH_ID: u8 = 0x03; - - -#[derive(Debug, Clone)] -pub enum ConnectionState { - Handshake, - Status, - Login, - Configuration, - Play -} pub fn handle_connection( client: Arc, // Контекст клиента @@ -38,7 +15,7 @@ pub fn handle_connection( // Получение пакетов производится через client.conn(), // ВАЖНО: не помещать сам client.conn() в переменные, // он должен сразу убиваться иначе соединение гдето задедлочится - let mut packet = client.read_packet(HANDSHAKE_ID)?; + let mut packet = client.read_packet(serverbound::handshake::HANDSHAKE)?; let protocol_version = packet.read_varint()?; // Получаем версия протокола, может быть отрицательным если наш клиент дэбил let server_address = packet.read_string()?; // Получаем домен/адрес сервера к которому пытается подключиться клиент, например "play.example.com", а не айпи @@ -56,8 +33,8 @@ pub fn handle_connection( let mut packet = client.read_any_packet()?; match packet.id() { - STATUS_REQUEST_ID => { // Запрос статуса - let mut packet = Packet::empty(STATUS_RESPONSE_ID); + serverbound::status::REQUEST => { // Запрос статуса + let mut packet = Packet::empty(clientbound::status::RESPONSE); // Дефолтный статус let mut status = "{ @@ -76,11 +53,11 @@ pub fn handle_connection( client.write_packet(&packet)?; }, - STATUS_PING_REQUEST_ID => { // Пинг + serverbound::status::PING_REQUEST => { // Пинг // Раньше мы просто отправляли ему его-же пакет, но сейчас, // С приходом к власти констант айди-пакетов, нам приходится делать такое непотребство let timestamp = packet.read_long()?; - let mut packet = Packet::empty(STATUS_PING_RESPONSE_ID); + let mut packet = Packet::empty(clientbound::status::PONG_RESPONSE); packet.write_long(timestamp)?; client.write_packet(&packet)?; }, @@ -94,7 +71,7 @@ pub fn handle_connection( client.set_state(ConnectionState::Login)?; // Мы находимся в режиме Login // Читаем пакет Login Start - let mut packet = client.read_packet(LOGIN_START_ID)?; + let mut packet = client.read_packet(serverbound::login::START)?; let name = packet.read_string()?; let uuid = packet.read_uuid()?; @@ -107,25 +84,25 @@ pub fn handle_connection( // Отправляем пакет Set Compression если сжатие указано if let Some(threshold) = client.server.config.server.compression_threshold { - client.write_packet(&Packet::build(LOGIN_SET_COMPRESSION_ID, |p| p.write_usize_varint(threshold))?)?; + client.write_packet(&Packet::build(clientbound::login::SET_COMPRESSION, |p| p.write_usize_varint(threshold))?)?; client.set_compression(Some(threshold)); // Устанавливаем сжатие на соединении } // Отправка пакета Login Success - client.write_packet(&Packet::build(LOGIN_SUCCESS_ID, |p| { + client.write_packet(&Packet::build(clientbound::login::SUCCESS, |p| { p.write_uuid(&uuid)?; p.write_string(&name)?; p.write_varint(0) })?)?; - client.read_packet(LOGIN_ACKNOWLEDGED_ID)?; // Пакет Login Acknowledged + client.read_packet(serverbound::login::ACKNOWLEDGED)?; // Пакет Login Acknowledged client.set_state(ConnectionState::Configuration)?; // Мы перешли в режим Configuration // Получение бренда клиента из Serverbound Plugin Message // Identifier канала откуда берется бренд: minecraft:brand let brand = loop { - let mut packet = client.read_packet(CONFIGURATION_SERVERBOUND_PLUGIN_MESSAGE_ID)?; // Пакет Serverbound Plugin Message + let mut packet = client.read_packet(serverbound::configuration::PLUGIN_MESSAGE)?; // Пакет Serverbound Plugin Message let identifier = packet.read_string()?; @@ -139,7 +116,7 @@ pub fn handle_connection( } }; - let mut packet = client.read_packet(CONFIGURATION_CLIENT_INFORMATION_ID)?; // Пакет Client Information + let mut packet = client.read_packet(serverbound::configuration::CLIENT_INFORMATION)?; // Пакет Client Information let locale = packet.read_string()?; // for example: en_us let view_distance = packet.read_signed_byte()?; // client-side render distance in chunks @@ -166,8 +143,8 @@ pub fn handle_connection( // TODO: Заюзать Listener'ы чтобы они подмешивали сюда чото - client.write_packet(&Packet::empty(CONFIGURATION_FINISH_ID))?; - client.read_packet(CONFIGURATION_ACKNOWLEDGE_FINISH_ID)?; + client.write_packet(&Packet::empty(clientbound::configuration::FINISH))?; + client.read_packet(serverbound::configuration::ACKNOWLEDGE_FINISH)?; client.set_state(ConnectionState::Play)?; // Мы перешли в режим Play @@ -179,18 +156,5 @@ pub fn handle_connection( } } - Ok(()) -} - -// Отдельная функция для работы с самой игрой -pub fn handle_play_state( - client: Arc, // Контекст клиента -) -> Result<(), ServerError> { - - // Отключение игрока с сообщением - client.protocol_helper().disconnect(TextComponent::rainbow("server is in developement suka".to_string()))?; - - // TODO: Сделать отправку пакетов Play - Ok(()) } \ No newline at end of file diff --git a/src/server/protocol/id.rs b/src/server/protocol/id.rs new file mode 100644 index 0000000..fe7bab2 --- /dev/null +++ b/src/server/protocol/id.rs @@ -0,0 +1,275 @@ +/* + + Generated with parse_ids.py + + */ + +pub mod clientbound { + pub mod status { + pub const RESPONSE: u8 = 0x00; + pub const PONG_RESPONSE: u8 = 0x01; + } + + pub mod login { + pub const DISCONNECT: u8 = 0x00; + pub const ENCRYPTION_REQUEST: u8 = 0x01; + pub const SUCCESS: u8 = 0x02; + pub const SET_COMPRESSION: u8 = 0x03; + pub const PLUGIN_REQUEST: u8 = 0x04; + pub const COOKIE_REQUEST: u8 = 0x05; + } + + pub mod configuration { + pub const COOKIE_REQUEST: u8 = 0x00; + pub const PLUGIN_MESSAGE: u8 = 0x01; + pub const DISCONNECT: u8 = 0x02; + pub const FINISH: u8 = 0x03; + pub const KEEP_ALIVE: u8 = 0x04; + pub const PING: u8 = 0x05; + pub const RESET_CHAT: u8 = 0x06; + pub const REGISTRY_DATA: u8 = 0x07; + pub const REMOVE_RESOURCE_PACK: u8 = 0x08; + pub const ADD_RESOURCE_PACK: u8 = 0x09; + pub const STORE_COOKIE: u8 = 0x0A; + pub const TRANSFER: u8 = 0x0B; + pub const FEATURE_FLAGS: u8 = 0x0C; + pub const UPDATE_TAGS: u8 = 0x0D; + pub const KNOWN_PACKS: u8 = 0x0E; + pub const CUSTOM_REPORT_DETAILS: u8 = 0x0F; + pub const SERVER_LINKS: u8 = 0x10; + } + + pub mod play { + pub const BUNDLE_DELIMITER: u8 = 0x00; + pub const SPAWN_ENTITY: u8 = 0x01; + pub const ENTITY_ANIMATION: u8 = 0x02; + pub const AWARD_STATISTICS: u8 = 0x03; + pub const ACKNOWLEDGE_BLOCK_CHANGE: u8 = 0x04; + pub const SET_BLOCK_DESTROY_STAGE: u8 = 0x05; + pub const BLOCK_ENTITY_DATA: u8 = 0x06; + pub const BLOCK_ACTION: u8 = 0x07; + pub const BLOCK_UPDATE: u8 = 0x08; + pub const BOSS_BAR: u8 = 0x09; + pub const CHANGE_DIFFICULTY: u8 = 0x0A; + pub const CHUNK_BATCH_FINISHED: u8 = 0x0B; + pub const CHUNK_BATCH_START: u8 = 0x0C; + pub const CHUNK_BIOMES: u8 = 0x0D; + pub const CLEAR_TITLES: u8 = 0x0E; + pub const COMMAND_SUGGESTIONS_RESPONSE: u8 = 0x0F; + pub const COMMANDS: u8 = 0x10; + pub const CLOSE_CONTAINER: u8 = 0x11; + pub const SET_CONTAINER_CONTENT: u8 = 0x12; + pub const SET_CONTAINER_PROPERTY: u8 = 0x13; + pub const SET_CONTAINER_SLOT: u8 = 0x14; + pub const COOKIE_REQUEST: u8 = 0x15; + pub const SET_COOLDOWN: u8 = 0x16; + pub const CHAT_SUGGESTIONS: u8 = 0x17; + pub const PLUGIN_MESSAGE: u8 = 0x18; + pub const DAMAGE_EVENT: u8 = 0x19; + pub const DEBUG_SAMPLE: u8 = 0x1A; + pub const DELETE_MESSAGE: u8 = 0x1B; + pub const DISCONNECT: u8 = 0x1C; + pub const DISGUISED_CHAT_MESSAGE: u8 = 0x1D; + pub const ENTITY_EVENT: u8 = 0x1E; + pub const TELEPORT_ENTITY: u8 = 0x1F; + pub const EXPLOSION: u8 = 0x20; + pub const UNLOAD_CHUNK: u8 = 0x21; + pub const GAME_EVENT: u8 = 0x22; + pub const OPEN_HORSE_SCREEN: u8 = 0x23; + pub const HURT_ANIMATION: u8 = 0x24; + pub const INITIALIZE_WORLD_BORDER: u8 = 0x25; + pub const KEEP_ALIVE: u8 = 0x26; + pub const CHUNK_DATA_AND_UPDATE_LIGHT: u8 = 0x27; + pub const WORLD_EVENT: u8 = 0x28; + pub const PARTICLE: u8 = 0x29; + pub const UPDATE_LIGHT: u8 = 0x2A; + pub const LOGIN: u8 = 0x2B; + pub const MAP_DATA: u8 = 0x2C; + pub const MERCHANT_OFFERS: u8 = 0x2D; + pub const UPDATE_ENTITY_POSITION: u8 = 0x2E; + pub const UPDATE_ENTITY_POSITION_AND_ROTATION: u8 = 0x2F; + pub const MOVE_MINECART_ALONG_TRACK: u8 = 0x30; + pub const UPDATE_ENTITY_ROTATION: u8 = 0x31; + pub const MOVE_VEHICLE: u8 = 0x32; + pub const OPEN_BOOK: u8 = 0x33; + pub const OPEN_SCREEN: u8 = 0x34; + pub const OPEN_SIGN_EDITOR: u8 = 0x35; + pub const PING: u8 = 0x36; + pub const PING_RESPONSE: u8 = 0x37; + pub const PLACE_GHOST_RECIPE: u8 = 0x38; + pub const PLAYER_ABILITIES: u8 = 0x39; + pub const PLAYER_CHAT_MESSAGE: u8 = 0x3A; + pub const END_COMBAT: u8 = 0x3B; + pub const ENTER_COMBAT: u8 = 0x3C; + pub const COMBAT_DEATH: u8 = 0x3D; + pub const PLAYER_INFO_REMOVE: u8 = 0x3E; + pub const PLAYER_INFO_UPDATE: u8 = 0x3F; + pub const LOOK_AT: u8 = 0x40; + pub const SYNCHRONIZE_PLAYER_POSITION: u8 = 0x41; + pub const PLAYER_ROTATION: u8 = 0x42; + pub const RECIPE_BOOK_ADD: u8 = 0x43; + pub const RECIPE_BOOK_REMOVE: u8 = 0x44; + pub const RECIPE_BOOK_SETTINGS: u8 = 0x45; + pub const REMOVE_ENTITIES: u8 = 0x46; + pub const REMOVE_ENTITY_EFFECT: u8 = 0x47; + pub const RESET_SCORE: u8 = 0x48; + pub const REMOVE_RESOURCE_PACK: u8 = 0x49; + pub const ADD_RESOURCE_PACK: u8 = 0x4A; + pub const RESPAWN: u8 = 0x4B; + pub const SET_HEAD_ROTATION: u8 = 0x4C; + pub const UPDATE_SECTION_BLOCKS: u8 = 0x4D; + pub const SELECT_ADVANCEMENTS_TAB: u8 = 0x4E; + pub const SERVER_DATA: u8 = 0x4F; + pub const SET_ACTION_BAR_TEXT: u8 = 0x50; + pub const SET_BORDER_CENTER: u8 = 0x51; + pub const SET_BORDER_LERP_SIZE: u8 = 0x52; + pub const SET_BORDER_SIZE: u8 = 0x53; + pub const SET_BORDER_WARNING_DELAY: u8 = 0x54; + pub const SET_BORDER_WARNING_DISTANCE: u8 = 0x55; + pub const SET_CAMERA: u8 = 0x56; + pub const SET_CENTER_CHUNK: u8 = 0x57; + pub const SET_RENDER_DISTANCE: u8 = 0x58; + pub const SET_CURSOR_ITEM: u8 = 0x59; + pub const SET_DEFAULT_SPAWN_POSITION: u8 = 0x5A; + pub const DISPLAY_OBJECTIVE: u8 = 0x5B; + pub const SET_ENTITY_METADATA: u8 = 0x5C; + pub const LINK_ENTITIES: u8 = 0x5D; + pub const SET_ENTITY_VELOCITY: u8 = 0x5E; + pub const SET_EQUIPMENT: u8 = 0x5F; + pub const SET_EXPERIENCE: u8 = 0x60; + pub const SET_HEALTH: u8 = 0x61; + pub const SET_HELD_ITEM: u8 = 0x62; + pub const UPDATE_OBJECTIVES: u8 = 0x63; + pub const SET_PASSENGERS: u8 = 0x64; + pub const SET_PLAYER_INVENTORY_SLOT: u8 = 0x65; + pub const UPDATE_TEAMS: u8 = 0x66; + pub const UPDATE_SCORE: u8 = 0x67; + pub const SET_SIMULATION_DISTANCE: u8 = 0x68; + pub const SET_SUBTITLE_TEXT: u8 = 0x69; + pub const UPDATE_TIME: u8 = 0x6A; + pub const SET_TITLE_TEXT: u8 = 0x6B; + pub const SET_TITLE_ANIMATION_TIMES: u8 = 0x6C; + pub const ENTITY_SOUND_EFFECT: u8 = 0x6D; + pub const SOUND_EFFECT: u8 = 0x6E; + pub const START_CONFIGURATION: u8 = 0x6F; + pub const STOP_SOUND: u8 = 0x70; + pub const STORE_COOKIE: u8 = 0x71; + pub const SYSTEM_CHAT_MESSAGE: u8 = 0x72; + pub const SET_TAB_LIST_HEADER_AND_FOOTER: u8 = 0x73; + pub const TAG_QUERY_RESPONSE: u8 = 0x74; + pub const PICKUP_ITEM: u8 = 0x75; + pub const SYNCHRONIZE_VEHICLE_POSITION: u8 = 0x76; + pub const TEST_INSTANCE_BLOCK_STATUS: u8 = 0x77; + pub const SET_TICKING_STATE: u8 = 0x78; + pub const STEP_TICK: u8 = 0x79; + pub const TRANSFER: u8 = 0x7A; + pub const UPDATE_ADVANCEMENTS: u8 = 0x7B; + pub const UPDATE_ATTRIBUTES: u8 = 0x7C; + pub const ENTITY_EFFECT: u8 = 0x7D; + pub const UPDATE_RECIPES: u8 = 0x7E; + pub const UPDATE_TAGS: u8 = 0x7F; + pub const PROJECTILE_POWER: u8 = 0x80; + pub const CUSTOM_REPORT_DETAILS: u8 = 0x81; + pub const SERVER_LINKS: u8 = 0x82; + } + +} + +pub mod serverbound { + pub mod handshake { + pub const HANDSHAKE: u8 = 0x00; + } + + pub mod status { + pub const REQUEST: u8 = 0x00; + pub const PING_REQUEST: u8 = 0x01; + } + + pub mod login { + pub const START: u8 = 0x00; + pub const ENCRYPTION_RESPONSE: u8 = 0x01; + pub const PLUGIN_RESPONSE: u8 = 0x02; + pub const ACKNOWLEDGED: u8 = 0x03; + pub const COOKIE_RESPONSE: u8 = 0x04; + } + + pub mod configuration { + pub const CLIENT_INFORMATION: u8 = 0x00; + pub const COOKIE_RESPONSE: u8 = 0x01; + pub const PLUGIN_MESSAGE: u8 = 0x02; + pub const ACKNOWLEDGE_FINISH: u8 = 0x03; + pub const KEEP_ALIVE: u8 = 0x04; + pub const PONG: u8 = 0x05; + pub const RESOURCE_PACK_RESPONSE: u8 = 0x06; + pub const KNOWN_PACKS: u8 = 0x07; + } + + pub mod play { + pub const CONFIRM_TELEPORTATION: u8 = 0x00; + pub const QUERY_BLOCK_ENTITY_TAG: u8 = 0x01; + pub const BUNDLE_ITEM_SELECTED: u8 = 0x02; + pub const CHANGE_DIFFICULTY: u8 = 0x03; + pub const ACKNOWLEDGE_MESSAGE: u8 = 0x04; + pub const CHAT_COMMAND: u8 = 0x05; + pub const SIGNED_CHAT_COMMAND: u8 = 0x06; + pub const CHAT_MESSAGE: u8 = 0x07; + pub const PLAYER_SESSION: u8 = 0x08; + pub const CHUNK_BATCH_RECEIVED: u8 = 0x09; + pub const CLIENT_STATUS: u8 = 0x0A; + pub const CLIENT_TICK_END: u8 = 0x0B; + pub const CLIENT_INFORMATION: u8 = 0x0C; + pub const COMMAND_SUGGESTIONS_REQUEST: u8 = 0x0D; + pub const ACKNOWLEDGE_CONFIGURATION: u8 = 0x0E; + pub const CLICK_CONTAINER_BUTTON: u8 = 0x0F; + pub const CLICK_CONTAINER: u8 = 0x10; + pub const CLOSE_CONTAINER: u8 = 0x11; + pub const CHANGE_CONTAINER_SLOT_STATE: u8 = 0x12; + pub const COOKIE_RESPONSE: u8 = 0x13; + pub const PLUGIN_MESSAGE: u8 = 0x14; + pub const DEBUG_SAMPLE_SUBSCRIPTION: u8 = 0x15; + pub const EDIT_BOOK: u8 = 0x16; + pub const QUERY_ENTITY_TAG: u8 = 0x17; + pub const INTERACT: u8 = 0x18; + pub const JIGSAW_GENERATE: u8 = 0x19; + pub const KEEP_ALIVE: u8 = 0x1A; + pub const LOCK_DIFFICULTY: u8 = 0x1B; + pub const SET_PLAYER_POSITION: u8 = 0x1C; + pub const SET_PLAYER_POSITION_AND_ROTATION: u8 = 0x1D; + pub const SET_PLAYER_ROTATION: u8 = 0x1E; + pub const SET_PLAYER_MOVEMENT_FLAGS: u8 = 0x1F; + pub const MOVE_VEHICLE: u8 = 0x20; + pub const PADDLE_BOAT: u8 = 0x21; + pub const PICK_ITEM_FROM_BLOCK: u8 = 0x22; + pub const PICK_ITEM_FROM_ENTITY: u8 = 0x23; + pub const PING_REQUEST: u8 = 0x24; + pub const PLACE_RECIPE: u8 = 0x25; + pub const PLAYER_ABILITIES: u8 = 0x26; + pub const PLAYER_ACTION: u8 = 0x27; + pub const PLAYER_COMMAND: u8 = 0x28; + pub const PLAYER_INPUT: u8 = 0x29; + pub const PLAYER_LOADED: u8 = 0x2A; + pub const PONG: u8 = 0x2B; + pub const CHANGE_RECIPE_BOOK_SETTINGS: u8 = 0x2C; + pub const SET_SEEN_RECIPE: u8 = 0x2D; + pub const RENAME_ITEM: u8 = 0x2E; + pub const RESOURCE_PACK_RESPONSE: u8 = 0x2F; + pub const SEEN_ADVANCEMENTS: u8 = 0x30; + pub const SELECT_TRADE: u8 = 0x31; + pub const SET_BEACON_EFFECT: u8 = 0x32; + pub const SET_HELD_ITEM: u8 = 0x33; + pub const PROGRAM_COMMAND_BLOCK: u8 = 0x34; + pub const PROGRAM_COMMAND_BLOCK_MINECART: u8 = 0x35; + pub const SET_CREATIVE_MODE_SLOT: u8 = 0x36; + pub const PROGRAM_JIGSAW_BLOCK: u8 = 0x37; + pub const PROGRAM_STRUCTURE_BLOCK: u8 = 0x38; + pub const SET_TEST_BLOCK: u8 = 0x39; + pub const UPDATE_SIGN: u8 = 0x3A; + pub const SWING_ARM: u8 = 0x3B; + pub const TELEPORT_TO_ENTITY: u8 = 0x3C; + pub const TEST_INSTANCE_BLOCK_ACTION: u8 = 0x3D; + pub const USE_ITEM_ON: u8 = 0x3E; + pub const USE_ITEM: u8 = 0x3F; + } + +} + diff --git a/src/server/protocol/mod.rs b/src/server/protocol/mod.rs new file mode 100644 index 0000000..53ab91d --- /dev/null +++ b/src/server/protocol/mod.rs @@ -0,0 +1,14 @@ +pub mod id; +pub mod play; +pub mod handler; + + +#[derive(Debug, Clone)] +pub enum ConnectionState { + Handshake, + Status, + Login, + Configuration, + Play +} + diff --git a/src/server/protocol/play.rs b/src/server/protocol/play.rs new file mode 100644 index 0000000..de5cff6 --- /dev/null +++ b/src/server/protocol/play.rs @@ -0,0 +1,16 @@ +use std::sync::Arc; + +use crate::server::{data::text_component::TextComponent, player::context::ClientContext, ServerError}; + +// Отдельная функция для работы с самой игрой +pub fn handle_play_state( + client: Arc, // Контекст клиента +) -> Result<(), ServerError> { + + // Отключение игрока с сообщением + client.protocol_helper().disconnect(TextComponent::rainbow("server is in developement suka".to_string()))?; + + // TODO: Сделать отправку пакетов Play + + Ok(()) +} \ No newline at end of file