From 470faf1cc56d205a473f5f7e592caa9f667e8571 Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Sun, 30 Nov 2025 11:47:57 +0300 Subject: [PATCH] Fixed camera data not being sent when coordinates are too large --- include/Helpers/Networking/NetLibrary.hpp | 2 +- src/Server/ClientData.hpp | 6 ++-- src/Server/CommandList.hpp | 6 ++-- src/Server/MainServer.cpp | 22 ++++++++++---- src/World.cpp | 35 +++++++++++++++++------ src/World.hpp | 8 +++++- 6 files changed, 58 insertions(+), 21 deletions(-) diff --git a/include/Helpers/Networking/NetLibrary.hpp b/include/Helpers/Networking/NetLibrary.hpp index 66d5457..bb8003e 100644 --- a/include/Helpers/Networking/NetLibrary.hpp +++ b/include/Helpers/Networking/NetLibrary.hpp @@ -14,7 +14,7 @@ template std::weak_ptr make_weak_ptr(std::shared_ptr ptr) { retu #define RELIABLE_COMMAND_CHANNEL "reliableCommand" #define UNRELIABLE_COMMAND_CHANNEL "unreliableCommand" #define RESOURCE_COMMAND_CHANNEL "resourceCommand" -#define MAIN_NETLIBRARY_CHANNEL "main00004" // NOTE: Change this value whenever netcode is incompatible with the previous version +#define MAIN_NETLIBRARY_CHANNEL "main00005" // NOTE: Change this value whenever netcode is incompatible with the previous version typedef uint8_t MessageCommandType; diff --git a/src/Server/ClientData.hpp b/src/Server/ClientData.hpp index 7c5d38f..2f0f61c 100644 --- a/src/Server/ClientData.hpp +++ b/src/Server/ClientData.hpp @@ -11,10 +11,10 @@ class MainServer; class ClientData { public: CoordSpaceHelper camCoords; - Vector2f windowSize; - Vector2f cursorPos; + Vector2f windowSize = {1000.0f, 1000.0f}; + Vector2f cursorPos = {1.0f, 1.0f}; - Vector3f cursorColor; + Vector3f cursorColor = {1.0f, 1.0f, 1.0f}; std::string displayName; ServerPortionID serverID = 0; diff --git a/src/Server/CommandList.hpp b/src/Server/CommandList.hpp index 0e97733..c015fc2 100644 --- a/src/Server/CommandList.hpp +++ b/src/Server/CommandList.hpp @@ -6,7 +6,8 @@ enum ServerCommands : MessageCommandType { SERVER_FRAGMENT = 0, SERVER_KEEP_ALIVE, SERVER_INITIAL_DATA, - SERVER_MOVE_MOUSE, + SERVER_MOVE_CAMERA, + SERVER_MOVE_SCREEN_MOUSE, SERVER_PLACE_SINGLE_COMPONENT, SERVER_PLACE_MANY_COMPONENTS, SERVER_TRANSFORM_MANY_COMPONENTS, @@ -36,7 +37,8 @@ enum ClientCommands : MessageCommandType { CLIENT_ERASE_SINGLE_COMPONENT, CLIENT_ERASE_MANY_COMPONENTS, CLIENT_UPDATE_COMPONENT, - CLIENT_MOVE_MOUSE, + CLIENT_MOVE_CAMERA, + CLIENT_MOVE_SCREEN_MOUSE, CLIENT_NEW_RESOURCE_ID, CLIENT_NEW_RESOURCE_DATA, CLIENT_CHAT_MESSAGE, diff --git a/src/Server/MainServer.cpp b/src/Server/MainServer.cpp index 9e21555..412d4e1 100644 --- a/src/Server/MainServer.cpp +++ b/src/Server/MainServer.cpp @@ -53,8 +53,15 @@ MainServer::MainServer(World& initWorld, const std::string& serverLocalID): message(newClient.displayName, isDirectConnect); ensure_display_name_unique(newClient.displayName); - if(isDirectConnect) + if(isDirectConnect) { fileDisplayName = newClient.displayName; + message(newClient.camCoords, newClient.windowSize); + } + else { + auto& [randomClientServerID, randomClient] = *clients.begin(); + newClient.camCoords = randomClient.camCoords; + newClient.windowSize = randomClient.windowSize; + } newClient.serverID = Random::get().int_range(1, std::numeric_limits::max()); client->customID = newClient.serverID; @@ -62,7 +69,7 @@ MainServer::MainServer(World& initWorld, const std::string& serverLocalID): if(isDirectConnect) netServer->send_items_to_client(client, RELIABLE_COMMAND_CHANNEL, CLIENT_INITIAL_DATA, isDirectConnect, newClient.serverID, newClient.cursorColor); else { - netServer->send_items_to_client(client, RELIABLE_COMMAND_CHANNEL, CLIENT_INITIAL_DATA, isDirectConnect, newClient.serverID, newClient.cursorColor, newClient.displayName, fileDisplayName, clients, data); + netServer->send_items_to_client(client, RELIABLE_COMMAND_CHANNEL, CLIENT_INITIAL_DATA, isDirectConnect, newClient.serverID, newClient.cursorColor, newClient.displayName, newClient.camCoords, newClient.windowSize, fileDisplayName, clients, data); for(auto& [id, rData] : data.resources) { netServer->send_items_to_client(client, RESOURCE_COMMAND_CHANNEL, CLIENT_NEW_RESOURCE_ID, id); netServer->send_items_to_client(client, RESOURCE_COMMAND_CHANNEL, CLIENT_NEW_RESOURCE_DATA, rData); @@ -70,10 +77,15 @@ MainServer::MainServer(World& initWorld, const std::string& serverLocalID): } clients.emplace(newClient.serverID, newClient); }); - netServer->add_recv_callback(SERVER_MOVE_MOUSE, [&](std::shared_ptr client, cereal::PortableBinaryInputArchive& message) { + netServer->add_recv_callback(SERVER_MOVE_CAMERA, [&](std::shared_ptr client, cereal::PortableBinaryInputArchive& message) { auto& c = clients[client->customID]; - message(c.camCoords, c.windowSize, c.cursorPos); - netServer->send_items_to_all_clients_except(client, UNRELIABLE_COMMAND_CHANNEL, CLIENT_MOVE_MOUSE, c.serverID, c.camCoords, c.windowSize, c.cursorPos); + message(c.camCoords, c.windowSize); + netServer->send_items_to_all_clients_except(client, RELIABLE_COMMAND_CHANNEL, CLIENT_MOVE_CAMERA, c.serverID, c.camCoords, c.windowSize); + }); + netServer->add_recv_callback(SERVER_MOVE_SCREEN_MOUSE, [&](std::shared_ptr client, cereal::PortableBinaryInputArchive& message) { + auto& c = clients[client->customID]; + message(c.cursorPos); + netServer->send_items_to_all_clients_except(client, UNRELIABLE_COMMAND_CHANNEL, CLIENT_MOVE_SCREEN_MOUSE, c.serverID, c.cursorPos); }); netServer->add_recv_callback(SERVER_PLACE_SINGLE_COMPONENT, [&](std::shared_ptr client, cereal::PortableBinaryInputArchive& message) { uint64_t placement; diff --git a/src/World.cpp b/src/World.cpp index de393b4..e3d2566 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -76,18 +76,17 @@ void World::init_client_callbacks() { message(isDirectConnect, ownID, userColor); if(!isDirectConnect) { std::string fileDisplayName; - message(displayName, fileDisplayName, clients); + CoordSpaceHelper camCoordsToMoveTo; + Vector2f windowSizeToMoveTo; + message(displayName, camCoordsToMoveTo, windowSizeToMoveTo, fileDisplayName, clients); set_name(fileDisplayName); + drawData.cam.smooth_move_to(*main.world, camCoordsToMoveTo, windowSizeToMoveTo, true); Vector3f newBackColor; message(newBackColor); set_canvas_background_color(newBackColor, false); message(canvasScale); drawProg.initialize_draw_data(message); message(bMan, gridMan); - if(!clients.empty()) { - auto& [randomClientServerID, randomClient] = *clients.begin(); - drawData.cam.smooth_move_to(*main.world, randomClient.camCoords, randomClient.windowSize, true); - } } nextClientID = get_max_id(ownID); clientStillConnecting = false; @@ -110,11 +109,17 @@ void World::init_client_callbacks() { clients.erase(id); } }); - con.client_add_recv_callback(CLIENT_MOVE_MOUSE, [&](cereal::PortableBinaryInputArchive& message) { + con.client_add_recv_callback(CLIENT_MOVE_CAMERA, [&](cereal::PortableBinaryInputArchive& message) { ServerPortionID id; message(id); auto& c = clients[id]; - message(c.camCoords, c.windowSize, c.cursorPos); + message(c.camCoords, c.windowSize); + }); + con.client_add_recv_callback(CLIENT_MOVE_SCREEN_MOUSE, [&](cereal::PortableBinaryInputArchive& message) { + ServerPortionID id; + message(id); + auto& c = clients[id]; + message(c.cursorPos); }); con.client_add_recv_callback(CLIENT_CHAT_MESSAGE, [&](cereal::PortableBinaryInputArchive& message) { ServerPortionID senderID; @@ -164,7 +169,19 @@ void World::focus_update() { } if(!clientStillConnecting) { - con.client_send_items_to_server(UNRELIABLE_COMMAND_CHANNEL, SERVER_MOVE_MOUSE, drawData.cam.c, main.window.size.cast().eval(), main.input.mouse.pos); + constexpr float SECONDS_TO_SEND_CAMERA_DATA = 0.5f; + timeToSendCameraData.update_time_since(); + if(timeToSendCameraData.get_time_since() > SECONDS_TO_SEND_CAMERA_DATA) { + timeToSendCameraData.update_time_point(); + if(!sentCameraData.has_value() || (sentCameraData.value().windowSize != main.window.size.cast().eval() || sentCameraData.value().camTransform != drawData.cam.c)) { + con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_MOVE_CAMERA, drawData.cam.c, main.window.size.cast().eval()); + sentCameraData = { + .camTransform = drawData.cam.c, + .windowSize = main.window.size.cast() + }; + } + } + con.client_send_items_to_server(UNRELIABLE_COMMAND_CHANNEL, SERVER_MOVE_SCREEN_MOUSE, main.input.mouse.pos); drawProg.update(); } @@ -263,7 +280,7 @@ void World::start_hosting(const std::string& initNetSource, const std::string& s bMan.init_client_callbacks(); gridMan.init_client_callbacks(); init_client_callbacks(); - con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_INITIAL_DATA, displayName, true); + con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_INITIAL_DATA, displayName, true, drawData.cam.c, main.window.size.cast().eval()); conType = CONNECTIONTYPE_SERVER; netSource = initNetSource; drawProg.components.set_server_from_client_list(); diff --git a/src/World.hpp b/src/World.hpp index cdfff6e..857fed7 100644 --- a/src/World.hpp +++ b/src/World.hpp @@ -100,7 +100,6 @@ class World { uint64_t canvasScale = 0; private: - ClientPortionID get_max_id(ServerPortionID serverID); void init_client_callbacks(); @@ -108,6 +107,13 @@ class World { void draw_other_player_cursors(SkCanvas* canvas, const DrawData& drawData); + TimePoint timeToSendCameraData; + struct SentCameraData { + CoordSpaceHelper camTransform; + Vector2f windowSize; + }; + std::optional sentCameraData; + ClientPortionID nextClientID = 0; WorldVec mousePreviousWorldVec = {0, 0}; WorldVec mouseWorldMove = {0, 0};