2019-06-12 00:15:47 -07:00
|
|
|
//
|
|
|
|
// Created by aurailus on 17/12/18.
|
|
|
|
//
|
|
|
|
|
2020-05-07 17:21:56 -07:00
|
|
|
#include "LocalLuaParser.h"
|
|
|
|
|
2020-11-03 23:29:30 -08:00
|
|
|
#include "client/Client.h"
|
2020-07-26 19:59:03 -07:00
|
|
|
#include "ErrorFormatter.h"
|
|
|
|
#include "register/RegisterItems.h"
|
2020-11-08 16:43:12 -08:00
|
|
|
#include "register/RegisterBlock.h"
|
2020-07-26 19:59:03 -07:00
|
|
|
#include "register/RegisterBiomes.h"
|
|
|
|
#include "register/RegisterKeybinds.h"
|
2020-02-19 15:55:48 -08:00
|
|
|
|
2020-02-25 15:14:07 -08:00
|
|
|
// Usertypes
|
2020-07-30 22:07:00 -07:00
|
|
|
#include "usertype/Target.h"
|
|
|
|
#include "usertype/Player.h"
|
2020-08-05 15:26:15 -07:00
|
|
|
#include "usertype/Entity.h"
|
2020-07-30 22:07:00 -07:00
|
|
|
#include "usertype/Inventory.h"
|
|
|
|
#include "usertype/Dimension.h"
|
2020-08-02 17:16:40 -07:00
|
|
|
#include "usertype/ItemStack.h"
|
2020-07-30 22:07:00 -07:00
|
|
|
#include "usertype/InventoryList.h"
|
2020-08-06 16:15:23 -07:00
|
|
|
#include "usertype/AnimationManager.h"
|
2020-07-30 22:07:00 -07:00
|
|
|
|
2020-07-26 19:59:03 -07:00
|
|
|
#include "usertype/LuaGuiElement.h"
|
2019-06-12 18:06:51 -07:00
|
|
|
|
2020-02-19 15:55:48 -08:00
|
|
|
// Modules
|
2020-07-26 19:59:03 -07:00
|
|
|
#include "modules/Time.h"
|
2020-07-30 22:07:00 -07:00
|
|
|
#include "modules/Dimension.h"
|
|
|
|
|
2020-07-26 19:59:03 -07:00
|
|
|
#include "modules/create_structure.h"
|
2019-10-11 15:13:46 -07:00
|
|
|
|
2020-11-08 16:43:12 -08:00
|
|
|
// Util
|
|
|
|
#include "lua/register/CreateRegister.h"
|
|
|
|
|
2020-08-02 17:16:40 -07:00
|
|
|
LocalLuaParser::LocalLuaParser(LocalSubgame& game): LuaParser(game), keybinds(this) {}
|
2020-05-07 17:21:56 -07:00
|
|
|
|
2020-11-03 23:29:30 -08:00
|
|
|
void LocalLuaParser::init(WorldPtr world, PlayerPtr player, Client& client) {
|
2020-11-02 15:18:09 -08:00
|
|
|
lua.open_libraries(sol::lib::base, sol::lib::string, sol::lib::math, sol::lib::table, sol::lib::debug);
|
2019-06-12 00:15:47 -07:00
|
|
|
|
2020-08-02 20:51:22 -07:00
|
|
|
loadApi(world, player);
|
|
|
|
handler.executeMods(Util::bind_this(this, &LocalLuaParser::runFileSandboxed));
|
2020-11-03 23:29:30 -08:00
|
|
|
client.renderer.window.input.setCallback(Util::bind_this(&keybinds, &LuaKeybindHandler::keybindHandler));
|
2020-02-19 15:55:48 -08:00
|
|
|
|
2020-08-02 17:16:40 -07:00
|
|
|
registerDefs();
|
2020-02-19 15:55:48 -08:00
|
|
|
}
|
|
|
|
|
2020-05-07 17:21:56 -07:00
|
|
|
void LocalLuaParser::update(double delta) {
|
2020-02-19 15:55:48 -08:00
|
|
|
this->delta += delta;
|
2020-03-06 18:07:22 -08:00
|
|
|
while (this->delta > static_cast<double>(UPDATE_STEP)) {
|
|
|
|
safe_function(core["__builtin"]["update_entities"], static_cast<double>(UPDATE_STEP));
|
2020-07-25 11:55:48 -07:00
|
|
|
safe_function(core["__builtin"]["update_delayed_functions"]);
|
2020-03-06 18:07:22 -08:00
|
|
|
this->delta -= static_cast<double>(UPDATE_STEP);
|
2020-02-19 15:55:48 -08:00
|
|
|
}
|
|
|
|
}
|
2019-06-29 00:43:48 -07:00
|
|
|
|
2020-02-19 15:55:48 -08:00
|
|
|
LocalModHandler& LocalLuaParser::getHandler() {
|
|
|
|
return handler;
|
2019-06-29 00:43:48 -07:00
|
|
|
}
|
|
|
|
|
2020-08-02 20:51:22 -07:00
|
|
|
void LocalLuaParser::loadApi(WorldPtr world, PlayerPtr player) {
|
2019-09-08 11:26:53 -07:00
|
|
|
//Create Zepha Table
|
|
|
|
core = lua.create_table();
|
|
|
|
lua["zepha"] = core;
|
2019-10-11 15:13:46 -07:00
|
|
|
core["__builtin"] = lua.create_table();
|
2019-06-12 00:15:47 -07:00
|
|
|
|
2020-02-19 15:55:48 -08:00
|
|
|
// Types
|
2020-04-13 16:33:15 -07:00
|
|
|
ClientApi::gui_element (lua);
|
2019-10-23 23:34:30 -07:00
|
|
|
|
2020-07-28 14:11:11 -07:00
|
|
|
Api::Usertype::Target::bind(Api::State::CLIENT, lua, core);
|
2020-08-05 15:26:15 -07:00
|
|
|
Api::Usertype::Entity::bind(Api::State::CLIENT, lua, core);
|
2020-07-30 22:07:00 -07:00
|
|
|
Api::Usertype::Inventory::bind(Api::State::CLIENT, lua, core);
|
2020-08-02 17:16:40 -07:00
|
|
|
Api::Usertype::Dimension::bind(Api::State::CLIENT, lua, core);
|
|
|
|
Api::Usertype::ItemStack::bind(Api::State::CLIENT, lua, core);
|
2020-07-30 22:07:00 -07:00
|
|
|
Api::Usertype::LocalPlayer::bind(Api::State::CLIENT, lua, core);
|
|
|
|
Api::Usertype::InventoryList::bind(Api::State::CLIENT, lua, core);
|
2020-08-12 19:42:27 -07:00
|
|
|
Api::Usertype::LocalAnimationManager::bind(Api::State::CLIENT, lua, core);
|
2020-07-28 14:11:11 -07:00
|
|
|
|
2019-12-17 17:26:48 -08:00
|
|
|
core["client"] = true;
|
2020-08-02 20:51:22 -07:00
|
|
|
core["player"] = Api::Usertype::LocalPlayer(player);
|
2019-08-31 23:58:38 -07:00
|
|
|
|
2020-02-19 15:55:48 -08:00
|
|
|
// Modules
|
2020-07-26 18:21:33 -07:00
|
|
|
modules.emplace_back(std::make_unique<Api::Module::Time>(Api::State::CLIENT, lua, core));
|
2020-08-05 15:26:15 -07:00
|
|
|
modules.emplace_back(std::make_unique<Api::Module::Dimension>(Api::State::CLIENT, core, game, **world));
|
2019-08-03 18:18:05 -07:00
|
|
|
|
2020-11-08 16:43:12 -08:00
|
|
|
// Register
|
|
|
|
Api::Util::createRegister(lua, core, "mesh");
|
|
|
|
Api::Util::createRegister(lua, core, "item");
|
|
|
|
Api::Util::createRegister(lua, core, "block",
|
|
|
|
[&](const std::string& iden) { RegisterBlock::client(core, static_cast<LocalSubgame&>(game), iden); });
|
|
|
|
Api::Util::createRegister(lua, core, "biome");
|
|
|
|
Api::Util::createRegister(lua, core, "keybind");
|
|
|
|
Api::Util::createRegister(lua, core, "blockmodel");
|
|
|
|
Api::Util::createRegister(lua, core, "entity", nullptr, "entities");
|
|
|
|
|
|
|
|
// Define keybind variables
|
|
|
|
core["keys"] = lua.create_table();
|
|
|
|
core["keycodes"] = lua.create_table();
|
|
|
|
|
|
|
|
for (unsigned short i = 0; i < 350; i++) {
|
|
|
|
auto key = ::Util::getKeyStr(i);
|
|
|
|
if (!key.empty()) {
|
|
|
|
core["keys"][key] = i;
|
|
|
|
core["keycodes"][i] = key;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-25 20:19:18 -07:00
|
|
|
bindModules();
|
2019-06-29 00:43:48 -07:00
|
|
|
|
2020-03-25 18:27:05 -07:00
|
|
|
Api::create_structure (lua, core);
|
|
|
|
|
2020-02-19 15:55:48 -08:00
|
|
|
// Create sandboxed runfile()
|
2019-11-12 01:15:06 -08:00
|
|
|
lua["dofile"] = lua["loadfile"] = sol::nil;
|
2020-02-19 15:20:59 -08:00
|
|
|
lua.set_function("runfile", &LocalLuaParser::runFileSandboxed, this);
|
2019-08-04 02:07:14 -07:00
|
|
|
}
|
2019-06-12 00:15:47 -07:00
|
|
|
|
2020-08-02 17:16:40 -07:00
|
|
|
void LocalLuaParser::registerDefs() {
|
|
|
|
auto& local = static_cast<LocalSubgame&>(game);
|
2020-11-08 16:43:12 -08:00
|
|
|
// RegisterBlocks ::client(core, local);
|
2020-08-02 17:16:40 -07:00
|
|
|
RegisterItems ::client(core, local);
|
|
|
|
RegisterBiomes ::client(core, local);
|
2020-05-07 17:21:56 -07:00
|
|
|
RegisterKeybinds::client(core, keybinds);
|
2019-06-15 23:04:10 -07:00
|
|
|
}
|
2019-08-03 18:18:05 -07:00
|
|
|
|
2020-07-30 22:07:00 -07:00
|
|
|
sol::protected_function_result LocalLuaParser::errorCallback(sol::protected_function_result r) const {
|
|
|
|
sol::error err = r;
|
2020-02-11 16:54:20 -08:00
|
|
|
std::string errString = err.what();
|
|
|
|
|
2020-07-23 18:54:11 -07:00
|
|
|
try {
|
|
|
|
std::string::size_type slash = errString.find('/');
|
|
|
|
if (slash != std::string::npos) throw "npos";
|
|
|
|
|
|
|
|
std::string modString = errString.substr(0, slash);
|
|
|
|
|
|
|
|
std::string::size_type lineNumStart = errString.find(':', slash);
|
|
|
|
if (lineNumStart != std::string::npos) throw "lineNumStart";
|
|
|
|
std::string::size_type lineNumEnd = errString.find(':', lineNumStart + 1);
|
|
|
|
if (lineNumStart != std::string::npos) throw "lineNumEnd";
|
|
|
|
|
|
|
|
std::string fileName = errString.substr(0, lineNumStart);
|
|
|
|
int lineNum = std::stoi(errString.substr(lineNumStart + 1, lineNumEnd - lineNumStart - 1));
|
|
|
|
|
|
|
|
for (const auto& mod : handler.cGetMods()) {
|
|
|
|
if (mod.config.name == modString) {
|
|
|
|
for (auto& file : mod.files) {
|
|
|
|
if (file.path == fileName) {
|
|
|
|
std::cout << std::endl << ErrorFormatter::formatError(fileName, lineNum, errString, file.file) << std::endl;
|
|
|
|
break;
|
|
|
|
}
|
2020-02-11 16:54:20 -08:00
|
|
|
}
|
2020-07-23 18:54:11 -07:00
|
|
|
break;
|
2020-02-11 16:54:20 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-07-23 18:54:11 -07:00
|
|
|
catch (...) {
|
|
|
|
std::cout << Log::err << "Zepha has encountered an error, and ErrorFormatter failed to format it:"
|
|
|
|
<< std::endl << std::endl << errString << Log::endl;
|
|
|
|
}
|
2020-02-25 15:14:07 -08:00
|
|
|
|
2020-07-26 18:21:33 -07:00
|
|
|
throw std::runtime_error("Exiting.");
|
2020-02-11 16:54:20 -08:00
|
|
|
}
|
|
|
|
|
2020-05-10 17:53:37 -07:00
|
|
|
sol::protected_function_result LocalLuaParser::runFileSandboxed(const std::string& file) {
|
2019-08-04 02:07:14 -07:00
|
|
|
size_t modname_length = file.find('/');
|
2020-05-10 17:53:37 -07:00
|
|
|
if (modname_length == std::string::npos) throw std::runtime_error("Error opening \"" + file + "\", specified file is invalid.");
|
2019-08-04 02:07:14 -07:00
|
|
|
std::string modname = file.substr(0, modname_length);
|
|
|
|
|
2020-02-19 15:55:48 -08:00
|
|
|
for (const LuaMod& mod : handler.cGetMods()) {
|
2020-05-10 17:53:37 -07:00
|
|
|
if (modname != mod.config.name) continue;
|
2020-07-26 19:59:03 -07:00
|
|
|
for (const LuaMod::File& f : mod.files) {
|
2020-05-10 17:53:37 -07:00
|
|
|
if (f.path != file) continue;
|
2020-02-28 13:03:19 -08:00
|
|
|
|
2020-05-10 17:53:37 -07:00
|
|
|
sol::environment env(lua, sol::create, lua.globals());
|
|
|
|
env["_PATH"] = f.path.substr(0, f.path.find_last_of('/') + 1);
|
|
|
|
env["_FILE"] = f.path;
|
|
|
|
env["_MODNAME"] = mod.config.name;
|
2019-09-09 16:40:19 -07:00
|
|
|
|
2020-05-10 17:53:37 -07:00
|
|
|
return lua.safe_script(f.file, env, std::bind(&LocalLuaParser::errorCallback, this, std::placeholders::_2), "@" + f.path, sol::load_mode::text);
|
2019-08-04 02:07:14 -07:00
|
|
|
}
|
2020-05-10 17:53:37 -07:00
|
|
|
throw std::runtime_error("Error opening \"" + file + "\", file not found.");
|
2019-08-03 18:18:05 -07:00
|
|
|
}
|
2020-05-10 17:53:37 -07:00
|
|
|
throw std::runtime_error("Error opening \"" + file + "\", mod not found.");
|
|
|
|
}
|