diff --git a/server/server.cpp b/server/server.cpp index a991dee..81dde92 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -74,10 +74,12 @@ class Session : public std::enable_shared_from_this { state_.discreteAngle = std::stoi(parts[2]); state_.discreteMag = std::stof(parts[3]); state_.apply_lag_compensation(now_server); + retranslateMessage(msg); } else if (parts[0] == "VEL") { state_.selectedVelocity = std::stoi(parts[2]); state_.apply_lag_compensation(now_server); + retranslateMessage(msg); } else if (parts[0] == "PING") { state_.handle_full_sync(parts); @@ -85,7 +87,17 @@ class Session : public std::enable_shared_from_this { } } + void retranslateMessage(const std::string& msg) + { + std::string event_msg = "EVENT:" + std::to_string(id_) + ":" + msg; + std::lock_guard lock(g_sessions_mutex); + for (auto& session : g_sessions) { + if (session->get_id() != id_) { // + session->send_message(event_msg); + } + } + } public: @@ -141,6 +153,10 @@ public: ws_.async_write(net::buffer(*ss), [ss](beast::error_code, std::size_t) {}); } + int get_id() const { + return id_; + } + private: void do_read() { ws_.async_read(buffer_, [self = shared_from_this()](beast::error_code ec, std::size_t) { diff --git a/src/Game.cpp b/src/Game.cpp index fe8cab4..6ff3bc4 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -768,8 +768,21 @@ namespace ZL } else { // Если джойстик не зажат — сбрасываем дискретные значения и плавно замедляем вращение - Environment::lastSentAngle = -1; - Environment::lastSentMagnitude = 0.0f; + int discreteAngle = -1; + float discreteMag = 0.0f; + + if (discreteAngle != Environment::lastSentAngle || discreteMag != Environment::lastSentMagnitude) { + Environment::lastSentAngle = discreteAngle; + Environment::lastSentMagnitude = discreteMag; + auto now_ms = std::chrono::duration_cast( + std::chrono::steady_clock::now().time_since_epoch() + ).count(); + + // Формируем сетевой пакет + // Нам нужно отправить: дискретный угол, дискретную силу и текущую матрицу/позицию для синхронизации + std::string msg = "ROT:" + std::to_string(now_ms) + ":" + std::to_string(discreteAngle) + ":" + std::to_string(discreteMag); + networkClient->Send(msg); + } float currentSpeed = Environment::currentAngularVelocity.norm(); @@ -802,33 +815,6 @@ namespace ZL Environment::shipPosition = Environment::shipPosition + velocityDirectionAdjusted; } - /* - if (Environment::tapDownHold) { - - float diffx = Environment::tapDownCurrentPos(0) - Environment::tapDownStartPos(0); - float diffy = Environment::tapDownCurrentPos(1) - Environment::tapDownStartPos(1); - - if (abs(diffy) > 5.0 || abs(diffx) > 5.0) //threshold - { - - float rotationPower = sqrtf(diffx * diffx + diffy * diffy); - float deltaAlpha = rotationPower * delta * static_cast(M_PI) / 500000.f; - - Eigen::Vector3f rotationDirection(diffy, diffx, 0.0f); - rotationDirection.normalize(); // Eigen-way нормализация - - // Создаем кватернион через AngleAxis - // Конструктор принимает (угол_в_радианах, ось_вращения) - Eigen::Quaternionf rotateQuat(Eigen::AngleAxisf(deltaAlpha, rotationDirection)); - - Matrix3f rotateMat = rotateQuat.toRotationMatrix(); - - Environment::shipMatrix = Environment::shipMatrix * rotateMat; - Environment::inverseShipMatrix = Environment::shipMatrix.inverse(); - - } - }*/ - for (auto& p : projectiles) { if (p && p->isActive()) { p->update(static_cast(delta), renderer); diff --git a/src/network/WebSocketClient.cpp b/src/network/WebSocketClient.cpp index 04c0b29..0d8046e 100644 --- a/src/network/WebSocketClient.cpp +++ b/src/network/WebSocketClient.cpp @@ -68,13 +68,56 @@ namespace ZL { void WebSocketClient::Poll() { std::lock_guard lock(queueMutex); + + auto now_ms = std::chrono::duration_cast( + std::chrono::steady_clock::now().time_since_epoch() + ).count(); + while (!messageQueue.empty()) { std::string msg = messageQueue.front(); messageQueue.pop(); - if (msg.rfind("WORLD_UPDATE|", 0) == 0) { + if (msg.rfind("EVENT:", 0) == 0) { + auto parts = split(msg, ':'); + if (parts.size() < 5) continue; // EVENT:ID:TYPE:TIME:DATA... + + int remoteId = std::stoi(parts[1]); + std::string subType = parts[2]; + uint64_t sentTime = std::stoull(parts[3]); + + std::lock_guard pLock(playersMutex); + if (remotePlayers.count(remoteId)) { + auto& rp = remotePlayers[remoteId]; + + if (subType == "VEL") { + rp.selectedVelocity = std::stoi(parts[4]); + } + else if (subType == "ROT") { + rp.discreteAngle = std::stoi(parts[4]); + rp.discreteMag = std::stof(parts[5]); + } + + // --- --- + // + float lag_s = static_cast(now_ms - sentTime) / 1000.0f; + + // ( ) + lag_s = std::max(0.0f, std::min(lag_s, 1.0f)); + + if (lag_s > 0.001f) { + // "" + // ClientState.h simulate_physics + // discreteAngle/Mag + rp.simulate_physics(lag_s); + } + + // , Game.cpp + // , now_ms + rp.lastUpdateServerTime = std::chrono::steady_clock::now(); + } + } + else if (msg.rfind("WORLD_UPDATE|", 0) == 0) { parseWorldUpdate(msg); - std::cout << msg << std::endl; } } }