refactor: random cleanups and efficiency improvements
This commit is contained in:
		| @@ -14,17 +14,17 @@ function log_player_positions() | |||||||
| 	end | 	end | ||||||
| end | end | ||||||
|  |  | ||||||
| function on_init() | add_listener("init", function() | ||||||
| 	info("client initialized, setting information...") | 	info("client initialized, setting information...") | ||||||
| 	client:set_client_information({ view_distance = 16 }) | 	client:set_client_information({ view_distance = 16 }) | ||||||
|  | end) | ||||||
|  |  | ||||||
| 	add_listener("login", function() | add_listener("login", function() | ||||||
| 		info("player successfully logged in!") | 	info("player successfully logged in!") | ||||||
| 	end) | end) | ||||||
|  |  | ||||||
| 	add_listener("death", function() | add_listener("death", function() | ||||||
| 		warn(string.format("player died at %.1f %.1f %.1f!", client.position.x, client.position.y, client.position.z)) | 	warn(string.format("player died at %.1f %.1f %.1f!", client.position.x, client.position.y, client.position.z)) | ||||||
| 	end, "warn_player_died") | end, "warn_player_died") | ||||||
|  |  | ||||||
| 	add_listener("tick", log_player_positions) | add_listener("tick", log_player_positions) | ||||||
| end |  | ||||||
|   | |||||||
| @@ -4,19 +4,18 @@ use crate::{ | |||||||
|     State, |     State, | ||||||
|     commands::CommandSource, |     commands::CommandSource, | ||||||
|     http::serve, |     http::serve, | ||||||
|     lua::{self, events::register_functions, player::Player}, |     lua::{self, player::Player}, | ||||||
| }; | }; | ||||||
| use azalea::{prelude::*, protocol::packets::game::ClientboundGamePacket}; | use azalea::{prelude::*, protocol::packets::game::ClientboundGamePacket}; | ||||||
| use hyper::{server::conn::http1, service::service_fn}; | use hyper::{server::conn::http1, service::service_fn}; | ||||||
| use hyper_util::rt::TokioIo; | use hyper_util::rt::TokioIo; | ||||||
| use log::{debug, error, info, trace}; | use log::{debug, error, info, trace}; | ||||||
| use mlua::{Function, IntoLuaMulti}; | use mlua::IntoLuaMulti; | ||||||
| use tokio::net::TcpListener; | use tokio::net::TcpListener; | ||||||
|  |  | ||||||
| #[allow(clippy::too_many_lines)] | #[allow(clippy::too_many_lines)] | ||||||
| pub async fn handle_event(client: Client, event: Event, state: State) -> anyhow::Result<()> { | pub async fn handle_event(client: Client, event: Event, state: State) -> anyhow::Result<()> { | ||||||
|     state.lua.gc_stop(); |     state.lua.gc_stop(); | ||||||
|     let globals = state.lua.globals(); |  | ||||||
|  |  | ||||||
|     match event { |     match event { | ||||||
|         Event::AddPlayer(player_info) => { |         Event::AddPlayer(player_info) => { | ||||||
| @@ -26,7 +25,7 @@ pub async fn handle_event(client: Client, event: Event, state: State) -> anyhow: | |||||||
|             let formatted_message = message.message(); |             let formatted_message = message.message(); | ||||||
|             info!("{}", formatted_message.to_ansi()); |             info!("{}", formatted_message.to_ansi()); | ||||||
|  |  | ||||||
|             let owners = globals.get::<Vec<String>>("Owners")?; |             let owners = state.lua.globals().get::<Vec<String>>("Owners")?; | ||||||
|             if message.is_whisper() |             if message.is_whisper() | ||||||
|                 && let (Some(sender), content) = message.split_sender_and_content() |                 && let (Some(sender), content) = message.split_sender_and_content() | ||||||
|                 && owners.contains(&sender) |                 && owners.contains(&sender) | ||||||
| @@ -78,20 +77,16 @@ pub async fn handle_event(client: Client, event: Event, state: State) -> anyhow: | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         Event::Init => { |         Event::Init => { | ||||||
|             debug!("client initialized"); |             debug!("received initialize event"); | ||||||
|  |  | ||||||
|  |             let globals = state.lua.globals(); | ||||||
|             globals.set( |             globals.set( | ||||||
|                 "client", |                 "client", | ||||||
|                 lua::client::Client { |                 lua::client::Client { | ||||||
|                     inner: Some(client), |                     inner: Some(client), | ||||||
|                 }, |                 }, | ||||||
|             )?; |             )?; | ||||||
|             register_functions(&state.lua, &globals, state.clone()).await?; |             call_listeners(&state, "init", ()).await; | ||||||
|             if let Ok(on_init) = globals.get::<Function>("on_init") |  | ||||||
|                 && let Err(error) = on_init.call::<()>(()) |  | ||||||
|             { |  | ||||||
|                 error!("failed to call lua on_init function: {error:?}"); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if let Some(address) = state.http_address { |             if let Some(address) = state.http_address { | ||||||
|                 let listener = TcpListener::bind(address).await.map_err(|error| { |                 let listener = TcpListener::bind(address).await.map_err(|error| { | ||||||
|   | |||||||
| @@ -1,17 +1,24 @@ | |||||||
| use crate::State; | use crate::ListenerMap; | ||||||
| use futures::executor::block_on; | use futures::{executor::block_on, lock::Mutex}; | ||||||
| use mlua::{Function, Lua, Result, Table}; | use mlua::{Function, Lua, Result, Table}; | ||||||
| use std::time::{SystemTime, UNIX_EPOCH}; | use std::{ | ||||||
|  |     sync::Arc, | ||||||
|  |     time::{SystemTime, UNIX_EPOCH}, | ||||||
|  | }; | ||||||
|  |  | ||||||
| pub async fn register_functions(lua: &Lua, globals: &Table, state: State) -> Result<()> { | pub fn register_functions( | ||||||
|     let l = state.event_listeners.clone(); |     lua: &Lua, | ||||||
|  |     globals: &Table, | ||||||
|  |     event_listeners: Arc<Mutex<ListenerMap>>, | ||||||
|  | ) -> Result<()> { | ||||||
|  |     let m = event_listeners.clone(); | ||||||
|     globals.set( |     globals.set( | ||||||
|         "add_listener", |         "add_listener", | ||||||
|         lua.create_function( |         lua.create_function( | ||||||
|             move |_, (event_type, callback, id): (String, Function, Option<String>)| { |             move |_, (event_type, callback, id): (String, Function, Option<String>)| { | ||||||
|                 let l = l.clone(); |                 let m = m.clone(); | ||||||
|                 tokio::spawn(async move { |                 tokio::spawn(async move { | ||||||
|                     l.lock().await.entry(event_type).or_default().push(( |                     m.lock().await.entry(event_type).or_default().push(( | ||||||
|                         id.unwrap_or(callback.info().name.unwrap_or(format!( |                         id.unwrap_or(callback.info().name.unwrap_or(format!( | ||||||
|                                 "anonymous @ {}", |                                 "anonymous @ {}", | ||||||
|                                 SystemTime::now() |                                 SystemTime::now() | ||||||
| @@ -27,21 +34,21 @@ pub async fn register_functions(lua: &Lua, globals: &Table, state: State) -> Res | |||||||
|         )?, |         )?, | ||||||
|     )?; |     )?; | ||||||
|  |  | ||||||
|     let l = state.event_listeners.clone(); |     let m = event_listeners.clone(); | ||||||
|     globals.set( |     globals.set( | ||||||
|         "remove_listener", |         "remove_listener", | ||||||
|         lua.create_function(move |_, (event_type, target_id): (String, String)| { |         lua.create_function(move |_, (event_type, target_id): (String, String)| { | ||||||
|             let l = l.clone(); |             let m = m.clone(); | ||||||
|             tokio::spawn(async move { |             tokio::spawn(async move { | ||||||
|                 let mut l = l.lock().await; |                 let mut m = m.lock().await; | ||||||
|                 let empty = if let Some(listeners) = l.get_mut(&event_type) { |                 let empty = if let Some(listeners) = m.get_mut(&event_type) { | ||||||
|                     listeners.retain(|(id, _)| target_id != *id); |                     listeners.retain(|(id, _)| target_id != *id); | ||||||
|                     listeners.is_empty() |                     listeners.is_empty() | ||||||
|                 } else { |                 } else { | ||||||
|                     false |                     false | ||||||
|                 }; |                 }; | ||||||
|                 if empty { |                 if empty { | ||||||
|                     l.remove(&event_type); |                     m.remove(&event_type); | ||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
|             Ok(()) |             Ok(()) | ||||||
| @@ -51,10 +58,10 @@ pub async fn register_functions(lua: &Lua, globals: &Table, state: State) -> Res | |||||||
|     globals.set( |     globals.set( | ||||||
|         "get_listeners", |         "get_listeners", | ||||||
|         lua.create_function(move |lua, (): ()| { |         lua.create_function(move |lua, (): ()| { | ||||||
|             let l = block_on(state.event_listeners.lock()); |             let m = block_on(event_listeners.lock()); | ||||||
|  |  | ||||||
|             let listeners = lua.create_table()?; |             let listeners = lua.create_table()?; | ||||||
|             for (event_type, callbacks) in l.iter() { |             for (event_type, callbacks) in m.iter() { | ||||||
|                 let type_listeners = lua.create_table()?; |                 let type_listeners = lua.create_table()?; | ||||||
|                 for (id, callback) in callbacks { |                 for (id, callback) in callbacks { | ||||||
|                     let listener = lua.create_table()?; |                     let listener = lua.create_table()?; | ||||||
|   | |||||||
| @@ -8,7 +8,10 @@ pub mod player; | |||||||
| pub mod system; | pub mod system; | ||||||
| pub mod vec3; | pub mod vec3; | ||||||
|  |  | ||||||
|  | use crate::ListenerMap; | ||||||
|  | use futures::lock::Mutex; | ||||||
| use mlua::{Lua, Table}; | use mlua::{Lua, Table}; | ||||||
|  | use std::{io, sync::Arc, time::Duration}; | ||||||
|  |  | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| #[allow(dead_code)] | #[allow(dead_code)] | ||||||
| @@ -18,19 +21,24 @@ pub enum Error { | |||||||
|     ExecChunk(mlua::Error), |     ExecChunk(mlua::Error), | ||||||
|     LoadChunk(mlua::Error), |     LoadChunk(mlua::Error), | ||||||
|     MissingPath(mlua::Error), |     MissingPath(mlua::Error), | ||||||
|     ReadFile(std::io::Error), |     ReadFile(io::Error), | ||||||
| } | } | ||||||
|  |  | ||||||
| pub fn register_functions(lua: &Lua, globals: &Table) -> mlua::Result<()> { | pub fn register_functions( | ||||||
|  |     lua: &Lua, | ||||||
|  |     globals: &Table, | ||||||
|  |     event_listeners: Arc<Mutex<ListenerMap>>, | ||||||
|  | ) -> mlua::Result<()> { | ||||||
|     globals.set( |     globals.set( | ||||||
|         "sleep", |         "sleep", | ||||||
|         lua.create_async_function(async |_, duration: u64| { |         lua.create_async_function(async |_, duration: u64| { | ||||||
|             tokio::time::sleep(std::time::Duration::from_millis(duration)).await; |             tokio::time::sleep(Duration::from_millis(duration)).await; | ||||||
|             Ok(()) |             Ok(()) | ||||||
|         })?, |         })?, | ||||||
|     )?; |     )?; | ||||||
|  |  | ||||||
|     block::register_functions(lua, globals)?; |     block::register_functions(lua, globals)?; | ||||||
|  |     events::register_functions(lua, globals, event_listeners)?; | ||||||
|     logging::register_functions(lua, globals)?; |     logging::register_functions(lua, globals)?; | ||||||
|     system::register_functions(lua, globals) |     system::register_functions(lua, globals) | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										43
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								src/main.rs
									
									
									
									
									
								
							| @@ -16,7 +16,6 @@ use bevy_log::{ | |||||||
| }; | }; | ||||||
| use clap::Parser; | use clap::Parser; | ||||||
| use commands::{CommandSource, register}; | use commands::{CommandSource, register}; | ||||||
| use events::handle_event; |  | ||||||
| use futures::lock::Mutex; | use futures::lock::Mutex; | ||||||
| use mlua::{Function, Lua}; | use mlua::{Function, Lua}; | ||||||
| use std::{ | use std::{ | ||||||
| @@ -43,13 +42,14 @@ pub struct State { | |||||||
| #[tokio::main] | #[tokio::main] | ||||||
| async fn main() -> anyhow::Result<()> { | async fn main() -> anyhow::Result<()> { | ||||||
|     let args = arguments::Arguments::parse(); |     let args = arguments::Arguments::parse(); | ||||||
|  |  | ||||||
|     let script_path = args.script.unwrap_or(PathBuf::from(DEFAULT_SCRIPT_PATH)); |     let script_path = args.script.unwrap_or(PathBuf::from(DEFAULT_SCRIPT_PATH)); | ||||||
|  |     let event_listeners = Arc::new(Mutex::new(HashMap::new())); | ||||||
|  |  | ||||||
|     let lua = Lua::new(); |     let lua = Lua::new(); | ||||||
|     let globals = lua.globals(); |     let globals = lua.globals(); | ||||||
|     globals.set("script_path", &*script_path)?; |     globals.set("script_path", &*script_path)?; | ||||||
|     lua::register_functions(&lua, &globals)?; |     lua::register_functions(&lua, &globals, event_listeners.clone())?; | ||||||
|  |  | ||||||
|     lua.load( |     lua.load( | ||||||
|         read_to_string(script_path) |         read_to_string(script_path) | ||||||
|             .expect(&(DEFAULT_SCRIPT_PATH.to_owned() + " should be in current directory")), |             .expect(&(DEFAULT_SCRIPT_PATH.to_owned() + " should be in current directory")), | ||||||
| @@ -65,28 +65,29 @@ async fn main() -> anyhow::Result<()> { | |||||||
|     let mut commands = CommandDispatcher::new(); |     let mut commands = CommandDispatcher::new(); | ||||||
|     register(&mut commands); |     register(&mut commands); | ||||||
|  |  | ||||||
|  |     let log_plugin = LogPlugin { | ||||||
|  |         custom_layer: |_| { | ||||||
|  |             env::var("LOG_FILE").ok().map(|log_file| { | ||||||
|  |                 layer() | ||||||
|  |                     .with_writer( | ||||||
|  |                         OpenOptions::new() | ||||||
|  |                             .append(true) | ||||||
|  |                             .create(true) | ||||||
|  |                             .open(log_file) | ||||||
|  |                             .expect("should have been able to open log file"), | ||||||
|  |                     ) | ||||||
|  |                     .boxed() | ||||||
|  |             }) | ||||||
|  |         }, | ||||||
|  |         ..Default::default() | ||||||
|  |     }; | ||||||
|     let Err(error) = ClientBuilder::new_without_plugins() |     let Err(error) = ClientBuilder::new_without_plugins() | ||||||
|         .add_plugins(DefaultPlugins.set(LogPlugin { |         .add_plugins(DefaultPlugins.set(log_plugin)) | ||||||
|             custom_layer: |_| { |  | ||||||
|                 env::var("LOG_FILE").ok().map(|log_file| { |  | ||||||
|                     layer() |  | ||||||
|                         .with_writer( |  | ||||||
|                             OpenOptions::new() |  | ||||||
|                                 .append(true) |  | ||||||
|                                 .create(true) |  | ||||||
|                                 .open(log_file) |  | ||||||
|                                 .expect("should have been able to open log file"), |  | ||||||
|                         ) |  | ||||||
|                         .boxed() |  | ||||||
|                 }) |  | ||||||
|             }, |  | ||||||
|             ..Default::default() |  | ||||||
|         })) |  | ||||||
|         .add_plugins(DefaultBotPlugins) |         .add_plugins(DefaultBotPlugins) | ||||||
|         .set_handler(handle_event) |         .set_handler(events::handle_event) | ||||||
|         .set_state(State { |         .set_state(State { | ||||||
|             lua, |             lua, | ||||||
|             event_listeners: Arc::new(Mutex::new(HashMap::new())), |             event_listeners, | ||||||
|             commands: Arc::new(commands), |             commands: Arc::new(commands), | ||||||
|             http_address: args.http_address, |             http_address: args.http_address, | ||||||
|         }) |         }) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user