Add exceptions to server api methods

master
Nicole Collings 2019-12-28 22:42:46 -08:00
parent 87eaf4058b
commit 12bfa015fe
19 changed files with 107 additions and 127 deletions

View File

@ -145,8 +145,7 @@ set(ZEPHA_SRC
lua/api/modules/cSetBlock.h
lua/api/modules/cGetBlock.h
lua/api/modules/cRemoveBlock.h
lua/api/modules/cPrintE.h
lua/client/LocalRegisterBlocks.cpp
lua/client/LocalRegisterBlocks.cpp
lua/client/LocalRegisterBlocks.h
lua/server/ServerRegisterBlocks.cpp
lua/server/ServerRegisterBlocks.h
@ -285,6 +284,6 @@ set(ZEPHA_SRC
game/hud/GuiBuilder.h
game/hud/GameGuiBuilder.cpp
game/hud/GameGuiBuilder.h
lua/api/modules/mStartGame.h lua/api/type/LuaInventoryList.cpp lua/api/type/LuaInventoryList.h lua/api/type/LuaInventory.cpp lua/api/type/LuaInventory.h game/scene/world/Inventory.cpp game/scene/world/Inventory.h lua/api/type/LuaItemStack.cpp lua/api/type/LuaItemStack.h game/scene/world/ItemStack.cpp lua/api/type/cLuaInventory.h lua/api/type/cLuaItemStack.h game/hud/components/basic/GUIModel.cpp game/hud/components/basic/GUIModel.h lua/api/modules/sAddEntity.h server/world/ServerEntity.cpp server/world/ServerEntity.h lua/api/type/ServerLuaEntity.cpp lua/api/type/ServerLuaEntity.h)
lua/api/modules/mStartGame.h lua/api/type/LuaInventoryList.cpp lua/api/type/LuaInventoryList.h lua/api/type/LuaInventory.cpp lua/api/type/LuaInventory.h game/scene/world/Inventory.cpp game/scene/world/Inventory.h lua/api/type/LuaItemStack.cpp lua/api/type/LuaItemStack.h game/scene/world/ItemStack.cpp lua/api/type/cLuaInventory.h lua/api/type/cLuaItemStack.h game/hud/components/basic/GUIModel.cpp game/hud/components/basic/GUIModel.h lua/api/modules/sAddEntity.h server/world/ServerEntity.cpp server/world/ServerEntity.h lua/api/type/ServerLuaEntity.cpp lua/api/type/ServerLuaEntity.h game/scene/LuaErrorScene.cpp game/scene/LuaErrorScene.h)
add_library (Zepha_Core ${ZEPHA_SRC})

View File

@ -1,17 +0,0 @@
//
// Created by aurailus on 28/06/19.
//
#pragma once
#include <sol2/sol.hpp>
namespace ClientApi {
void printe(sol::state &lua) {
lua.script(R"(
function printe(str)
print("\27[31m[!] " .. str .. "\27[0m")
end
)");
}
}

View File

@ -9,40 +9,44 @@
#include "../type/ServerLuaEntity.h"
namespace ServerApi {
static int local_entities_ind = 0;
static int server_entities_ind = 0;
void add_entity(sol::state& lua, sol::table& core, ServerDefs& defs, ServerWorld& world) {
core["entities"] = lua.create_table();
core.set_function("add_entity", [&](std::string entityStr, sol::table pos, sol::object staticData) {
if (core["registered_entities"][entityStr] != sol::nil) {
sol::table entityDef = core["registered_entities"][entityStr];
core.set_function("add_entity", [&](sol::optional<std::string> identifier, sol::optional<sol::table> pos, sol::object staticData) {
if (!identifier || !identifier->length()) throw "expected a string as the first argument.";
if (!pos) throw "expected a vector as the second argument.";
auto entity = std::make_unique<ServerEntity>();
entity->setPos({pos.get<float>("x"), pos.get<float>("y"), pos.get<float>("z")});
auto entityRef = std::make_shared<ServerLuaEntity>(std::move(entity), local_entities_ind++, defs);
if (core["registered_entities"][*identifier] == sol::nil) throw "identifier '" + *identifier + "' is not a valid entity identifier.";
sol::table entityDef = core["registered_entities"][*identifier];
sol::table luaEntity = lua.create_table();
luaEntity[sol::metatable_key] = entityDef;
luaEntity["object"] = entityRef;
luaEntity["name"] = entityStr;
auto entity = std::make_unique<ServerEntity>();
entity->setPos({pos->get<float>("x"), pos->get<float>("y"), pos->get<float>("z")});
auto entityRef = std::make_shared<ServerLuaEntity>(std::move(entity), server_entities_ind++, defs);
auto displayType = luaEntity.get<sol::optional<std::string>>("display");
auto displayObject = luaEntity.get<sol::optional<std::string>>("display_object");
auto displayTexture = luaEntity.get<sol::optional<std::string>>("display_texture");
if (!displayType || !displayObject) throw "Missing display or display_object field.";
if (*displayType == "model" && !displayTexture) throw "Missing model display_texture field.";
sol::table luaEntity = lua.create_table();
luaEntity[sol::metatable_key] = entityDef;
luaEntity["object"] = entityRef;
luaEntity["name"] = identifier;
entityRef->set_display_type(*displayType, *displayObject, displayTexture);
auto displayType = luaEntity.get<sol::optional<std::string>>("display");
auto displayObject = luaEntity.get<sol::optional<std::string>>("display_object");
auto displayTexture = luaEntity.get<sol::optional<std::string>>("display_texture");
core.get<sol::table>("entities")[entityRef->id] = luaEntity;
auto on_create = entityDef.get<sol::optional<sol::function>>("on_create");
if (on_create) (*on_create)(luaEntity, staticData);
//TODO: Move these checks to register_entity
if (!displayType) throw "entity '" + *identifier + "' is missing the display property.";
if (!displayObject) throw "entity '" + *identifier + "' is missing the display_object property.";
if (!displayTexture) throw "entity '" + *identifier + "' is missing the display_texture property.";
world.dimension.addLuaEntity(entityRef);
return luaEntity;
}
throw "Tried to create undefined entity.";
entityRef->set_display_type(*displayType, *displayObject, displayTexture);
core.get<sol::table>("entities")[entityRef->id] = luaEntity;
auto on_create = entityDef.get<sol::optional<sol::function>>("on_create");
if (on_create) (*on_create)(luaEntity, staticData);
world.dimension.addLuaEntity(entityRef);
return luaEntity;
});
}
}

View File

@ -9,10 +9,13 @@
namespace ServerApi {
void delay(sol::table &core, std::list<ServerLuaParser::DelayedFunction> &funcs) {
core.set_function("delay", [&](sol::function function, float delay, sol::variadic_args args) {
std::vector<sol::object> argsObject;
core.set_function("delay", [&](sol::optional<sol::function> function, sol::optional<float> delay, sol::variadic_args args) {
if (!function) throw "expected a function as the first argument.";
if (!delay) throw "expected a number as the second argument.";
std::vector<sol::object> argsObject {};
for (auto arg : args) argsObject.push_back(arg);
funcs.push_back(ServerLuaParser::DelayedFunction{function, argsObject, delay, delay});
funcs.push_back({*function, argsObject, *delay, *delay});
});
}
}

View File

@ -11,11 +11,8 @@
namespace ServerApi {
void get_block(sol::table &core, ServerDefs& defs, ServerWorld& world) {
core.set_function("get_block", [&](sol::table pos) -> std::string {
if (!pos["x"] || !pos["y"] || !pos["z"]) {
std::cout << Log::err << "get_block vector is ill formed." << Log::endl;
return "";
}
return defs.defs.fromId(world.getBlock({pos["x"], pos["y"], pos["z"]})).identifier;
if (!pos["x"] || !pos["y"] || !pos["z"]) throw "expected a vector as the first argument.";
return defs.defs.fromId(world.getBlock({pos.get<float>("x"), pos.get<float>("y"), pos.get<float>("z")})).identifier;
});
}
}

View File

@ -1,17 +0,0 @@
//
// Created by aurailus on 28/06/19.
//
#pragma once
#include <sol2/sol.hpp>
namespace ServerApi {
void printe(sol::state& lua) {
lua.script(R"(
function printe(str)
print("\27[31m[!] " .. str .. "\27[0m")
end
)");
}
}

View File

@ -11,12 +11,14 @@ namespace ServerApi {
void register_biome(sol::state& lua, sol::table& core) {
core["registered_biomes"] = lua.create_table();
core.set_function("register_biome", [&](sol::this_environment env, std::string identifier, sol::table data) {
if (identifier.length() == 0) throw "Missing Identifier";
core.set_function("register_biome", [&](sol::this_environment env, sol::optional<std::string> identifier, sol::optional<sol::table> data) {
if (!identifier || !identifier->length()) throw "expected a string as the first argument.";
if (!data) throw "expected a table as the second argument.";
auto modname = static_cast<sol::environment>(env).get<std::string>("_MODNAME");
if (identifier.compare(0, modname.length() + 1, modname + ":")) {
std::cout << Log::err << "\"" << identifier << "\" does not begin with its mod's prefix \"" << modname << "\"!" << Log::endl;
}
if (identifier->compare(0, modname.length() + 1, modname + ":")) throw
"identifier '" + *identifier + "' must begin with the calling mod's prefix, '" + modname + "'.";
core["registered_biomes"][identifier] = data;
});
}

View File

@ -10,12 +10,15 @@ namespace ServerApi {
void register_block(sol::state& lua, sol::table& core) {
core["registered_blocks"] = lua.create_table();
core.set_function("register_block", [&](sol::this_environment env, std::string identifier, sol::table data) {
if (identifier.length() == 0) throw "Missing Identifier";
core.set_function("register_block", [&](sol::this_environment env, sol::optional<std::string> identifier, sol::optional<sol::table> data) {
if (!identifier || !identifier->length()) throw "expected a string as the first argument.";
if (!data) throw "expected a table as the second argument.";
auto modname = static_cast<sol::environment>(env).get<std::string>("_MODNAME");
if (identifier.compare(0, modname.length() + 1, modname + ":")) {
std::cout << Log::err << "\"" << identifier << "\" does not begin with its mod's prefix \"" << modname << "\"!" << Log::endl;
}
if (identifier->compare(0, modname.length() + 1, modname + ":")) throw
"identifier '" + *identifier + "' must begin with the calling mod's prefix, '" + modname + "'.";
core["registered_blocks"][identifier] = data;
});
}

View File

@ -10,12 +10,15 @@ namespace ServerApi {
void register_blockmodel(sol::state& lua, sol::table& core) {
core["registered_blockmodels"] = lua.create_table();
core.set_function("register_blockmodel", [&](sol::this_environment env, std::string identifier, sol::table data) {
if (identifier.length() == 0) throw "Missing Identifier";
core.set_function("register_blockmodel", [&](sol::this_environment env, sol::optional<std::string> identifier, sol::optional<sol::table> data) {
if (!identifier || !identifier->length()) throw "expected a string as the first argument.";
if (!data) throw "expected a table as the second argument.";
auto modname = static_cast<sol::environment>(env).get<std::string>("_MODNAME");
if (identifier.compare(0, modname.length() + 1, modname + ":")) {
std::cout << Log::err << "\"" << identifier << "\" does not begin with its mod's prefix \"" << modname << "\"!" << Log::endl;
}
if (identifier->compare(0, modname.length() + 1, modname + ":")) throw
"identifier '" + *identifier + "' must begin with the calling mod's prefix, '" + modname + "'.";
core["registered_blockmodels"][identifier] = data;
});
}

View File

@ -8,17 +8,19 @@
namespace ServerApi {
void register_entity(sol::state& lua, sol::table& core) {
//TODO: Do anything
core["registered_entities"] = lua.create_table();
core.set_function("register_entity", [&](sol::this_environment env, std::string identifier, sol::table data) {
if (identifier.length() == 0) throw "Missing Identifier";
core.set_function("register_entity", [&](sol::this_environment env, sol::optional<std::string> identifier, sol::optional<sol::table> data) {
if (!identifier || !identifier->length()) throw "expected a string as the first argument.";
if (!data) throw "expected a table as the second argument.";
auto modname = static_cast<sol::environment>(env).get<std::string>("_MODNAME");
if (identifier.compare(0, modname.length() + 1, modname + ":")) {
std::cout << Log::err << "\"" << identifier << "\" does not begin with its mod's prefix \"" << modname << "\"!" << Log::endl;
}
data["__index"] = data;
core["registered_entities"][identifier] = data;
if (identifier->compare(0, modname.length() + 1, modname + ":")) throw
"identifier '" + *identifier + "' must begin with the calling mod's prefix, '" + modname + "'.";
(*data)["__index"] = *data;
core["registered_entities"][*identifier] = *data;
});
}
}

View File

@ -10,12 +10,15 @@ namespace ServerApi {
void register_item(sol::state& lua, sol::table& core) {
core["registered_items"] = lua.create_table();
core.set_function("register_item", [&](sol::this_environment env, std::string identifier, sol::table data) {
if (identifier.length() == 0) throw "Missing Identifier";
core.set_function("register_item", [&](sol::this_environment env, sol::optional<std::string> identifier, sol::optional<sol::table> data) {
if (!identifier || !identifier->length()) throw "expected a string as the first argument.";
if (!data) throw "expected a table as the second argument.";
auto modname = static_cast<sol::environment>(env).get<std::string>("_MODNAME");
if (identifier.compare(0, modname.length() + 1, modname + ":")) {
std::cout << Log::err << "\"" << identifier << "\" does not begin with its mod's prefix \"" << modname << "\"!" << Log::endl;
}
if (identifier->compare(0, modname.length() + 1, modname + ":")) throw
"identifier '" + *identifier + "' must begin with the calling mod's prefix, '" + modname + "'.";
core["registered_items"][identifier] = data;
});
}

View File

@ -20,12 +20,15 @@ namespace ServerApi {
}
}
core.set_function("register_keybind", [&](sol::this_environment env, std::string identifier, sol::table data) {
if (identifier.length() == 0) throw "Missing Identifier";
// auto modname = static_cast<sol::environment>(env).get<std::string>("_MODNAME");
// if (identifier.compare(0, modname.length() + 1, modname + ":")) {
// std::cout << Log::err << "\"" << identifier << "\" does not begin with its mod's prefix \"" << modname << "\"!" << Log::endl;
// }
core.set_function("register_keybind", [&](sol::this_environment env, sol::optional<std::string> identifier, sol::optional<sol::table> data) {
if (!identifier || !identifier->length()) throw "expected a string as the first argument.";
if (!data) throw "expected a table as the second argument.";
auto modname = static_cast<sol::environment>(env).get<std::string>("_MODNAME");
if (identifier->compare(0, modname.length() + 1, modname + ":")) throw
"identifier '" + *identifier + "' must begin with the calling mod's prefix, '" + modname + "'.";
core["registered_keybinds"][identifier] = data;
});
}

View File

@ -11,11 +11,8 @@
namespace ServerApi {
void remove_block(sol::table &core, ServerDefs& defs, ServerWorld& world) {
core.set_function("remove_block", [&](sol::table pos) {
if (!pos["x"] || !pos["y"] || !pos["z"]) {
std::cout << Log::err << "remove_block vector is ill formed." << Log::endl;
return;
}
world.setBlock({pos["x"], pos["y"], pos["z"]}, LocalDefinitionAtlas::AIR);
if (!pos["x"] || !pos["y"] || !pos["z"]) throw "expected a vector as the first argument.";
world.setBlock({pos.get<float>("x"), pos.get<float>("y"), pos.get<float>("z")}, LocalDefinitionAtlas::AIR);
});
}
}

View File

@ -11,11 +11,8 @@
namespace ServerApi {
void set_block(sol::table &core, ServerDefs& defs, ServerWorld& world) {
core.set_function("set_block", [&](sol::table pos, std::string identifier) {
if (!pos["x"] || !pos["y"] || !pos["z"]) {
std::cout << Log::err << "set_block vector is ill formed." << Log::endl;
return;
}
world.setBlock({pos["x"], pos["y"], pos["z"]}, defs.defs.fromStr(identifier).index);
if (!pos["x"] || !pos["y"] || !pos["z"]) throw "expected a vector as the first argument.";
world.setBlock({pos.get<float>("x"), pos.get<float>("y"), pos.get<float>("z")}, defs.defs.fromStr(identifier).index);
});
}
}

View File

@ -16,8 +16,6 @@
#include "../api/type/cLuaInventory.h"
#include "../api/type/cLuaItemStack.h"
#include "../api/modules/cPrintE.h"
#include "../api/modules/cDelay.h"
#include "../api/modules/cRegisterBlock.h"
@ -70,8 +68,6 @@ void LocalLuaParser::loadModules(LocalDefs &defs, LocalWorld &world, Player& pla
core["player"] = LocalLuaPlayer(player);
//Load Modules
ClientApi::printe(lua);
ClientApi::delay(core, delayed_functions);
ClientApi::register_block(lua, core);

View File

@ -11,8 +11,6 @@
#include "../../def/ServerDefs.h"
#include "../api/modules/sPrintE.h"
#include "../api/modules/sDelay.h"
#include "../api/modules/sRegisterBlock.h"
@ -56,8 +54,6 @@ void ServerLuaParser::loadModules(ServerDefs &defs, ServerWorld &world) {
core["player"] = sol::nil;
//Load Modules
ServerApi::printe(lua);
ServerApi::delay(core, delayed_functions);
ServerApi::register_block(lua, core);
@ -379,6 +375,14 @@ void ServerLuaParser::serializeMods() {
}
}
sol::protected_function_result ServerLuaParser::errorCallback(lua_State*, sol::protected_function_result errPfr) {
sol::error err = errPfr;
std::cout << Log::err << "The Zepha sandbox has encountered an error:"
<< std::endl << std::endl << err.what() << std::endl << Log::endl;
exit(1);
return errPfr;
}
sol::protected_function_result ServerLuaParser::DoFileSandboxed(std::string file) {
size_t modname_length = file.find('/');
std::string modname = file.substr(0, modname_length);
@ -393,11 +397,9 @@ sol::protected_function_result ServerLuaParser::DoFileSandboxed(std::string file
env["_FILE"] = f.path;
env["_MODNAME"] = mod.config.name;
auto pfr = lua.safe_script(f.file, env, [&](lua_State*, sol::protected_function_result errPfr) {
sol::error err = errPfr;
std::cout << Log::err << file << " returned an error: \n" << err.what() << Log::endl;
return errPfr;
}, "@" + f.path);
//TODO: figure out how to do this lambda thing properly with bind
// auto pfr = lua.safe_script(f.file, env, [&](lua_State*, sol::protected_function_result errPfr) { errorCallback(errPfr); return errPfr; }, "@" + f.path);
auto pfr = lua.safe_script(f.file, env, &ServerLuaParser::errorCallback, "@" + f.path);
return pfr;
}
}
@ -406,4 +408,4 @@ sol::protected_function_result ServerLuaParser::DoFileSandboxed(std::string file
break;
}
}
}
}

View File

@ -36,6 +36,7 @@ private:
void handleDependencies();
void serializeMods();
static sol::protected_function_result errorCallback(lua_State*, sol::protected_function_result errPfr);
sol::protected_function_result DoFileSandboxed(std::string file);
};

View File

@ -16,6 +16,7 @@ namespace Log {
static void clear() { auto s = system("cls"); }
#else
static const char* info = "\033[36m[INFO] ";
static const char* warn = "\033[31m[WARN] ";
static const char* err = "\033[31m[ERR!] ";
static const char* endl = "\033[0m\n";

View File

@ -2,6 +2,7 @@ zepha.register_entity("zeus:default:test", {
display = "model",
display_object = "zeus:default:player",
display_texture = "zeus:default:player",
on_create = function(self)
-- self.object:set_scale(1/4)
end,