plugin_lua_cygnixy/
lib.rs1use cygnixy_plugin_interface::{export_plugin, PluginLua};
2use mlua::prelude::LuaError;
3use mlua::{Function, Lua};
4use serenity::all::{ExecuteWebhook, Http, Webhook};
5use std::collections::HashMap;
6use std::error::Error;
7use tokio::runtime::Builder;
8use tracing::{debug, error, info, trace, warn};
9
10pub struct PluginLuaCygnixy;
11
12impl Default for PluginLuaCygnixy {
13 fn default() -> Self {
14 Self
15 }
16}
17
18impl PluginLuaCygnixy {
19 pub fn new() -> Self {
20 PluginLuaCygnixy
21 }
22}
23
24impl PluginLua for PluginLuaCygnixy {
25 fn name(&self) -> &str {
26 "cygnixy"
27 }
28
29 fn on_load(&mut self) -> Result<(), Box<dyn Error>> {
30 trace!("PluginLuaCygnixy loaded!");
31 Ok(())
32 }
33
34 fn on_unload(&mut self) -> Result<(), Box<dyn Error>> {
35 trace!("PluginLuaCygnixy unloaded!");
36 Ok(())
37 }
38
39 fn get_lua_functions(&self, lua: &Lua, name: &str) -> HashMap<String, Function> {
40 let mut functions = HashMap::new();
41
42 if let Err(e) = self.register_functions(lua, name, &mut functions) {
43 error!("Failed to register Lua functions: {}", e);
44 }
45
46 functions
47 }
48}
49
50impl PluginLuaCygnixy {
51 fn register_functions(
52 &self,
53 lua: &Lua,
54 name: &str,
55 functions: &mut HashMap<String, Function>,
56 ) -> Result<(), Box<dyn Error>> {
57 let span = tracing::span!(tracing::Level::DEBUG, "lua", uuid = ?name);
58
59 functions.insert(
61 "sleep".to_string(),
62 lua.create_function(|_, n: u64| {
63 std::thread::sleep(std::time::Duration::from_millis(n));
64 Ok(())
65 })?,
66 );
67
68 #[allow(unused_variables)]
70 functions.insert(
71 "mouse_move".to_string(),
72 lua.create_function(|_, (x, y): (i32, i32)| {
73 #[cfg(target_os = "windows")]
74 control_craft::set_cursor_pos(x, y);
75 Ok(())
76 })?,
77 );
78
79 #[allow(unused_variables)]
81 functions.insert(
82 "drag_and_drop".to_string(),
83 lua.create_function(|_, (x, y): (i32, i32)| {
84 #[cfg(target_os = "windows")]
85 control_craft::drag_and_drop(x, y);
86 Ok(())
87 })?,
88 );
89
90 functions.insert(
92 "mouse_click_left".to_string(),
93 lua.create_function(|_, ()| {
94 #[cfg(target_os = "windows")]
95 control_craft::click_mouse_button_left();
96 Ok(())
97 })?,
98 );
99
100 functions.insert(
102 "mouse_click_right".to_string(),
103 lua.create_function(|_, ()| {
104 #[cfg(target_os = "windows")]
105 control_craft::click_mouse_button_right();
106 Ok(())
107 })?,
108 );
109
110 #[allow(unused_variables)]
112 functions.insert(
113 "press_key".to_string(),
114 lua.create_function(|_, key: u8| {
115 #[cfg(target_os = "windows")]
116 control_craft::press_key(key);
117 Ok(())
118 })?,
119 );
120
121 functions.insert(
123 "info".to_string(),
124 lua.create_function({
125 let span = span.clone();
126 move |_, message: String| {
127 let _enter = span.enter();
128 info!("{}", message);
129 Ok(())
130 }
131 })?,
132 );
133
134 functions.insert(
136 "warn".to_string(),
137 lua.create_function({
138 let span = span.clone();
139 move |_, message: String| {
140 let _enter = span.enter();
141 warn!("{}", message);
142 Ok(())
143 }
144 })?,
145 );
146
147 functions.insert(
149 "trace".to_string(),
150 lua.create_function({
151 let span = span.clone();
152 move |_, message: String| {
153 let _enter = span.enter();
154 trace!("{}", message);
155 Ok(())
156 }
157 })?,
158 );
159
160 functions.insert(
162 "debug".to_string(),
163 lua.create_function({
164 let span = span.clone();
165 move |_, message: String| {
166 let _enter = span.enter();
167 debug!("{}", message);
168 Ok(())
169 }
170 })?,
171 );
172
173 functions.insert(
175 "error".to_string(),
176 lua.create_function({
177 let span = span.clone();
178 move |_, message: String| {
179 let _enter = span.enter();
180 error!("{}", message);
181 Ok(())
182 }
183 })?,
184 );
185
186 functions.insert(
188 "discord_send".to_string(),
189 lua.create_function(
190 |_, (webhook_url, username, message): (String, String, String)| {
191 if webhook_url.trim().is_empty() {
192 return Ok(());
193 }
194 if username.trim().is_empty() {
195 return Ok(());
196 }
197 if message.trim().is_empty() {
198 return Ok(());
199 }
200
201 let runtime = Builder::new_current_thread().enable_all().build().unwrap();
203
204 let result = runtime.block_on(async {
205 let http = Http::new("");
206 let webhook = Webhook::from_url(&http, &webhook_url)
207 .await
208 .map_err(|e| format!("Failed to load webhook: {}", e))?;
209
210 let builder = ExecuteWebhook::new().content(&message).username(&username);
211
212 webhook
213 .execute(&http, false, builder)
214 .await
215 .map_err(|e| format!("Failed to execute webhook: {}", e))
216 });
217
218 match result {
220 Ok(_) => Ok(()),
221 Err(err) => Err(LuaError::external(err)),
222 }
223 },
224 )?,
225 );
226
227 Ok(())
228 }
229}
230
231export_plugin!(PluginLuaCygnixy);