use log::trace;
use mlua::Lua;
use crate::config::{entity_ro, Dandelion};
use crate::{dynload, security, transmit};
use crate::dynload::runtime;
use crate::security::detailed_restrict::enable_detailed_restrict_fio;
use crate::security::env_modify;
use crate::security::env_modify::LuaApis;
pub fn init_runtime(entity: &entity_ro, flags: Vec<String>) -> Result<(), mlua::Error> {
let lua = Lua::new();
let work_path = &entity.pkg_path;
let pkg = Dandelion::autofill(work_path);
trace!("限制模块加载路径");
dynload::restrict_module_load_path(&pkg, &lua)?;
trace!("加载用户 mint 或 wing 模块");
let package_path: String = lua.globals().get("package.path").unwrap_or_default();
let package_cpath: String = lua.globals().get("package.cpath").unwrap_or_default();
log::trace!("package.path: {}", package_path);
log::trace!("package.cpath: {}", package_cpath);
lua.load(dynload::generate_lua_script_for_lib_loading(entity.lua_access_no_suffix.clone())).exec()?;
trace!("加载 lua 的 c 拓展");
lua.load(dynload::generate_lua_script_for_lib_loading(entity.native_access_no_suffix.clone())).exec()?;
if !security::check_exec::check_executable_lua_file(&entity.executor_script_or_compiled) {
eprintln!("[ERROR] Executor 不可执行:{}", &entity.executor_script_or_compiled);
std::process::exit(1);
}
let executor_bytecode = std::fs::read(&entity.executor_script_or_compiled).unwrap_or_else(|e| {
eprintln!("[ERROR] 读取 executor 字节码失败:{}", e);
std::process::exit(1);
});
log::info!("Loading executor bytecode from: {}", &entity.executor_script_or_compiled);
lua.load(executor_bytecode).exec().unwrap_or_else(|e| {
eprintln!("[ERROR] 执行 executor 字节码失败:{}", e);
std::process::exit(1);
});
log::info!("Executor loaded successfully");
log::debug!("About to call batch_hook_sec...");
let hook_task = security::generate_basic_ctrl_hook_task(&entity.basic_authority); env_modify::batch_hook_sec(&lua, hook_task).unwrap_or_else(|e| {
eprintln!("[ERROR] batch_hook_sec 失败:{}", e);
std::process::exit(1);
});
log::debug!("batch_hook_sec completed");
enable_detailed_restrict_fio(&lua, &entity.file_access_allow, &entity.command_allow).unwrap_or_else(|e| {
eprintln!("[ERROR] 启用详细限制失败:{}", e);
std::process::exit(1);
});
env_modify::deny_module_except(&lua, LuaApis::new()).unwrap_or_else(|e| {
eprintln!("[ERROR] 禁用模块失败:{}", e);
std::process::exit(1);
});
let rt_log_mod = lua.create_table()?;
rt_log_mod.set("info", lua.create_function(|_, loginfo: String| -> Result<Option<String>, mlua::Error> {
Ok(crate::dynload::runtime::log::log_info(loginfo))
})?)?;
rt_log_mod.set("warn", lua.create_function(|_, loginfo: String| -> Result<Option<String>, mlua::Error> {
Ok(crate::dynload::runtime::log::log_warn(loginfo))
})?)?;
rt_log_mod.set("error", lua.create_function(|_, loginfo: String| -> Result<Option<String>, mlua::Error> {
Ok(crate::dynload::runtime::log::log_error(loginfo))
})?)?;
rt_log_mod.set("trace", lua.create_function(|_, loginfo: String| -> Result<Option<String>, mlua::Error> {
Ok(crate::dynload::runtime::log::log_trace(loginfo))
})?)?;
let runtime = lua.create_table()?;
runtime.set("log", rt_log_mod)?;
let _transmit_manager = transmit::init_transmit(&lua, &runtime)?;
lua.globals().set("runtime", runtime)?;
let args_table = lua.create_table()?;
for (index, flag) in flags.iter().enumerate() {
args_table.set(index + 1, flag.clone())?;
}
lua.globals().set("args", args_table)?;
let user_script = std::fs::read_to_string(entity.thinker_script.clone()).unwrap_or_else(|e| {
eprintln!("[ERROR] 读取用户脚本失败:{}", e);
std::process::exit(1);
});
log::info!("加载用户脚本:{}", entity.thinker_script);
lua.load(user_script).exec().unwrap_or_else(|e| {
eprintln!("[ERROR] 执行用户脚本失败:{}", e);
std::process::exit(1);
});
log::info!("用户脚本执行完成");
Ok(())
}