Packets are now compressed using zlib. Legacy and unused UDP code removed.
This commit is contained in:
parent
05a652bbb6
commit
c277dc7d87
4
.gitmodules
vendored
4
.gitmodules
vendored
@ -9,3 +9,7 @@
|
||||
[submodule "external/gamekit"]
|
||||
path = external/gamekit
|
||||
url = git://github.com/Unarelith/GameKit.git
|
||||
[submodule "external/zlib"]
|
||||
path = external/zlib
|
||||
url = git://github.com/Unarelith/zlib.git
|
||||
ignore = dirty
|
||||
|
@ -201,6 +201,12 @@ set(BUILD_SHARED_LIBS OFF)
|
||||
|
||||
add_subdirectory(external/SFML)
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# - zlib
|
||||
#------------------------------------------------------------------------------
|
||||
add_subdirectory(external/zlib)
|
||||
include_directories(external/zlib)
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Subdirectories
|
||||
#------------------------------------------------------------------------------
|
||||
|
1
external/zlib
vendored
Submodule
1
external/zlib
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 9c920698c36f1f059d5ed4501e38b08421780164
|
@ -61,5 +61,6 @@ target_link_libraries(${PROJECT_NAME}
|
||||
${LUA_LIBRARIES}
|
||||
sfml-system
|
||||
sfml-network
|
||||
zlib
|
||||
${UNIX_LIBS})
|
||||
|
||||
|
@ -42,11 +42,11 @@ void Client::connect(sf::IpAddress serverAddress, u16 serverPort) {
|
||||
if (m_socket.bind(0) != sf::Socket::Done)
|
||||
throw ClientConnectException("Network error: Bind failed");
|
||||
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::ClientConnect << sf::IpAddress::getLocalAddress().toString() << m_socket.getLocalPort();
|
||||
m_tcpSocket->send(packet);
|
||||
|
||||
sf::Packet answer;
|
||||
Network::Packet answer;
|
||||
m_tcpSocket->receive(answer);
|
||||
|
||||
Network::Command command;
|
||||
@ -69,52 +69,31 @@ void Client::connect(sf::IpAddress serverAddress, u16 serverPort) {
|
||||
}
|
||||
|
||||
void Client::disconnect() {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::ClientDisconnect;
|
||||
m_tcpSocket->send(packet);
|
||||
|
||||
m_tcpSocket->disconnect();
|
||||
}
|
||||
|
||||
void Client::send(sf::Packet &packet) {
|
||||
void Client::send(Network::Packet &packet) {
|
||||
if (m_tcpSocket)
|
||||
m_tcpSocket->send(packet);
|
||||
else
|
||||
throw EXCEPTION("Network error: Trying to send a packet without being connected");
|
||||
}
|
||||
|
||||
void Client::sendKeyState() {
|
||||
if (!m_keyUpdateTimer.isStarted())
|
||||
m_keyUpdateTimer.start();
|
||||
|
||||
if (m_keyUpdateTimer.time() > 15) {
|
||||
gk::InputHandler *inputHandler = gk::GamePad::getInputHandler();
|
||||
if (inputHandler) {
|
||||
sf::Packet packet;
|
||||
packet << Network::Command::KeyState << gk::GameClock::getInstance().getTicks() << m_id;
|
||||
for (auto &it : inputHandler->keysPressed()) {
|
||||
packet << static_cast<u8>(it.first) << it.second;
|
||||
}
|
||||
|
||||
m_socket.send(packet, m_serverAddress, m_serverPort);
|
||||
}
|
||||
|
||||
m_keyUpdateTimer.reset();
|
||||
m_keyUpdateTimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
void Client::update() {
|
||||
sf::Packet packet;
|
||||
sf::IpAddress senderAddress;
|
||||
u16 senderPort;
|
||||
while (m_socket.receive(packet, senderAddress, senderPort) == sf::Socket::Done) {
|
||||
Network::Command command;
|
||||
packet >> command;
|
||||
|
||||
// gkDebug() << "UDP Message of type" << Network::commandToString(command) << "received from:" << senderAddress << ":" << senderPort;
|
||||
}
|
||||
// sf::IpAddress senderAddress;
|
||||
// u16 senderPort;
|
||||
// while (m_socket.receive(packet, senderAddress, senderPort) == sf::Socket::Done) {
|
||||
// Network::Command command;
|
||||
// packet >> command;
|
||||
//
|
||||
// // gkDebug() << "UDP Message of type" << Network::commandToString(command) << "received from:" << senderAddress << ":" << senderPort;
|
||||
// }
|
||||
|
||||
Network::Packet packet;
|
||||
while (m_tcpSocket->receive(packet) == sf::Socket::Done) {
|
||||
Network::Command command;
|
||||
packet >> command;
|
||||
|
@ -53,14 +53,13 @@ class ClientConnectException {
|
||||
};
|
||||
|
||||
class Client {
|
||||
using CommandCallback = std::function<void(sf::Packet &packet)>;
|
||||
using CommandCallback = std::function<void(Network::Packet &packet)>;
|
||||
|
||||
public:
|
||||
void connect(sf::IpAddress serverAddress, u16 serverPort);
|
||||
void disconnect();
|
||||
|
||||
void send(sf::Packet &packet);
|
||||
void sendKeyState();
|
||||
void send(Network::Packet &packet);
|
||||
|
||||
void update();
|
||||
|
||||
|
@ -43,7 +43,7 @@
|
||||
#include "Registry.hpp"
|
||||
|
||||
void ClientCommandHandler::sendPlayerInvUpdate() {
|
||||
sf::Packet invPacket;
|
||||
Network::Packet invPacket;
|
||||
invPacket << Network::Command::PlayerInvUpdate;
|
||||
// FIXME: Sending client id shouldn't be necessary
|
||||
invPacket << m_client.id();
|
||||
@ -52,7 +52,7 @@ void ClientCommandHandler::sendPlayerInvUpdate() {
|
||||
}
|
||||
|
||||
void ClientCommandHandler::sendPlayerPosUpdate() {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::PlayerPosUpdate;
|
||||
// FIXME: Sending client id shouldn't be necessary
|
||||
packet << m_client.id();
|
||||
@ -64,7 +64,7 @@ void ClientCommandHandler::sendPlayerPosUpdate() {
|
||||
}
|
||||
|
||||
void ClientCommandHandler::sendPlayerDigBlock(const glm::ivec4 &selectedBlock) {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::PlayerDigBlock
|
||||
<< s32(selectedBlock.x)
|
||||
<< s32(selectedBlock.y)
|
||||
@ -73,27 +73,27 @@ void ClientCommandHandler::sendPlayerDigBlock(const glm::ivec4 &selectedBlock) {
|
||||
}
|
||||
|
||||
void ClientCommandHandler::sendPlayerPlaceBlock(s32 x, s32 y, s32 z, u32 block) {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::PlayerPlaceBlock << x << y << z << block;
|
||||
m_client.send(packet);
|
||||
}
|
||||
|
||||
void ClientCommandHandler::sendPlayerInventoryRequest() {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::PlayerInventory
|
||||
<< u16(Config::screenWidth) << u16(Config::screenHeight) << u8(Config::guiScale);
|
||||
m_client.send(packet);
|
||||
}
|
||||
|
||||
void ClientCommandHandler::sendPlayerCreativeWindowRequest() {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::PlayerCreativeWindow
|
||||
<< u16(Config::screenWidth) << u16(Config::screenHeight) << u8(Config::guiScale);
|
||||
m_client.send(packet);
|
||||
}
|
||||
|
||||
void ClientCommandHandler::sendBlockActivated(const glm::ivec4 &selectedBlock) {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::BlockActivated
|
||||
<< s32(selectedBlock.x)
|
||||
<< s32(selectedBlock.y)
|
||||
@ -103,7 +103,7 @@ void ClientCommandHandler::sendBlockActivated(const glm::ivec4 &selectedBlock) {
|
||||
}
|
||||
|
||||
void ClientCommandHandler::sendBlockInvUpdate(Inventory &inventory) {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::BlockInvUpdate;
|
||||
packet << s32(inventory.blockPos().x) << s32(inventory.blockPos().y) << s32(inventory.blockPos().z);
|
||||
packet << inventory;
|
||||
@ -111,14 +111,14 @@ void ClientCommandHandler::sendBlockInvUpdate(Inventory &inventory) {
|
||||
}
|
||||
|
||||
void ClientCommandHandler::sendChunkRequest(s32 chunkX, s32 chunkY, s32 chunkZ) {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::ChunkRequest;
|
||||
packet << chunkX << chunkY << chunkZ;
|
||||
m_client.send(packet);
|
||||
}
|
||||
|
||||
void ClientCommandHandler::sendChatMessage(const std::string &message) {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::ChatMessage;
|
||||
// FIXME: Sending client id shouldn't be necessary
|
||||
packet << m_client.id();
|
||||
@ -127,7 +127,7 @@ void ClientCommandHandler::sendChatMessage(const std::string &message) {
|
||||
}
|
||||
|
||||
void ClientCommandHandler::setupCallbacks() {
|
||||
m_client.setCommandCallback(Network::Command::ClientDisconnect, [this](sf::Packet &packet) {
|
||||
m_client.setCommandCallback(Network::Command::ClientDisconnect, [this](Network::Packet &packet) {
|
||||
u16 clientID;
|
||||
packet >> clientID;
|
||||
|
||||
@ -136,7 +136,7 @@ void ClientCommandHandler::setupCallbacks() {
|
||||
m_playerBoxes.erase(it);
|
||||
});
|
||||
|
||||
m_client.setCommandCallback(Network::Command::RegistryData, [this](sf::Packet &packet) {
|
||||
m_client.setCommandCallback(Network::Command::RegistryData, [this](Network::Packet &packet) {
|
||||
// FIXME: This is a quick fix for concurrency between client and server in singleplayer
|
||||
if (!m_isSingleplayer)
|
||||
Registry::getInstance().deserialize(packet);
|
||||
@ -144,11 +144,11 @@ void ClientCommandHandler::setupCallbacks() {
|
||||
m_isRegistryInitialized = true;
|
||||
});
|
||||
|
||||
m_client.setCommandCallback(Network::Command::ChunkData, [this](sf::Packet &packet) {
|
||||
m_client.setCommandCallback(Network::Command::ChunkData, [this](Network::Packet &packet) {
|
||||
m_world.receiveChunkData(packet);
|
||||
});
|
||||
|
||||
m_client.setCommandCallback(Network::Command::BlockUpdate, [this](sf::Packet &packet) {
|
||||
m_client.setCommandCallback(Network::Command::BlockUpdate, [this](Network::Packet &packet) {
|
||||
s32 x, y, z;
|
||||
u32 block;
|
||||
packet >> x >> y >> z >> block;
|
||||
@ -156,7 +156,7 @@ void ClientCommandHandler::setupCallbacks() {
|
||||
m_world.setData(x, y, z, block >> 16);
|
||||
});
|
||||
|
||||
m_client.setCommandCallback(Network::Command::PlayerInvUpdate, [this](sf::Packet &packet) {
|
||||
m_client.setCommandCallback(Network::Command::PlayerInvUpdate, [this](Network::Packet &packet) {
|
||||
u16 clientId;
|
||||
packet >> clientId;
|
||||
|
||||
@ -166,7 +166,7 @@ void ClientCommandHandler::setupCallbacks() {
|
||||
packet >> m_playerBoxes.at(clientId).inventory();
|
||||
});
|
||||
|
||||
m_client.setCommandCallback(Network::Command::PlayerPosUpdate, [this](sf::Packet &packet) {
|
||||
m_client.setCommandCallback(Network::Command::PlayerPosUpdate, [this](Network::Packet &packet) {
|
||||
double x, y, z;
|
||||
u16 clientId;
|
||||
bool isTeleportation;
|
||||
@ -184,7 +184,7 @@ void ClientCommandHandler::setupCallbacks() {
|
||||
}
|
||||
});
|
||||
|
||||
m_client.setCommandCallback(Network::Command::PlayerSpawn, [this](sf::Packet &packet) {
|
||||
m_client.setCommandCallback(Network::Command::PlayerSpawn, [this](Network::Packet &packet) {
|
||||
u16 clientId;
|
||||
gk::Vector3d pos;
|
||||
packet >> clientId >> pos.x >> pos.y >> pos.z;
|
||||
@ -199,7 +199,7 @@ void ClientCommandHandler::setupCallbacks() {
|
||||
}
|
||||
});
|
||||
|
||||
m_client.setCommandCallback(Network::Command::PlayerChangeDimension, [this](sf::Packet &packet) {
|
||||
m_client.setCommandCallback(Network::Command::PlayerChangeDimension, [this](Network::Packet &packet) {
|
||||
u16 clientId, dimension;
|
||||
s32 x, y, z;
|
||||
packet >> clientId >> x >> y >> z >> dimension;
|
||||
@ -213,11 +213,11 @@ void ClientCommandHandler::setupCallbacks() {
|
||||
}
|
||||
});
|
||||
|
||||
m_client.setCommandCallback(Network::Command::BlockGUIData, [this](sf::Packet &packet) {
|
||||
m_client.setCommandCallback(Network::Command::BlockGUIData, [this](Network::Packet &packet) {
|
||||
gk::ApplicationStateStack::getInstance().push<LuaGUIState>(*this, m_player, m_world, packet, &gk::ApplicationStateStack::getInstance().top());
|
||||
});
|
||||
|
||||
m_client.setCommandCallback(Network::Command::BlockInvUpdate, [this](sf::Packet &packet) {
|
||||
m_client.setCommandCallback(Network::Command::BlockInvUpdate, [this](Network::Packet &packet) {
|
||||
gk::Vector3<s32> pos;
|
||||
packet >> pos.x >> pos.y >> pos.z;
|
||||
|
||||
@ -229,7 +229,7 @@ void ClientCommandHandler::setupCallbacks() {
|
||||
packet >> data->inventory;
|
||||
});
|
||||
|
||||
m_client.setCommandCallback(Network::Command::BlockDataUpdate, [this](sf::Packet &packet) {
|
||||
m_client.setCommandCallback(Network::Command::BlockDataUpdate, [this](Network::Packet &packet) {
|
||||
gk::Vector3<s32> pos;
|
||||
packet >> pos.x >> pos.y >> pos.z;
|
||||
|
||||
@ -251,7 +251,7 @@ void ClientCommandHandler::setupCallbacks() {
|
||||
}
|
||||
});
|
||||
|
||||
m_client.setCommandCallback(Network::Command::EntitySpawn, [this](sf::Packet &packet) {
|
||||
m_client.setCommandCallback(Network::Command::EntitySpawn, [this](Network::Packet &packet) {
|
||||
entt::entity entityID;
|
||||
packet >> entityID;
|
||||
|
||||
@ -268,7 +268,7 @@ void ClientCommandHandler::setupCallbacks() {
|
||||
}
|
||||
});
|
||||
|
||||
m_client.setCommandCallback(Network::Command::EntityDespawn, [this](sf::Packet &packet) {
|
||||
m_client.setCommandCallback(Network::Command::EntityDespawn, [this](Network::Packet &packet) {
|
||||
entt::entity entityID;
|
||||
packet >> entityID;
|
||||
|
||||
@ -280,7 +280,7 @@ void ClientCommandHandler::setupCallbacks() {
|
||||
gkError() << "EntityDespawn: Entity ID" << std::underlying_type_t<entt::entity>(entityID) << "is invalid";
|
||||
});
|
||||
|
||||
m_client.setCommandCallback(Network::Command::EntityPosition, [this](sf::Packet &packet) {
|
||||
m_client.setCommandCallback(Network::Command::EntityPosition, [this](Network::Packet &packet) {
|
||||
entt::entity entityID;
|
||||
packet >> entityID;
|
||||
|
||||
@ -293,7 +293,7 @@ void ClientCommandHandler::setupCallbacks() {
|
||||
gkError() << "EntityPosition: Entity ID" << std::underlying_type_t<entt::entity>(entityID) << "is invalid";
|
||||
});
|
||||
|
||||
m_client.setCommandCallback(Network::Command::EntityRotation, [this](sf::Packet &packet) {
|
||||
m_client.setCommandCallback(Network::Command::EntityRotation, [this](Network::Packet &packet) {
|
||||
entt::entity entityID;
|
||||
packet >> entityID;
|
||||
|
||||
@ -309,7 +309,7 @@ void ClientCommandHandler::setupCallbacks() {
|
||||
gkError() << "EntityRotation: Entity ID" << std::underlying_type_t<entt::entity>(entityID) << "is invalid";
|
||||
});
|
||||
|
||||
m_client.setCommandCallback(Network::Command::EntityAnimation, [this](sf::Packet &packet) {
|
||||
m_client.setCommandCallback(Network::Command::EntityAnimation, [this](Network::Packet &packet) {
|
||||
entt::entity entityID;
|
||||
packet >> entityID;
|
||||
|
||||
@ -322,7 +322,7 @@ void ClientCommandHandler::setupCallbacks() {
|
||||
gkError() << "EntityAnimation: Entity ID" << std::underlying_type_t<entt::entity>(entityID) << "is invalid";
|
||||
});
|
||||
|
||||
m_client.setCommandCallback(Network::Command::EntityDrawableDef, [this](sf::Packet &packet) {
|
||||
m_client.setCommandCallback(Network::Command::EntityDrawableDef, [this](Network::Packet &packet) {
|
||||
entt::entity entityID;
|
||||
packet >> entityID;
|
||||
|
||||
|
@ -114,7 +114,7 @@ void ClientWorld::updateSky(u16 dimensionID) {
|
||||
m_sky = &sky;
|
||||
}
|
||||
|
||||
void ClientWorld::receiveChunkData(sf::Packet &packet) {
|
||||
void ClientWorld::receiveChunkData(Network::Packet &packet) {
|
||||
s32 cx, cy, cz;
|
||||
packet >> cx >> cy >> cz;
|
||||
|
||||
|
@ -55,7 +55,7 @@ class ClientWorld : public World, public gk::Drawable {
|
||||
|
||||
void updateSky(u16 dimensionID);
|
||||
|
||||
void receiveChunkData(sf::Packet &packet);
|
||||
void receiveChunkData(Network::Packet &packet);
|
||||
void removeChunk(ChunkMap::iterator &it);
|
||||
|
||||
Chunk *getChunk(int cx, int cy, int cz) const override;
|
||||
|
@ -18,7 +18,7 @@ endforeach(HEADER_FILE)
|
||||
# Add library
|
||||
#------------------------------------------------------------------------------
|
||||
add_library(${PROJECT_NAME} STATIC ${SOURCE_FILES})
|
||||
add_dependencies(${PROJECT_NAME} EnTT sfml-network gamekit)
|
||||
add_dependencies(${PROJECT_NAME} zlib EnTT sfml-network gamekit)
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Compiler flags
|
||||
@ -35,5 +35,5 @@ target_compile_options(${PROJECT_NAME} PRIVATE -DSOL_CHECK_ARGUMENTS -DSOL_PRINT
|
||||
|
||||
# target_compile_options(${PROJECT_NAME} PRIVATE -pg)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} sfml-system sfml-network)
|
||||
target_link_libraries(${PROJECT_NAME} sfml-system sfml-network zlib)
|
||||
|
||||
|
94
source/common/network/CompressedPacket.cpp
Normal file
94
source/common/network/CompressedPacket.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* OpenMiner
|
||||
*
|
||||
* Copyright (C) 2018-2020 Unarelith, Quentin Bazin <openminer@unarelith.net>
|
||||
* Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md)
|
||||
*
|
||||
* This file is part of OpenMiner.
|
||||
*
|
||||
* OpenMiner is free software; you can redistribute it and/or
|
||||
* 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.
|
||||
*
|
||||
* OpenMiner is distributed in the hope that it will be useful,
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with OpenMiner; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
#include <cassert>
|
||||
|
||||
#include "CompressedPacket.hpp"
|
||||
|
||||
// Note: This class was implemented thanks to this SFML forum topic:
|
||||
// https://en.sfml-dev.org/forums/index.php?topic=14344.0
|
||||
|
||||
const void* CompressedPacket::onSend(std::size_t& size) {
|
||||
// We only support data with a maximum size of
|
||||
// an unsigned short (so the size can be sent
|
||||
// in the first two bytes of the packet)
|
||||
assert(size <= 65535);
|
||||
|
||||
// Cast the data to a bytef pointer
|
||||
const Bytef* srcData = static_cast<const Bytef*>(getData());
|
||||
|
||||
// Get the size of the packet to send
|
||||
uLong srcSize = getDataSize();
|
||||
|
||||
// Compute the size of the compressed data
|
||||
uLong dstSize = compressBound(srcSize);
|
||||
|
||||
// Resize the vector to accomodate the compressed data,
|
||||
// plus two bytes for our uncompressed size
|
||||
m_compressionBuffer.resize(dstSize + 2);
|
||||
|
||||
// Take the first 8 bytes of srcSize
|
||||
m_compressionBuffer[0] = srcSize & 0xFF;
|
||||
|
||||
// And the second 8 bytes
|
||||
m_compressionBuffer[1] = (srcSize >> 8) & 0xFF;
|
||||
|
||||
// Compress the data into the rest of the buffer
|
||||
compress(m_compressionBuffer.data() + 2, &dstSize, srcData, srcSize);
|
||||
|
||||
// Set the size to the compressed size plus
|
||||
// two bytes for the size marker
|
||||
size = (dstSize + 2);
|
||||
|
||||
// Return data to send
|
||||
return m_compressionBuffer.data();
|
||||
}
|
||||
|
||||
void CompressedPacket::onReceive(const void* data, std::size_t size) {
|
||||
// Cast the data to Bytef*, the format zlib deals with
|
||||
const Bytef* srcData = static_cast<const Bytef*>(data);
|
||||
|
||||
// Extract the uncompressed data size from the first two
|
||||
// bytes in the packet so we can use it for the buffer
|
||||
sf::Uint16 uncompressedSize = srcData[1] << 8 | srcData[0];
|
||||
|
||||
// Resize the vector to accomodate the uncompressed data
|
||||
m_compressionBuffer.resize(uncompressedSize);
|
||||
|
||||
// Declare a variable for the destination size
|
||||
uLong dstSize;
|
||||
|
||||
// Uncompress the data (remove the first two bytes)
|
||||
uncompress(m_compressionBuffer.data(), &dstSize, (srcData + 2), size - 2);
|
||||
|
||||
// Assert that the uncompressed size is the same as the
|
||||
// size we were sent for the buffer
|
||||
assert(dstSize == uncompressedSize);
|
||||
|
||||
// Append it to the packet
|
||||
append(m_compressionBuffer.data(), dstSize);
|
||||
}
|
||||
|
44
source/common/network/CompressedPacket.hpp
Normal file
44
source/common/network/CompressedPacket.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* OpenMiner
|
||||
*
|
||||
* Copyright (C) 2018-2020 Unarelith, Quentin Bazin <openminer@unarelith.net>
|
||||
* Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md)
|
||||
*
|
||||
* This file is part of OpenMiner.
|
||||
*
|
||||
* OpenMiner is free software; you can redistribute it and/or
|
||||
* 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.
|
||||
*
|
||||
* OpenMiner is distributed in the hope that it will be useful,
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with OpenMiner; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
#ifndef COMPRESSEDPACKET_HPP_
|
||||
#define COMPRESSEDPACKET_HPP_
|
||||
|
||||
#include <gk/core/IntTypes.hpp>
|
||||
|
||||
#include <SFML/Network/Packet.hpp>
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
class CompressedPacket : public sf::Packet {
|
||||
private:
|
||||
const void* onSend(std::size_t& size) override;
|
||||
void onReceive(const void* data, std::size_t size) override;
|
||||
|
||||
std::vector<Bytef> m_compressionBuffer;
|
||||
};
|
||||
|
||||
#endif // COMPRESSEDPACKET_HPP_
|
@ -37,8 +37,6 @@ std::string Network::commandToString(Network::Command command) {
|
||||
{Network::Command::ClientOk, "ClientOk"},
|
||||
{Network::Command::ClientRefused, "ClientRefused"},
|
||||
|
||||
{Network::Command::KeyState, "KeyState"},
|
||||
|
||||
{Network::Command::ChunkData, "ChunkData"},
|
||||
{Network::Command::ChunkRequest, "ChunkRequest"},
|
||||
|
||||
|
@ -27,53 +27,52 @@
|
||||
#ifndef NETWORK_HPP_
|
||||
#define NETWORK_HPP_
|
||||
|
||||
#include <SFML/Network/Packet.hpp>
|
||||
#include "CompressedPacket.hpp"
|
||||
|
||||
namespace Network {
|
||||
using Packet = CompressedPacket;
|
||||
|
||||
enum class Command {
|
||||
// Client commands
|
||||
ClientConnect = 0, // <TCP> [NetworkCommand][u16 udp port] (from Client only)
|
||||
ClientDisconnect = 1, // <TCP> [NetworkCommand] (from Client only)
|
||||
ClientOk = 2, // <TCP> [NetworkCommand][u16 client id][bool isSingleplayer] (from Server only)
|
||||
ClientRefused = 3, // <TCP> [NetworkCommand] (from Server only)
|
||||
|
||||
// Input commands
|
||||
KeyState = 4, // <UDP> [NetworkCommand][u32 timestamp][u16 client id][u32 keycode][bool isPressed]...
|
||||
ClientConnect = 0x00, // <TCP> [NetworkCommand][u16 udp port] (from Client only)
|
||||
ClientDisconnect = 0x01, // <TCP> [NetworkCommand] (from Client only)
|
||||
ClientOk = 0x02, // <TCP> [NetworkCommand][u16 client id][bool isSingleplayer] (from Server only)
|
||||
ClientRefused = 0x03, // <TCP> [NetworkCommand] (from Server only)
|
||||
|
||||
// Chunk commands
|
||||
ChunkData = 5, // <TCP> [NetworkCommand][s32 cx, cy, cz][u32...] (from Server only)
|
||||
ChunkRequest = 6, // <TCP> [NetworkCommand][s32 cx, cy, cz] (from Client only)
|
||||
ChunkData = 0x04, // <TCP> [NetworkCommand][s32 cx, cy, cz][u32...] (from Server only)
|
||||
ChunkRequest = 0x05, // <TCP> [NetworkCommand][s32 cx, cy, cz] (from Client only)
|
||||
|
||||
// Player commands
|
||||
PlayerPlaceBlock = 7, // <TCP> [NetworkCommand][s32 x, y, z][u32 block] (from Client only)
|
||||
PlayerDigBlock = 8, // <TCP> [NetworkCommand][s32 x, y, z] (from Client only)
|
||||
PlayerInvUpdate = 9, // <TCP> [NetworkCommand][u16 client id][[std::string item][u16 amount][u8 x, y]...] (both) [FIXME]
|
||||
PlayerPosUpdate = 10, // <TCP> [NetworkCommand][u16 client id][s32 x, y, z][bool isTeleportation] (both) // FIXME
|
||||
PlayerSpawn = 11, // <TCP> [NetworkCommand][u16 client id][s32 x, y, z] (from Server only)
|
||||
PlayerInventory = 12, // <TCP> [NetworkCommand][u16 screenWidth, screenHeight][u8 guiScale] (from Client only)
|
||||
PlayerCreativeWindow = 13, // <TCP> [NetworkCommand][u16 screenWidth, screenHeight][u8 guiScale] (from Client only)
|
||||
PlayerChangeDimension = 14, // <TCP> [NetworkCommand][u16 client id][s32 x, y, z][u16 dimension] (from Server only)
|
||||
PlayerPlaceBlock = 0x06, // <TCP> [NetworkCommand][s32 x, y, z][u32 block] (from Client only)
|
||||
PlayerDigBlock = 0x07, // <TCP> [NetworkCommand][s32 x, y, z] (from Client only)
|
||||
PlayerInvUpdate = 0x08, // <TCP> [NetworkCommand][u16 client id][[std::string item][u16 amount][u8 x, y]...] (both) [FIXME]
|
||||
PlayerPosUpdate = 0x09, // <TCP> [NetworkCommand][u16 client id][s32 x, y, z][bool isTeleportation] (both) // FIXME
|
||||
PlayerSpawn = 0x0a, // <TCP> [NetworkCommand][u16 client id][s32 x, y, z] (from Server only)
|
||||
PlayerInventory = 0x0b, // <TCP> [NetworkCommand][u16 screenWidth, screenHeight][u8 guiScale] (from Client only)
|
||||
PlayerCreativeWindow = 0x0c, // <TCP> [NetworkCommand][u16 screenWidth, screenHeight][u8 guiScale] (from Client only)
|
||||
PlayerChangeDimension = 0x0d, // <TCP> [NetworkCommand][u16 client id][s32 x, y, z][u16 dimension] (from Server only)
|
||||
|
||||
// Block commands
|
||||
BlockUpdate = 15, // <TCP> [NetworkCommand][s32 x, y, z][u32 block] (from Server only)
|
||||
BlockActivated = 16, // <TCP> [NetworkCommand][s32 x, y, z][u16 screenWidth, screenHeight][u8 guiScale] (from Client only)
|
||||
BlockGUIData = 17, // <TCP> [NetworkCommand][LuaGUIData data] (from Server only)
|
||||
BlockInvUpdate = 18, // <TCP> [NetworkCommand][s32 x, y, z][[std::string item][u16 amount][u8 x, y]...] (both) [FIXME]
|
||||
BlockDataUpdate = 19, // <TCP> [NetworkCommand][s32 x, y, z][u64 data] (both) [FIXME]
|
||||
BlockUpdate = 0x0e, // <TCP> [NetworkCommand][s32 x, y, z][u32 block] (from Server only)
|
||||
BlockActivated = 0x0f, // <TCP> [NetworkCommand][s32 x, y, z][u16 screenWidth, screenHeight][u8 guiScale] (from Client only)
|
||||
BlockGUIData = 0x10, // <TCP> [NetworkCommand][LuaGUIData data] (from Server only)
|
||||
BlockInvUpdate = 0x11, // <TCP> [NetworkCommand][s32 x, y, z][[std::string item][u16 amount][u8 x, y]...] (both) [FIXME]
|
||||
BlockDataUpdate = 0x12, // <TCP> [NetworkCommand][s32 x, y, z][u64 data] (both) [FIXME]
|
||||
|
||||
// Registry commands
|
||||
RegistryData = 20, // <TCP> [NetworkCommand][Block block] (from Server only)
|
||||
RegistryData = 0x13, // <TCP> [NetworkCommand][Block block] (from Server only)
|
||||
|
||||
// Chat commands
|
||||
ChatMessage = 21, // <TCP> [NetworkCommand][u16 client id][std::string message] (both)
|
||||
ChatMessage = 0x14, // <TCP> [NetworkCommand][u16 client id][std::string message] (both)
|
||||
|
||||
// Entity commands
|
||||
EntitySpawn = 22, // <TCP> [NetworkCommand][u32 entity id] (from Server only)
|
||||
EntityDespawn = 23, // <TCP> [NetworkCommand][u32 entity id] (from Server only)
|
||||
EntityPosition = 24, // <TCP> [NetworkCommand][u32 entity id][double x, double y, double z] (from Server only)
|
||||
EntityRotation = 25, // <TCP> [NetworkCommand][u32 entity id][float w, float x, float y, float z] (from Server only)
|
||||
EntityAnimation = 26, // <TCP> [NetworkCommand][u32 entity id][AnimationComponent anim] (from Server only)
|
||||
EntityDrawableDef = 27, // <TCP> [NetworkCommand][u32 entity id][DrawableDef def] (from Server only)
|
||||
EntitySpawn = 0x15, // <TCP> [NetworkCommand][u32 entity id] (from Server only)
|
||||
EntityDespawn = 0x16, // <TCP> [NetworkCommand][u32 entity id] (from Server only)
|
||||
EntityPosition = 0x17, // <TCP> [NetworkCommand][u32 entity id][double x, double y, double z] (from Server only)
|
||||
EntityRotation = 0x18, // <TCP> [NetworkCommand][u32 entity id][float w, float x, float y, float z] (from Server only)
|
||||
EntityAnimation = 0x19, // <TCP> [NetworkCommand][u32 entity id][AnimationComponent anim] (from Server only)
|
||||
EntityDrawableDef = 0x1a, // <TCP> [NetworkCommand][u32 entity id][DrawableDef def] (from Server only)
|
||||
};
|
||||
|
||||
std::string commandToString(Command command);
|
||||
|
@ -80,5 +80,6 @@ target_link_libraries(${PROJECT_NAME}
|
||||
${LUA_LIBRARIES}
|
||||
sfml-system
|
||||
sfml-network
|
||||
zlib
|
||||
${UNIX_LIBS})
|
||||
|
||||
|
@ -121,8 +121,6 @@ void ServerApplication::mainLoop() {
|
||||
while (m_server.isRunning()) {
|
||||
m_server.handleGameEvents();
|
||||
|
||||
m_server.handleKeyState();
|
||||
|
||||
m_clock.updateGame([this] {
|
||||
update();
|
||||
});
|
||||
|
@ -92,7 +92,7 @@ void LuaGUI::addInventory(const sol::table &table) {
|
||||
}
|
||||
|
||||
void LuaGUI::show(ClientInfo &client) {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::BlockGUIData;
|
||||
|
||||
packet << m_width << m_height << m_isCentered;
|
||||
|
@ -27,12 +27,7 @@
|
||||
#include "Server.hpp"
|
||||
|
||||
void Server::init(u16 port) {
|
||||
if (m_udpSocket.bind(port) != sf::Socket::Done)
|
||||
throw EXCEPTION("Network error: Bind failed");
|
||||
|
||||
m_udpSocket.setBlocking(false);
|
||||
|
||||
m_port = m_udpSocket.getLocalPort();
|
||||
m_port = port;
|
||||
|
||||
if (m_tcpListener.listen(m_port) != sf::Socket::Done)
|
||||
throw EXCEPTION("Network error: Listen failed");
|
||||
@ -42,38 +37,6 @@ void Server::init(u16 port) {
|
||||
m_selector.add(m_tcpListener);
|
||||
}
|
||||
|
||||
void Server::handleKeyState() {
|
||||
sf::Packet packet;
|
||||
sf::IpAddress senderAddress;
|
||||
u16 senderPort;
|
||||
while (m_udpSocket.receive(packet, senderAddress, senderPort) == sf::Socket::Status::Done) {
|
||||
Network::Command command;
|
||||
u32 timestamp;
|
||||
u16 clientId;
|
||||
packet >> command >> timestamp >> clientId;
|
||||
|
||||
// gkDebug() << "UDP Message of type" << Network::commandToString(command) << "received from:" << senderAddress << ":" << senderPort;
|
||||
|
||||
if (command == Network::Command::KeyState) {
|
||||
ClientInfo *client = m_info.getClient(clientId);
|
||||
if (client && client->previousKeyTimestamp < timestamp) {
|
||||
client->previousKeyTimestamp = timestamp;
|
||||
|
||||
while (!packet.endOfPacket()) {
|
||||
u8 key;
|
||||
bool isPressed;
|
||||
packet >> key >> isPressed;
|
||||
|
||||
if (client->inputHandler.keysPressed().at(key) != isPressed)
|
||||
gkDebug() << (int)key << "changed state to" << (isPressed ? "true" : "false");
|
||||
|
||||
client->inputHandler.setKeyPressed(key, isPressed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Server::handleGameEvents() {
|
||||
if (m_selector.wait(sf::milliseconds(10))) {
|
||||
if (m_selector.isReady(m_tcpListener)) {
|
||||
@ -88,7 +51,7 @@ void Server::handleGameEvents() {
|
||||
void Server::handleNewConnections() {
|
||||
std::shared_ptr<sf::TcpSocket> clientSocket = std::make_shared<sf::TcpSocket>();
|
||||
if (m_tcpListener.accept(*clientSocket) == sf::Socket::Done) {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
clientSocket->receive(packet);
|
||||
|
||||
Network::Command command;
|
||||
@ -104,7 +67,7 @@ void Server::handleNewConnections() {
|
||||
ClientInfo &client = m_info.addClient(address, port, clientSocket);
|
||||
m_selector.add(*client.tcpSocket);
|
||||
|
||||
sf::Packet outPacket;
|
||||
Network::Packet outPacket;
|
||||
outPacket << Network::Command::ClientOk << client.id << m_isSingleplayer;
|
||||
client.tcpSocket->send(outPacket);
|
||||
// client.tcpSocket->setBlocking(false);
|
||||
@ -113,7 +76,7 @@ void Server::handleNewConnections() {
|
||||
m_connectionCallback(client);
|
||||
}
|
||||
else {
|
||||
sf::Packet outPacket;
|
||||
Network::Packet outPacket;
|
||||
outPacket << Network::Command::ClientRefused;
|
||||
clientSocket->send(outPacket);
|
||||
}
|
||||
@ -127,7 +90,7 @@ void Server::handleClientMessages() {
|
||||
for (size_t i = 0 ; i < m_info.clients().size() ; ++i) {
|
||||
ClientInfo &client = m_info.clients()[i];
|
||||
if (m_selector.isReady(*client.tcpSocket)) {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
sf::Socket::Status status = client.tcpSocket->receive(packet);
|
||||
if (status == sf::Socket::Done) {
|
||||
Network::Command command;
|
||||
@ -158,7 +121,7 @@ void Server::handleClientMessages() {
|
||||
}
|
||||
|
||||
void Server::disconnectClient(ClientInfo &client) {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::ClientDisconnect << client.id;
|
||||
sendToAllClients(packet);
|
||||
|
||||
@ -173,7 +136,7 @@ void Server::disconnectClient(ClientInfo &client) {
|
||||
}
|
||||
}
|
||||
|
||||
void Server::sendToAllClients(sf::Packet &packet) const {
|
||||
void Server::sendToAllClients(Network::Packet &packet) const {
|
||||
for (const ClientInfo &client : m_info.clients()) {
|
||||
client.tcpSocket->send(packet);
|
||||
}
|
||||
|
@ -39,16 +39,14 @@
|
||||
|
||||
class Server {
|
||||
using ConnectionCallback = std::function<void(ClientInfo &)>;
|
||||
using CommandCallback = std::function<void(ClientInfo &, sf::Packet &packet)>;
|
||||
using CommandCallback = std::function<void(ClientInfo &, Network::Packet &packet)>;
|
||||
|
||||
public:
|
||||
void init(u16 port = 4242);
|
||||
|
||||
void handleKeyState();
|
||||
|
||||
void handleGameEvents();
|
||||
|
||||
void sendToAllClients(sf::Packet &packet) const;
|
||||
void sendToAllClients(Network::Packet &packet) const;
|
||||
|
||||
bool isRunning() const { return m_isRunning; }
|
||||
|
||||
@ -56,8 +54,6 @@ class Server {
|
||||
|
||||
const ServerInfo &info() const { return m_info; }
|
||||
|
||||
sf::UdpSocket &udpSocket() { return m_udpSocket; }
|
||||
|
||||
void setRunning(bool isRunning) { m_isRunning = isRunning; }
|
||||
void setSingleplayer(bool isSingleplayer) { m_isSingleplayer = isSingleplayer; }
|
||||
|
||||
@ -77,8 +73,6 @@ class Server {
|
||||
|
||||
ServerInfo m_info;
|
||||
|
||||
sf::UdpSocket m_udpSocket;
|
||||
|
||||
sf::TcpListener m_tcpListener;
|
||||
sf::SocketSelector m_selector;
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include "WorldController.hpp"
|
||||
|
||||
void ServerCommandHandler::sendBlockDataUpdate(s32 x, s32 y, s32 z, const BlockData *blockData, const ClientInfo *client) const {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::BlockDataUpdate << x << y << z
|
||||
<< blockData->meta << blockData->useAltTiles;
|
||||
|
||||
@ -48,7 +48,7 @@ void ServerCommandHandler::sendBlockDataUpdate(s32 x, s32 y, s32 z, const BlockD
|
||||
}
|
||||
|
||||
void ServerCommandHandler::sendBlockInvUpdate(s32 x, s32 y, s32 z, const Inventory &inventory, const ClientInfo *client) const {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::BlockInvUpdate << x << y << z << inventory;
|
||||
|
||||
if (!client)
|
||||
@ -60,7 +60,7 @@ void ServerCommandHandler::sendBlockInvUpdate(s32 x, s32 y, s32 z, const Invento
|
||||
void ServerCommandHandler::sendPlayerPosUpdate(u16 clientID, bool isTeleportation, const ClientInfo *client) const {
|
||||
const ServerPlayer *player = m_players.getPlayer(clientID);
|
||||
if (player) {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::PlayerPosUpdate;
|
||||
packet << clientID;
|
||||
packet << player->x() << player->y() << player->z();
|
||||
@ -78,7 +78,7 @@ void ServerCommandHandler::sendPlayerPosUpdate(u16 clientID, bool isTeleportatio
|
||||
void ServerCommandHandler::sendPlayerInvUpdate(u16 clientID, const ClientInfo *client) const {
|
||||
ServerPlayer *player = m_players.getPlayer(clientID);
|
||||
if (player) {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::PlayerInvUpdate;
|
||||
packet << clientID << player->inventory();
|
||||
|
||||
@ -92,7 +92,7 @@ void ServerCommandHandler::sendPlayerInvUpdate(u16 clientID, const ClientInfo *c
|
||||
}
|
||||
|
||||
void ServerCommandHandler::sendPlayerChangeDimension(u16 clientID, s32 x, s32 y, s32 z, u16 dimension, const ClientInfo *client) const {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::PlayerChangeDimension;
|
||||
packet << clientID << x << y << z << dimension;
|
||||
|
||||
@ -109,7 +109,7 @@ void ServerCommandHandler::sendPlayerChangeDimension(u16 clientID, s32 x, s32 y,
|
||||
}
|
||||
|
||||
void ServerCommandHandler::sendChatMessage(u16 clientID, const std::string &message, const ClientInfo *client) const {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::ChatMessage << clientID << message;
|
||||
|
||||
if (!client)
|
||||
@ -119,7 +119,7 @@ void ServerCommandHandler::sendChatMessage(u16 clientID, const std::string &mess
|
||||
}
|
||||
|
||||
void ServerCommandHandler::sendEntitySpawn(entt::entity entityID, const ClientInfo *client) const {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::EntitySpawn << entityID;
|
||||
|
||||
if (!client)
|
||||
@ -129,7 +129,7 @@ void ServerCommandHandler::sendEntitySpawn(entt::entity entityID, const ClientIn
|
||||
}
|
||||
|
||||
void ServerCommandHandler::sendEntityDespawn(entt::entity entityID, const ClientInfo *client) const {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::EntityDespawn << entityID;
|
||||
|
||||
if (!client)
|
||||
@ -139,7 +139,7 @@ void ServerCommandHandler::sendEntityDespawn(entt::entity entityID, const Client
|
||||
}
|
||||
|
||||
void ServerCommandHandler::sendEntityPosition(entt::entity entityID, double x, double y, double z, const ClientInfo *client) const {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::EntityPosition << entityID << x << y << z;
|
||||
|
||||
if (!client)
|
||||
@ -149,7 +149,7 @@ void ServerCommandHandler::sendEntityPosition(entt::entity entityID, double x, d
|
||||
}
|
||||
|
||||
void ServerCommandHandler::sendEntityRotation(entt::entity entityID, float w, float x, float y, float z, const ClientInfo *client) const {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::EntityRotation << entityID << w << x << y << z;
|
||||
|
||||
if (!client)
|
||||
@ -159,7 +159,7 @@ void ServerCommandHandler::sendEntityRotation(entt::entity entityID, float w, fl
|
||||
}
|
||||
|
||||
void ServerCommandHandler::sendEntityAnimation(entt::entity entityID, const AnimationComponent &animation, const ClientInfo *client) const {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::EntityAnimation << entityID << animation;
|
||||
|
||||
if (!client)
|
||||
@ -169,7 +169,7 @@ void ServerCommandHandler::sendEntityAnimation(entt::entity entityID, const Anim
|
||||
}
|
||||
|
||||
void ServerCommandHandler::sendEntityDrawableDef(entt::entity entityID, const DrawableDef &drawableDef, const ClientInfo *client) const {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::EntityDrawableDef << entityID << drawableDef;
|
||||
|
||||
if (!client)
|
||||
@ -180,14 +180,14 @@ void ServerCommandHandler::sendEntityDrawableDef(entt::entity entityID, const Dr
|
||||
|
||||
void ServerCommandHandler::setupCallbacks() {
|
||||
m_server.setConnectionCallback([this](ClientInfo &client) {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::RegistryData;
|
||||
m_registry.serialize(packet);
|
||||
client.tcpSocket->send(packet);
|
||||
|
||||
// Send already connected players to the new client
|
||||
for (auto &it : m_players) {
|
||||
sf::Packet spawnPacket;
|
||||
Network::Packet spawnPacket;
|
||||
spawnPacket << Network::Command::PlayerSpawn << it.first;
|
||||
spawnPacket << it.second.x() << it.second.y() << it.second.z();
|
||||
client.tcpSocket->send(spawnPacket);
|
||||
@ -199,13 +199,13 @@ void ServerCommandHandler::setupCallbacks() {
|
||||
// FIXME: Find a better way to give starting items
|
||||
m_scriptEngine.lua()["init"](player);
|
||||
|
||||
sf::Packet invPacket;
|
||||
Network::Packet invPacket;
|
||||
invPacket << Network::Command::PlayerInvUpdate << client.id;
|
||||
invPacket << player.inventory();
|
||||
client.tcpSocket->send(invPacket);
|
||||
|
||||
// Send spawn packet to all clients for this player
|
||||
sf::Packet spawnPacket;
|
||||
Network::Packet spawnPacket;
|
||||
spawnPacket << Network::Command::PlayerSpawn << client.id;
|
||||
spawnPacket << m_spawnPosition.x << m_spawnPosition.y << m_spawnPosition.z;
|
||||
m_server.sendToAllClients(spawnPacket);
|
||||
@ -214,18 +214,18 @@ void ServerCommandHandler::setupCallbacks() {
|
||||
m_worldController.getWorld(player.dimension()).scene().sendEntities(client);
|
||||
});
|
||||
|
||||
m_server.setCommandCallback(Network::Command::ClientDisconnect, [this](ClientInfo &client, sf::Packet &) {
|
||||
m_server.setCommandCallback(Network::Command::ClientDisconnect, [this](ClientInfo &client, Network::Packet &) {
|
||||
m_players.removePlayer(client.id);
|
||||
});
|
||||
|
||||
m_server.setCommandCallback(Network::Command::ChunkRequest, [this](ClientInfo &client, sf::Packet &packet) {
|
||||
m_server.setCommandCallback(Network::Command::ChunkRequest, [this](ClientInfo &client, Network::Packet &packet) {
|
||||
s32 cx, cy, cz;
|
||||
packet >> cx >> cy >> cz;
|
||||
|
||||
getWorldForClient(client.id).sendRequestedData(client, cx, cy, cz);
|
||||
});
|
||||
|
||||
m_server.setCommandCallback(Network::Command::PlayerInvUpdate, [this](ClientInfo &client, sf::Packet &packet) {
|
||||
m_server.setCommandCallback(Network::Command::PlayerInvUpdate, [this](ClientInfo &client, Network::Packet &packet) {
|
||||
u16 clientId;
|
||||
packet >> clientId;
|
||||
|
||||
@ -239,7 +239,7 @@ void ServerCommandHandler::setupCallbacks() {
|
||||
gkError() << ("Failed to update inventory of player " + std::to_string(client.id) + ": Player not found").c_str();
|
||||
});
|
||||
|
||||
m_server.setCommandCallback(Network::Command::PlayerPosUpdate, [this](ClientInfo &client, sf::Packet &packet) {
|
||||
m_server.setCommandCallback(Network::Command::PlayerPosUpdate, [this](ClientInfo &client, Network::Packet &packet) {
|
||||
double x, y, z;
|
||||
u16 clientId;
|
||||
packet >> clientId;
|
||||
@ -254,7 +254,7 @@ void ServerCommandHandler::setupCallbacks() {
|
||||
gkError() << ("Failed to update position of player " + std::to_string(client.id) + ": Player not found").c_str();
|
||||
});
|
||||
|
||||
m_server.setCommandCallback(Network::Command::PlayerPlaceBlock, [this](ClientInfo &client, sf::Packet &packet) {
|
||||
m_server.setCommandCallback(Network::Command::PlayerPlaceBlock, [this](ClientInfo &client, Network::Packet &packet) {
|
||||
ServerPlayer *player = m_players.getPlayer(client.id);
|
||||
if (player) {
|
||||
s32 x, y, z;
|
||||
@ -267,7 +267,7 @@ void ServerCommandHandler::setupCallbacks() {
|
||||
|
||||
m_scriptEngine.luaCore().onEvent(LuaEventType::OnBlockPlaced, glm::ivec3{x, y, z}, *player, world, client, *this);
|
||||
|
||||
sf::Packet answer;
|
||||
Network::Packet answer;
|
||||
answer << Network::Command::BlockUpdate << x << y << z << block;
|
||||
m_server.sendToAllClients(answer);
|
||||
}
|
||||
@ -275,7 +275,7 @@ void ServerCommandHandler::setupCallbacks() {
|
||||
gkError() << ("Failed to place block using player " + std::to_string(client.id) + ": Player not found").c_str();
|
||||
});
|
||||
|
||||
m_server.setCommandCallback(Network::Command::PlayerDigBlock, [this](ClientInfo &client, sf::Packet &packet) {
|
||||
m_server.setCommandCallback(Network::Command::PlayerDigBlock, [this](ClientInfo &client, Network::Packet &packet) {
|
||||
ServerPlayer *player = m_players.getPlayer(client.id);
|
||||
if (player) {
|
||||
s32 x, y, z;
|
||||
@ -287,7 +287,7 @@ void ServerCommandHandler::setupCallbacks() {
|
||||
|
||||
m_scriptEngine.luaCore().onEvent(LuaEventType::OnBlockDigged, glm::ivec3{x, y, z}, *player, world, client, *this);
|
||||
|
||||
sf::Packet answer;
|
||||
Network::Packet answer;
|
||||
answer << Network::Command::BlockUpdate << x << y << z << u32(0);
|
||||
m_server.sendToAllClients(answer);
|
||||
}
|
||||
@ -295,7 +295,7 @@ void ServerCommandHandler::setupCallbacks() {
|
||||
gkError() << ("Failed to dig block using player " + std::to_string(client.id) + ": Player not found").c_str();
|
||||
});
|
||||
|
||||
m_server.setCommandCallback(Network::Command::PlayerInventory, [this](ClientInfo &client, sf::Packet &packet) {
|
||||
m_server.setCommandCallback(Network::Command::PlayerInventory, [this](ClientInfo &client, Network::Packet &packet) {
|
||||
u16 screenWidth, screenHeight;
|
||||
u8 guiScale;
|
||||
packet >> screenWidth >> screenHeight >> guiScale;
|
||||
@ -310,7 +310,7 @@ void ServerCommandHandler::setupCallbacks() {
|
||||
}
|
||||
});
|
||||
|
||||
m_server.setCommandCallback(Network::Command::PlayerCreativeWindow, [this](ClientInfo &client, sf::Packet &packet) {
|
||||
m_server.setCommandCallback(Network::Command::PlayerCreativeWindow, [this](ClientInfo &client, Network::Packet &packet) {
|
||||
u16 screenWidth, screenHeight;
|
||||
u8 guiScale;
|
||||
packet >> screenWidth >> screenHeight >> guiScale;
|
||||
@ -325,7 +325,7 @@ void ServerCommandHandler::setupCallbacks() {
|
||||
}
|
||||
});
|
||||
|
||||
m_server.setCommandCallback(Network::Command::BlockActivated, [this](ClientInfo &client, sf::Packet &packet) {
|
||||
m_server.setCommandCallback(Network::Command::BlockActivated, [this](ClientInfo &client, Network::Packet &packet) {
|
||||
ServerPlayer *player = m_players.getPlayer(client.id);
|
||||
if (player) {
|
||||
s32 x, y, z;
|
||||
@ -346,7 +346,7 @@ void ServerCommandHandler::setupCallbacks() {
|
||||
gkError() << ("Failed to activate block using player " + std::to_string(client.id) + ": Player not found").c_str();
|
||||
});
|
||||
|
||||
m_server.setCommandCallback(Network::Command::BlockInvUpdate, [this](ClientInfo &client, sf::Packet &packet) {
|
||||
m_server.setCommandCallback(Network::Command::BlockInvUpdate, [this](ClientInfo &client, Network::Packet &packet) {
|
||||
gk::Vector3<s32> pos;
|
||||
packet >> pos.x >> pos.y >> pos.z;
|
||||
|
||||
@ -357,7 +357,7 @@ void ServerCommandHandler::setupCallbacks() {
|
||||
gkError() << "BlockInvUpdate: No block data found at" << pos.x << pos.y << pos.z;
|
||||
});
|
||||
|
||||
m_server.setCommandCallback(Network::Command::BlockDataUpdate, [this](ClientInfo &client, sf::Packet &packet) {
|
||||
m_server.setCommandCallback(Network::Command::BlockDataUpdate, [this](ClientInfo &client, Network::Packet &packet) {
|
||||
gk::Vector3<s32> pos;
|
||||
packet >> pos.x >> pos.y >> pos.z;
|
||||
|
||||
@ -367,7 +367,7 @@ void ServerCommandHandler::setupCallbacks() {
|
||||
}
|
||||
});
|
||||
|
||||
m_server.setCommandCallback(Network::Command::ChatMessage, [this](ClientInfo &client, sf::Packet &packet) {
|
||||
m_server.setCommandCallback(Network::Command::ChatMessage, [this](ClientInfo &client, Network::Packet &packet) {
|
||||
u16 clientID;
|
||||
std::string message;
|
||||
packet >> clientID >> message;
|
||||
|
@ -49,6 +49,11 @@ class ServerPlayer;
|
||||
class ServerWorld;
|
||||
class WorldController;
|
||||
|
||||
//=================================================================================================
|
||||
// IMPORTANT: ServerCommandHandler is the only class that should be creating and sending packets.
|
||||
// The only exceptions to this rule are ServerWorld::sendRequestedChunks and LuaGUI::show
|
||||
//=================================================================================================
|
||||
|
||||
class ServerCommandHandler {
|
||||
public:
|
||||
ServerCommandHandler(ScriptEngine &scriptEngine, Server &server, WorldController &worldController, PlayerList &players, Registry ®istry)
|
||||
|
@ -104,7 +104,7 @@ void ServerWorld::createChunkNeighbours(ServerChunk &chunk) {
|
||||
}
|
||||
|
||||
void ServerWorld::sendChunkData(const ClientInfo &client, ServerChunk &chunk) {
|
||||
sf::Packet packet;
|
||||
Network::Packet packet;
|
||||
packet << Network::Command::ChunkData;
|
||||
packet << chunk.x() << chunk.y() << chunk.z();
|
||||
for (u16 z = 0 ; z < CHUNK_HEIGHT ; ++z) {
|
||||
|
@ -54,7 +54,7 @@ void WorldController::load(const std::string &name) {
|
||||
char *buffer = new char[length];
|
||||
file.read(buffer, length);
|
||||
|
||||
sf::Packet save;
|
||||
Network::Packet save;
|
||||
save.append(buffer, length);
|
||||
|
||||
delete[] buffer;
|
||||
@ -98,9 +98,9 @@ void WorldController::save(const std::string &name) {
|
||||
|
||||
std::ofstream file(name + ".dat", std::ofstream::binary | std::ofstream::trunc);
|
||||
|
||||
sf::Packet save;
|
||||
Network::Packet save;
|
||||
for (auto &world : m_worldList) {
|
||||
sf::Packet chunks;
|
||||
Network::Packet chunks;
|
||||
unsigned int chunkCount = 0;
|
||||
for (auto &chunk : world.chunks()) {
|
||||
if (!chunk.second->isInitialized()) continue;
|
||||
|
Loading…
x
Reference in New Issue
Block a user