From 251a59ddbe14ac65bb32d44209c1119107a1604d Mon Sep 17 00:00:00 2001 From: Vladislav Khorev Date: Tue, 10 Feb 2026 11:42:23 +0300 Subject: [PATCH] added hash --- server/server.cpp | 37 ++++++++++++++++++++++++++++--- src/Game.cpp | 6 ++--- src/network/ClientState.h | 3 +++ src/network/WebSocketClient.cpp | 18 ++++++++++++++- src/network/WebSocketClientBase.h | 1 + 5 files changed, 58 insertions(+), 7 deletions(-) diff --git a/server/server.cpp b/server/server.cpp index 4615a1a..c9f1d8f 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -129,6 +129,28 @@ public: }); } + bool IsMessageValid(const std::string& fullMessage) { +#ifdef ENABLE_NETWORK_CHECKSUM + size_t hashPos = fullMessage.find("#hash:"); + if (hashPos == std::string::npos) { + return false; // Хеша нет, хотя он ожидался + } + + std::string originalContent = fullMessage.substr(0, hashPos); + std::string receivedHashStr = fullMessage.substr(hashPos + 6); // 6 — длина "#hash:" + + // Вычисляем ожидаемый хеш от контента + size_t expectedHash = std::hash{}(originalContent + NET_SECRET); + + std::stringstream ss; + ss << std::hex << expectedHash; + + return ss.str() == receivedHashStr; +#else + return true; // В режиме отладки пропускаем всё +#endif + } + private: /* void init() { @@ -299,8 +321,17 @@ private: } void process_message(const std::string& msg) { - std::cout << "Received from player " << id_ << ": " << msg << std::endl; - auto parts = split(msg, ':'); + if (!IsMessageValid(msg)) { + // Логируем попытку подмены и просто выходим из обработки + std::cout << "[Security] Invalid packet hash. Dropping message." << std::endl; + return; + } + std::string cleanMessage = msg.substr(0, msg.find("#hash:")); + + + + std::cout << "Received from player " << id_ << ": " << cleanMessage << std::endl; + auto parts = split(cleanMessage, ':'); if (parts.empty()) return; @@ -326,7 +357,7 @@ private: receivedState.handle_full_sync(parts, 2); timedClientStates.add_state(receivedState); - retranslateMessage(msg); + retranslateMessage(cleanMessage); } else if (parts[0] == "RESPAWN") { { diff --git a/src/Game.cpp b/src/Game.cpp index 4d75e39..760545c 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -884,8 +884,8 @@ namespace ZL int64_t localNow = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()).count(); - std::cout << "getSyncTimeMs localNow = " << localNow << std::endl; - std::cout << "getSyncTimeMs getTimeOffset = " << networkClient->getTimeOffset() << std::endl; + //std::cout << "getSyncTimeMs localNow = " << localNow << std::endl; + //std::cout << "getSyncTimeMs getTimeOffset = " << networkClient->getTimeOffset() << std::endl; // Добавляем смещение, полученное от сервера return localNow + networkClient->getTimeOffset(); // Нужно добавить геттер в интерфейс @@ -917,7 +917,7 @@ namespace ZL auto now_ms = newTickCount; - std::cout << "processTickCount = " << now_ms << std::endl; + //std::cout << "processTickCount = " << now_ms << std::endl; sparkEmitter.update(static_cast(delta)); planetObject.update(static_cast(delta)); diff --git a/src/network/ClientState.h b/src/network/ClientState.h index 7820834..8dd52ba 100644 --- a/src/network/ClientState.h +++ b/src/network/ClientState.h @@ -9,6 +9,9 @@ using std::min; using std::max; +constexpr auto NET_SECRET = "880b3713b9ff3e7a94b2712d54679e1f"; +#define ENABLE_NETWORK_CHECKSUM + constexpr float ANGULAR_ACCEL = 0.005f * 1000.0f; constexpr float SHIP_ACCEL = 1.0f * 1000.0f; constexpr float ROTATION_SENSITIVITY = 0.002f; diff --git a/src/network/WebSocketClient.cpp b/src/network/WebSocketClient.cpp index f614dc3..be31377 100644 --- a/src/network/WebSocketClient.cpp +++ b/src/network/WebSocketClient.cpp @@ -78,7 +78,23 @@ namespace ZL { void WebSocketClient::Send(const std::string& message) { if (!connected) return; - auto ss = std::make_shared(message); + std::string finalMessage = message; + +#ifdef ENABLE_NETWORK_CHECKSUM + // Вычисляем хеш. Для примера используем std::hash, + // но в продакшене лучше взять быструю реализацию типа MurmurHash3. + size_t hashValue = std::hash{}(message + NET_SECRET); + + // Преобразуем хеш в hex-строку для передачи + std::stringstream ss_hash; + ss_hash << std::hex << hashValue; + + // Добавляем хеш в конец сообщения через разделитель + // Например: "UPD:12345:pos...#hash:a1b2c3d4" + finalMessage += "#hash:" + ss_hash.str(); +#endif + + auto ss = std::make_shared(finalMessage); std::lock_guard lock(writeMutex_); writeQueue_.push(ss); diff --git a/src/network/WebSocketClientBase.h b/src/network/WebSocketClientBase.h index 1aabf0e..ed9639f 100644 --- a/src/network/WebSocketClientBase.h +++ b/src/network/WebSocketClientBase.h @@ -6,6 +6,7 @@ namespace ZL { + class WebSocketClientBase : public INetworkClient { protected: