Added CLI

This commit is contained in:
2025-12-21 14:43:48 +01:00
parent f5a6b01399
commit 8062cfc8fa
4 changed files with 115 additions and 22 deletions
Vendored
BIN
View File
Binary file not shown.
+104
View File
@@ -0,0 +1,104 @@
use std::{fs::File, io, path::PathBuf, str::FromStr, sync::Arc};
use zip::ZipArchive;
use crate::{logger, plugin::loader::PluginLoader, server::Server};
logger!(LOGGER "CLI");
pub fn parse_args(input: &str) -> Vec<String> {
let mut args = Vec::new();
let mut current = String::new();
let mut in_dq = false;
let mut in_q = false;
let mut escape = false;
for c in input.chars() {
if escape {
current.push(c);
escape = false;
continue;
}
match c {
'\\' => {
escape = true;
}
'"' if !in_q && !escape => {
in_dq = !in_dq;
}
'\'' if !in_dq && !escape => {
in_q = !in_q;
}
' ' if !in_dq && !in_q => {
if !current.is_empty() {
args.push(current.clone());
current.clear();
}
}
_ => {
current.push(c);
}
}
}
if escape {
current.push('\\');
}
if !current.is_empty() {
args.push(current);
}
args
}
pub fn require_args(args: &[String], required: &[&str]) -> bool {
if required.len() + 1 > args.len() {
LOGGER.error(format!("Required arguments: {}", required.join(" ")));
return false;
}
true
}
pub fn start_cli(server: Arc<Server>, plugin_loader: PluginLoader) {
std::thread::spawn(move || {
loop {
let mut buf = String::new();
io::stdin().read_line(&mut buf).unwrap();
let args = parse_args(buf.trim());
if args.len() == 0 {
continue;
}
match args[0].as_str() {
"install" => {
if require_args(&args, &["<path.vxp>"]) {
let path = PathBuf::from_str(&args[1]).unwrap();
if path.extension().and_then(|s| s.to_str()) == Some("vxp") {
LOGGER.info(format!("Installing {:?}", path));
let d = path.with_extension("");
if !d.exists() {
let file = File::open(&path).unwrap();
let mut archive = ZipArchive::new(file).unwrap();
archive.extract(&d).unwrap();
}
} else {
LOGGER.error("File must be .vxp");
}
}
}
"load" => {
if require_args(&args, &["<plugin-dir>"]) {
plugin_loader.load(&server.root.join("plugins").join(&args[1]));
}
}
_ => {
LOGGER.error(format!("Command not found ({})", args[0]));
}
}
}
});
}
+1
View File
@@ -1,3 +1,4 @@
mod cli;
mod macros;
mod plugin;
mod requests;
+10 -22
View File
@@ -1,16 +1,14 @@
use std::{
collections::HashSet,
fs::{self, File},
fs::{self},
net::{TcpListener, TcpStream},
path::{Path, PathBuf},
sync::{Arc, Mutex},
};
use zip::ZipArchive;
use crate::{
logger,
plugin::{self, Plugin, loader::PluginLoader, types::LoaderMessage},
cli, logger,
plugin::{Plugin, loader::PluginLoader, types::LoaderMessage},
types,
utils::{self, client::Client},
};
@@ -80,22 +78,8 @@ impl Server {
let entry = entry?;
let path = entry.path();
let p = if path.extension().and_then(|s| s.to_str()) == Some("vxp") {
plugin::loader::LOGGER.info(format!("Installing {:?}", path));
let d = path.with_extension("");
if !d.exists() {
let file = File::open(&path)?;
let mut archive = ZipArchive::new(file)?;
archive.extract(&d)?;
}
d
} else {
path
};
if p.is_dir() {
let mut p = plugin_loader.load(&p);
if path.is_dir() {
let mut p = plugin_loader.load(&path);
let s = self.clone();
self.plugins.lock().unwrap().push(p.clone());
std::thread::spawn(move || p.run(&s));
@@ -106,6 +90,10 @@ impl Server {
// Initialize plugins
Self::LOGGER.info("Initializing plugins");
// Initialize CLI
Self::LOGGER.info("Initializing CLI");
cli::start_cli(self.clone(), plugin_loader);
// Start server
let listener = TcpListener::bind(format!("0.0.0.0:{}", self.config.port))?;
Self::LOGGER.info(format!("Server listening at 0.0.0.0:{}", self.config.port));
@@ -223,7 +211,7 @@ impl Server {
res
}
pub fn send_plugin_message(&self, msg: &LoaderMessage) -> crate::Result<()> {
pub fn send_plugin_message(self: &Arc<Self>, msg: &LoaderMessage) -> crate::Result<()> {
for p in self.plugins.lock().unwrap().iter_mut() {
p.send(msg)?;
}