diff --git a/source/client/network/ClientCommandHandler.cpp b/source/client/network/ClientCommandHandler.cpp index 3a7056e53..823739e2d 100644 --- a/source/client/network/ClientCommandHandler.cpp +++ b/source/client/network/ClientCommandHandler.cpp @@ -46,7 +46,7 @@ void ClientCommandHandler::sendPlayerInvUpdate() { Network::Packet invPacket; invPacket << Network::Command::PlayerInvUpdate; - // FIXME: Sending client id shouldn't be necessary + // FIXME: Sending client id shouldn't be necessary when sending this packet from client invPacket << m_client.id(); invPacket << m_player.inventory(); m_client.send(invPacket); @@ -55,7 +55,7 @@ void ClientCommandHandler::sendPlayerInvUpdate() { void ClientCommandHandler::sendPlayerPosUpdate() { Network::Packet packet; packet << Network::Command::PlayerPosUpdate; - // FIXME: Sending client id shouldn't be necessary + // FIXME: Sending client id shouldn't be necessary when sending this packet from client packet << m_client.id(); packet << m_player.x(); packet << m_player.y(); @@ -64,6 +64,16 @@ void ClientCommandHandler::sendPlayerPosUpdate() { m_client.send(packet); } +void ClientCommandHandler::sendPlayerRotUpdate() { + Network::Packet packet; + packet << Network::Command::PlayerRotUpdate; + // FIXME: Sending client id shouldn't be necessary when sending this packet from client + packet << m_client.id(); + packet << m_player.cameraYaw(); + packet << m_player.cameraPitch(); + m_client.send(packet); +} + void ClientCommandHandler::sendPlayerDigBlock(const glm::ivec4 &selectedBlock) { Network::Packet packet; packet << Network::Command::PlayerDigBlock diff --git a/source/client/network/ClientCommandHandler.hpp b/source/client/network/ClientCommandHandler.hpp index 3499f41a1..bf1f61e2d 100644 --- a/source/client/network/ClientCommandHandler.hpp +++ b/source/client/network/ClientCommandHandler.hpp @@ -48,6 +48,7 @@ class ClientCommandHandler { void sendPlayerInvUpdate(); void sendPlayerPosUpdate(); + void sendPlayerRotUpdate(); void sendPlayerDigBlock(const glm::ivec4 &selectedBlock); void sendPlayerPlaceBlock(s32 x, s32 y, s32 z, u32 block); void sendPlayerInventoryRequest(); diff --git a/source/client/states/GameState.cpp b/source/client/states/GameState.cpp index 5a00571cb..ee1f43bbf 100644 --- a/source/client/states/GameState.cpp +++ b/source/client/states/GameState.cpp @@ -155,6 +155,7 @@ void GameState::update() { if (gk::GameClock::getInstance().getTicks() % 100 < 10) { m_clientCommandHandler.sendPlayerPosUpdate(); + m_clientCommandHandler.sendPlayerRotUpdate(); } m_client.update(); diff --git a/source/client/world/ClientPlayer.cpp b/source/client/world/ClientPlayer.cpp index a91111419..7f1f7b956 100644 --- a/source/client/world/ClientPlayer.cpp +++ b/source/client/world/ClientPlayer.cpp @@ -62,16 +62,6 @@ void ClientPlayer::turnViewV(float angle) { updateDir(); } -// Note: This function returns an angle4 -u8 ClientPlayer::getDirection() const { - return int(floorf(m_viewAngleH / 90.f + 0.5f)) & 3; -} - -// Note: This function returns an angle4 -u8 ClientPlayer::getOppositeDirection() const { - return getDirection() ^ 2; -} - void ClientPlayer::updateDir() { float ch = cosf(m_viewAngleH * RADIANS_PER_DEGREES); float sh = sinf(m_viewAngleH * RADIANS_PER_DEGREES); diff --git a/source/client/world/ClientPlayer.hpp b/source/client/world/ClientPlayer.hpp index 36fc5ccf2..e2d487460 100644 --- a/source/client/world/ClientPlayer.hpp +++ b/source/client/world/ClientPlayer.hpp @@ -52,11 +52,6 @@ class ClientPlayer : public Player { void turnH(float angle); void turnViewV(float angle); - // West, East, South, North - // Same order as enum BlockFace in TilesDef.hpp - u8 getDirection() const; - u8 getOppositeDirection() const; - void move(float direction); void processInputs(); @@ -71,10 +66,6 @@ class ClientPlayer : public Player { static ClientPlayer &getInstance() { return *s_instance; } static void setInstance(ClientPlayer *instance) { s_instance = instance; } - float cameraYaw() const { return m_viewAngleH; } - float cameraPitch() const { return m_viewAngleV; } - float cameraRoll() const { return m_viewAngleRoll; } - void setPosition(double x, double y, double z); void setCameraRoll(float angle) { m_viewAngleRoll = angle; updateDir(); }; @@ -88,10 +79,6 @@ class ClientPlayer : public Player { gk::Camera &m_camera; - float m_viewAngleH; - float m_viewAngleV; - float m_viewAngleRoll; - gk::Vector3f m_forwardDir; gk::Vector3f m_cameraLocalPos; diff --git a/source/common/network/Network.cpp b/source/common/network/Network.cpp index 6acbc66c8..502a1952d 100644 --- a/source/common/network/Network.cpp +++ b/source/common/network/Network.cpp @@ -46,6 +46,7 @@ std::string Network::commandToString(Network::Command command) { {Network::Command::PlayerDigBlock, "PlayerDigBlock"}, {Network::Command::PlayerInvUpdate, "PlayerInvUpdate"}, {Network::Command::PlayerPosUpdate, "PlayerPosUpdate"}, + {Network::Command::PlayerRotUpdate, "PlayerRotUpdate"}, {Network::Command::PlayerSpawn, "PlayerSpawn"}, {Network::Command::PlayerInventory, "PlayerInventory"}, {Network::Command::PlayerCreativeWindow, "PlayerCreativeWindow"}, diff --git a/source/common/network/Network.hpp b/source/common/network/Network.hpp index 2d18cf7e6..fcf829054 100644 --- a/source/common/network/Network.hpp +++ b/source/common/network/Network.hpp @@ -51,32 +51,33 @@ namespace Network { PlayerDigBlock = 0x08, // [NetworkCommand][s32 x, y, z] (from Client only) PlayerInvUpdate = 0x09, // [NetworkCommand][u16 client id][[std::string item][u16 amount][u8 x, y]...] (both) [FIXME] PlayerPosUpdate = 0x0a, // [NetworkCommand][u16 client id][s32 x, y, z][bool isTeleportation] (both) // FIXME - PlayerSpawn = 0x0b, // [NetworkCommand][u16 client id][s32 x, y, z] (from Server only) - PlayerInventory = 0x0c, // [NetworkCommand][u16 screenWidth, screenHeight][u8 guiScale] (from Client only) - PlayerCreativeWindow = 0x0d, // [NetworkCommand][u16 screenWidth, screenHeight][u8 guiScale] (from Client only) - PlayerChangeDimension = 0x0e, // [NetworkCommand][u16 client id][s32 x, y, z][u16 dimension] (from Server only) - PlayerHeldItemChanged = 0x0f, // [NetworkCommand][u8 hotbar slot][u16 item id (to check match with server)] (from Client only) + PlayerRotUpdate = 0x0b, // [NetworkCommand][u16 client id][float yaw][float pitch] (from Client only) + PlayerSpawn = 0x0c, // [NetworkCommand][u16 client id][s32 x, y, z] (from Server only) + PlayerInventory = 0x0d, // [NetworkCommand][u16 screenWidth, screenHeight][u8 guiScale] (from Client only) + PlayerCreativeWindow = 0x0e, // [NetworkCommand][u16 screenWidth, screenHeight][u8 guiScale] (from Client only) + PlayerChangeDimension = 0x0f, // [NetworkCommand][u16 client id][s32 x, y, z][u16 dimension] (from Server only) + PlayerHeldItemChanged = 0x10, // [NetworkCommand][u8 hotbar slot][u16 item id (to check match with server)] (from Client only) // Block commands - BlockUpdate = 0x10, // [NetworkCommand][s32 x, y, z][u32 block] (from Server only) - BlockActivated = 0x11, // [NetworkCommand][s32 x, y, z][u16 screenWidth, screenHeight][u8 guiScale] (from Client only) - BlockGUIData = 0x12, // [NetworkCommand][LuaGUIData data] (from Server only) - BlockInvUpdate = 0x13, // [NetworkCommand][s32 x, y, z][[std::string item][u16 amount][u8 x, y]...] (both) [FIXME] - BlockDataUpdate = 0x14, // [NetworkCommand][s32 x, y, z][u64 data] (both) [FIXME] + BlockUpdate = 0x11, // [NetworkCommand][s32 x, y, z][u32 block] (from Server only) + BlockActivated = 0x12, // [NetworkCommand][s32 x, y, z][u16 screenWidth, screenHeight][u8 guiScale] (from Client only) + BlockGUIData = 0x13, // [NetworkCommand][LuaGUIData data] (from Server only) + BlockInvUpdate = 0x14, // [NetworkCommand][s32 x, y, z][[std::string item][u16 amount][u8 x, y]...] (both) [FIXME] + BlockDataUpdate = 0x15, // [NetworkCommand][s32 x, y, z][u64 data] (both) [FIXME] // Registry commands - RegistryData = 0x15, // [NetworkCommand][Block block] (from Server only) + RegistryData = 0x16, // [NetworkCommand][Block block] (from Server only) // Chat commands - ChatMessage = 0x16, // [NetworkCommand][u16 client id][std::string message] (both) + ChatMessage = 0x17, // [NetworkCommand][u16 client id][std::string message] (both) // Entity commands - EntitySpawn = 0x17, // [NetworkCommand][u32 entity id] (from Server only) - EntityDespawn = 0x18, // [NetworkCommand][u32 entity id] (from Server only) - EntityPosition = 0x19, // [NetworkCommand][u32 entity id][double x, double y, double z] (from Server only) - EntityRotation = 0x1a, // [NetworkCommand][u32 entity id][float w, float x, float y, float z] (from Server only) - EntityAnimation = 0x1b, // [NetworkCommand][u32 entity id][AnimationComponent anim] (from Server only) - EntityDrawableDef = 0x1c, // [NetworkCommand][u32 entity id][DrawableDef def] (from Server only) + EntitySpawn = 0x18, // [NetworkCommand][u32 entity id] (from Server only) + EntityDespawn = 0x19, // [NetworkCommand][u32 entity id] (from Server only) + EntityPosition = 0x1a, // [NetworkCommand][u32 entity id][double x, double y, double z] (from Server only) + EntityRotation = 0x1b, // [NetworkCommand][u32 entity id][float w, float x, float y, float z] (from Server only) + EntityAnimation = 0x1c, // [NetworkCommand][u32 entity id][AnimationComponent anim] (from Server only) + EntityDrawableDef = 0x1d, // [NetworkCommand][u32 entity id][DrawableDef def] (from Server only) }; std::string commandToString(Command command); diff --git a/source/common/world/Player.cpp b/source/common/world/Player.cpp index 844d96885..f23a827f5 100644 --- a/source/common/world/Player.cpp +++ b/source/common/world/Player.cpp @@ -31,6 +31,16 @@ Player::Player() { m_hitbox = gk::FloatBox{-0.3125, -0.3125, 0, 0.625, 0.625, 1.75}; } +// Note: This function returns an angle4 +u8 Player::getDirection() const { + return int(floorf(m_viewAngleH / 90.f + 0.5f)) & 3; +} + +// Note: This function returns an angle4 +u8 Player::getOppositeDirection() const { + return getDirection() ^ 2; +} + void Player::serialize(sf::Packet &packet) const { packet << m_x << m_y << m_z << m_dimension << m_inventory; } diff --git a/source/common/world/Player.hpp b/source/common/world/Player.hpp index 5289d4925..9fc517704 100644 --- a/source/common/world/Player.hpp +++ b/source/common/world/Player.hpp @@ -36,6 +36,11 @@ class Player : public ISerializable { public: Player(); + // West, East, South, North + // Same order as enum BlockFace in TilesDef.hpp + u8 getDirection() const; + u8 getOppositeDirection() const; + void serialize(sf::Packet &packet) const override; void deserialize(sf::Packet &packet) override; @@ -45,11 +50,16 @@ class Player : public ISerializable { u16 dimension() const { return m_dimension; } + float cameraYaw() const { return m_viewAngleH; } + float cameraPitch() const { return m_viewAngleV; } + float cameraRoll() const { return m_viewAngleRoll; } + u16 clientID() const { return m_clientID; } Inventory &inventory() { return m_inventory; } void setPosition(double x, double y, double z) { m_x = x; m_y = y; m_z = z; } + void setRotation(float yaw, float pitch) { m_viewAngleH = yaw; m_viewAngleV = pitch; } void setDimension(u16 dimension) { m_dimension = dimension; } void setClientID(u16 clientID) { m_clientID = clientID; } @@ -64,6 +74,10 @@ class Player : public ISerializable { u16 m_dimension = 0; + float m_viewAngleH; + float m_viewAngleV; + float m_viewAngleRoll; + u16 m_clientID = 0; Inventory m_inventory{9, 4}; diff --git a/source/server/core/ServerApplication.cpp b/source/server/core/ServerApplication.cpp index 8857d20ce..14935a550 100644 --- a/source/server/core/ServerApplication.cpp +++ b/source/server/core/ServerApplication.cpp @@ -144,6 +144,7 @@ void ServerApplication::update() { if (m_clock.getTicks() % 100 < 10) { for (auto &it : m_players) { m_serverCommandHandler.sendPlayerPosUpdate(it.first); + m_serverCommandHandler.sendPlayerRotUpdate(it.first); } } } diff --git a/source/server/network/ServerCommandHandler.cpp b/source/server/network/ServerCommandHandler.cpp index 956868f84..4c85cdcf2 100644 --- a/source/server/network/ServerCommandHandler.cpp +++ b/source/server/network/ServerCommandHandler.cpp @@ -82,7 +82,24 @@ void ServerCommandHandler::sendPlayerPosUpdate(u16 clientID, bool isTeleportatio client->tcpSocket->send(packet); } else - gkError() << ("Failed to send pos update for player " + std::to_string(clientID) + ": Player not found").c_str(); + 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(); } void ServerCommandHandler::sendPlayerInvUpdate(u16 clientID, const ClientInfo *client) const { @@ -98,7 +115,7 @@ void ServerCommandHandler::sendPlayerInvUpdate(u16 clientID, const ClientInfo *c client->tcpSocket->send(packet); } else - gkError() << ("Failed to send inv update for player " + std::to_string(clientID) + ": Player not found").c_str(); + gkError() << ("Failed to send inventory update for player " + std::to_string(clientID) + ": Player not found").c_str(); } void ServerCommandHandler::sendPlayerChangeDimension(u16 clientID, s32 x, s32 y, s32 z, u16 dimension, const ClientInfo *client) const { @@ -223,6 +240,20 @@ 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::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(); + }); + m_server.setCommandCallback(Network::Command::PlayerPlaceBlock, [this](ClientInfo &client, Network::Packet &packet) { ServerPlayer *player = m_players.getPlayer(client.id); if (player) { diff --git a/source/server/network/ServerCommandHandler.hpp b/source/server/network/ServerCommandHandler.hpp index 040d27232..99bbaf94f 100644 --- a/source/server/network/ServerCommandHandler.hpp +++ b/source/server/network/ServerCommandHandler.hpp @@ -65,6 +65,7 @@ class ServerCommandHandler { void sendBlockDataUpdate(s32 x, s32 y, s32 z, const BlockData *blockData, const ClientInfo *client = nullptr) const; void sendBlockInvUpdate(s32 x, s32 y, s32 z, const Inventory &inventory, const ClientInfo *client = nullptr) const; void sendPlayerPosUpdate(u16 clientID, bool isTeleportation = false, const ClientInfo *client = nullptr) const; + void sendPlayerRotUpdate(u16 clientID, const ClientInfo *client = nullptr) const; void sendPlayerInvUpdate(u16 clientID, const ClientInfo *client = nullptr) const; void sendPlayerChangeDimension(u16 clientID, s32 x, s32 y, s32 z, u16 dimension, const ClientInfo *client = nullptr) const; void sendChatMessage(u16 clientID, const std::string &message, const ClientInfo *client = nullptr) const;