2019-03-17 17:22:53 +01:00
|
|
|
/*
|
|
|
|
* =====================================================================================
|
|
|
|
*
|
2020-02-08 18:34:26 +09:00
|
|
|
* OpenMiner
|
2020-02-25 01:42:10 +09:00
|
|
|
*
|
2020-02-08 18:34:26 +09:00
|
|
|
* Copyright (C) 2018-2020 Unarelith, Quentin Bazin <openminer@unarelith.net>
|
2020-02-25 01:42:10 +09:00
|
|
|
* Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md)
|
|
|
|
*
|
|
|
|
* This file is part of OpenMiner.
|
2019-03-17 17:22:53 +01:00
|
|
|
*
|
2020-02-25 01:42:10 +09:00
|
|
|
* OpenMiner is free software; you can redistribute it and/or
|
2020-02-08 18:34:26 +09:00
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
2019-03-17 17:22:53 +01:00
|
|
|
*
|
2020-02-25 01:42:10 +09:00
|
|
|
* OpenMiner is distributed in the hope that it will be useful,
|
2020-02-08 18:34:26 +09:00
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
2019-03-17 17:22:53 +01:00
|
|
|
*
|
2020-02-08 18:34:26 +09:00
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
2020-02-25 01:42:10 +09:00
|
|
|
* along with OpenMiner; if not, write to the Free Software Foundation, Inc.,
|
2020-02-08 18:34:26 +09:00
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
2019-03-17 17:22:53 +01:00
|
|
|
*
|
|
|
|
* =====================================================================================
|
|
|
|
*/
|
2020-04-29 00:27:05 +02:00
|
|
|
#include "AnimationComponent.hpp"
|
2020-02-11 15:00:03 +09:00
|
|
|
#include "BlockData.hpp"
|
2020-04-28 18:16:40 +02:00
|
|
|
#include "DrawableDef.hpp"
|
|
|
|
#include "NetworkComponent.hpp"
|
2020-04-05 23:11:34 +02:00
|
|
|
#include "PlayerList.hpp"
|
2019-03-17 17:22:53 +01:00
|
|
|
#include "Registry.hpp"
|
2019-04-07 18:20:15 +02:00
|
|
|
#include "ScriptEngine.hpp"
|
2019-03-17 17:22:53 +01:00
|
|
|
#include "Server.hpp"
|
|
|
|
#include "ServerBlock.hpp"
|
|
|
|
#include "ServerCommandHandler.hpp"
|
2020-03-08 14:44:23 +01:00
|
|
|
#include "WorldController.hpp"
|
2019-03-17 17:22:53 +01:00
|
|
|
|
2020-05-26 17:51:04 +02:00
|
|
|
void ServerCommandHandler::sendServerClosed(const std::string &message, const ClientInfo *client) const {
|
|
|
|
Network::Packet packet;
|
|
|
|
packet << Network::Command::ServerClosed << message;
|
|
|
|
|
|
|
|
if (!client)
|
|
|
|
m_server.sendToAllClients(packet);
|
|
|
|
else
|
|
|
|
client->tcpSocket->send(packet);
|
|
|
|
}
|
|
|
|
|
2020-03-04 14:38:31 +01:00
|
|
|
void ServerCommandHandler::sendBlockDataUpdate(s32 x, s32 y, s32 z, const BlockData *blockData, const ClientInfo *client) const {
|
2020-05-10 19:36:39 +02:00
|
|
|
Network::Packet packet;
|
2020-02-11 15:00:03 +09:00
|
|
|
packet << Network::Command::BlockDataUpdate << x << y << z
|
|
|
|
<< blockData->meta << blockData->useAltTiles;
|
|
|
|
|
|
|
|
if (!client)
|
|
|
|
m_server.sendToAllClients(packet);
|
|
|
|
else
|
|
|
|
client->tcpSocket->send(packet);
|
|
|
|
}
|
|
|
|
|
2020-03-04 14:38:31 +01:00
|
|
|
void ServerCommandHandler::sendBlockInvUpdate(s32 x, s32 y, s32 z, const Inventory &inventory, const ClientInfo *client) const {
|
2020-05-10 19:36:39 +02:00
|
|
|
Network::Packet packet;
|
2020-02-11 15:00:03 +09:00
|
|
|
packet << Network::Command::BlockInvUpdate << x << y << z << inventory;
|
|
|
|
|
|
|
|
if (!client)
|
|
|
|
m_server.sendToAllClients(packet);
|
|
|
|
else
|
|
|
|
client->tcpSocket->send(packet);
|
|
|
|
}
|
|
|
|
|
2020-03-04 14:38:31 +01:00
|
|
|
void ServerCommandHandler::sendPlayerPosUpdate(u16 clientID, bool isTeleportation, const ClientInfo *client) const {
|
2020-04-05 23:11:34 +02:00
|
|
|
const ServerPlayer *player = m_players.getPlayer(clientID);
|
|
|
|
if (player) {
|
2020-05-10 19:36:39 +02:00
|
|
|
Network::Packet packet;
|
2020-04-05 23:11:34 +02:00
|
|
|
packet << Network::Command::PlayerPosUpdate;
|
|
|
|
packet << clientID;
|
|
|
|
packet << player->x() << player->y() << player->z();
|
|
|
|
packet << isTeleportation;
|
2020-02-22 01:44:00 +09:00
|
|
|
|
2020-04-05 23:11:34 +02:00
|
|
|
if (!client)
|
|
|
|
m_server.sendToAllClients(packet);
|
|
|
|
else
|
|
|
|
client->tcpSocket->send(packet);
|
|
|
|
}
|
2020-02-22 01:44:00 +09:00
|
|
|
else
|
2020-06-04 17:36:09 +02:00
|
|
|
gkError() << ("Failed to send position update for player " + std::to_string(clientID) + ": Player not found").c_str();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ServerCommandHandler::sendPlayerRotUpdate(u16 clientID, const ClientInfo *client) const {
|
|
|
|
const ServerPlayer *player = m_players.getPlayer(clientID);
|
|
|
|
if (player) {
|
|
|
|
Network::Packet packet;
|
|
|
|
packet << Network::Command::PlayerRotUpdate;
|
|
|
|
packet << clientID;
|
|
|
|
packet << player->cameraYaw() << player->cameraPitch();
|
|
|
|
|
|
|
|
if (!client)
|
|
|
|
m_server.sendToAllClients(packet);
|
|
|
|
else
|
|
|
|
client->tcpSocket->send(packet);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
gkError() << ("Failed to send rotation update for player " + std::to_string(clientID) + ": Player not found").c_str();
|
2020-02-22 01:44:00 +09:00
|
|
|
}
|
|
|
|
|
2020-04-29 01:09:07 +02:00
|
|
|
void ServerCommandHandler::sendPlayerInvUpdate(u16 clientID, const ClientInfo *client) const {
|
|
|
|
ServerPlayer *player = m_players.getPlayer(clientID);
|
|
|
|
if (player) {
|
2020-05-10 19:36:39 +02:00
|
|
|
Network::Packet packet;
|
2020-04-29 01:09:07 +02:00
|
|
|
packet << Network::Command::PlayerInvUpdate;
|
|
|
|
packet << clientID << player->inventory();
|
|
|
|
|
|
|
|
if (!client)
|
|
|
|
m_server.sendToAllClients(packet);
|
|
|
|
else
|
|
|
|
client->tcpSocket->send(packet);
|
|
|
|
}
|
|
|
|
else
|
2020-06-04 17:36:09 +02:00
|
|
|
gkError() << ("Failed to send inventory update for player " + std::to_string(clientID) + ": Player not found").c_str();
|
2020-04-29 01:09:07 +02:00
|
|
|
}
|
|
|
|
|
2020-03-08 15:28:46 +01:00
|
|
|
void ServerCommandHandler::sendPlayerChangeDimension(u16 clientID, s32 x, s32 y, s32 z, u16 dimension, const ClientInfo *client) const {
|
2020-05-10 19:36:39 +02:00
|
|
|
Network::Packet packet;
|
2020-03-08 15:28:46 +01:00
|
|
|
packet << Network::Command::PlayerChangeDimension;
|
|
|
|
packet << clientID << x << y << z << dimension;
|
|
|
|
|
|
|
|
if (!client)
|
|
|
|
m_server.sendToAllClients(packet);
|
|
|
|
else
|
|
|
|
client->tcpSocket->send(packet);
|
2020-04-29 19:09:37 +02:00
|
|
|
|
|
|
|
// FIXME: sendPlayerChangeDimension shouldn't be exposed to Lua
|
|
|
|
// Instead, there should be a world.changePlayerDimension function that sends
|
|
|
|
// the packet above + the entities (instead of doing that here)
|
|
|
|
if (client)
|
|
|
|
m_worldController.getWorld(dimension).scene().sendEntities(*client);
|
2020-03-08 15:28:46 +01:00
|
|
|
}
|
|
|
|
|
2020-03-04 14:38:31 +01:00
|
|
|
void ServerCommandHandler::sendChatMessage(u16 clientID, const std::string &message, const ClientInfo *client) const {
|
2020-05-10 19:36:39 +02:00
|
|
|
Network::Packet packet;
|
2020-02-22 01:44:00 +09:00
|
|
|
packet << Network::Command::ChatMessage << clientID << message;
|
2020-02-11 15:00:03 +09:00
|
|
|
|
|
|
|
if (!client)
|
|
|
|
m_server.sendToAllClients(packet);
|
|
|
|
else
|
|
|
|
client->tcpSocket->send(packet);
|
|
|
|
}
|
|
|
|
|
2020-04-29 17:58:07 +02:00
|
|
|
void ServerCommandHandler::sendEntitySpawn(entt::entity entityID, const ClientInfo *client) const {
|
2020-05-10 19:36:39 +02:00
|
|
|
Network::Packet packet;
|
2020-04-28 18:16:40 +02:00
|
|
|
packet << Network::Command::EntitySpawn << entityID;
|
|
|
|
|
|
|
|
if (!client)
|
|
|
|
m_server.sendToAllClients(packet);
|
|
|
|
else
|
|
|
|
client->tcpSocket->send(packet);
|
|
|
|
}
|
|
|
|
|
2020-04-29 17:58:07 +02:00
|
|
|
void ServerCommandHandler::sendEntityDespawn(entt::entity entityID, const ClientInfo *client) const {
|
2020-05-10 19:36:39 +02:00
|
|
|
Network::Packet packet;
|
2020-04-28 19:18:08 +02:00
|
|
|
packet << Network::Command::EntityDespawn << entityID;
|
|
|
|
|
|
|
|
if (!client)
|
|
|
|
m_server.sendToAllClients(packet);
|
|
|
|
else
|
|
|
|
client->tcpSocket->send(packet);
|
|
|
|
}
|
|
|
|
|
2019-03-17 17:22:53 +01:00
|
|
|
void ServerCommandHandler::setupCallbacks() {
|
2020-03-04 14:38:31 +01:00
|
|
|
m_server.setConnectionCallback([this](ClientInfo &client) {
|
2020-05-10 19:36:39 +02:00
|
|
|
Network::Packet packet;
|
2019-03-17 17:22:53 +01:00
|
|
|
packet << Network::Command::RegistryData;
|
|
|
|
m_registry.serialize(packet);
|
|
|
|
client.tcpSocket->send(packet);
|
|
|
|
|
2020-03-08 22:10:35 +01:00
|
|
|
// Send already connected players to the new client
|
2019-04-08 15:29:19 +02:00
|
|
|
for (auto &it : m_players) {
|
2020-05-10 19:36:39 +02:00
|
|
|
Network::Packet spawnPacket;
|
2019-04-08 15:29:19 +02:00
|
|
|
spawnPacket << Network::Command::PlayerSpawn << it.first;
|
|
|
|
spawnPacket << it.second.x() << it.second.y() << it.second.z();
|
|
|
|
client.tcpSocket->send(spawnPacket);
|
|
|
|
}
|
2019-04-07 18:20:15 +02:00
|
|
|
|
2020-04-05 23:11:34 +02:00
|
|
|
auto &player = m_players.addPlayer(client);
|
2020-01-17 14:39:29 +09:00
|
|
|
player.setPosition(m_spawnPosition.x, m_spawnPosition.y, m_spawnPosition.z);
|
2019-04-08 15:29:19 +02:00
|
|
|
|
2020-05-22 05:34:02 +02:00
|
|
|
m_scriptEngine.luaCore().onEvent(LuaEventType::PlayerConnected, glm::ivec3{m_spawnPosition.x, m_spawnPosition.y, m_spawnPosition.z}, player, client, *this);
|
2019-04-07 18:20:15 +02:00
|
|
|
|
2020-05-10 19:36:39 +02:00
|
|
|
Network::Packet invPacket;
|
2019-03-17 17:22:53 +01:00
|
|
|
invPacket << Network::Command::PlayerInvUpdate << client.id;
|
2020-04-05 23:11:34 +02:00
|
|
|
invPacket << player.inventory();
|
2019-03-17 17:22:53 +01:00
|
|
|
client.tcpSocket->send(invPacket);
|
|
|
|
|
2020-03-08 22:10:35 +01:00
|
|
|
// Send spawn packet to all clients for this player
|
2020-05-10 19:36:39 +02:00
|
|
|
Network::Packet spawnPacket;
|
2019-03-17 17:22:53 +01:00
|
|
|
spawnPacket << Network::Command::PlayerSpawn << client.id;
|
|
|
|
spawnPacket << m_spawnPosition.x << m_spawnPosition.y << m_spawnPosition.z;
|
|
|
|
m_server.sendToAllClients(spawnPacket);
|
2020-04-28 18:16:40 +02:00
|
|
|
|
|
|
|
// Send entities to the client
|
|
|
|
m_worldController.getWorld(player.dimension()).scene().sendEntities(client);
|
2019-03-17 17:22:53 +01:00
|
|
|
});
|
|
|
|
|
2020-05-10 19:36:39 +02:00
|
|
|
m_server.setCommandCallback(Network::Command::ClientDisconnect, [this](ClientInfo &client, Network::Packet &) {
|
2020-04-05 23:11:34 +02:00
|
|
|
m_players.removePlayer(client.id);
|
2020-02-24 17:20:49 +09:00
|
|
|
});
|
|
|
|
|
2020-05-10 19:36:39 +02:00
|
|
|
m_server.setCommandCallback(Network::Command::ChunkRequest, [this](ClientInfo &client, Network::Packet &packet) {
|
2020-01-20 13:40:07 +09:00
|
|
|
s32 cx, cy, cz;
|
|
|
|
packet >> cx >> cy >> cz;
|
|
|
|
|
2020-03-08 14:44:23 +01:00
|
|
|
getWorldForClient(client.id).sendRequestedData(client, cx, cy, cz);
|
2020-01-20 13:40:07 +09:00
|
|
|
});
|
|
|
|
|
2020-05-10 19:36:39 +02:00
|
|
|
m_server.setCommandCallback(Network::Command::PlayerInvUpdate, [this](ClientInfo &client, Network::Packet &packet) {
|
2019-03-17 17:22:53 +01:00
|
|
|
u16 clientId;
|
|
|
|
packet >> clientId;
|
2020-04-05 23:11:34 +02:00
|
|
|
|
|
|
|
ServerPlayer *player = m_players.getPlayer(clientId);
|
|
|
|
if (player) {
|
|
|
|
if (clientId == client.id) {
|
|
|
|
packet >> player->inventory();
|
|
|
|
}
|
2019-03-17 17:22:53 +01:00
|
|
|
}
|
2020-04-05 23:11:34 +02:00
|
|
|
else
|
|
|
|
gkError() << ("Failed to update inventory of player " + std::to_string(client.id) + ": Player not found").c_str();
|
2019-03-17 17:22:53 +01:00
|
|
|
});
|
|
|
|
|
2020-05-10 19:36:39 +02:00
|
|
|
m_server.setCommandCallback(Network::Command::PlayerPosUpdate, [this](ClientInfo &client, Network::Packet &packet) {
|
2020-03-02 20:41:47 +01:00
|
|
|
double x, y, z;
|
2019-04-07 17:20:35 +02:00
|
|
|
u16 clientId;
|
|
|
|
packet >> clientId;
|
|
|
|
packet >> x >> y >> z;
|
2019-03-17 17:22:53 +01:00
|
|
|
|
2020-04-05 23:11:34 +02:00
|
|
|
ServerPlayer *player = m_players.getPlayer(clientId);
|
|
|
|
if (player) {
|
|
|
|
if (clientId == client.id)
|
|
|
|
player->setPosition(x, y, z);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
gkError() << ("Failed to update position of player " + std::to_string(client.id) + ": Player not found").c_str();
|
2019-03-17 17:22:53 +01:00
|
|
|
});
|
|
|
|
|
2020-06-04 17:36:09 +02:00
|
|
|
m_server.setCommandCallback(Network::Command::PlayerRotUpdate, [this](ClientInfo &client, Network::Packet &packet) {
|
|
|
|
u16 clientId;
|
|
|
|
float yaw, pitch;
|
|
|
|
packet >> clientId >> yaw >> pitch;
|
|
|
|
|
|
|
|
ServerPlayer *player = m_players.getPlayer(client.id);
|
|
|
|
if (player) {
|
|
|
|
if (clientId == client.id)
|
|
|
|
player->setRotation(yaw, pitch);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
gkError() << ("Failed to update rotation of player " + std::to_string(client.id) + ": Player not found").c_str();
|
|
|
|
});
|
|
|
|
|
2020-05-10 19:36:39 +02:00
|
|
|
m_server.setCommandCallback(Network::Command::PlayerPlaceBlock, [this](ClientInfo &client, Network::Packet &packet) {
|
2020-04-05 23:11:34 +02:00
|
|
|
ServerPlayer *player = m_players.getPlayer(client.id);
|
|
|
|
if (player) {
|
|
|
|
s32 x, y, z;
|
|
|
|
u32 block;
|
|
|
|
packet >> x >> y >> z >> block;
|
2020-03-08 14:44:23 +01:00
|
|
|
|
2020-04-05 23:11:34 +02:00
|
|
|
ServerWorld &world = getWorldForClient(client.id);
|
|
|
|
world.setData(x, y, z, block >> 16);
|
|
|
|
world.setBlock(x, y, z, block & 0xffff);
|
2020-05-17 02:21:54 +02:00
|
|
|
const Block &blockDef = Registry::getInstance().getBlock(block & 0xffff);
|
2019-03-17 17:22:53 +01:00
|
|
|
|
2020-05-22 05:34:02 +02:00
|
|
|
m_scriptEngine.luaCore().onEvent(LuaEventType::BlockPlaced, glm::ivec3{x, y, z}, blockDef, *player, world, client, *this);
|
2020-03-10 14:02:20 +01:00
|
|
|
|
2020-05-10 19:36:39 +02:00
|
|
|
Network::Packet answer;
|
2020-04-05 23:11:34 +02:00
|
|
|
answer << Network::Command::BlockUpdate << x << y << z << block;
|
|
|
|
m_server.sendToAllClients(answer);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
gkError() << ("Failed to place block using player " + std::to_string(client.id) + ": Player not found").c_str();
|
2019-03-17 17:22:53 +01:00
|
|
|
});
|
|
|
|
|
2020-05-10 19:36:39 +02:00
|
|
|
m_server.setCommandCallback(Network::Command::PlayerDigBlock, [this](ClientInfo &client, Network::Packet &packet) {
|
2020-04-29 01:55:14 +02:00
|
|
|
ServerPlayer *player = m_players.getPlayer(client.id);
|
|
|
|
if (player) {
|
|
|
|
s32 x, y, z;
|
|
|
|
packet >> x >> y >> z;
|
|
|
|
|
|
|
|
ServerWorld &world = getWorldForClient(client.id);
|
2020-05-17 02:21:54 +02:00
|
|
|
const Block &blockDef = Registry::getInstance().getBlock(world.getBlock(x, y, z));
|
2020-04-29 01:55:14 +02:00
|
|
|
world.setBlock(x, y, z, 0);
|
2019-03-17 17:22:53 +01:00
|
|
|
|
2020-05-22 05:34:02 +02:00
|
|
|
m_scriptEngine.luaCore().onEvent(LuaEventType::BlockDigged, glm::ivec3{x, y, z}, blockDef, *player, world, client, *this);
|
2020-05-04 11:39:01 +02:00
|
|
|
|
2020-05-10 19:36:39 +02:00
|
|
|
Network::Packet answer;
|
2020-04-29 01:55:14 +02:00
|
|
|
answer << Network::Command::BlockUpdate << x << y << z << u32(0);
|
|
|
|
m_server.sendToAllClients(answer);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
gkError() << ("Failed to dig block using player " + std::to_string(client.id) + ": Player not found").c_str();
|
2019-03-17 17:22:53 +01:00
|
|
|
});
|
|
|
|
|
2020-05-10 19:36:39 +02:00
|
|
|
m_server.setCommandCallback(Network::Command::PlayerInventory, [this](ClientInfo &client, Network::Packet &packet) {
|
2020-02-15 14:42:29 +09:00
|
|
|
u16 screenWidth, screenHeight;
|
|
|
|
u8 guiScale;
|
|
|
|
packet >> screenWidth >> screenHeight >> guiScale;
|
|
|
|
|
2020-03-07 15:41:19 +01:00
|
|
|
sol::unsafe_function func = m_scriptEngine.lua()["show_inventory"];
|
|
|
|
|
|
|
|
try {
|
|
|
|
func(client, screenWidth, screenHeight, guiScale);
|
|
|
|
}
|
|
|
|
catch (const sol::error &error) {
|
2020-04-03 07:27:57 +02:00
|
|
|
gkError() << "Failed to send inventory GUI: " << error.what();
|
2020-03-07 15:41:19 +01:00
|
|
|
}
|
2020-02-08 02:48:39 +09:00
|
|
|
});
|
|
|
|
|
2020-05-10 19:36:39 +02:00
|
|
|
m_server.setCommandCallback(Network::Command::PlayerCreativeWindow, [this](ClientInfo &client, Network::Packet &packet) {
|
2020-02-29 18:07:01 +01:00
|
|
|
u16 screenWidth, screenHeight;
|
|
|
|
u8 guiScale;
|
|
|
|
packet >> screenWidth >> screenHeight >> guiScale;
|
|
|
|
|
2020-03-07 15:41:19 +01:00
|
|
|
sol::unsafe_function func = m_scriptEngine.lua()["show_creative_window"];
|
|
|
|
|
|
|
|
try {
|
|
|
|
func(client, screenWidth, screenHeight, guiScale);
|
|
|
|
}
|
|
|
|
catch (const sol::error &error) {
|
2020-04-03 07:27:57 +02:00
|
|
|
gkError() << "Failed to send creative window GUI: " << error.what();
|
2020-03-07 15:41:19 +01:00
|
|
|
}
|
2020-02-29 18:07:01 +01:00
|
|
|
});
|
|
|
|
|
2020-06-02 05:51:10 +02:00
|
|
|
m_server.setCommandCallback(Network::Command::PlayerHeldItemChanged, [this](ClientInfo &client, Network::Packet &packet) {
|
|
|
|
ServerPlayer *player = m_players.getPlayer(client.id);
|
|
|
|
if (player) {
|
|
|
|
u8 hotbarSlot;
|
|
|
|
u16 itemID;
|
|
|
|
packet >> hotbarSlot >> itemID;
|
|
|
|
if (player->inventory().getStack(hotbarSlot, 0).item().id() != itemID)
|
|
|
|
gkWarning() << "PlayerHeldItemChanged:" << "Desync of item ID between client and server";
|
|
|
|
|
|
|
|
player->setHeldItemSlot(hotbarSlot);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
gkError() << ("Failed to change held item of player " + std::to_string(client.id) + ": Player not found").c_str();
|
|
|
|
});
|
|
|
|
|
2020-05-10 19:36:39 +02:00
|
|
|
m_server.setCommandCallback(Network::Command::BlockActivated, [this](ClientInfo &client, Network::Packet &packet) {
|
2020-04-05 23:11:34 +02:00
|
|
|
ServerPlayer *player = m_players.getPlayer(client.id);
|
|
|
|
if (player) {
|
|
|
|
s32 x, y, z;
|
|
|
|
u16 screenWidth, screenHeight;
|
|
|
|
u8 guiScale;
|
|
|
|
packet >> x >> y >> z >> screenWidth >> screenHeight >> guiScale;
|
2019-03-17 17:22:53 +01:00
|
|
|
|
2020-04-05 23:11:34 +02:00
|
|
|
ServerWorld &world = getWorldForClient(client.id);
|
2020-03-08 14:44:23 +01:00
|
|
|
|
2020-04-05 23:11:34 +02:00
|
|
|
u16 id = world.getBlock(x, y, z);
|
|
|
|
ServerBlock &block = (ServerBlock &)(m_registry.getBlock(id));
|
|
|
|
bool hasBeenActivated = block.onBlockActivated({x, y, z}, *player, world, client, *this, screenWidth, screenHeight, guiScale);
|
2020-03-10 14:25:38 +01:00
|
|
|
|
2020-04-05 23:11:34 +02:00
|
|
|
if (hasBeenActivated)
|
2020-05-22 05:34:02 +02:00
|
|
|
m_scriptEngine.luaCore().onEvent(LuaEventType::BlockActivated, glm::ivec3{x, y, z}, block, *player, world, client, *this);
|
2020-04-05 23:11:34 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
gkError() << ("Failed to activate block using player " + std::to_string(client.id) + ": Player not found").c_str();
|
2019-03-17 17:22:53 +01:00
|
|
|
});
|
|
|
|
|
2020-05-10 19:36:39 +02:00
|
|
|
m_server.setCommandCallback(Network::Command::BlockInvUpdate, [this](ClientInfo &client, Network::Packet &packet) {
|
2019-03-17 17:22:53 +01:00
|
|
|
gk::Vector3<s32> pos;
|
|
|
|
packet >> pos.x >> pos.y >> pos.z;
|
|
|
|
|
2020-03-08 14:44:23 +01:00
|
|
|
BlockData *data = getWorldForClient(client.id).getBlockData(pos.x, pos.y, pos.z);
|
2019-03-17 17:22:53 +01:00
|
|
|
if (data)
|
|
|
|
packet >> data->inventory;
|
|
|
|
else
|
2020-04-03 07:27:57 +02:00
|
|
|
gkError() << "BlockInvUpdate: No block data found at" << pos.x << pos.y << pos.z;
|
2019-03-17 17:22:53 +01:00
|
|
|
});
|
|
|
|
|
2020-05-10 19:36:39 +02:00
|
|
|
m_server.setCommandCallback(Network::Command::BlockDataUpdate, [this](ClientInfo &client, Network::Packet &packet) {
|
2019-03-17 17:22:53 +01:00
|
|
|
gk::Vector3<s32> pos;
|
|
|
|
packet >> pos.x >> pos.y >> pos.z;
|
|
|
|
|
2020-03-08 14:44:23 +01:00
|
|
|
BlockData *data = getWorldForClient(client.id).getBlockData(pos.x, pos.y, pos.z);
|
2019-03-17 17:22:53 +01:00
|
|
|
if (data) {
|
2020-02-08 17:45:20 +09:00
|
|
|
packet >> data->meta >> data->useAltTiles;
|
2019-03-17 17:22:53 +01:00
|
|
|
}
|
|
|
|
});
|
2020-02-21 17:25:56 +09:00
|
|
|
|
2020-05-10 19:36:39 +02:00
|
|
|
m_server.setCommandCallback(Network::Command::ChatMessage, [this](ClientInfo &client, Network::Packet &packet) {
|
2020-02-22 01:44:00 +09:00
|
|
|
u16 clientID;
|
|
|
|
std::string message;
|
|
|
|
packet >> clientID >> message;
|
2020-02-21 17:25:56 +09:00
|
|
|
|
2020-02-22 02:21:42 +09:00
|
|
|
if (message[0] != '/' || (message.length() > 1 && message[1] == '/')) {
|
|
|
|
if (message[0] == '/' && message.length() > 1 && message[1] == '/')
|
|
|
|
sendChatMessage(clientID, message.substr(1));
|
|
|
|
else
|
|
|
|
sendChatMessage(clientID, message);
|
2020-02-22 01:44:00 +09:00
|
|
|
}
|
|
|
|
else {
|
2020-03-08 23:08:18 +01:00
|
|
|
m_chatCommandHandler.parseCommand(message.substr(1), client);
|
2020-02-22 01:44:00 +09:00
|
|
|
}
|
2020-02-21 17:25:56 +09:00
|
|
|
});
|
2019-03-17 17:22:53 +01:00
|
|
|
}
|
|
|
|
|
2020-03-08 23:08:18 +01:00
|
|
|
void ServerCommandHandler::setPlayerPosition(u16 clientID, s32 x, s32 y, s32 z) {
|
2020-04-05 23:11:34 +02:00
|
|
|
ServerPlayer *player = m_players.getPlayer(clientID);
|
|
|
|
if (player)
|
|
|
|
player->setPosition(x, y, z);
|
|
|
|
else
|
|
|
|
gkError() << ("Failed to set position for player " + std::to_string(clientID) + ": Player not found").c_str();
|
2020-03-08 23:08:18 +01:00
|
|
|
}
|
|
|
|
|
2020-03-08 14:44:23 +01:00
|
|
|
inline ServerWorld &ServerCommandHandler::getWorldForClient(u16 clientID) {
|
2020-04-05 23:11:34 +02:00
|
|
|
ServerPlayer *player = m_players.getPlayer(clientID);
|
|
|
|
if (!player)
|
2020-03-08 14:44:23 +01:00
|
|
|
throw EXCEPTION("Player instance not found for client", clientID);
|
|
|
|
|
2020-04-05 23:11:34 +02:00
|
|
|
return m_worldController.getWorld(player->dimension());
|
2020-03-08 14:44:23 +01:00
|
|
|
}
|
|
|
|
|
2020-06-19 02:51:33 +02:00
|
|
|
void ServerCommandHandler::stopServer() const {
|
|
|
|
m_server.setRunning(false);
|
|
|
|
}
|
|
|
|
|
2020-05-22 04:54:34 +02:00
|
|
|
// Please update 'docs/lua-api-cpp.md' if you change this
|
|
|
|
void ServerCommandHandler::initUsertype(sol::state &lua) {
|
|
|
|
lua.new_usertype<ServerCommandHandler>("ServerCommandHandler",
|
|
|
|
"send_player_change_dimension", &ServerCommandHandler::sendPlayerChangeDimension,
|
|
|
|
"send_chat_message", &ServerCommandHandler::sendChatMessage
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|