event system

This commit is contained in:
MeexReay 2024-11-17 00:26:52 +03:00
parent 5a4c1d6d2b
commit 9236636025
8 changed files with 148 additions and 60 deletions

9
Cargo.lock generated
View File

@ -157,6 +157,14 @@ version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "make_event"
version = "0.1.0"
dependencies = [
"quote",
"syn",
]
[[package]] [[package]]
name = "meexprox" name = "meexprox"
version = "0.1.0" version = "0.1.0"
@ -164,6 +172,7 @@ dependencies = [
"bytebuffer", "bytebuffer",
"ignore-result", "ignore-result",
"log", "log",
"make_event",
"random-string", "random-string",
"ring", "ring",
"rust_mc_proto", "rust_mc_proto",

View File

@ -12,4 +12,10 @@ simplelog = "0.12.2"
ignore-result = "0.2.0" ignore-result = "0.2.0"
random-string = "1.1.0" random-string = "1.1.0"
ring = "0.17.8" ring = "0.17.8"
bytebuffer = "2.3.0" bytebuffer = "2.3.0"
make_event = { path = "make_event" }
[workspace]
members = [
"make_event"
]

View File

@ -13,7 +13,7 @@ forwarding:
### Player forwarding types ### Player forwarding types
- `meexprox` - meexprox player forwarding ([about it](meexprox_forwarding.md)) - `meexprox` - meexprox player forwarding ([about it](meexprox_forwarding.md)) ([plugin](https://github.com/MeexReay/meexprox_plugin))
- `velocity` - velocity 'modern' player forwarding, secret key is required - `velocity` - velocity 'modern' player forwarding, secret key is required
- `bungeecord` (with secret) - bungeecord player forwarding - `bungeecord` (with secret) - bungeecord player forwarding
- `bungeecord` (without secret) - bungeeguard player forwarding - `bungeecord` (without secret) - bungeeguard player forwarding

11
make_event/Cargo.toml Normal file
View File

@ -0,0 +1,11 @@
[package]
name = "make_event"
version = "0.1.0"
edition = "2021"
[dependencies]
quote = "1.0.37"
syn = "2.0.87"
[lib]
proc-macro = true

70
make_event/src/lib.rs Normal file
View File

@ -0,0 +1,70 @@
use proc_macro::TokenStream;
use quote::{quote, format_ident};
use syn::{parse_macro_input, DeriveInput, Data, Fields};
#[proc_macro_derive(MakeEvent, attributes(MakeEvent, setter))]
pub fn make_event_derive(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let struct_name = &input.ident;
let event_name = input.attrs.iter()
.find_map(|attr| {
if attr.path().is_ident("MakeEvent") {
attr.parse_args::<syn::LitStr>().ok()
} else {
None
}
})
.expect("Expected MakeEvent attribute with a name argument")
.value();
let mut getters = Vec::new();
let mut setters = Vec::new();
if let Data::Struct(data) = input.data {
if let Fields::Named(fields) = data.fields {
for field in fields.named.iter() {
let field_name = &field.ident;
let field_ty = &field.ty;
getters.push(quote! {
pub fn #field_name(&self) -> &#field_ty {
&self.#field_name
}
});
if field.attrs.iter().any(|attr| attr.path().is_ident("setter")) {
let setter_name = format_ident!("set_{}", field_name.as_ref().unwrap());
setters.push(quote! {
pub fn #setter_name(&mut self, value: #field_ty) {
self.#field_name = value;
}
});
}
}
}
} else {
panic!("MakeEvent can only be derived for structs with named fields");
}
let expanded = quote! {
impl #struct_name {
#(#getters)*
#(#setters)*
}
impl Event for #struct_name {
fn cancel(&mut self) {
self.cancelled = true;
}
fn is_cancelled(&self) -> bool {
self.cancelled
}
fn name(&self) -> String {
#event_name.to_string()
}
}
};
TokenStream::from(expanded)
}

View File

@ -1,3 +1,3 @@
pub mod meexprox; pub mod meexprox;
pub use meexprox::*; pub use meexprox::*;

View File

@ -1,59 +1,51 @@
use std::net::SocketAddr; use std::{any::Any, net::SocketAddr};
use rust_mc_proto::Packet; use make_event::MakeEvent;
use super::{config::ServerInfo, connection::Player, error::ProxyError}; use super::error::ProxyError;
pub trait EventListener { pub trait Event {
fn on_server_recv_packet( fn name(&self) -> String;
&self, fn is_cancelled(&self) -> bool;
packet: &mut Packet, fn cancel(&mut self);
player: &Player, }
) -> Result<(), ProxyError>;
fn on_server_send_packet( pub trait AsAny {
&self, fn as_any_ref(&self) -> &dyn Any;
packet: &mut Packet, fn as_any_mut(&mut self) -> &mut dyn Any;
cancel: &mut bool, fn as_any_box(self: Box<Self>) -> Box<dyn Any>;
player: &Player, }
) -> Result<(), ProxyError>;
fn on_client_send_packet( impl<T> AsAny for T
&self, where
packet: &mut Packet, T: Any,
cancel: &mut bool, {
player: &Player, fn as_any_ref(&self) -> &dyn Any {
) -> Result<(), ProxyError>; self
}
fn on_client_recv_packet( fn as_any_mut(&mut self) -> &mut dyn Any {
&self, self
packet: &mut Packet, }
player: &Player,
) -> Result<(), ProxyError>;
fn on_player_connected( fn as_any_box(self: Box<Self>) -> Box<dyn Any> {
&self, self
player: &Player, }
) -> Result<(), ProxyError>; }
fn on_player_disconnected( pub trait EventListener<T: Event>: AsAny {
&self, fn on_event(&self, event: &mut T) -> Result<(), ProxyError>;
player: &Player, }
) -> Result<(), ProxyError>;
fn on_player_connecting_server(
&self,
player: &Player,
cancel: &mut bool,
server: &mut ServerInfo
) -> Result<(), ProxyError>;
fn on_status_request( #[derive(MakeEvent)]
&self, #[MakeEvent("status")]
status: String, pub struct StatusEvent {
client_address: SocketAddr, cancelled: bool,
server_address: String, addr: SocketAddr,
server_port: u16, #[setter]
cancel: &mut bool, motd: String,
) -> Result<(), ProxyError>; server_address: String,
server_port: u16,
protocol_version: u16
} }

View File

@ -9,13 +9,13 @@ use std::{
}, thread, }, thread,
}; };
use super::{config::ProxyConfig, connection::Player, error::{AsProxyResult, ProxyError}, event::EventListener}; use super::{config::ProxyConfig, connection::Player, error::{AsProxyResult, ProxyError}, event::{Event, EventListener}};
pub struct MeexProx { pub struct MeexProx {
config: ProxyConfig, config: ProxyConfig,
players: RwLock<Vec<Player>>, players: RwLock<Vec<Player>>,
event_listeners: Vec<Box<dyn EventListener + Send + Sync>> event_listeners: Vec<Box<dyn EventListener<dyn Event> + Send + Sync>>
} }
impl MeexProx { impl MeexProx {
@ -29,17 +29,17 @@ impl MeexProx {
pub fn add_event_listener( pub fn add_event_listener(
&mut self, &mut self,
event_listener: Box<dyn EventListener + Send + Sync>, event_listener: Box<dyn EventListener<dyn Event> + Send + Sync>,
) { ) {
self.event_listeners.push(event_listener); self.event_listeners.push(event_listener);
} }
pub fn trigger_event( pub fn trigger_event<T: Event + 'static>(&self, event: &mut T) -> Result<(), ProxyError> {
&self, for listener in &self.event_listeners {
trigger: fn(&dyn EventListener) -> Result<(), ProxyError> if let Some(listener) =
) -> Result<(), ProxyError> { listener.as_any_ref().downcast_ref::<Box<dyn EventListener<T> + Send + Sync + 'static>>() {
for event_listener in &self.event_listeners { listener.on_event(event)?;
trigger(event_listener.as_ref())? }
} }
Ok(()) Ok(())
} }