Add (dis)connect events, add ServerLuaPlayer, create ServerModHandler

* Remove drop callbacks from all blocks
* Create chest inventory background
master
Nicole Collings 2020-02-19 15:20:59 -08:00
parent 2097d3a954
commit 3c128c95d6
66 changed files with 1115 additions and 798 deletions

View File

@ -31,8 +31,8 @@ set(ZEPHA_SRC
game/scene/GameScene.h
game/graph/Renderer.cpp
game/graph/Renderer.h
lua/client/LocalLuaParser.cpp
lua/client/LocalLuaParser.h
lua/parser/LocalLuaParser.cpp
lua/parser/LocalLuaParser.h
game/hud/components/basic/GUIText.cpp
game/hud/components/basic/GUIText.h
game/hud/DebugGui.cpp
@ -61,12 +61,11 @@ set(ZEPHA_SRC
util/net/NetHandler.h
game/hud/GameGui.cpp
game/hud/GameGui.h
server/conn/ServerClients.cpp
server/conn/ServerClients.h
server/conn/ClientList.cpp
server/conn/ClientList.h
server/conn/ServerClient.h
util/net/PacketChannel.h
game/entity/world/PlayerEntity.cpp
game/entity/world/PlayerEntity.h
game/entity/world/PlayerEntity.h
game/hud/components/basic/GUIRect.cpp
game/hud/components/basic/GUIRect.h
game/hud/components/basic/GUIGraph.cpp
@ -128,8 +127,8 @@ set(ZEPHA_SRC
def/DefinitionAtlas.h
lua/LuaParser.cpp
lua/LuaParser.h
lua/client/ServerLuaParser.cpp
lua/client/ServerLuaParser.h
lua/parser/ServerLuaParser.cpp
lua/parser/ServerLuaParser.h
util/Log.h
lua/Callback.h
game/graph/shader/GuiUniforms.h
@ -201,7 +200,7 @@ set(ZEPHA_SRC
server/asset/AssetType.h
def/model/ModelStore.h
lua/api/modules/remove_entity.h
lua/api/functions/cUpdateEntities.h
lua/api/functions/update_entities.h
lua/api/modules/register_keybind.h
lua/LuaInputManager.cpp
lua/LuaInputManager.h
@ -267,8 +266,7 @@ set(ZEPHA_SRC
lua/api/type/ServerLuaEntity.h
game/scene/LuaErrorScene.cpp
game/scene/LuaErrorScene.h
lua/api/functions/sUpdateEntities.h
lua/api/type/sServerLuaEntity.h
lua/api/type/sServerLuaEntity.h
util/net/Serializer.h
util/net/Deserializer.h
lua/api/type/ServerLocalLuaEntity.cpp
@ -297,6 +295,6 @@ set(ZEPHA_SRC
lua/VenusParser.h
lua/ErrorFormatter.cpp
lua/ErrorFormatter.h
util/RIE.h)
util/RIE.h lua/api/type/ServerLuaPlayer.cpp lua/api/type/ServerLuaPlayer.h lua/api/type/sServerLuaPlayer.h lua/api/modules/register_on.h lua/api/functions/trigger_event.h lua/parser/ServerModHandler.cpp lua/parser/ServerModHandler.h)
add_library (Zepha_Core ${ZEPHA_SRC})

View File

@ -4,11 +4,11 @@
#pragma once
#include "texture/TextureAtlas.h"
#include "LocalDefinitionAtlas.h"
#include "../lua/client/LocalLuaParser.h"
#include "model/ModelStore.h"
#include "gen/LocalBiomeAtlas.h"
#include "model/ModelStore.h"
#include "texture/TextureAtlas.h"
#include "../lua/parser/LocalLuaParser.h"
class LocalDefs {
public:

View File

@ -3,6 +3,7 @@
//
#include "ServerDefs.h"
#include "../server/conn/ClientList.h"
ServerDefs::ServerDefs(const std::string& subgame, const std::string& execPath) {
size_t exec = execPath.find_last_of('/');
@ -23,6 +24,6 @@ void ServerDefs::init(ServerWorld &world) {
luaApi.init(*this, world, subgamePath);
}
void ServerDefs::update(double delta) {
void ServerDefs::update(double delta, ClientList& clients) {
luaApi.update(delta);
}

View File

@ -5,19 +5,20 @@
#pragma once
#include "ServerDefinitionAtlas.h"
#include "../lua/client/ServerLuaParser.h"
#include "../server/asset/AssetStorage.h"
#include "gen/ServerBiomeAtlas.h"
#include "ServerDefinitionAtlas.h"
#include "../server/asset/AssetStorage.h"
#include "../lua/parser/ServerLuaParser.h"
class ServerWorld;
class ClientList;
class ServerDefs {
public:
ServerDefs(const std::string& subgame, const std::string& execPath);
void init(ServerWorld& world);
void update(double delta);
void update(double delta, ClientList& clients);
~ServerDefs() = default;
std::string subgamePath = "";

View File

@ -288,5 +288,6 @@ std::shared_ptr<BlockChunk> MapGen::combinePartials(std::shared_ptr<BlockChunk>
res->generated = src->generated || res->generated;
res->partial = !res->generated;
res->calcNonAirBlocks();
return res;
}

View File

@ -1,12 +0,0 @@
//
// Created by aurailus on 08/02/19.
//
#include "PlayerEntity.h"
PlayerEntity::PlayerEntity(glm::vec3 pos, int peer_id, const std::shared_ptr<Model>& playerModel) :
peer_id(peer_id) {
setModel(playerModel);
setPos(pos);
}

View File

@ -10,6 +10,15 @@
class PlayerEntity : public Entity {
public:
PlayerEntity(glm::vec3 pos, int peer_id, const std::shared_ptr<Model>& playerModel);
int peer_id;
};
PlayerEntity(glm::vec3 pos, unsigned int cid, const std::shared_ptr<Model>& playerModel) : cid(cid) {
setModel(playerModel);
setPos(pos);
}
unsigned int getCid() {
return cid;
}
private:
unsigned int cid;
};

View File

@ -117,8 +117,10 @@ void GuiBuilder::clear(bool clrCallbacks) {
void GuiBuilder::recursivelyCreate(std::vector<SerializedGuiElem> components, std::shared_ptr<GUIComponent> parent) {
for (auto& data : components) {
std::shared_ptr<GUIComponent> component = createComponent(data);
parent->add(component);
recursivelyCreate(data.children, component);
if (component != nullptr) {
parent->add(component);
recursivelyCreate(data.children, component);
}
}
}

View File

@ -6,7 +6,7 @@
GameScene::GameScene(ClientState& state) : Scene(state),
defs(state.defs),
server(state.connection, defs),
server(state.connection, defs, player),
world(defs, &playerPos, &server),
player(world, defs, state.renderer),
@ -30,7 +30,7 @@ GameScene::GameScene(ClientState& state) : Scene(state),
void GameScene::update() {
defs.update(state.deltaTime, state.renderer.window.keys);
defs.textures.update();
server.update(player);
server.update();
Window& window = state.renderer.window;

View File

@ -3,6 +3,9 @@
//
#include "LuaErrorScene.h"
#include "../../def/texture/Font.h"
#include "../hud/components/basic/GUIRect.h"
#include "../hud/components/basic/GUIText.h"
LuaErrorScene::LuaErrorScene(ClientState &state, const std::string &err) : Scene(state), err(err) {
state.renderer.setClearColor(0, 0, 0);

View File

@ -6,6 +6,7 @@
#include <string>
#include "../graph/scene/Scene.h"
#include "../hud/components/basic/GUIContainer.h"
class LuaErrorScene : public Scene {
public:

View File

@ -2,13 +2,28 @@
// Created by aurailus on 11/01/19.
//
#include "ClientNetworkInterpreter.h"
#include "../world/Player.h"
#include "../../../util/net/NetHandler.h"
#include "../../../util/net/Serializer.h"
ClientNetworkInterpreter::ClientNetworkInterpreter(ServerConnection &connection, LocalDefs &defs) :
connection(connection),
#include "ClientNetworkInterpreter.h"
//#include <string>
//#include <iostream>
//#include <glm/vec3.hpp>
//
//#include "../../../util/Timer.h"
//#include "../../../util/net/Packet.h"
//#include "../../entity/world/PlayerEntity.h"
//#include "../../graph/drawable/DrawableGroup.h"
//#include "../../../util/net/Address.h"
ClientNetworkInterpreter::ClientNetworkInterpreter(ServerConnection &connection, LocalDefs &defs, Player& player) :
world(nullptr),
playerModel(std::make_shared<Model>()){
player(player),
connection(connection),
playerModel(std::make_shared<Model>()) {
playerModel->fromSerialized(defs.models.models["zeus:default:player"], {defs.textures["zeus:default:player"]});
}
@ -16,7 +31,7 @@ void ClientNetworkInterpreter::init(LocalWorld *world) {
this->world = world;
}
void ClientNetworkInterpreter::update(Player &player) {
void ClientNetworkInterpreter::update() {
recvPackets = 0;
ENetEvent event;
@ -24,6 +39,7 @@ void ClientNetworkInterpreter::update(Player &player) {
recvPackets++;
switch (event.type) {
default: break;
case ENET_EVENT_TYPE_CONNECT: {
std::cout << Log::info << "Connected to server "
<< NetHandler::intToIPString(event.peer->address.host)
@ -32,56 +48,7 @@ void ClientNetworkInterpreter::update(Player &player) {
}
case ENET_EVENT_TYPE_RECEIVE: {
std::unique_ptr<Packet> p = std::make_unique<Packet>(event.packet);
Deserializer d(p->data);
switch (p->type) {
case PacketType::THIS_PLAYER_INFO: {
id = d.read<unsigned int>();
player.setPos(d.read<glm::vec3>());
player.setYaw(d.read<float>());
break;
}
case PacketType::PLAYER_INFO: {
unsigned int peer_id = d.read<unsigned int>();
if (peer_id == id) break;
bool found = false;
for (auto& ent : world->dimension.playerEntities) {
if (ent.peer_id == peer_id) {
ent.interpPos(d.read<glm::vec3>());
ent.interpRotateY(-d.read<float>() + 90);
found = true;
break;
}
}
if (!found) world->dimension.playerEntities.emplace_back(d.read<glm::vec3>(), peer_id, playerModel);
break;
}
case PacketType::ENTITY_INFO: {
world->dimension.handleServerEntity(*p);
break;
}
case PacketType::BLOCK_SET: {
auto pos = d.read<glm::ivec3>();
auto block = d.read<unsigned int>();
world->setBlock(pos, block);
break;
}
case PacketType::CHUNK: {
chunkPackets.push_back(std::move(p));
break;
}
case PacketType::SERVER_INFO: {
serverSideChunkGens = d.read<unsigned int>();
break;
}
default:
std::cout << Log::err << "Received unknown packet of type " << static_cast<int>(p->type)
<< ". Is the server on a different protocol version?" << Log::endl;
break;
}
receivedPacket(std::move(p));
enet_packet_destroy(event.packet);
break;
}
@ -90,9 +57,6 @@ void ClientNetworkInterpreter::update(Player &player) {
<< event.peer->address.host << ":" << event.peer->address.port << "." << Log::endl;
break;
}
default:
break;
}
}
@ -100,20 +64,13 @@ void ClientNetworkInterpreter::update(Player &player) {
Packet p(PacketType::THIS_PLAYER_INFO);
p.data = Serializer()
.append(player.getPos())
.append(player.getPitch())
.append(player.getYaw())
.data;
p.sendTo(connection.getPeer(), PacketChannel::PLAYER);
}
void ClientNetworkInterpreter::cleanup() {
connection.disconnect();
}
ClientNetworkInterpreter::~ClientNetworkInterpreter() {
cleanup();
}
void ClientNetworkInterpreter::setBlock(glm::ivec3 pos, unsigned int block) {
Packet p(PacketType::BLOCK_SET);
Serializer()
@ -121,4 +78,73 @@ void ClientNetworkInterpreter::setBlock(glm::ivec3 pos, unsigned int block) {
.append(block)
.packet(PacketType::BLOCK_SET)
.sendTo(connection.getPeer(), PacketChannel::BLOCK);
}
void ClientNetworkInterpreter::receivedPacket(std::unique_ptr<Packet> p) {
Deserializer d(p->data);
switch (p->type) {
default: {
std::cout << Log::err << "Received unknown packet of type " << static_cast<int>(p->type)
<< ". Is the server on a different protocol version?" << Log::endl;
break;
}
case PacketType::THIS_PLAYER_INFO: {
id = d.read<unsigned int>();
player.setPos(d.read<glm::vec3>());
player.setYaw(d.read<float>());
break;
}
case PacketType::PLAYER_INFO: {
unsigned int cid = d.read<unsigned int>();
if (cid == id) break;
bool found = false;
for (auto& entity : world->dimension.playerEntities) {
if (entity.getCid() == cid) {
// Update an existing PlayerEntity
entity.interpPos(d.read<glm::vec3>());
entity.interpRotateY(-d.read<float>() + 90);
entity.interpRotateZ(-d.read<float>());
found = true;
break;
}
}
if (found) break;
// Instantiate a new PlayerEntity
world->dimension.playerEntities.emplace_back(d.read<glm::vec3>(), cid, playerModel);
break;
}
case PacketType::ENTITY_INFO: {
world->dimension.handleServerEntity(*p);
break;
}
case PacketType::BLOCK_SET: {
auto pos = d.read<glm::ivec3>();
auto block = d.read<unsigned int>();
world->setBlock(pos, block);
break;
}
case PacketType::CHUNK: {
chunkPackets.push_back(std::move(p));
break;
}
case PacketType::SERVER_INFO: {
serverSideChunkGens = d.read<unsigned int>();
break;
}
}
}
ClientNetworkInterpreter::~ClientNetworkInterpreter() {
connection.disconnect();
}

View File

@ -4,42 +4,33 @@
#pragma once
#include <string>
#include <iostream>
#include <glm/vec3.hpp>
#include "../../../util/Timer.h"
#include "../../../util/net/Packet.h"
#include "../../../util/net/NetHandler.h"
#include "../../entity/world/PlayerEntity.h"
#include "../../graph/drawable/DrawableGroup.h"
#include "../world/Player.h"
#include "../world/LocalWorld.h"
#include "../../../util/net/Address.h"
#include "ServerConnection.h"
#include "../world/LocalWorld.h"
class ClientNetworkInterpreter {
public:
ClientNetworkInterpreter(ServerConnection& connection, LocalDefs& defs);
ClientNetworkInterpreter(ServerConnection& connection, LocalDefs& defs, Player& player);
ClientNetworkInterpreter(const ClientNetworkInterpreter& other) = default;
void init(LocalWorld* world);
void update(Player &player);
void cleanup();
void update();
void receivedPacket(std::unique_ptr<Packet> ePacket);
void setBlock(glm::ivec3 pos, unsigned int block);
~ClientNetworkInterpreter();
std::vector<std::unique_ptr<Packet>> chunkPackets;
int serverSideChunkGens = 0;
int recvPackets = 0;
int serverSideChunkGens = 0;
std::vector<std::unique_ptr<Packet>> chunkPackets;
private:
std::shared_ptr<AtlasRef> playerFrontTex, playerBackTex, shadowTex;
int id = 0;
Player& player;
ServerConnection& connection;
LocalWorld* world = nullptr;
ServerConnection& connection;
std::shared_ptr<Model> playerModel;
int id = 0;
};

View File

@ -1,23 +0,0 @@
//
// Created by aurailus on 11/10/19.
//
#pragma once
#include <sol2/sol.hpp>
#include "../type/LocalLuaEntity.h"
#include "../../../game/scene/world/LocalWorld.h"
namespace ClientApi {
void update_entities(sol::state& lua) {
lua.script(R"(
zepha.__builtin.update_entities = function(delta)
for k, v in pairs(zepha.entities) do
if (type(v.on_update) == "function") then
v:on_update(delta)
end
end
end
)");
}
}

View File

@ -0,0 +1,23 @@
//
// Created by aurailus on 2020-02-18.
//
#pragma once
#include <sol2/sol.hpp>
namespace Api {
static void trigger_event(sol::state& lua) {
lua.script(R"(
zepha.__builtin.trigger_event = function(event, ...)
if zepha.registered_callbacks[event] == nil then return nil end
for _, v in pairs(zepha.registered_callbacks[event]) do
if (type(v) == "function") then
v(unpack(arg))
end
end
end
)");
}
}

View File

@ -1,13 +1,13 @@
//
// Created by aurailus on 2020-01-05.
// Created by aurailus on 11/10/19.
//
#pragma once
#include <sol2/sol.hpp>
namespace ServerApi {
void update_entities(sol::state& lua) {
namespace Api {
static void update_entities(sol::state& lua) {
lua.script(R"(
zepha.__builtin.update_entities = function(delta)
for k, v in pairs(zepha.entities) do

View File

@ -0,0 +1,24 @@
//
// Created by aurailus on 2020-02-17.
//
#pragma once
namespace Api {
static void register_on_s(sol::state& lua, sol::table& core, ServerLuaParser& parser) {
core["registered_callbacks"] = lua.create_table();
core["registered_callbacks"]["player_join"] = lua.create_table();
core["registered_callbacks"]["player_connect"] = lua.create_table();
core["registered_callbacks"]["player_disconnect"] = lua.create_table();
lua.script(R"(
zepha.register_on = function(event, callback)
if type(event) ~= "string" then return nil end
if type(callback) ~= "function" then return nil end
if zepha.registered_callbacks[event] == nil then return nil end
table.insert(zepha.registered_callbacks[event], callback)
end
)");
}
}

View File

@ -5,9 +5,10 @@
#pragma once
#include <sol2/sol.hpp>
#include "LuaInventory.h"
#include "../../../def/LocalDefs.h"
#include "../../../game/scene/world/Player.h"
#include "LuaInventory.h"
class LocalLuaPlayer {
public:

View File

@ -0,0 +1,69 @@
//
// Created by aurailus on 2020-02-17.
//
#include "ServerLuaPlayer.h"
#include "../../../util/net/NetHandler.h"
void ServerLuaPlayer::set_pos(const sol::table &pos) {
player.setPos({pos["x"], pos["y"], pos["z"]});
}
sol::table ServerLuaPlayer::get_pos(sol::this_state s) {
glm::vec3 pos = player.getPos();
return sol::state_view(s).create_table_with("x", pos.x, "y", pos.y, "z", pos.z);
}
sol::table ServerLuaPlayer::get_block_pos(sol::this_state s) {
glm::vec3 pos = glm::floor(player.getPos());
return sol::state_view(s).create_table_with("x", pos.x, "y", pos.y, "z", pos.z);
}
//void ServerLuaPlayer::set_vel(const sol::table &vel) {
// player.setVel({vel["x"], vel["y"], vel["z"]});
//}
//sol::table ServerLuaPlayer::get_vel(sol::this_state s) {
// glm::vec3 vel = player.getVel();
// return sol::state_view(s).create_table_with("x", vel.x, "y", vel.y, "z", vel.z);
//}
void ServerLuaPlayer::set_look_yaw(float rot) {
player.setYaw(rot);
}
float ServerLuaPlayer::get_look_yaw() {
return player.getYaw();
}
void ServerLuaPlayer::set_look_pitch(float rot) {
player.setPitch(rot);
}
float ServerLuaPlayer::get_look_pitch() {
return player.getPitch();
}
void ServerLuaPlayer::set_flying(bool shouldFly) {
player.setFlying(shouldFly);
}
bool ServerLuaPlayer::get_flying() {
return player.isFlying();
}
std::string ServerLuaPlayer::get_name() {
return player.username;
}
unsigned int ServerLuaPlayer::get_cid() {
return cid;
}
std::string ServerLuaPlayer::get_address() {
return NetHandler::intToIPString(player.address.host) + ":" + std::to_string(player.address.port);
}
LuaInventory ServerLuaPlayer::get_inventory() {
return LuaInventory(player.getInventory());
}

View File

@ -0,0 +1,46 @@
//
// Created by aurailus on 2020-02-17.
//
#pragma once
#include <sol2/sol.hpp>
#include "LuaInventory.h"
#include "../../../server/conn/ServerClient.h"
class ServerLuaPlayer {
public:
ServerLuaPlayer(ServerClient& player) : player(player), cid(player.cid) {}
ServerClient& player;
unsigned int cid;
bool is_player = true;
void set_pos(const sol::table& pos);
sol::table get_pos(sol::this_state s);
sol::table get_block_pos(sol::this_state s);
// void set_vel(const sol::table& vel);
// sol::table get_vel(sol::this_state s);
void set_look_yaw(float rot);
float get_look_yaw();
void set_look_pitch(float rot);
float get_look_pitch();
// std::string get_menu_state();
// void close_menu();
// void open_menu(sol::this_state s, std::string menu, sol::optional<sol::table> callbacks);
LuaInventory get_inventory();
// void set_selected_block(std::string block);
void set_flying(bool shouldFly);
bool get_flying();
std::string get_name();
unsigned int get_cid();
std::string get_address();
};

View File

@ -7,9 +7,8 @@
#include <sol2/sol.hpp>
#include "LuaInventory.h"
void remove_list(std::string name);
namespace ClientApi {
void inventory(sol::state& lua) {
static void inventory(sol::state& lua) {
lua.new_usertype<LuaInventory>("InventoryRef",
"add_list", &LuaInventory::add_list,
"get_list", &LuaInventory::get_list,

View File

@ -4,10 +4,8 @@
#pragma once
#include "LocalLuaEntity.h"
#include "../../../game/scene/world/LocalWorld.h"
#include "LocalLuaPlayer.h"
#include <sol2/sol.hpp>
#include "LocalLuaPlayer.h"
namespace ClientApi {
void local_player(sol::state& lua) {

View File

@ -0,0 +1,45 @@
//
// Created by aurailus on 2020-02-17.
//
#pragma once
#include <sol2/sol.hpp>
#include "ServerLuaPlayer.h"
namespace ServerApi {
void server_player(sol::state& lua) {
lua.new_usertype<ServerLuaPlayer>("ServerPlayer",
"is_player", sol::readonly(&ServerLuaPlayer::is_player),
"set_pos", &ServerLuaPlayer::set_pos,
"get_pos", &ServerLuaPlayer::get_pos,
"get_block_pos", &ServerLuaPlayer::get_block_pos,
// "set_vel", &ServerLuaPlayer::set_vel,
// "get_vel", &ServerLuaPlayer::get_vel,
"set_look_yaw", &ServerLuaPlayer::set_look_yaw,
"get_look_yaw", &ServerLuaPlayer::get_look_yaw,
"set_look_pitch", &ServerLuaPlayer::set_look_pitch,
"get_look_pitch", &ServerLuaPlayer::get_look_pitch,
"get_inventory", &ServerLuaPlayer::get_inventory,
// "open_menu", &ServerLuaPlayer::open_menu,
// "close_menu", &ServerLuaPlayer::close_menu,
"pos", sol::property(&ServerLuaPlayer::get_pos, &ServerLuaPlayer::set_pos),
"block_pos", sol::property(&ServerLuaPlayer::get_block_pos, &ServerLuaPlayer::set_pos),
// "vel", sol::property(&ServerLuaPlayer::get_vel, &ServerLuaPlayer::set_vel),
"look_yaw", sol::property(&ServerLuaPlayer::get_look_yaw, &ServerLuaPlayer::set_look_yaw),
"look_yaw", sol::property(&ServerLuaPlayer::get_look_pitch, &ServerLuaPlayer::set_look_pitch),
"flying", sol::property(&ServerLuaPlayer::set_flying, &ServerLuaPlayer::get_flying),
"name", sol::property(&ServerLuaPlayer::get_name),
"cid", sol::property(&ServerLuaPlayer::get_cid),
"address", sol::property(&ServerLuaPlayer::get_address)
// "menu_state", sol::property(&ServerLuaPlayer::get_menu_state)
);
}
}

View File

@ -1,46 +0,0 @@
//
// Created by aurailus on 11/06/19.
//
#pragma once
#include "../LuaMod.h"
#include "../LuaParser.h"
#include "../../util/Timer.h"
#include "../../server/asset/ServerTexture.h"
#include <cute_files/cute_files.h>
#include <json/json.hpp>
#include <iomanip>
using nlohmann::json;
class ServerDefs;
class ServerWorld;
class ServerLuaParser : public LuaParser {
public:
void init(ServerDefs& defs, ServerWorld& world, std::string rootPath);
void loadModules(ServerDefs& defs, ServerWorld& world);
void loadMods(ServerDefs& defs, const std::string& rootPath);
void registerDefinitions(ServerDefs &defs);
void update(double delta) override;
~ServerLuaParser() = default;
std::vector<LuaMod> mods;
private:
std::list<std::string> findModDirs(const std::string& rootPath);
std::vector<LuaMod> createLuaMods(std::list<std::string> modDirs);
void createTextures(ServerDefs& defs);
void createModels(ServerDefs& defs);
void handleDependencies();
void serializeMods();
sol::protected_function_result errorCallback(lua_State*, sol::protected_function_result errPfr);
sol::protected_function_result DoFileSandboxed(std::string file);
double delta = 0;
};

View File

@ -12,7 +12,6 @@
#include "../register/RegisterBiomes.h"
#include "../api/type/LocalLuaPlayer.h"
#include "../api/type/cLocalLuaEntity.h"
#include "../api/type/cLuaLocalPlayer.h"
#include "../api/type/cLuaInventory.h"
@ -20,23 +19,19 @@
#include "../api/type/cLocalLuaAnimationManager.h"
#include "../api/modules/delay.h"
#include "../api/modules/register_block.h"
#include "../api/modules/register_blockmodel.h"
#include "../api/modules/register_biome.h"
#include "../api/modules/register_item.h"
#include "../api/modules/register_entity.h"
#include "../api/modules/set_block.h"
#include "../api/modules/get_block.h"
#include "../api/modules/remove_block.h"
#include "../api/modules/add_entity.h"
#include "../api/modules/remove_entity.h"
#include "../api/modules/register_keybind.h"
#include "../api/functions/cUpdateEntities.h"
#include "../api/functions/update_entities.h"
void LocalLuaParser::init(LocalDefs& defs, LocalWorld& world, Player& player) {
//Load Base Libraries
@ -88,25 +83,25 @@ void LocalLuaParser::loadModules(LocalDefs &defs, LocalWorld &world, Player& pla
Api::add_entity_c (lua, core, defs, world);
Api::remove_entity_c (lua, core, defs, world);
ClientApi::update_entities(lua);
Api::update_entities(lua);
//Sandbox the dofile function
lua["dofile"] = lua["loadfile"] = sol::nil;
lua.set_function("runfile", &LocalLuaParser::DoFileSandboxed, this);
lua.set_function("runfile", &LocalLuaParser::runFileSandboxed, this);
}
void LocalLuaParser::loadMods() {
//Load "base" if it exists.
for (const std::string& modName : modsOrder) {
if (modName == "base") {
DoFileSandboxed(modName + "/main");
runFileSandboxed(modName + "/main");
break;
}
}
for (const std::string& modName : modsOrder) {
if (modName != "base") {
DoFileSandboxed(modName + "/main");
runFileSandboxed(modName + "/main");
}
}
}
@ -164,7 +159,7 @@ sol::protected_function_result LocalLuaParser::errorCallback(lua_State*, sol::pr
return errPfr;
}
sol::protected_function_result LocalLuaParser::DoFileSandboxed(std::string file) {
sol::protected_function_result LocalLuaParser::runFileSandboxed(std::string file) {
size_t modname_length = file.find('/');
std::string modname = file.substr(0, modname_length);

View File

@ -28,8 +28,8 @@ public:
std::vector<LuaMod> mods;
std::vector<std::string> modsOrder;
private:
sol::protected_function_result DoFileSandboxed(std::string file);
sol::protected_function_result errorCallback(lua_State*, sol::protected_function_result errPfr);
sol::protected_function_result runFileSandboxed(std::string file);
double delta = 0;
LuaInputManager manager;

View File

@ -0,0 +1,196 @@
//
// Created by aurailus on 11/06/19.
//
#include <gzip/compress.hpp>
#include <enet/enet.h>
#include "../ErrorFormatter.h"
#include "../register/RegisterBlocks.h"
#include "../register/RegisterItems.h"
#include "../register/RegisterBiomes.h"
#include "ServerLuaParser.h"
// Types
#include "../api/type/sServerLuaPlayer.h"
#include "../api/type/sServerLuaEntity.h"
#include "../api/type/cLuaInventory.h"
// Modules
#include "../api/modules/delay.h"
#include "../api/modules/register_block.h"
#include "../api/modules/register_blockmodel.h"
#include "../api/modules/register_biome.h"
#include "../api/modules/register_item.h"
#include "../api/modules/register_entity.h"
#include "../api/modules/register_keybind.h"
#include "../api/modules/register_on.h"
#include "../api/modules/set_block.h"
#include "../api/modules/get_block.h"
#include "../api/modules/remove_block.h"
#include "../api/modules/add_entity.h"
#include "../api/modules/remove_entity.h"
// Functions
#include "../api/functions/trigger_event.h"
#include "../api/functions/update_entities.h"
void ServerLuaParser::init(ServerDefs& defs, ServerWorld& world, std::string path) {
lua.open_libraries(sol::lib::base, sol::lib::string, sol::lib::math, sol::lib::table);
loadApi(defs, world);
handler.loadMods(defs, path + "mods");
handler.executeMods(std::bind(&ServerLuaParser::runFileSandboxed, this, std::placeholders::_1));
registerDefs(defs);
std::cout << Log::info << "Loaded " << handler.cGetMods().size() << " mods: [ ";
for (unsigned int i = 0; i < handler.cGetMods().size(); i++)
std::cout << handler.cGetMods()[i].config.name << (i < handler.cGetMods().size() - 1 ? ", " : " ]\n");
}
void ServerLuaParser::update(double delta) {
LuaParser::update(delta);
this->delta += delta;
while (this->delta > double(UPDATE_STEP)) {
core["__builtin"]["update_entities"](double(UPDATE_STEP));
this->delta -= double(UPDATE_STEP);
}
}
void ServerLuaParser::sendModsPacket(ENetPeer* peer) const {
for (const LuaMod& mod : handler.cGetMods())
Serializer().append(mod.serialized).packet(PacketType::MODS).sendTo(peer, PacketChannel::CONNECT);
std::vector<std::string> order {};
for (const LuaMod& mod : handler.cGetMods()) order.push_back(mod.config.name);
Serializer().append(order).packet(PacketType::MOD_ORDER).sendTo(peer, PacketChannel::CONNECT);
}
void ServerLuaParser::playerConnected(std::shared_ptr<ServerClient> client) {
auto players = core.get<sol::table>("players");
players.add(ServerLuaPlayer(*client));
core["__builtin"]["trigger_event"]("player_join", players[players.size()]);
core["__builtin"]["trigger_event"]("player_connect", players[players.size()]);
}
void ServerLuaParser::playerDisconnected(std::shared_ptr<ServerClient> client) {
for (auto& pair : core.get<sol::table>("players")) {
ServerLuaPlayer& p = pair.second.as<ServerLuaPlayer>();
if (p.cid == client->cid) {
core["__builtin"]["trigger_event"]("player_disconnect", p);
p.is_player = false;
core.get<sol::table>("players")[pair.first] = sol::nil;
break;
}
}
}
void ServerLuaParser::loadApi(ServerDefs &defs, ServerWorld &world) {
//Create Zepha Table
core = lua.create_table();
lua["zepha"] = core;
core["__builtin"] = lua.create_table();
//Load Types
ServerApi::entity(lua);
ServerApi::server_player(lua);
ClientApi::inventory(lua);
core["server"] = true;
core["players"] = lua.create_table();
//Load Modules
Api::delay(core, delayed_functions);
Api::register_block (lua, core);
Api::register_blockmodel (lua, core);
Api::register_biome (lua, core);
Api::register_item (lua, core);
Api::register_entity (lua, core);
Api::register_keybind (lua, core);
Api::register_on_s (lua, core, *this);
Api::get_block (core, defs.defs, world);
Api::set_block (core, defs.defs, world);
Api::remove_block (core, defs.defs, world);
Api::add_entity_s (lua, core, defs, world);
Api::remove_entity_s (lua, core, defs, world);
Api::trigger_event(lua);
Api::update_entities(lua);
//Sandbox the dofile function
lua["dofile"] = lua["loadfile"] = sol::nil;
lua.set_function("runfile", &ServerLuaParser::runFileSandboxed, this);
}
void ServerLuaParser::registerDefs(ServerDefs &defs) {
RegisterBlocks::server(core, defs);
RegisterItems ::server(core, defs);
RegisterBiomes::server(core, defs);
}
sol::protected_function_result ServerLuaParser::errorCallback(lua_State*, sol::protected_function_result errPfr) {
sol::error err = errPfr;
std::string errString = err.what();
std::string::size_type slash = errString.find('/');
assert(slash != std::string::npos);
std::string modString = errString.substr(0, slash);
std::string::size_type lineNumStart = errString.find(':', slash);
assert(lineNumStart != std::string::npos);
std::string::size_type lineNumEnd = errString.find(':', lineNumStart + 1);
assert(lineNumEnd != std::string::npos);
std::string fileName = errString.substr(0, lineNumStart);
int lineNum = std::stoi(errString.substr(lineNumStart + 1, lineNumEnd - lineNumStart - 1));
for (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;
}
}
break;
}
}
exit(1);
return errPfr;
}
sol::protected_function_result ServerLuaParser::runFileSandboxed(const std::string& file) {
size_t modname_length = file.find('/');
std::string modname = file.substr(0, modname_length);
for (const LuaMod& mod : handler.cGetMods()) {
if (strncmp(mod.config.name.c_str(), modname.c_str(), modname_length) == 0) {
for (const LuaModFile& f : mod.files) {
if (f.path == file) {
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;
auto pfr = lua.safe_script(f.file, env, std::bind(&ServerLuaParser::errorCallback, this,
std::placeholders::_1, std::placeholders::_2), "@" + f.path, sol::load_mode::text);
return pfr;
}
}
std::cout << Log::err << "Error opening \"" + file + "\", not found." << Log::endl;
break;
}
}
}

View File

@ -0,0 +1,34 @@
//
// Created by aurailus on 11/06/19.
//
#pragma once
#include "../LuaParser.h"
#include "ServerModHandler.h"
#include "../../server/conn/ServerClient.h"
class ServerDefs;
class ServerWorld;
class EnetPeer;
class ServerLuaParser : public LuaParser {
public:
void init(ServerDefs& defs, ServerWorld& world, std::string rootPath);
void update(double delta) override;
void sendModsPacket(ENetPeer* peer) const;
void playerConnected(std::shared_ptr<ServerClient> client);
void playerDisconnected(std::shared_ptr<ServerClient> client);
private:
void loadApi(ServerDefs& defs, ServerWorld& world);
void registerDefs(ServerDefs &defs);
sol::protected_function_result errorCallback(lua_State*, sol::protected_function_result errPfr);
sol::protected_function_result runFileSandboxed(const std::string& file);
ServerModHandler handler;
double delta = 0;
};

View File

@ -1,132 +1,48 @@
//
// Created by aurailus on 11/06/19.
// Created by aurailus on 2020-02-19.
//
#include <fstream>
#include <json/json.hpp>
#include <gzip/compress.hpp>
#include "ServerLuaParser.h"
#include "../register/RegisterBlocks.h"
#include "../register/RegisterItems.h"
#include "../register/RegisterBiomes.h"
#include "../api/type/sServerLuaEntity.h"
#include "../api/modules/delay.h"
#include "../api/modules/register_block.h"
#include "../api/modules/register_blockmodel.h"
#include "../api/modules/register_biome.h"
#include "../api/modules/register_item.h"
#include "../api/modules/register_entity.h"
#include "../api/modules/register_keybind.h"
#include "../api/modules/set_block.h"
#include "../api/modules/get_block.h"
#include "../api/modules/remove_block.h"
#include "../api/modules/add_entity.h"
#include "../api/modules/remove_entity.h"
#include "../api/functions/sUpdateEntities.h"
#include "../VenusParser.h"
#include "../ErrorFormatter.h"
#include "../../def/ServerDefs.h"
#include "../../util/net/Serializer.h"
void ServerLuaParser::init(ServerDefs& defs, ServerWorld& world, std::string path) {
//Load Base Libraries
lua.open_libraries(sol::lib::base, sol::lib::string, sol::lib::math, sol::lib::table);
#include "ServerModHandler.h"
//Define Panic Callback
// lua_atpanic(lua, sol::c_call<decltype(&LuaParser::override_panic), &LuaParser::override_panic>);
void ServerModHandler::loadMods(ServerDefs& defs, const std::string &path) {
auto modDirs = findModDirectories(path);
mods = initializeLuaMods(modDirs);
//Load Modules
loadModules(defs, world);
loadTextures(defs, mods);
loadModels(defs, mods);
//Load Mods
loadMods(defs, path + "mods");
//Register Blocks
registerDefinitions(defs);
organizeDependencies(mods);
serializeMods(mods);
}
void ServerLuaParser::loadModules(ServerDefs &defs, ServerWorld &world) {
//Create Zepha Table
core = lua.create_table();
lua["zepha"] = core;
core["__builtin"] = lua.create_table();
//Load Types
ServerApi::entity(lua);
core["server"] = true;
core["player"] = sol::nil;
//Load Modules
Api::delay(core, delayed_functions);
Api::register_block (lua, core);
Api::register_blockmodel (lua, core);
Api::register_biome (lua, core);
Api::register_item (lua, core);
Api::register_entity (lua, core);
Api::register_keybind (lua, core);
Api::get_block (core, defs.defs, world);
Api::set_block (core, defs.defs, world);
Api::remove_block (core, defs.defs, world);
Api::add_entity_s (lua, core, defs, world);
Api::remove_entity_s (lua, core, defs, world);
ServerApi::update_entities(lua);
//Sandbox the dofile function
lua["dofile"] = lua["loadfile"] = sol::nil;
lua.set_function("runfile", &ServerLuaParser::DoFileSandboxed, this);
}
void ServerLuaParser::registerDefinitions(ServerDefs &defs) {
RegisterBlocks::server(core, defs);
RegisterItems ::server(core, defs);
RegisterBiomes::server(core, defs);
}
void ServerLuaParser::loadMods(ServerDefs& defs, const std::string& rootPath) {
auto modDirs = findModDirs(rootPath);
mods = createLuaMods(modDirs);
createTextures(defs);
createModels(defs);
handleDependencies();
serializeMods();
//Load "base" if it exists.
void ServerModHandler::executeMods(std::function<void(std::string)> run) {
for (LuaMod& mod : mods) {
if (mod.config.name == "base") {
DoFileSandboxed(mod.config.name + "/main");
run(mod.config.name + "/main");
break;
}
}
for (LuaMod& mod : mods) {
if (mod.config.name != "base") {
DoFileSandboxed(mod.config.name + "/main");
}
if (mod.config.name != "base") run(mod.config.name + "/main");
}
}
void ServerLuaParser::update(double delta) {
LuaParser::update(delta);
this->delta += delta;
while (this->delta > double(UPDATE_STEP)) {
core["__builtin"]["update_entities"](double(UPDATE_STEP));
this->delta -= double(UPDATE_STEP);
}
const std::vector<LuaMod>& ServerModHandler::cGetMods() const {
return mods;
}
std::list<std::string> ServerLuaParser::findModDirs(const std::string& rootPath) {
//Find Mod Directories
std::list<std::string> ServerModHandler::findModDirectories(const std::string& path) {
std::list<std::string> modDirs {};
std::list<std::string> dirsToScan {rootPath};
std::list<std::string> dirsToScan {path};
cf_dir_t dir;
@ -140,16 +56,18 @@ std::list<std::string> ServerLuaParser::findModDirs(const std::string& rootPath)
std::list<std::string> subDirs;
while (dir.has_next) {
// Read through files in the directory
cf_file_t scannedFile;
cf_read_file(&dir, &scannedFile);
if (strncmp(scannedFile.name, ".", 1) != 0) {
if (scannedFile.is_dir) subDirs.emplace_back(scannedFile.path);
else if (strncmp(scannedFile.name, "conf.json", 10) == 0) {
isModFolder = true;
break;
}
if (strncmp(scannedFile.name, ".", 1) == 0) {
cf_dir_next(&dir);
continue;
}
if (scannedFile.is_dir) subDirs.emplace_back(scannedFile.path);
else if (strlen(scannedFile.name) == 9 && strncmp(scannedFile.name, "conf.json", 9) == 0) {
isModFolder = true;
break;
}
cf_dir_next(&dir);
@ -164,10 +82,11 @@ std::list<std::string> ServerLuaParser::findModDirs(const std::string& rootPath)
return std::move(modDirs);
}
std::vector<LuaMod> ServerLuaParser::createLuaMods(std::list<std::string> modDirs) {
cf_dir_t dir;
std::vector<LuaMod> ServerModHandler::initializeLuaMods(const std::list<std::string> modDirs) {
using nlohmann::json;
std::vector<LuaMod> mods;
std::vector<LuaMod> mods {};
cf_dir_t dir;
for (const std::string& modDir : modDirs) {
std::string root = modDir + "/script";
@ -182,7 +101,6 @@ std::vector<LuaMod> ServerLuaParser::createLuaMods(std::list<std::string> modDir
cf_dir_open(&dir, dirStr.c_str());
while (dir.has_next) {
// Read through files in the directory
cf_file_t scannedFile;
cf_read_file(&dir, &scannedFile);
@ -246,9 +164,7 @@ std::vector<LuaMod> ServerLuaParser::createLuaMods(std::list<std::string> modDir
exit(1);
}
}
else {
modPath.resize(modPath.size() - 4);
}
else modPath.resize(modPath.size() - 4);
LuaModFile f {modPath, fileStr};
mod.files.push_back(f);
@ -260,7 +176,7 @@ std::vector<LuaMod> ServerLuaParser::createLuaMods(std::list<std::string> modDir
return mods;
}
void ServerLuaParser::createTextures(ServerDefs &defs) {
void ServerModHandler::loadTextures(ServerDefs &defs, const std::vector<LuaMod>& mods) {
cf_dir_t dir;
for (const LuaMod& mod : mods) {
std::string root = mod.modPath + "/textures";
@ -274,10 +190,7 @@ void ServerLuaParser::createTextures(ServerDefs &defs) {
if (!cf_file_exists(dirStr.c_str())) continue;
cf_dir_open(&dir, dirStr.c_str());
cf_dir_open(&dir, dirStr.c_str());
while (dir.has_next) {
// Read through files in the directory
cf_file_t scannedFile;
cf_read_file(&dir, &scannedFile);
@ -303,13 +216,12 @@ void ServerLuaParser::createTextures(ServerDefs &defs) {
cf_dir_next(&dir);
}
cf_dir_close(&dir);
}
}
}
void ServerLuaParser::createModels(ServerDefs &defs) {
void ServerModHandler::loadModels(ServerDefs &defs, const std::vector<LuaMod>& mods) {
cf_dir_t dir;
for (const LuaMod& mod : mods) {
std::string root = mod.modPath + "/models";
@ -324,7 +236,6 @@ void ServerLuaParser::createModels(ServerDefs &defs) {
cf_dir_open(&dir, dirStr.c_str());
while (dir.has_next) {
// Read through files in the directory
cf_file_t scannedFile;
cf_read_file(&dir, &scannedFile);
@ -348,13 +259,12 @@ void ServerLuaParser::createModels(ServerDefs &defs) {
cf_dir_next(&dir);
}
cf_dir_close(&dir);
}
}
}
void ServerLuaParser::handleDependencies() {
void ServerModHandler::organizeDependencies(std::vector<LuaMod>& mods) {
for (int i = 0; i < mods.size(); i++) {
LuaMod& mod = mods[i];
auto& deps = mod.config.depends;
@ -381,7 +291,7 @@ void ServerLuaParser::handleDependencies() {
}
}
void ServerLuaParser::serializeMods() {
void ServerModHandler::serializeMods(std::vector<LuaMod>& mods) {
for (LuaMod& mod : mods) {
Serializer s = {};
s.append(mod.config.name)
@ -406,62 +316,3 @@ void ServerLuaParser::serializeMods() {
mod.serialized = comp;
}
}
sol::protected_function_result ServerLuaParser::errorCallback(lua_State*, sol::protected_function_result errPfr) {
sol::error err = errPfr;
std::string errString = err.what();
std::string::size_type slash = errString.find('/');
assert(slash != std::string::npos);
std::string modString = errString.substr(0, slash);
std::string::size_type lineNumStart = errString.find(':', slash);
assert(lineNumStart != std::string::npos);
std::string::size_type lineNumEnd = errString.find(':', lineNumStart + 1);
assert(lineNumEnd != std::string::npos);
std::string fileName = errString.substr(0, lineNumStart);
int lineNum = std::stoi(errString.substr(lineNumStart + 1, lineNumEnd - lineNumStart - 1));
for (auto& mod : mods) {
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;
}
}
break;
}
}
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);
for (LuaMod& mod : mods) {
if (strncmp(mod.config.name.c_str(), modname.c_str(), modname_length) == 0) {
for (LuaModFile& f : mod.files) {
if (f.path == file) {
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;
auto pfr = lua.safe_script(f.file, env, std::bind(&ServerLuaParser::errorCallback, this,
std::placeholders::_1, std::placeholders::_2), "@" + f.path, sol::load_mode::text);
return pfr;
}
}
std::cout << Log::err << "Error opening \"" + file + "\", not found." << Log::endl;
break;
}
}
}

View File

@ -0,0 +1,27 @@
//
// Created by aurailus on 2020-02-19.
//
#pragma once
#include <list>
#include <string>
#include "../LuaMod.h"
class ServerDefs;
class ServerModHandler {
public:
void loadMods(ServerDefs& defs, const std::string& path);
void executeMods(std::function<void(std::string)> run);
const std::vector<LuaMod>& cGetMods() const;
private:
static std::list<std::string> findModDirectories(const std::string& path);
static std::vector<LuaMod> initializeLuaMods(const std::list<std::string> modDirs);
static void loadTextures(ServerDefs &defs, const std::vector<LuaMod>& mods);
static void loadModels(ServerDefs &defs, const std::vector<LuaMod>& mods);
static void organizeDependencies(std::vector<LuaMod>& mods);
static void serializeMods(std::vector<LuaMod>& mods);
std::vector<LuaMod> mods {};
};

View File

@ -4,11 +4,13 @@
#include <thread>
#include "../util/Timer.h"
#include "Server.h"
Server::Server(const std::string& path, unsigned short port, const std::string& subgame) :
defs(subgame, path),
clientList(),
clientList(defs),
world(10, defs, clientList),
port(port),
handler(port, 32),
@ -18,12 +20,6 @@ Server::Server(const std::string& path, unsigned short port, const std::string&
world.init();
config.init();
std::cout << Log::info << "Loaded " << defs.luaApi.mods.size() << " mods: [ ";
for (unsigned int i = 0; i < defs.luaApi.mods.size(); i++) {
std::cout << defs.luaApi.mods[i].config.name << (i < defs.luaApi.mods.size() - 1 ? ", " : " ]");
}
std::cout << std::endl;
std::cout << Log::info << "Server started successfully, listening for clients." << Log::endl;
while (alive) update();
}
@ -33,7 +29,7 @@ void Server::update() {
Timer loop("");
world.update(0);
defs.update(deltaTime);
defs.update(deltaTime, clientList);
ENetEvent event;
while (handler.update(&event) && loop.elapsedNs() < interval_ns) {
@ -63,7 +59,15 @@ void Server::update() {
else {
bool done = config.handlePacket(*client, p);
if (done) {
clientList.createPlayer(*client);
std::shared_ptr<ServerClient> clientShared = nullptr;
for (auto& sClient : clientList.clients) {
if (sClient->cid == client->cid) {
clientShared = sClient;
break;
}
}
if (!clientShared) break;
clientList.createPlayer(clientShared);
}
}
@ -91,14 +95,16 @@ void Server::handlePlayerPacket(ServerClient &client, Packet& p) {
case PacketType::THIS_PLAYER_INFO: {
Deserializer d(p.data);
client.setPos(d.read<glm::vec3>());
client.setAngle(d.read<float>());
client.setPitch(d.read<float>());
client.setYaw(d.read<float>());
//Send All ServerClients the new positon
//Send All ClientList the new positon
Packet r(PacketType::PLAYER_INFO);
r.data = Serializer()
.append(client.cid)
.append(client.getPos())
.append(client.getAngle())
.append(client.getPitch())
.append(client.getYaw())
.data;
for (auto& iter : clientList.clients) {

View File

@ -4,7 +4,7 @@
#pragma once
#include "conn/ServerClients.h"
#include "conn/ClientList.h"
#include "world/ServerWorld.h"
#include "config/ServerConfig.h"
#include "../def/ServerDefs.h"
@ -29,7 +29,7 @@ private:
ServerDefs defs;
ServerWorld world;
NetHandler handler;
ServerClients clientList;
ClientList clientList;
ServerConfig config;
double elapsedSeconds = 0;

View File

@ -18,12 +18,13 @@ void ServerConfig::init() {
}
}
bool ServerConfig::handlePacket(ServerClient &client, Packet &r) {
bool ServerConfig::handlePacket(ServerClient& client, Packet& r) {
switch (r.type) {
default: break;
case PacketType::CONNECT_DATA_RECVD: {
return true;
}
case PacketType::BLOCK_IDENTIFIER_LIST: {
Serializer()
.append(blockIdentifierList)
@ -31,6 +32,7 @@ bool ServerConfig::handlePacket(ServerClient &client, Packet &r) {
.sendTo(client.peer, PacketChannel::CONNECT);
break;
}
case PacketType::BIOME_IDENTIFIER_LIST: {
Serializer()
.append(biomeIdentifierList)
@ -38,18 +40,12 @@ bool ServerConfig::handlePacket(ServerClient &client, Packet &r) {
.sendTo(client.peer, PacketChannel::CONNECT);
break;
}
case PacketType::MODS: {
for (LuaMod& mod : defs.luaApi.mods) {
Packet p(PacketType::MODS);
p.data = Serializer().append(mod.serialized).data;
p.sendTo(client.peer, PacketChannel::CONNECT);
}
std::vector<std::string> order {};
for (LuaMod& mod : defs.luaApi.mods) order.push_back(mod.config.name);
Serializer().append(order).packet(PacketType::MOD_ORDER).sendTo(client.peer, PacketChannel::CONNECT);
case PacketType::MODS: {
defs.luaApi.sendModsPacket(client.peer);
break;
}
case PacketType::MEDIA: {
const unsigned int MAX_PACKET_SIZE = 32*1024;
unsigned int packetSize = 0;
@ -107,5 +103,6 @@ bool ServerConfig::handlePacket(ServerClient &client, Packet &r) {
d.sendTo(client.peer, PacketChannel::CONNECT);
}
}
return false;
}

View File

@ -0,0 +1,55 @@
//
// Created by aurailus on 07/02/19.
//
#include "ClientList.h"
#include "../../util/net/Serializer.h"
#include "../../util/net/NetHandler.h"
#include "../../def/ServerDefs.h"
ClientList::ClientList(ServerDefs& defs) :
defs(defs) {}
void ClientList::handleConnect(ENetEvent e) {
ENetPeer* peer = e.peer;
ENetAddress& addr = peer->address;
auto client = std::make_shared<ServerClient>(peer, addr, defs.defs);
clients.push_back(client);
peer->data = client.get();
std::cout << Log::info << NetHandler::intToIPString(addr.host) << ":" << addr.port << " connected." << Log::endl;
}
void ClientList::handleDisconnect(ENetEvent e) {
unsigned int cid = static_cast<ServerClient*>(e.peer->data)->cid;
for (unsigned int i = 0; i < clients.size(); i++) {
if (clients[i]->cid == cid) {
defs.luaApi.playerDisconnected(clients[i]);
clients.erase(clients.begin() + i);
break;
}
}
ENetAddress& addr = e.peer->address;
std::cout << Log::info << NetHandler::intToIPString(addr.host) << ":" << addr.port << " disconnected." << Log::endl;
}
void ClientList::createPlayer(std::shared_ptr<ServerClient> c) {
c->hasPlayer = true;
c->setUsername("TEMPORaRY");
defs.luaApi.playerConnected(c);
Packet p(PacketType::THIS_PLAYER_INFO);
p.data = Serializer()
.append(c->cid)
.append(c->getPos())
.append(c->getPitch())
.append(c->getYaw())
.data;
p.sendTo(c->peer, PacketChannel::ENTITY);
}

View File

@ -0,0 +1,23 @@
//
// Created by aurailus on 07/02/19.
//
#pragma once
#include <vector>
#include "ServerClient.h"
#include "../../lua/parser/ServerLuaParser.h"
class ClientList {
public:
explicit ClientList(ServerDefs& defs);
void handleConnect(ENetEvent e);
void handleDisconnect(ENetEvent e);
void createPlayer(std::shared_ptr<ServerClient> c);
std::vector<std::shared_ptr<ServerClient>> clients;
private:
ServerDefs& defs;
};

View File

@ -5,18 +5,15 @@
#include <iostream>
#include "ServerClient.h"
ServerClient::ServerClient(ENetPeer *peer, ENetAddress address) :
ServerClient::ServerClient(ENetPeer *peer, ENetAddress address, DefinitionAtlas& defs) :
peer(peer),
address(address),
cid(peer->connectID) {}
cid(peer->connectID),
hand(defs, "hand", 1, 1),
inventory(defs) {}
void ServerClient::setMapBlockIntegrity(glm::ivec3 pos, unsigned long long integrity) {
mapBlockIntegrity[pos] = integrity;
}
unsigned long long ServerClient::getMapBlockIntegrity(glm::ivec3 pos) {
if (mapBlockIntegrity.count(pos)) return mapBlockIntegrity[pos];
return 0;
void ServerClient::setUsername(const std::string &name) {
this->username = name;
}
void ServerClient::setPos(glm::vec3 pos) {
@ -35,10 +32,39 @@ glm::vec3 ServerClient::getPos() {
return pos;
}
void ServerClient::setAngle(float angle) {
this->angle = angle;
void ServerClient::setPitch(float pitch) {
this->pitch = pitch;
}
float ServerClient::getAngle() {
return angle;
float ServerClient::getPitch() {
return pitch;
}
void ServerClient::setYaw(float yaw) {
this->yaw = yaw;
}
float ServerClient::getYaw() {
return yaw;
}
void ServerClient::setFlying(bool flying) {
this->flying = flying;
}
bool ServerClient::isFlying() {
return flying;
}
void ServerClient::setMapBlockIntegrity(glm::ivec3 pos, unsigned long long integrity) {
mapBlockIntegrity[pos] = integrity;
}
unsigned long long ServerClient::getMapBlockIntegrity(glm::ivec3 pos) {
if (mapBlockIntegrity.count(pos)) return mapBlockIntegrity[pos];
return 0;
}
Inventory &ServerClient::getInventory() {
return inventory;
}

View File

@ -9,22 +9,34 @@
#include <unordered_map>
#include "../../util/Vec.h"
#include "../../game/scene/world/InventoryList.h"
#include "../../game/scene/world/Inventory.h"
class ServerClient {
public:
const static int CHUNK_SEND_RANGE = 32;
ServerClient(ENetPeer* peer, ENetAddress address);
ServerClient(ENetPeer* peer, ENetAddress address, DefinitionAtlas& defs);
void setUsername(const std::string& name);
void setPos(glm::vec3 pos);
glm::vec3 getPos();
void setAngle(float angle);
float getAngle();
void setPitch(float pitch);
float getPitch();
void setYaw(float yaw);
float getYaw();
void setFlying(bool flying);
bool isFlying();
void setMapBlockIntegrity(glm::ivec3 pos, unsigned long long integrity);
unsigned long long getMapBlockIntegrity(glm::ivec3 pos);
Inventory& getInventory();
bool hasPlayer = false;
unsigned int cid;
@ -38,7 +50,13 @@ public:
private:
glm::vec3 pos {};
float angle = 0;
float pitch = 0;
float yaw = 0;
bool flying = false;
InventoryList hand;
Inventory inventory;
std::unordered_map<glm::ivec3, unsigned long long, Vec::ivec3> mapBlockIntegrity {};
};

View File

@ -1,52 +0,0 @@
//
// Created by aurailus on 07/02/19.
//
#include "ServerClients.h"
#include "../../util/net/Serializer.h"
void ServerClients::handleConnect(ENetEvent e) {
ENetPeer* peer = e.peer;
ENetAddress& addr = peer->address;
std::cout << Log::info << NetHandler::intToIPString(addr.host) << ":" << addr.port << " connected." << Log::endl;
auto client = new ServerClient(peer, addr);
clients.push_back(client);
peer->data = client;
}
void ServerClients::handleDisconnect(ENetEvent e) {
ENetPeer* peer = e.peer;
ENetAddress& addr = peer->address;
unsigned int cid = static_cast<ServerClient*>(peer->data)->cid;
std::cout << Log::info << NetHandler::intToIPString(addr.host) << ":" << addr.port << " disconnected." << Log::endl;
bool found = false;
auto it = clients.begin();
while (it != clients.end()) {
if ((*it)->cid == cid) {
found = true;
clients.erase(it);
break;
}
it ++;
}
if (!found) std::cout << Log::err << "Tried to disconnect nonexistent client!" << Log::endl;
}
void ServerClients::createPlayer(ServerClient &c) {
c.hasPlayer = true;
Packet p(PacketType::THIS_PLAYER_INFO);
p.data = Serializer()
.append(c.cid)
.append(c.getPos())
.append(c.getAngle())
.data;
p.sendTo(c.peer, PacketChannel::ENTITY);
}

View File

@ -1,23 +0,0 @@
//
// Created by aurailus on 07/02/19.
//
#pragma once
#include <vector>
#include <string>
#include "ServerClient.h"
#include "../../util/net/Packet.h"
#include "../../util/net/PacketChannel.h"
#include "../../util/Log.h"
#include "../../util/net/NetHandler.h"
class ServerClients {
public:
void handleConnect(ENetEvent e);
void handleDisconnect(ENetEvent e);
void createPlayer(ServerClient& c);
std::vector<ServerClient*> clients;
};

View File

@ -13,7 +13,7 @@
#include "ServerWorld.h"
ServerWorld::ServerWorld(unsigned int seed, ServerDefs& defs, ServerClients& clients) :
ServerWorld::ServerWorld(unsigned int seed, ServerDefs& defs, ClientList& clients) :
clientList(clients),
seed(seed),
defs(defs) {

View File

@ -6,17 +6,17 @@
#include <unordered_set>
#include "WorldGenStream.h"
#include "../conn/ServerClients.h"
#include "../conn/ClientList.h"
#include "../../def/ServerDefs.h"
#include "../../game/scene/world/World.h"
#include "../../world/ServerDimension.h"
class ServerWorld : public World {
public:
const static int MB_GEN_H = 6;
const static int MB_GEN_V = 4;
const static int MB_GEN_H = 3;
const static int MB_GEN_V = 3;
explicit ServerWorld(unsigned int seed, ServerDefs& defs, ServerClients& clients);
explicit ServerWorld(unsigned int seed, ServerDefs& defs, ClientList& clients);
void init();
void update(double delta) override;
@ -42,7 +42,7 @@ private:
unsigned int seed;
ServerDefs& defs;
ServerClients& clientList;
ClientList& clientList;
unsigned int generatedChunks = 0;

View File

@ -17,7 +17,7 @@
class WorldGenStream {
public:
static const int THREAD_QUEUE_SIZE = 4;
static const int THREAD_QUEUE_SIZE = 6;
static const int THREADS = 4;
static const int TOTAL_QUEUE_SIZE = THREADS * THREAD_QUEUE_SIZE;

View File

@ -9,9 +9,9 @@
namespace Log {
#ifdef _WIN32
static const char* info = "[INFO] ";
static const char* warn = "[WARN] ";
static const char* err = "[ERR!] ";
static const char* info = "[info] ";
static const char* warn = "[warn] ";
static const char* err = "[err] ";
static const char* endl = "\n";
static const char* undl = "";
@ -21,9 +21,9 @@ 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* 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";
static const char* undl = "\033[4m";

View File

@ -9,7 +9,7 @@
Packet::Packet(PacketType type, bool reliable) : type(type), reliable(reliable) {}
Packet::Packet(ENetPacket *packet) {
Packet::Packet(ENetPacket *packet) : reliable(true) {
std::string packetData(packet->data, packet->data + packet->dataLength);
this->type = static_cast<PacketType>(Deserializer(packetData).read<unsigned int>());
@ -31,4 +31,4 @@ void Packet::sendTo(ENetPeer *peer, PacketChannel channel) {
void Packet::sendTo(const ENetPeer &peer, PacketChannel channel) {
ENetPacket* enet = toENetPacket();
enet_peer_send(const_cast<ENetPeer*>(&peer), static_cast<enet_uint8>(channel), enet);
}
}

View File

@ -24,10 +24,8 @@ public:
void sendTo(ENetPeer* peer, PacketChannel channel);
void sendTo(const ENetPeer &peer, PacketChannel channel);
~Packet() = default;
PacketType type = PacketType::UNDEFINED;
std::string data;
bool reliable;
std::string data {};
bool reliable = true;
};

View File

@ -187,7 +187,9 @@ void LocalDimension::attemptMeshChunk(const std::shared_ptr<BlockChunk>& chunk,
}
if (allExists) {
if (chunk->shouldHaveMesh) pendingMesh.push_back(chunk->pos);
if (chunk->shouldHaveMesh) {
pendingMesh.push_back(chunk->pos);
}
else removeMeshChunk(chunk->pos);
chunk->dirty = false; //TODO: Make dirty work

View File

@ -7,7 +7,7 @@
#include "../server/world/ServerWorld.h"
#include "ServerDimension.h"
void ServerDimension::update(const std::vector<ServerClient*> &clients) {
void ServerDimension::update(const std::vector<std::shared_ptr<ServerClient>> &clients) {
for (const auto& region : regions) {
for (unsigned short i = 0; i < 64; i++) {
if (region.second->operator[](i) == nullptr) continue;

View File

@ -13,7 +13,7 @@ class ServerDimension : public Dimension {
public:
ServerDimension() = default;
void update(const std::vector<ServerClient*>& clients);
void update(const std::vector<std::shared_ptr<ServerClient>>& clients);
void setChunk(std::shared_ptr<BlockChunk> chunk) override;
bool setBlock(glm::ivec3 pos, unsigned int block) override;

View File

@ -23,17 +23,20 @@ bool BlockChunk::setBlock(unsigned int ind, unsigned int blk) {
// Exit if someone is doing something stupid
if (ind >= 4096) return false;
// Mesh emptiness manipulation
if (blk == DefinitionAtlas::AIR && (nonAirBlocks = fmax(nonAirBlocks - 1, 0)) == 0) {
empty = true;
shouldHaveMesh = false;
if (blk == DefinitionAtlas::AIR) {
if ((nonAirBlocks = fmax(nonAirBlocks - 1, 0)) == 0) {
empty = true;
shouldHaveMesh = false;
}
}
else if (blk != DefinitionAtlas::AIR && getBlock(ind) == DefinitionAtlas::AIR) {
if (nonAirBlocks == 0) shouldHaveMesh = true;
else if (getBlock(ind) == DefinitionAtlas::AIR) {
shouldHaveMesh = true;
empty = false;
nonAirBlocks++;
}
// Return the value
RIE::write(ind, blk, blocks, 4096);
// Actually set the block
return RIE::write(ind, blk, blocks, 4096);
}
const std::vector<unsigned int> &BlockChunk::cGetBlocks() const {
@ -82,12 +85,12 @@ void BlockChunk::calcNonAirBlocks() {
for (unsigned int i = 0; i < blocks.size(); i += 2) {
unsigned int cInd = blocks[i];
unsigned int lInd = (i == 0 ? 0 : blocks[i - 2]);
unsigned int nInd = (i == blocks.size() - 2 ? 4095 : blocks[i + 2]);
unsigned int blk = blocks[i + 1];
if (blk > DefinitionAtlas::AIR) {
empty = false;
nonAirBlocks += cInd - lInd;
nonAirBlocks += nInd - cInd;
}
}

View File

@ -11,9 +11,5 @@ zepha.register_block("zeus:default:bush_stem", {
hand = 0.3,
axe = 0.1
},
drop = "zeus:default:wood",
on_break_client = fn(pos) {
zepha.add_entity("zeus:default:dropped_item", vector.add(pos, v(0.5)),
{item = zepha.registered_blocks["zeus:default:bush_stem"].drop});
}
drop = "zeus:default:wood"
})

View File

@ -6,9 +6,5 @@ zepha.register_block("zeus:default:cobblestone", {
hand = 14,
pick = 3
},
drop = "zeus:default:cobblestone",
on_break_client = fn(pos) {
zepha.add_entity("zeus:default:dropped_item", vector.add(pos, v(0.5)),
{item = zepha.registered_blocks["zeus:default:cobblestone"].drop});
}
drop = "zeus:default:cobblestone"
})

View File

@ -7,9 +7,5 @@ zepha.register_block("zeus:default:dirt", {
shovel = 1,
pick = 2
},
drop = "zeus:materials:rock",
on_break_client = fn(pos) {
zepha.add_entity("zeus:default:dropped_item", vector.add(pos, v(0.5)),
{item = zepha.registered_blocks["zeus:default:dirt"].drop});
}
drop = "zeus:materials:rock"
})

View File

@ -17,11 +17,7 @@ zepha.register_block("zeus:default:grass", {
shovel = 1,
pick = 2
},
drop = "zeus:default:dirt",
on_break = fn(pos) {
zepha.add_entity("zeus:default:dropped_item", vector.add(pos, v(0.5)),
{item = zepha.registered_blocks["zeus:default:grass"].drop});
}
drop = "zeus:default:dirt"
})
zepha.register_block("zeus:default:grass_slab", {
@ -48,9 +44,5 @@ zepha.register_block("zeus:default:grass_slab", {
collision_box = {
{0, 0, 0, 1, 0.5, 1}
},
drop = "zeus:default:grass_slab",
on_break_client = fn(pos) {
zepha.add_entity("zeus:default:dropped_item", vector.add(pos, v(0.5)),
{item = zepha.registered_blocks["zeus:default:grass_slab"].drop});
}
drop = "zeus:default:grass_slab"
})

View File

@ -14,9 +14,5 @@ zepha.register_block("zeus:default:leaves", {
hand = 1,
axe = 0.2,
},
drop = "zeus:materials:stick",
on_break_client = fn(pos) {
zepha.add_entity("zeus:default:dropped_item", vector.add(pos, v(0.5)),
{item = zepha.registered_blocks["zeus:default:leaves"].drop});
}
drop = "zeus:materials:stick"
})

View File

@ -7,9 +7,5 @@ zepha.register_block("zeus:default:sand", {
shovel = 1,
pick = 2
},
drop = "zeus:default:sand",
on_break_client = fn(pos) {
zepha.add_entity("zeus:default:dropped_item", vector.add(pos, v(0.5)),
{item = zepha.registered_blocks["zeus:default:sand"].drop});
}
drop = "zeus:default:sand"
})

View File

@ -7,9 +7,5 @@ zepha.register_block("zeus:default:sandstone", {
hand = 14,
pick = 3
},
drop = "zeus:default:sand",
on_break_client = fn(pos) {
zepha.add_entity("zeus:default:dropped_item", vector.add(pos, v(0.5)),
{item = zepha.registered_blocks["zeus:default:sandstone"].drop});
}
drop = "zeus:default:sand"
})

View File

@ -6,9 +6,5 @@ zepha.register_block("zeus:default:stone", {
hand = 14,
pick = 3
},
drop = "zeus:default:cobblestone",
on_break_client = fn(pos) {
zepha.add_entity("zeus:default:dropped_item", vector.add(pos, v(0.5)),
{item = zepha.registered_blocks["zeus:default:stone"].drop});
}
drop = "zeus:default:cobblestone"
})

View File

@ -13,12 +13,6 @@ for i = 1, 5, 1 {
},
toughness = {
hand = 0
},
on_break_client = fn(pos) {
if (math.random() > 0.8) {
zepha.add_entity("zeus:default:dropped_item", vector.add(pos, v(0.5)),
{item = "zeus:materials:plant_fibre"});
}
}
})
}

View File

@ -10,9 +10,5 @@ zepha.register_block("zeus:default:wood", {
hand = 5,
axe = 3,
},
drop = "zeus:default:wood",
on_break_client = fn(pos) {
zepha.add_entity("zeus:default:dropped_item", vector.add(pos, v(0.5)),
{item = zepha.registered_blocks["zeus:default:wood"].drop});
}
drop = "zeus:default:wood"
})

View File

@ -0,0 +1,51 @@
## Register the inventory menu and keybind
zepha.register_keybind("zeus:inventory:open_inventory", {
description = "Open Inventory",
default = zepha.keys.e,
on_press = () => {
if (zepha.player.menu_state == "") {
zepha.player:open_menu([[
body[body]
background: #0003
rect[inventory]
position: 50% 50%
position_anchor: 50% 32%
size: 218px 160px
rect[inv_background]
position: 0px 50px
size: 218px 100px
padding: 20px 10px 8px 10px
background: asset(zeus:inventory:inventory)
inventory
source: current_player
list: main
position: 1px 1px
slot_spacing: 2px 2px
end
end
rect[chest_background]
position: 0px -48px
size: 218px 100px
padding: 20px 10px 8px 10px
background: asset(zeus:inventory:chest)
inventory
source: current_player
list: main
position: 1px 1px
slot_spacing: 2px 2px
end
end
end
end
]])
}
else {
zepha.player:close_menu()
}
}
})

View File

@ -1,189 +1,2 @@
if (zepha.server) { return } ## Only run the following code on the client.
local inventory = zepha.player:get_inventory()
local shit_adding = false
local main = inventory:add_list("main", 44, 11)
zepha.register_keybind("zeus:inventory:add_shit_b", {
description = "Add testing items to inventory",
default = zepha.keys.b,
on_press = () => { shit_adding = 1 },
on_release = () => { shit_adding = 0 }
})
zepha.register_keybind("zeus:inventory:add_shit_i", {
description = "Add testing items to inventory",
default = zepha.keys.n,
on_press = () => { shit_adding = 2 },
on_release = () => { shit_adding = 0 }
})
zepha.delay(() => {
if (shit_adding == 1) {
main:add_stack({"zeus:default:cobblestone", 1})
main:add_stack({"zeus:default:tallgrass_5", 1})
main:add_stack({"zeus:default:leaves", 1})
main:add_stack({"zeus:kinetic:axle_0", 1})
main:add_stack({"zeus:default:wood", 1})
}
if (shit_adding == 2) {
main:add_stack({"zeus:materials:plant_fibre", 1})
main:add_stack({"zeus:materials:plant_twine", 1})
main:add_stack({"zeus:materials:stick", 1})
main:add_stack({"zeus:materials:flint", 1})
}
return true
}, 0)
zepha.register_keybind("zeus:inventory:open_inventory", {
description = "Open Inventory",
default = zepha.keys.e,
on_press = () => {
if (zepha.player.menu_state == "") {
zepha.player:open_menu([[
body[body]
background: #0003
rect[inventory]
position: 50% 50%
position_anchor: 50% 55%
size: 218px 160px
rect[inv_background]
position: 0px 45px
size: 218px 100px
padding: 20px 10px 8px 10px
background: asset(zeus:inventory:inventory)
inventory
source: current_player
list: main
position: 1px 1px
slot_spacing: 2px 2px
end
end
rect[craft_background]
size: 218px 72px
position: 0px -15px
padding: 20px 10px 8px 10px
background: asset(zeus:inventory:crafting)
inventory
source: current_player
list: craft
position: 111px 1px
slot_spacing: 2px 2px
end
inventory
source: current_player
list: craft_result
position: 163px 10px
slot_spacing: 2px 2px
end
end
rect[hot_wheel]
size: 214px 67px
position: 2px 160px
background: asset(zeus:inventory:inventory_wheel)
inventory
source: current_player
list: hot_wheel_1
position: 9px 1px
slot_spacing: 2px 2px
end
inventory
source: current_player
list: hot_wheel_2
position: 117px 1px
slot_spacing: 2px 2px
end
inventory
source: current_player
list: hot_wheel_3
position: 125px 25px
slot_spacing: 2px 2px
end
inventory
source: current_player
list: hot_wheel_4
position: 117px 50px
slot_spacing: 2px 2px
end
inventory
source: current_player
list: hot_wheel_5
position: 9px 50px
slot_spacing: 2px 2px
end
inventory
source: current_player
list: hot_wheel_6
position: 1px 25px
slot_spacing: 2px 2px
end
end
model
scale: 96 96
position: 195 145
type: model
source: zeus:default:player
texture: zeus:default:player
anim_range: 0 300
end
end
end
]], {
body = {
left = fn() {
zepha.player:close_menu()
}
},
inv_background = {
left = fn() {} ## Prevent close menu from triggering.
}
})
}
else {
zepha.player:close_menu()
}
}
})
## Bind crafting
local craft_input = inventory:add_list("craft", 4, 2)
local craft_output = inventory:add_list("craft_result", 2, 2)
crafting.bind(craft_input, craft_output)
## Make hotwheel
local invs = {
inventory:add_list("hot_wheel_1", 5, 5),
inventory:add_list("hot_wheel_2", 5, 5),
inventory:add_list("hot_wheel_3", 5, 5),
inventory:add_list("hot_wheel_4", 5, 5),
inventory:add_list("hot_wheel_5", 5, 5),
inventory:add_list("hot_wheel_6", 5, 5)
}
foreach inv in invs {
inv.allow_take = fn() {
return 0
}
inv.allow_put = fn(slot, item) {
zepha.delay(() => {
## This delay is necessary to avoid the engine overwriting it with nothing
inv:set_stack(slot, item)
}, 0)
return 0
}
}
if (zepha.server) { runfile(_PATH .. "register") }
if (zepha.client) { runfile(_PATH .. "menu") }

View File

@ -0,0 +1,119 @@
## Register the inventory menu and keybind
zepha.register_keybind("zeus:inventory:open_inventory", {
description = "Open Inventory",
default = zepha.keys.e,
on_press = () => {
if (zepha.player.menu_state == "") {
zepha.player:open_menu([[
body[body]
background: #0003
rect[inventory]
position: 50% 50%
position_anchor: 50% 55%
size: 218px 160px
rect[inv_background]
position: 0px 45px
size: 218px 100px
padding: 20px 10px 8px 10px
background: asset(zeus:inventory:inventory)
inventory
source: current_player
list: main
position: 1px 1px
slot_spacing: 2px 2px
end
end
rect[craft_background]
size: 218px 72px
position: 0px -15px
padding: 20px 10px 8px 10px
background: asset(zeus:inventory:crafting)
inventory
source: current_player
list: craft
position: 111px 1px
slot_spacing: 2px 2px
end
inventory
source: current_player
list: craft_result
position: 163px 10px
slot_spacing: 2px 2px
end
end
rect[hot_wheel]
size: 214px 67px
position: 2px 160px
background: asset(zeus:inventory:inventory_wheel)
inventory
source: current_player
list: hot_wheel_1
position: 9px 1px
slot_spacing: 2px 2px
end
inventory
source: current_player
list: hot_wheel_2
position: 117px 1px
slot_spacing: 2px 2px
end
inventory
source: current_player
list: hot_wheel_3
position: 125px 25px
slot_spacing: 2px 2px
end
inventory
source: current_player
list: hot_wheel_4
position: 117px 50px
slot_spacing: 2px 2px
end
inventory
source: current_player
list: hot_wheel_5
position: 9px 50px
slot_spacing: 2px 2px
end
inventory
source: current_player
list: hot_wheel_6
position: 1px 25px
slot_spacing: 2px 2px
end
end
model
scale: 96 96
position: 195 145
type: model
source: zeus:default:player
texture: zeus:default:player
anim_range: 0 300
end
end
end
]], {
body = {
left = fn() {
zepha.player:close_menu()
}
},
inv_background = {
left = fn() {} ## Prevent close menu from triggering.
}
})
}
else {
zepha.player:close_menu()
}
}
})

View File

@ -0,0 +1,71 @@
zepha.register_on("player_join", (p) => {
## Create the main inventory list
local inv = p:get_inventory()
local main = inv:add_list("main", 44, 11)
local shit_adding = false
zepha.register_keybind("zeus:inventory:add_shit_b", {
description = "Add testing items to inventory",
default = zepha.keys.b,
on_press = () => { shit_adding = 1 },
on_release = () => { shit_adding = 0 }
})
zepha.register_keybind("zeus:inventory:add_shit_i", {
description = "Add testing items to inventory",
default = zepha.keys.n,
on_press = () => { shit_adding = 2 },
on_release = () => { shit_adding = 0 }
})
zepha.delay(() => {
if (shit_adding == 1) {
main:add_stack({"zeus:default:cobblestone", 1})
main:add_stack({"zeus:default:tallgrass_5", 1})
main:add_stack({"zeus:default:leaves", 1})
main:add_stack({"zeus:kinetic:axle_0", 1})
main:add_stack({"zeus:default:wood", 1})
}
if (shit_adding == 2) {
main:add_stack({"zeus:materials:plant_fibre", 1})
main:add_stack({"zeus:materials:plant_twine", 1})
main:add_stack({"zeus:materials:stick", 1})
main:add_stack({"zeus:materials:flint", 1})
}
return true
}, 0)
## Bind crafting
local craft_input = inv:add_list("craft", 4, 2)
local craft_output = inv:add_list("craft_result", 2, 2)
crafting.bind(craft_input, craft_output)
## Make hotwheel
local invs = {
inv:add_list("hot_wheel_1", 5, 5),
inv:add_list("hot_wheel_2", 5, 5),
inv:add_list("hot_wheel_3", 5, 5),
inv:add_list("hot_wheel_4", 5, 5),
inv:add_list("hot_wheel_5", 5, 5),
inv:add_list("hot_wheel_6", 5, 5)
}
foreach inv in invs {
inv.allow_take = fn() {
return 0
}
inv.allow_put = fn(slot, item) {
zepha.delay(() => {
## This delay is necessary to avoid the engine overwriting it with nothing
inv:set_stack(slot, item)
}, 0)
return 0
}
}
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

View File

@ -26,10 +26,6 @@ zepha.register_block('zeus:kinetic:axle_0', {
zepha.delay(() => {
zepha.set_block(pos, "zeus:kinetic:axle_1")
}, 4)
},
on_break_client = fn(pos) {
zepha.add_entity("zeus:default:dropped_item", {x = pos.x + 0.5, y = pos.y + 0.5, z = pos.z + 0.5},
{item = zepha.registered_blocks["zeus:kinetic:axle_0"].drop});
}
})