event system
This commit is contained in:
parent
5a4c1d6d2b
commit
9236636025
9
Cargo.lock
generated
9
Cargo.lock
generated
@ -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",
|
||||||
|
@ -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"
|
||||||
|
]
|
@ -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
11
make_event/Cargo.toml
Normal 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
70
make_event/src/lib.rs
Normal 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)
|
||||||
|
}
|
@ -1,3 +1,3 @@
|
|||||||
pub mod meexprox;
|
pub mod meexprox;
|
||||||
|
|
||||||
pub use meexprox::*;
|
pub use meexprox::*;
|
@ -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
|
||||||
}
|
}
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user