Updated arg system & made websocked somehow work???
This commit is contained in:
@@ -6,10 +6,12 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
clap = { version = "4.5.28", features = ["derive"] }
|
||||||
futures = "0.3.31"
|
futures = "0.3.31"
|
||||||
poise = "0.6.1"
|
poise = "0.6.1"
|
||||||
pyo3 = "0.23.4"
|
pyo3 = "0.23.4"
|
||||||
rand = "0.9.0"
|
rand = "0.9.0"
|
||||||
|
serde = "1.0.217"
|
||||||
serde_json = "1.0.138"
|
serde_json = "1.0.138"
|
||||||
tokio = { version = "1.43.0", features = ["rt-multi-thread"] }
|
tokio = { version = "1.43.0", features = ["rt-multi-thread"] }
|
||||||
tokio-tungstenite = "0.26.1"
|
tokio-tungstenite = "0.26.1"
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ use crate::messages::send_msg;
|
|||||||
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
|
|
||||||
#[poise::command(slash_command, prefix_command)]
|
#[poise::command(slash_command, prefix_command)]
|
||||||
pub async fn bk_week_help(
|
pub async fn bk_week_help(
|
||||||
ctx: Context<'_>,
|
ctx: Context<'_>,
|
||||||
|
|||||||
+1
-2
@@ -25,8 +25,7 @@ pub async fn stop(
|
|||||||
#[description = "Type \"i want to stop the bot now\" to confirm."] confirmation: Option<String>,
|
#[description = "Type \"i want to stop the bot now\" to confirm."] confirmation: Option<String>,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
{
|
{
|
||||||
let dev_enabled = ctx.data().dev;
|
let should_stop = ctx.data().args.dev
|
||||||
let should_stop = dev_enabled
|
|
||||||
|| confirmation.unwrap_or_else(|| "".to_string()).to_lowercase() == "i want to stop the bot now";
|
|| confirmation.unwrap_or_else(|| "".to_string()).to_lowercase() == "i want to stop the bot now";
|
||||||
|
|
||||||
let is_creator = ctx.author().id == UserId::new(ctx.data().creator_id);
|
let is_creator = ctx.author().id == UserId::new(ctx.data().creator_id);
|
||||||
|
|||||||
@@ -22,3 +22,16 @@ macro_rules! rs_errln {
|
|||||||
process::exit(-1);
|
process::exit(-1);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! errln {
|
||||||
|
($($arg:tt)*) => {
|
||||||
|
println!("{}ERROR{} - {}",
|
||||||
|
"\x1b[41m",
|
||||||
|
"\x1b[0m",
|
||||||
|
format!($($arg)*)
|
||||||
|
);
|
||||||
|
process::exit(-1);
|
||||||
|
};
|
||||||
|
}
|
||||||
+36
-29
@@ -1,6 +1,7 @@
|
|||||||
#![warn(unused_extern_crates)]
|
#![warn(unused_extern_crates)]
|
||||||
|
|
||||||
mod cmds;
|
mod cmds;
|
||||||
|
#[allow(unused_variables)]
|
||||||
mod bk_week_cmds;
|
mod bk_week_cmds;
|
||||||
mod events;
|
mod events;
|
||||||
mod messages;
|
mod messages;
|
||||||
@@ -8,21 +9,35 @@ mod python;
|
|||||||
mod macros;
|
mod macros;
|
||||||
mod websocket;
|
mod websocket;
|
||||||
|
|
||||||
use std::env;
|
|
||||||
use std::process;
|
use std::process;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::fs;
|
|
||||||
|
|
||||||
use tokio::runtime::Runtime;
|
use clap::Parser;
|
||||||
use poise::serenity_prelude::Client;
|
|
||||||
use poise::serenity_prelude as serenity;
|
use poise::serenity_prelude as serenity;
|
||||||
|
use poise::serenity_prelude::Client;
|
||||||
|
use serde::Serialize;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
use tokio::runtime::Runtime;
|
||||||
|
use serde_json;
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Parser, Serialize, Clone)]
|
||||||
|
struct Args {
|
||||||
|
#[arg(short = 'p', long, default_value = "2920", help = "Sets the port number, e.g 2200.")]
|
||||||
|
port: u16,
|
||||||
|
#[arg(long, help = "Runs only the Python part of the program.")]
|
||||||
|
py: bool,
|
||||||
|
#[arg(long, help = "Runs only the Rust part of the program.")]
|
||||||
|
rs: bool,
|
||||||
|
#[arg(short = 'd', long, help = "Enables dev mode. Dev mode shows more debug info and turns of certain security measures.")]
|
||||||
|
dev: bool
|
||||||
|
}
|
||||||
|
|
||||||
struct Data {
|
struct Data {
|
||||||
dev: bool,
|
|
||||||
ball_prompts: [Vec<String>; 2],
|
ball_prompts: [Vec<String>; 2],
|
||||||
creator_id: u64,
|
creator_id: u64,
|
||||||
reddit_data: Option<Value>,
|
reddit_data: Option<Value>,
|
||||||
|
args: Args
|
||||||
// TODO: schedules
|
// TODO: schedules
|
||||||
}
|
}
|
||||||
type Error = Box<dyn std::error::Error + Send + Sync>;
|
type Error = Box<dyn std::error::Error + Send + Sync>;
|
||||||
@@ -31,38 +46,32 @@ type Context<'a> = poise::Context<'a, Data, Error>;
|
|||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let args: Vec<String> = env::args().collect();
|
let args = <Args as clap::Parser>::parse();
|
||||||
|
let args_str = serde_json::to_string(&args).expect("Error serializing args to JSON");
|
||||||
|
|
||||||
if args.contains(&"--h".to_string()) || args.contains(&"--help".to_string()) {
|
if args.dev { println!("----- DEV MODE ENABLED -----"); rs_println!("ARGS: {}", args_str); }
|
||||||
let help = fs::read_to_string("./help.txt").unwrap_or_else(|_| "No help.txt file found.".to_string());
|
|
||||||
println!("HELP MENU:\n{}", help);
|
|
||||||
process::exit(1);
|
|
||||||
}
|
|
||||||
if args.contains(&"--dev".to_string()) { println!("----- DEV MODE ENABLED -----"); }
|
|
||||||
|
|
||||||
if args.contains(&"--py".to_string())
|
if args.py && !args.rs {
|
||||||
&& !args.contains(&"--rs".to_string())
|
|
||||||
{
|
|
||||||
println!("----- PYTHON ONLY MODE -----");
|
println!("----- PYTHON ONLY MODE -----");
|
||||||
let _ = python::start(args);
|
let _ = python::start(args_str);
|
||||||
process::exit(0);
|
process::exit(0);
|
||||||
}
|
}
|
||||||
else if args.contains(&"--rs".to_string())
|
else if args.rs && ! args.py {
|
||||||
&& ! args.contains(&"--py".to_string())
|
|
||||||
{
|
|
||||||
println!("----- RUST ONLY MODE -----");
|
println!("----- RUST ONLY MODE -----");
|
||||||
start(args).await;
|
start(args).await;
|
||||||
process::exit(0);
|
process::exit(0);
|
||||||
}
|
}
|
||||||
|
else if args.py && args.rs {
|
||||||
|
errln!("Invalid arguments: Arguments cannot include both --rs and --py.");
|
||||||
|
}
|
||||||
|
|
||||||
let rt = Runtime::new().unwrap();
|
let rt = Runtime::new().unwrap();
|
||||||
let rust_args = args.clone();
|
let python_args = args_str;
|
||||||
let python_args = args.clone();
|
|
||||||
|
|
||||||
let rust = thread::spawn(move || {
|
let rust = thread::spawn(move || {
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
websocket::start(rust_args.clone()).await;
|
websocket::start(args.clone()).await;
|
||||||
start(rust_args).await;
|
start(args).await;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -75,9 +84,7 @@ async fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async fn start(args: Vec<String>) {
|
async fn start(args: Args) {
|
||||||
rs_println!("ARGS: {:?}", &args[1..]);
|
|
||||||
|
|
||||||
let data = gen_data(args);
|
let data = gen_data(args);
|
||||||
let mut bot = gen_bot(data).await;
|
let mut bot = gen_bot(data).await;
|
||||||
|
|
||||||
@@ -86,7 +93,7 @@ async fn start(args: Vec<String>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn gen_data(args: Vec<String>) -> Data {
|
fn gen_data(args: Args) -> Data {
|
||||||
let ball_classic_str = std::fs::read_to_string("./data/8-ball_classic.txt").unwrap();
|
let ball_classic_str = std::fs::read_to_string("./data/8-ball_classic.txt").unwrap();
|
||||||
let ball_quirk_str = std::fs::read_to_string("./data/8-ball_quirky.txt").unwrap();
|
let ball_quirk_str = std::fs::read_to_string("./data/8-ball_quirky.txt").unwrap();
|
||||||
|
|
||||||
@@ -94,10 +101,10 @@ fn gen_data(args: Vec<String>) -> Data {
|
|||||||
let ball_quirk: Vec<String> = ball_quirk_str .lines().map(String::from).collect();
|
let ball_quirk: Vec<String> = ball_quirk_str .lines().map(String::from).collect();
|
||||||
|
|
||||||
return Data {
|
return Data {
|
||||||
dev: args.contains(&"--dev".to_string()),
|
|
||||||
ball_prompts: [ball_classic, ball_quirk],
|
ball_prompts: [ball_classic, ball_quirk],
|
||||||
creator_id: 697149665166229614,
|
creator_id: 697149665166229614,
|
||||||
reddit_data: None
|
reddit_data: None,
|
||||||
|
args
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-3
@@ -8,13 +8,14 @@ use pyo3::prelude::*;
|
|||||||
use pyo3::types::PyList;
|
use pyo3::types::PyList;
|
||||||
|
|
||||||
|
|
||||||
pub fn start(args: Vec<String>) -> PyResult<()> {
|
pub fn start(args: String) -> PyResult<()> {
|
||||||
rs_println!("Running Python program...");
|
rs_println!("Running Python program...");
|
||||||
|
|
||||||
let path = concat!(env!("CARGO_MANIFEST_DIR"), "\\src\\python");
|
let path = concat!(env!("CARGO_MANIFEST_DIR"), "\\src\\python");
|
||||||
|
|
||||||
let code = get_code(&(path.to_owned() + "\\main.py"));
|
let code = get_code(&(path.to_owned() + "\\main.py"));
|
||||||
let app_path = CString::new(format!("args = {:?}\n{}", args, code)).unwrap();
|
let py_args = args.replace(":true", ":True").replace(":false", ":False");
|
||||||
|
let app_path = CString::new(format!("args = {}\n{}", py_args, code)).unwrap();
|
||||||
|
|
||||||
pyo3::prepare_freethreaded_python();
|
pyo3::prepare_freethreaded_python();
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ pub fn start(args: Vec<String>) -> PyResult<()> {
|
|||||||
return app.call0(py);
|
return app.call0(py);
|
||||||
});
|
});
|
||||||
|
|
||||||
println!("py: {}", from_python?);
|
if from_python.is_err() { println!("py: {:?}", from_python); }
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -6,7 +6,7 @@ import os
|
|||||||
from macros import *
|
from macros import *
|
||||||
|
|
||||||
class Bot:
|
class Bot:
|
||||||
args: list[str] = ["NO_RUST", "--dev", "--py"]
|
args: dict = {"NO_RUST": True, "dev": True, "py": True, "port": 2920}
|
||||||
password: str = os.environ.get("ASSISTANT_R_PASS")
|
password: str = os.environ.get("ASSISTANT_R_PASS")
|
||||||
secret: str = os.environ.get("ASSISTANT_R_TOKEN")
|
secret: str = os.environ.get("ASSISTANT_R_TOKEN")
|
||||||
|
|
||||||
@@ -26,5 +26,5 @@ class Bot:
|
|||||||
data_f: TextIOWrapper = None
|
data_f: TextIOWrapper = None
|
||||||
data: dict = {}
|
data: dict = {}
|
||||||
|
|
||||||
def set_args(self, args: list[str]):
|
def set_args(self, args: dict):
|
||||||
self.args = args
|
self.args = args
|
||||||
+5
-4
@@ -15,15 +15,16 @@ def main():
|
|||||||
except NameError:
|
except NameError:
|
||||||
py_print("No command args found from Rust. Don't worry though, we have backup in place.")
|
py_print("No command args found from Rust. Don't worry though, we have backup in place.")
|
||||||
|
|
||||||
py_print("ARGS:", str(bot.args[1:]))
|
if bot.args["dev"]:
|
||||||
|
py_print("ARGS:", str(bot.args))
|
||||||
py_print("Reading data...")
|
py_print("Reading data...")
|
||||||
data.read_data(bot)
|
data.read_data(bot)
|
||||||
|
|
||||||
if "--py" not in bot.args:
|
if True: #bot.args["py"]:
|
||||||
py_print("Connecting to local websocket...")
|
py_print("Connecting to local websocket...")
|
||||||
asyncio.run(py_websocket.websocket_client())
|
asyncio.run(py_websocket.websocket_client(bot))
|
||||||
|
|
||||||
py_websocket.send_message("[Connection test] Hello from Python!")
|
#py_websocket.send_message("[Connection test] Hello from Python!")
|
||||||
|
|
||||||
|
|
||||||
main()
|
main()
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import websockets
|
import websockets
|
||||||
from macros import py_print
|
from macros import py_print
|
||||||
|
import bot as botPy
|
||||||
|
|
||||||
ws_global = None
|
ws_global = None
|
||||||
|
|
||||||
@@ -9,11 +10,11 @@ async def send_message(message: str):
|
|||||||
await ws_global.send(message)
|
await ws_global.send(message)
|
||||||
|
|
||||||
|
|
||||||
async def websocket_client():
|
async def websocket_client(bot: botPy.Bot):
|
||||||
global ws_global
|
global ws_global
|
||||||
async with websockets.connect("ws://127.0.0.1:9001") as ws:
|
async with websockets.connect(f"ws://127.0.0.1:{bot.args["port"]}") as ws:
|
||||||
ws_global = ws
|
ws_global = ws
|
||||||
py_print("Connected webSocket server on ws://127.0.0.1:9001")
|
py_print(f"Connected webSocket server on ws://127.0.0.1:{bot.args["port"]}")
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
response = await ws.recv()
|
response = await ws.recv()
|
||||||
|
|||||||
+10
-8
@@ -6,6 +6,7 @@ use futures::StreamExt;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::rs_println;
|
use crate::rs_println;
|
||||||
|
use crate::Args;
|
||||||
|
|
||||||
type Sender = Arc<Mutex<Option<futures::stream::SplitSink<tokio_tungstenite::WebSocketStream<tokio::net::TcpStream>, tungstenite::Message>>>>;
|
type Sender = Arc<Mutex<Option<futures::stream::SplitSink<tokio_tungstenite::WebSocketStream<tokio::net::TcpStream>, tungstenite::Message>>>>;
|
||||||
|
|
||||||
@@ -32,16 +33,17 @@ pub async fn send_msg(msg: &str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub async fn start(args: Vec<String>) {
|
pub async fn start(args: Args) {
|
||||||
rs_println!("Starting local websocket...");
|
rs_println!("Starting local websocket...");
|
||||||
let listener = TcpListener::bind("127.0.0.1:9001").await.unwrap();
|
let ip = format!("127.0.0.1:{}", args.port);
|
||||||
rs_println!("WebSocket server running on ws://127.0.0.1:9001");
|
let listener = TcpListener::bind(&ip).await.unwrap();
|
||||||
|
rs_println!("WebSocket server running on ws://{}", ip);
|
||||||
|
|
||||||
tokio::spawn(handle_connections(listener, args));
|
tokio::spawn(handle_connections(listener, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async fn handle_connections(listener: TcpListener, args: Vec<String>) {
|
async fn handle_connections(listener: TcpListener, args: Args) {
|
||||||
while let Ok((stream, _)) = listener.accept().await {
|
while let Ok((stream, _)) = listener.accept().await {
|
||||||
let ws_stream = accept_async(stream).await.unwrap();
|
let ws_stream = accept_async(stream).await.unwrap();
|
||||||
let (sender, mut receiver) = ws_stream.split();
|
let (sender, mut receiver) = ws_stream.split();
|
||||||
@@ -50,13 +52,13 @@ async fn handle_connections(listener: TcpListener, args: Vec<String>) {
|
|||||||
set_sender(sender_arc.clone()).await;
|
set_sender(sender_arc.clone()).await;
|
||||||
|
|
||||||
while let Some(Ok(msg)) = receiver.next().await {
|
while let Some(Ok(msg)) = receiver.next().await {
|
||||||
handle_message(msg, &args).await;
|
handle_message(msg, args.clone()).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async fn handle_message(msg: tungstenite::protocol::Message, args: &[String]) {
|
async fn handle_message(msg: tungstenite::protocol::Message, args: Args) {
|
||||||
match msg {
|
match msg {
|
||||||
tungstenite::Message::Text(text) => {
|
tungstenite::Message::Text(text) => {
|
||||||
rs_println!("Received from Python: {}", text);
|
rs_println!("Received from Python: {}", text);
|
||||||
@@ -70,12 +72,12 @@ async fn handle_message(msg: tungstenite::protocol::Message, args: &[String]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
tungstenite::Message::Binary(bytes) => {
|
tungstenite::Message::Binary(bytes) => {
|
||||||
if args.contains(&"--dev".to_string()) {
|
if args.dev {
|
||||||
rs_println!("[Binary] from Python: {:?}", bytes);
|
rs_println!("[Binary] from Python: {:?}", bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if args.contains(&"--dev".to_string()) {
|
if args.dev {
|
||||||
rs_println!("Received from Python: [UNKNOWN / OTHER]");
|
rs_println!("Received from Python: [UNKNOWN / OTHER]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user