From 14115755255dc710dd4e5ac2200a83d3cd488971 Mon Sep 17 00:00:00 2001 From: Eric Galvan Date: Sun, 5 Nov 2023 18:04:05 -0800 Subject: [PATCH] can now load/execute multiple scripts --- EmuAPI/EmuAPI.vcproj | 8 +++ EmuAPI/EmuLoader.cpp | 19 +---- EmuAPI/emu/EmuConsole.cpp | 35 ++++----- EmuAPI/emu/EmuScriptMgr.cpp | 139 +++++++++++++++++++++--------------- EmuAPI/emu/EmuScriptMgr.h | 20 ++++-- 5 files changed, 117 insertions(+), 104 deletions(-) diff --git a/EmuAPI/EmuAPI.vcproj b/EmuAPI/EmuAPI.vcproj index 35eab8a..ba67e44 100644 --- a/EmuAPI/EmuAPI.vcproj +++ b/EmuAPI/EmuAPI.vcproj @@ -204,6 +204,10 @@ RelativePath=".\emu\EmuRegister.cpp" > + + + + @@ -17,33 +16,25 @@ void EmuConsole::tokenize() { std::string token = ""; // TODO: fix try/catch. Crashes if error found. - try + if (!std::getline(std::cin, token)) { + return; + } + + if (token.size() > 100) { - - std::getline(std::cin, token); + // this limit will be increased, it's just a pre-emptive measure + std::cout << "100 char limit in buffer. Please try again." << std::endl; + // std::cin.ignore(32767, '\n'); + } else { + std::istringstream iss(token); - if (token.size() > 100) + while (std::getline(iss, token, ' ')) { - // this limit will be increased, it's just a pre-emptive measure - std::cout << "100 char limit in buffer. Please try again." << std::endl; - throw; + tokens.push_back(token); } } - catch(const std::exception& e) - { - std::cout << e.what() << std::endl; - token = ""; - std::cin.clear(); - std::getline(std::cin, token); - - } - - std::istringstream iss(token); - while (std::getline(iss, token, ' ')) - { - tokens.push_back(token); - } + } /// diff --git a/EmuAPI/emu/EmuScriptMgr.cpp b/EmuAPI/emu/EmuScriptMgr.cpp index 071da7a..51f4622 100644 --- a/EmuAPI/emu/EmuScriptMgr.cpp +++ b/EmuAPI/emu/EmuScriptMgr.cpp @@ -1,15 +1,22 @@ #include "EmuScriptMgr.h" -// EmuScriptMgr::EmuScriptMgr() { - +// EmuScriptMgr::EmuScriptMgr() : lua(NULL), f(std::ofstream("out.log", std::ios_base::app)), timestamp(*new char) { +// // do not use default constructor // } -EmuScriptMgr::EmuScriptMgr(lua_State* lua, std::ofstream& fs) : lua(lua), f(fs) { +EmuScriptMgr::EmuScriptMgr(std::ofstream& fs, char* ts) : f(fs), timestamp(ts) { + //------ Initializing Lua + lua = luaL_newstate(); // Open Lua + int iErr = 0; + if (!lua) { + f << "[" << timestamp << "] " << "Failed to create Lua state." << std::endl; + } + + //------ Register API functions to Lua + RegZooState::register_zoo_state(lua); - //------ Timestamp for logging - *t = std::time(0); - timestamp = new char[80]; // timestamp buffer - std::strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", std::localtime(t)); + //------ Load Lua libraries + luaL_openlibs (lua); } EmuScriptMgr::~EmuScriptMgr() { @@ -17,70 +24,87 @@ EmuScriptMgr::~EmuScriptMgr() { /// @brief Executes all emu scripts in a directory. int EmuScriptMgr::executeScripts() { - std::string function_name; - try { - for (size_t i = 0; i < files.size() - 1; i++) { - // lua_CFunction script_fun = script_functions[i]; - //script_fun(lua); - std::stringstream ss; - ss << "emu_run";// << i + 1; - function_name = ss.str(); - lua_getglobal(lua, function_name.c_str()); // call emu_run from script - if (lua_isfunction(lua, -1)) { - int pcall = lua_pcall(lua, 0, 0, 0); - if (pcall != 0) { - const char* error_message = lua_tostring(lua, -1); - if(error_message != NULL) { - f << "[" << timestamp << "] " << "Lua pcall error: <" << function_name << "> " << error_message << std::endl; - } else { - f << "[" << timestamp << "] " << "Lua pcall error: <" << function_name << "> err unavailable" << std::endl; + + for (int i = 0; i < scripts.size(); i++) { + lua = luaL_newstate(); // Open Lua + + int iErr = 0; + if (!lua) { + f << "[" << timestamp << "] " << "Failed to create Lua state." << std::endl; + } + //------ Register API functions to Lua + RegZooState::register_zoo_state(lua); + luaL_openlibs (lua); + if (luaL_loadstring(lua, scripts[i].c_str()) == 0) { + if (lua_pcall(lua, 0, LUA_MULTRET, 0) == 0) + { + // script is loaded, now load specific function + lua_getglobal(lua, "emu_run"); + // check if we can call function + if (lua_isfunction(lua, -1)) { + if (lua_pcall(lua, 0, LUA_MULTRET, 0) != 0) { + // errors if can't execute script + const char* error_message = lua_tostring(lua, -1); + f << "Error executing Lua function: " << error_message << std::endl; + lua_close (lua); + return 1; } - - lua_pop(lua, 1); + } else { + f << "[" << timestamp << "] " << "Function 'emu_run' not found or not callable" << std::endl; + lua_close (lua); + return 1; } lua_pop(lua, 1); - } - else { + } else { + // error handling + const char* error_message = lua_tostring(lua, -1); + f << "[" << timestamp << "] " << "Error executing Lua script " << i << ": " << error_message << std::endl; + + // remove err from stack lua_pop(lua, 1); - f << "[" << timestamp << "] " << "Error while finding function: <" << function_name << "> null function" << std::endl; - return 2; + lua_close (lua); + return 1; } + } else { + // error handling + const char* error_message = lua_tostring(lua, -1); + f << "[" << timestamp << "] " << "Error loading Lua script " << i << ": " << error_message << std::endl; + + // remove err from stack + lua_pop(lua, 1); + lua_close (lua); + return 1; } + lua_close (lua); } - catch (const std::bad_alloc& e) { - f << "[" << timestamp << "] " << "Error while executing function: <" << function_name << "> " << e.what() << std::endl; - } + return 0; } -/// @brief Serializes all emu scripts in a directory as a binary format. -void EmuScriptMgr::serializeScripts() { - int err = 0; +/// @brief Stores all emu scripts in a directory in memory. +void EmuScriptMgr::storeScripts() { - //------ Load scripts for (int i = 0; i < files.size(); i++) { - std::string file = files[i]; - std::string file_name = file_names[i]; - - //------ Load script into Lua state (if no errors - if ((err = luaL_loadfile(lua, file.c_str())) == 0) { - lua_pcall(lua, 0, LUA_MULTRET, 0); - f << "[" << timestamp << "] " << "Loading script: " << file_name << std::endl; + //------ Read script file + std::ifstream file(files[i].c_str()); + std::string script; + char c; + while (file.get(c)) { + script += c; } - else - { - const char* error_message = lua_tostring(lua, -1); - if (error_message != NULL) - { - f << "[" << timestamp << "] " << "Error loading script: <" << file_name << "> " << error_message << std::endl; - } - else - { - f << "[" << timestamp << "] " << "Error loading script: <" << file_name << std::endl; - } - + scripts.push_back(script); + file.close(); + //------ Compile script + if ((luaL_loadstring(lua, script.c_str())) == 0) { + lua_CFunction script_funct = lua_tocfunction(lua, -1); + compiled_scripts.push_back(script_funct); + lua_pop(lua, 1); + } else { + f << "[" << timestamp << "] " << "Error loading script: " << files[i].substr(0, files[i].size() - (int)(files[i].size() * 0.30)) << " [..]" << std::endl; } } + lua_close (lua); + } /// @brief Finds all scripts within the /scripts directory and stores their location in memory. @@ -99,9 +123,6 @@ void EmuScriptMgr::findScripts() { //------ Convert wide string to narrow string, std::string path(wpath.begin(), wpath.end()); - //------ Store all file directories into vector - std::vector files; - //------ Find first .emu file in directory WIN32_FIND_DATA find_emu_file; HANDLE hFind = FindFirstFile((wpath + L"\\*.emu").c_str(), &find_emu_file); // wide string used here diff --git a/EmuAPI/emu/EmuScriptMgr.h b/EmuAPI/emu/EmuScriptMgr.h index 1405a71..7877c9a 100644 --- a/EmuAPI/emu/EmuScriptMgr.h +++ b/EmuAPI/emu/EmuScriptMgr.h @@ -1,3 +1,6 @@ +#ifndef EMUSCRIPTMGR_H +#define EMUSCRIPTMGR_H + #include #include #include @@ -7,24 +10,29 @@ #include #include "lua.hpp" #include +#include +#include "RegZooState.h" class EmuScriptMgr { public: EmuScriptMgr(); - EmuScriptMgr(lua_State*, std::ofstream&); // overloaded constructor + EmuScriptMgr(std::ofstream&, char*); // overloaded constructor ~EmuScriptMgr(); void findScripts(); - void serializeScripts(); + void storeScripts(); int executeScripts(); private: std::vector files; std::vector file_names; - - std::time_t* t; - char* timestamp; + std::vector compiled_scripts; + std::vector scripts; + static int writer(const void*, size_t, void*); + char* timestamp; lua_State *lua; std::ofstream& f; -}; \ No newline at end of file +}; + +#endif \ No newline at end of file