more docs
This commit is contained in:
parent
8b537f8339
commit
8a1aa4b31f
@ -97,6 +97,8 @@ impl PacketHandler for ExamplePacketHandler {
|
||||
|
||||
|
||||
fn main() {
|
||||
// Инициализируем логи
|
||||
// Чтобы читать debug-логи, юзаем `RUST_LOG=debug cargo run`
|
||||
colog::init();
|
||||
|
||||
// Получение аргументов
|
||||
|
@ -6,6 +6,8 @@ use uuid::Uuid;
|
||||
|
||||
use super::{config::Config, event::{Listener, PacketHandler}, player::context::ClientContext};
|
||||
|
||||
// Контекст сервера
|
||||
// Должен быть обернут в Arc для передачи между потоками
|
||||
pub struct ServerContext {
|
||||
pub config: Arc<Config>,
|
||||
pub clients: DashMap<SocketAddr, Arc<ClientContext>>,
|
||||
|
@ -1,2 +1,11 @@
|
||||
use rust_mc_proto::{DataReader, DataWriter};
|
||||
|
||||
use super::ServerError;
|
||||
|
||||
pub mod text_component;
|
||||
|
||||
// Трейт для чтения NBT-совместимых приколов
|
||||
pub trait ReadWriteNBT<T>: DataReader + DataWriter {
|
||||
fn read_nbt(&mut self) -> Result<T, ServerError>;
|
||||
fn write_nbt(&mut self, val: &T) -> Result<(), ServerError>;
|
||||
}
|
@ -1,13 +1,13 @@
|
||||
use std::io::Read;
|
||||
|
||||
use palette::{Hsl, IntoColor, Srgb};
|
||||
use rust_mc_proto::{DataReader, Packet};
|
||||
use rust_mc_proto::Packet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::skip_serializing_none;
|
||||
|
||||
use crate::server::ServerError;
|
||||
|
||||
|
||||
use super::ReadWriteNBT;
|
||||
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
@ -21,6 +21,7 @@ pub struct TextComponent {
|
||||
pub strikethrough: Option<bool>,
|
||||
pub obfuscated: Option<bool>,
|
||||
pub extra: Option<Vec<TextComponent>>,
|
||||
// TODO: добавить все остальные стандартные поля для текст-компонента типа клик ивентов и сделать отдельный структ для транслейт компонент
|
||||
}
|
||||
|
||||
impl TextComponent {
|
||||
@ -161,11 +162,7 @@ impl TextComponentBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ReadWriteNBT<T>: DataReader {
|
||||
fn read_nbt(&mut self) -> Result<T, ServerError>;
|
||||
fn write_nbt(&mut self, val: &T) -> Result<(), ServerError>;
|
||||
}
|
||||
|
||||
// Реализуем читалку-записывалку текст-компонентов для пакета
|
||||
impl ReadWriteNBT<TextComponent> for Packet {
|
||||
fn read_nbt(&mut self) -> Result<TextComponent, ServerError> {
|
||||
let mut data = Vec::new();
|
||||
|
@ -17,6 +17,20 @@ macro_rules! generate_handlers {
|
||||
};
|
||||
}
|
||||
|
||||
// Пример использования:
|
||||
// let packet_dst = trigger_packet!(packet_src, client, Handshake, incoming);
|
||||
// │ │ │ │
|
||||
// ┌────────────────────┼───────────┼────────┼──────────┘
|
||||
// │ │ │ │
|
||||
// │ ┌─────┼───────────┘ │
|
||||
// │ │ │ │
|
||||
// │ │ │ └──────────────────┐
|
||||
// │ ▼ └───────────┐ │
|
||||
// Сделается вот такой вызов на всех packet_handler'ах: ▼ ▼ ▼
|
||||
// handler.on_incoming_packet(client.clone(), &mut packet, ConnectionState::Handshake)
|
||||
// packet_src можно заменить на получение пакета, например: trigger_packet!(client.conn().read_packet()?, client, Handshake, incoming);
|
||||
// В packet_dst будет лежать обратботанный пакет, прошедший через все хандлеры
|
||||
// TODO: сделать чтобы можно было ваще отключить обработку
|
||||
#[macro_export]
|
||||
macro_rules! trigger_packet {
|
||||
($packet:expr, $client:ident, $state:ident, $bound:ident) => {
|
||||
@ -35,49 +49,25 @@ macro_rules! trigger_packet {
|
||||
};
|
||||
}
|
||||
|
||||
// Честно ни разу не проверял работу этого дерьма
|
||||
// Пример использования:
|
||||
// trigger_event!(client, status, $mut response, state);
|
||||
// Сделается вот такой вызов на всех листенерах:
|
||||
// listener.on_status(client.clone(), &mut response, state);
|
||||
#[macro_export]
|
||||
macro_rules! trigger_event {
|
||||
($client:ident, $event:ident, $($arg:expr),* $(,)?) => {{
|
||||
($client:ident, $event:ident, $(, $arg_ty:ty)* $(,)?) => {{
|
||||
paste::paste! {
|
||||
trigger_event!(@declare_mut_vars 0, $($arg),*);
|
||||
|
||||
for handler in $client.server.listeners(
|
||||
|o| o.[<on_ $event _priority>]()
|
||||
).iter() {
|
||||
handler.[<on_ $event>](
|
||||
$client.clone(),
|
||||
$(trigger_event!(@expand_arg 0, $arg)),*
|
||||
$(, $arg_ty)*
|
||||
)?;
|
||||
}
|
||||
}
|
||||
}};
|
||||
|
||||
(@declare_mut_vars $i:tt, &mut $head:expr, $($tail:tt)*) => {
|
||||
paste::paste! {
|
||||
let mut [<__arg $i>] = $head;
|
||||
}
|
||||
trigger_event!(@declare_mut_vars trigger_event!(@inc $i), $($tail)*);
|
||||
};
|
||||
(@declare_mut_vars $i:tt, $head:expr, $($tail:tt)*) => {
|
||||
trigger_event!(@declare_mut_vars trigger_event!(@inc $i), $($tail)*);
|
||||
};
|
||||
(@declare_mut_vars $_i:tt,) => {};
|
||||
|
||||
(@expand_arg $i:tt, &mut $head:expr) => {
|
||||
paste::paste! { &mut [<__arg $i>] }
|
||||
};
|
||||
(@expand_arg $_i:tt, $head:expr) => {
|
||||
$head
|
||||
};
|
||||
|
||||
(@inc 0) => { 1 };
|
||||
(@inc 1) => { 2 };
|
||||
(@inc 2) => { 3 };
|
||||
(@inc 3) => { 4 };
|
||||
(@inc 4) => { 5 };
|
||||
(@inc 5) => { 6 };
|
||||
(@inc 6) => { 7 };
|
||||
(@inc 7) => { 8 };
|
||||
}
|
||||
|
||||
pub trait Listener: Sync + Send {
|
||||
|
@ -17,12 +17,13 @@ pub mod protocol;
|
||||
// Ошибки сервера
|
||||
#[derive(Debug)]
|
||||
pub enum ServerError {
|
||||
UnknownPacket(String),
|
||||
Protocol(ProtocolError),
|
||||
ConnectionClosed,
|
||||
SerTextComponent,
|
||||
DeTextComponent,
|
||||
UnexpectedState
|
||||
UnknownPacket(String), // Неизвестный пакет, в строке указана ситуация в которой он неизвестен
|
||||
Protocol(ProtocolError), // Ошибка в протоколе при работе с rust_mc_proto
|
||||
ConnectionClosed, // Соединение закрыто, единственная ошибка которая не логируется у handle_connection
|
||||
SerTextComponent, // Ошибка при сериализации текст-компонента
|
||||
DeTextComponent, // Ошибка при десериализации текст-компонента
|
||||
UnexpectedState, // Указывает на то что этот пакет не может быть отправлен в данном режиме (в основном через ProtocolHelper)
|
||||
Other(String) // Другая ошибка, либо очень специфичная, либо хз, лучше не использовать и создавать новое поле ошибки
|
||||
}
|
||||
|
||||
impl Display for ServerError {
|
||||
@ -76,6 +77,8 @@ pub fn start_server(server: Arc<ServerContext>) {
|
||||
// Передавется во все листенеры и хандлеры чтобы определять именно этот клиент
|
||||
let client = Arc::new(ClientContext::new(server.clone(), conn));
|
||||
|
||||
// Добавляем клиента в список клиентов сервера
|
||||
// Используем адрес как ключ, врятли ipv4 будет нам врать
|
||||
server.clients.insert(client.addr, client.clone());
|
||||
|
||||
// Обработка подключения
|
||||
@ -88,6 +91,7 @@ pub fn start_server(server: Arc<ServerContext>) {
|
||||
},
|
||||
};
|
||||
|
||||
// Удаляем клиента из списка клиентов
|
||||
server.clients.remove(&client.addr);
|
||||
|
||||
info!("Отключение: {}", addr);
|
||||
|
@ -7,7 +7,8 @@ use crate::server::{context::ServerContext, protocol::ConnectionState, ServerErr
|
||||
|
||||
use super::protocol::ProtocolHelper;
|
||||
|
||||
|
||||
// Клиент контекст
|
||||
// Должен быть обернут в Arc для передачи между потоками
|
||||
pub struct ClientContext {
|
||||
pub server: Arc<ServerContext>,
|
||||
pub addr: SocketAddr,
|
||||
@ -18,6 +19,8 @@ pub struct ClientContext {
|
||||
state: RwLock<ConnectionState>
|
||||
}
|
||||
|
||||
// Реализуем сравнение через адрес
|
||||
// IPv4 не должен обманывать, иначе у нас случится коллапс
|
||||
impl PartialEq for ClientContext {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.addr == other.addr
|
||||
|
@ -2,11 +2,18 @@ use std::{io::Read, sync::Arc};
|
||||
|
||||
use rust_mc_proto::{DataReader, DataWriter, Packet};
|
||||
|
||||
use crate::server::{data::text_component::{ReadWriteNBT, TextComponent}, protocol::ConnectionState, ServerError};
|
||||
use crate::server::{data::text_component::TextComponent, data::ReadWriteNBT, protocol::ConnectionState, ServerError};
|
||||
|
||||
use super::context::ClientContext;
|
||||
|
||||
|
||||
// Помощник в работе с протоколом
|
||||
// Может быть использован где угодно, но сделан именно для листенеров и пакет хандлеров
|
||||
// Через него удобно делать всякую одинаковую херь
|
||||
// Возможно надо было бы сделать прям обязательный какойто структ через который только можно было отправлять пакеты ...
|
||||
// ... но мне лень
|
||||
// Пусть юзают подключение и отправляют пакеты через него если хотят
|
||||
// Почему бы и нет если да
|
||||
pub struct ProtocolHelper {
|
||||
client: Arc<ClientContext>,
|
||||
state: ConnectionState
|
||||
|
Loading…
Reference in New Issue
Block a user