Fixing bugs, more freq updated

This commit is contained in:
Vladislav Khorev 2026-01-17 15:03:37 +03:00
parent e0a60dcd6f
commit 3c55b59c8d
6 changed files with 136 additions and 28 deletions

View File

@ -42,9 +42,6 @@ class Session : public std::enable_shared_from_this<Session> {
void process_message(const std::string& msg) { void process_message(const std::string& msg) {
auto now_server = std::chrono::system_clock::now(); auto now_server = std::chrono::system_clock::now();
// Ïðåäïîëîæèì ôîðìàò ñîîáùåíèé:
// ROT:ANGLE:MAG:TIMESTAMP
// VEL:SELECTED_VEL:TIMESTAMP
auto parts = split(msg, ':'); auto parts = split(msg, ':');
if (parts.empty()) return; if (parts.empty()) return;
@ -73,6 +70,7 @@ class Session : public std::enable_shared_from_this<Session> {
if (parts[0] == "ROT") { if (parts[0] == "ROT") {
state_.discreteAngle = std::stoi(parts[2]); state_.discreteAngle = std::stoi(parts[2]);
state_.discreteMag = std::stof(parts[3]); state_.discreteMag = std::stof(parts[3]);
state_.handle_full_sync(parts, 4);
std::cout << "ROT id = " << this->id_ << " discreteMag=" << state_.discreteMag << std::endl; std::cout << "ROT id = " << this->id_ << " discreteMag=" << state_.discreteMag << std::endl;
state_.apply_lag_compensation(now_server); state_.apply_lag_compensation(now_server);
state_.lastUpdateServerTime = now_server; state_.lastUpdateServerTime = now_server;
@ -80,12 +78,13 @@ class Session : public std::enable_shared_from_this<Session> {
} }
else if (parts[0] == "VEL") { else if (parts[0] == "VEL") {
state_.selectedVelocity = std::stoi(parts[2]); state_.selectedVelocity = std::stoi(parts[2]);
state_.handle_full_sync(parts, 3);
state_.apply_lag_compensation(now_server); state_.apply_lag_compensation(now_server);
state_.lastUpdateServerTime = now_server; state_.lastUpdateServerTime = now_server;
retranslateMessage(msg); retranslateMessage(msg);
} }
else if (parts[0] == "PING") { else if (parts[0] == "PING") {
state_.handle_full_sync(parts); state_.handle_full_sync(parts, 2);
std::cout << "PING id = " << this->id_ <<" discreteMag=" << state_.discreteMag << std::endl; std::cout << "PING id = " << this->id_ <<" discreteMag=" << state_.discreteMag << std::endl;
state_.apply_lag_compensation(now_server); state_.apply_lag_compensation(now_server);
state_.lastUpdateServerTime = now_server; state_.lastUpdateServerTime = now_server;

View File

@ -245,6 +245,7 @@ namespace ZL
std::chrono::system_clock::now().time_since_epoch() std::chrono::system_clock::now().time_since_epoch()
).count(); ).count();
std::string msg = "VEL:" + std::to_string(now_ms) + ":" + std::to_string(Environment::shipSelectedVelocity); std::string msg = "VEL:" + std::to_string(now_ms) + ":" + std::to_string(Environment::shipSelectedVelocity);
msg = msg + ":" + formPingMessageContent();
networkClient->Send(msg); networkClient->Send(msg);
} }
}); });
@ -583,6 +584,18 @@ namespace ZL
renderer.PushMatrix(); renderer.PushMatrix();
renderer.LoadIdentity(); renderer.LoadIdentity();
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
renderer.RotateMatrix(Environment::inverseShipMatrix);
renderer.TranslateMatrix(-Environment::shipPosition);
Eigen::Vector3f relativePos = playerState.position;// -Environment::shipPosition;
renderer.TranslateMatrix(relativePos);
// 3. Поворот врага
renderer.RotateMatrix(playerState.rotation);
/*
// 1. Камера и вид игрока // 1. Камера и вид игрока
renderer.TranslateMatrix({ 0, 0, -1.0f * Environment::zoom }); renderer.TranslateMatrix({ 0, 0, -1.0f * Environment::zoom });
renderer.RotateMatrix(Environment::inverseShipMatrix); renderer.RotateMatrix(Environment::inverseShipMatrix);
@ -601,6 +614,8 @@ namespace ZL
// В твоем drawShip() есть: renderer.TranslateMatrix({ 0, -6.f, 0 }); // В твоем drawShip() есть: renderer.TranslateMatrix({ 0, -6.f, 0 });
renderer.TranslateMatrix({ 0, -6.f, 0 }); renderer.TranslateMatrix({ 0, -6.f, 0 });
*/
renderer.DrawVertexRenderStruct(spaceship); renderer.DrawVertexRenderStruct(spaceship);
renderer.PopMatrix(); renderer.PopMatrix();
} }
@ -638,6 +653,7 @@ namespace ZL
).count(); ).count();
// 1. Извлекаем кватернион из матрицы поворота // 1. Извлекаем кватернион из матрицы поворота
/*
Eigen::Quaternionf q(Environment::shipMatrix); Eigen::Quaternionf q(Environment::shipMatrix);
// 2. Формируем строку PING согласно протоколу сервера // 2. Формируем строку PING согласно протоколу сервера
@ -657,6 +673,8 @@ namespace ZL
+ std::to_string(Environment::shipSelectedVelocity) + ":" + std::to_string(Environment::shipSelectedVelocity) + ":"
+ std::to_string(Environment::lastSentMagnitude) + ":" // Используем те же static переменные из блока ROT + std::to_string(Environment::lastSentMagnitude) + ":" // Используем те же static переменные из блока ROT
+ std::to_string(Environment::lastSentAngle); + std::to_string(Environment::lastSentAngle);
*/
std::string pingMsg = "PING:" + std::to_string(now_ms) + ":" + formPingMessageContent();
networkClient->Send(pingMsg); networkClient->Send(pingMsg);
std::cout << "Sending: " << pingMsg << std::endl; std::cout << "Sending: " << pingMsg << std::endl;
@ -720,6 +738,7 @@ namespace ZL
// Формируем сетевой пакет // Формируем сетевой пакет
// Нам нужно отправить: дискретный угол, дискретную силу и текущую матрицу/позицию для синхронизации // Нам нужно отправить: дискретный угол, дискретную силу и текущую матрицу/позицию для синхронизации
std::string msg = "ROT:" + std::to_string(now_ms) + ":" + std::to_string(discreteAngle) + ":" + std::to_string(discreteMag); std::string msg = "ROT:" + std::to_string(now_ms) + ":" + std::to_string(discreteAngle) + ":" + std::to_string(discreteMag);
msg = msg + ":" + formPingMessageContent();
networkClient->Send(msg); networkClient->Send(msg);
} }
@ -784,6 +803,7 @@ namespace ZL
// Формируем сетевой пакет // Формируем сетевой пакет
// Нам нужно отправить: дискретный угол, дискретную силу и текущую матрицу/позицию для синхронизации // Нам нужно отправить: дискретный угол, дискретную силу и текущую матрицу/позицию для синхронизации
std::string msg = "ROT:" + std::to_string(now_ms) + ":" + std::to_string(discreteAngle) + ":" + std::to_string(discreteMag); std::string msg = "ROT:" + std::to_string(now_ms) + ":" + std::to_string(discreteAngle) + ":" + std::to_string(discreteMag);
msg = msg + ":" + formPingMessageContent();
networkClient->Send(msg); networkClient->Send(msg);
} }
@ -1138,5 +1158,28 @@ namespace ZL
} }
std::string Game::formPingMessageContent()
{
Eigen::Quaternionf q(Environment::shipMatrix);
std::string pingMsg = std::to_string(Environment::shipPosition.x()) + ":"
+ std::to_string(Environment::shipPosition.y()) + ":"
+ std::to_string(Environment::shipPosition.z()) + ":"
+ std::to_string(q.w()) + ":"
+ std::to_string(q.x()) + ":"
+ std::to_string(q.y()) + ":"
+ std::to_string(q.z()) + ":"
+ std::to_string(Environment::currentAngularVelocity.x()) + ":"
+ std::to_string(Environment::currentAngularVelocity.y()) + ":"
+ std::to_string(Environment::currentAngularVelocity.z()) + ":"
+ std::to_string(Environment::shipVelocity) + ":"
+ std::to_string(Environment::shipSelectedVelocity) + ":"
+ std::to_string(Environment::lastSentMagnitude) + ":" // Используем те же static переменные из блока ROT
+ std::to_string(Environment::lastSentAngle);
return pingMsg;
}
} // namespace ZL } // namespace ZL

View File

@ -52,6 +52,7 @@ namespace ZL {
void handleMotion(int mx, int my); void handleMotion(int mx, int my);
void extrapolateRemotePlayers(); void extrapolateRemotePlayers();
std::string formPingMessageContent();
SDL_Window* window; SDL_Window* window;
SDL_GLContext glContext; SDL_GLContext glContext;

View File

@ -14,7 +14,7 @@ constexpr float SHIP_ACCEL = 1.0f * 1000.0f;
constexpr float ROTATION_SENSITIVITY = 0.002f; constexpr float ROTATION_SENSITIVITY = 0.002f;
struct ClientState { struct ClientState {
int id; int id = 0;
Eigen::Vector3f position = { 0, 0, 45000.0f }; Eigen::Vector3f position = { 0, 0, 45000.0f };
Eigen::Matrix3f rotation = Eigen::Matrix3f::Identity(); Eigen::Matrix3f rotation = Eigen::Matrix3f::Identity();
Eigen::Vector3f currentAngularVelocity = Eigen::Vector3f::Zero(); Eigen::Vector3f currentAngularVelocity = Eigen::Vector3f::Zero();
@ -201,19 +201,26 @@ struct ClientState {
return s; return s;
} }
void handle_full_sync(const std::vector<std::string>& parts) { void handle_full_sync(const std::vector<std::string>& parts, int startFrom) {
// Позиция // Позиция
position = { std::stof(parts[2]), std::stof(parts[3]), std::stof(parts[4]) }; position = { std::stof(parts[startFrom]), std::stof(parts[startFrom+1]), std::stof(parts[startFrom+2]) };
// Для вращения клиент должен прислать либо кватернион, либо углы Эйлера. // Для вращения клиент должен прислать либо кватернион, либо углы Эйлера.
// Предположим, мы передаем 4 значения кватерниона для экономии: // Предположим, мы передаем 4 значения кватерниона для экономии:
Eigen::Quaternionf q(std::stof(parts[5]), std::stof(parts[6]), std::stof(parts[7]), std::stof(parts[8])); Eigen::Quaternionf q(
std::stof(parts[startFrom+3]),
std::stof(parts[startFrom+4]),
std::stof(parts[startFrom+5]),
std::stof(parts[startFrom+6]));
rotation = q.toRotationMatrix(); rotation = q.toRotationMatrix();
currentAngularVelocity = Eigen::Vector3f{ std::stof(parts[9]), std::stof(parts[10]), std::stof(parts[11]) }; currentAngularVelocity = Eigen::Vector3f{
velocity = std::stof(parts[12]); std::stof(parts[startFrom+7]),
selectedVelocity = std::stoi(parts[13]); std::stof(parts[startFrom+8]),
discreteMag = std::stof(parts[14]); std::stof(parts[startFrom+9]) };
discreteAngle = std::stoi(parts[15]); velocity = std::stof(parts[startFrom+10]);
selectedVelocity = std::stoi(parts[startFrom+11]);
discreteMag = std::stof(parts[startFrom+12]);
discreteAngle = std::stoi(parts[startFrom+13]);
} }
}; };

View File

@ -69,13 +69,14 @@ namespace ZL {
void WebSocketClient::Poll() { void WebSocketClient::Poll() {
std::lock_guard<std::mutex> lock(queueMutex); std::lock_guard<std::mutex> lock(queueMutex);
while (!messageQueue.empty()) {
auto nowTime = std::chrono::system_clock::now(); auto nowTime = std::chrono::system_clock::now();
auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>( auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
nowTime.time_since_epoch() nowTime.time_since_epoch()
).count(); ).count();
while (!messageQueue.empty()) {
std::string msg = messageQueue.front(); std::string msg = messageQueue.front();
messageQueue.pop(); messageQueue.pop();
@ -93,10 +94,65 @@ namespace ZL {
if (subType == "VEL") { if (subType == "VEL") {
rp.selectedVelocity = std::stoi(parts[4]); rp.selectedVelocity = std::stoi(parts[4]);
int startFrom = 5;
rp.position = { std::stof(parts[startFrom]), std::stof(parts[startFrom+1]), std::stof(parts[startFrom+2]) };
Eigen::Quaternionf q(
std::stof(parts[startFrom + 3]),
std::stof(parts[startFrom + 4]),
std::stof(parts[startFrom + 5]),
std::stof(parts[startFrom + 6]));
rp.rotation = q.toRotationMatrix();
rp.currentAngularVelocity = Eigen::Vector3f{
std::stof(parts[startFrom + 7]),
std::stof(parts[startFrom + 8]),
std::stof(parts[startFrom + 9]) };
rp.velocity = std::stof(parts[startFrom + 10]);
rp.selectedVelocity = std::stoi(parts[startFrom + 11]);
rp.discreteMag = std::stof(parts[startFrom + 12]);
rp.discreteAngle = std::stoi(parts[startFrom + 13]);
/*position = { std::stof(parts[startFrom]), std::stof(parts[startFrom+1]), std::stof(parts[startFrom+2]) };
// Äëÿ âðàùåíèÿ êëèåíò äîëæåí ïðèñëàòü ëèáî êâàòåðíèîí, ëèáî óãëû Ýéëåðà.
// Ïðåäïîëîæèì, ìû ïåðåäàåì 4 çíà÷åíèÿ êâàòåðíèîíà äëÿ ýêîíîìèè:
Eigen::Quaternionf q(
std::stof(parts[startFrom+3]),
std::stof(parts[startFrom+4]),
std::stof(parts[startFrom+5]),
std::stof(parts[startFrom+6]));
rotation = q.toRotationMatrix();
currentAngularVelocity = Eigen::Vector3f{
std::stof(parts[startFrom+7]),
std::stof(parts[startFrom+8]),
std::stof(parts[startFrom+9]) };
velocity = std::stof(parts[startFrom+10]);
selectedVelocity = std::stoi(parts[startFrom+11]);
discreteMag = std::stof(parts[startFrom+12]);
discreteAngle = std::stoi(parts[15]);
*/
} }
else if (subType == "ROT") { else if (subType == "ROT") {
rp.discreteAngle = std::stoi(parts[4]); rp.discreteAngle = std::stoi(parts[4]);
rp.discreteMag = std::stof(parts[5]); rp.discreteMag = std::stof(parts[5]);
int startFrom = 6;
rp.position = { std::stof(parts[startFrom]), std::stof(parts[startFrom + 1]), std::stof(parts[startFrom + 2]) };
Eigen::Quaternionf q(
std::stof(parts[startFrom + 3]),
std::stof(parts[startFrom + 4]),
std::stof(parts[startFrom + 5]),
std::stof(parts[startFrom + 6]));
rp.rotation = q.toRotationMatrix();
rp.currentAngularVelocity = Eigen::Vector3f{
std::stof(parts[startFrom + 7]),
std::stof(parts[startFrom + 8]),
std::stof(parts[startFrom + 9]) };
rp.velocity = std::stof(parts[startFrom + 10]);
rp.selectedVelocity = std::stoi(parts[startFrom + 11]);
rp.discreteMag = std::stof(parts[startFrom + 12]);
rp.discreteAngle = std::stoi(parts[startFrom + 13]);
} }
std::cout << "EVENT Received discreteMag=" << rp.discreteMag << std::endl; std::cout << "EVENT Received discreteMag=" << rp.discreteMag << std::endl;
@ -121,12 +177,15 @@ namespace ZL {
} }
} }
else if (msg.rfind("WORLD_UPDATE|", 0) == 0) { else if (msg.rfind("WORLD_UPDATE|", 0) == 0) {
parseWorldUpdate(msg); parseWorldUpdate(msg, nowTime);
} }
} }
} }
void WebSocketClient::parseWorldUpdate(const std::string& msg) { void WebSocketClient::parseWorldUpdate(const std::string& msg, std::chrono::system_clock::time_point now_ms) {
// Èñïîëüçóåì ìüþòåêñ, òàê êàê ýòîò ìåòîä âûçûâàåòñÿ èç ñåòåâîãî ïîòîêà (TaskManager)
std::lock_guard<std::mutex> lock(playersMutex);
// Ôîðìàò: WORLD_UPDATE|server_now_ms|count|id,x,y,z,w,qx,qy,qz,v;... // Ôîðìàò: WORLD_UPDATE|server_now_ms|count|id,x,y,z,w,qx,qy,qz,v;...
auto parts = split(msg, '|'); auto parts = split(msg, '|');
if (parts.size() < 4) return; if (parts.size() < 4) return;
@ -143,13 +202,11 @@ namespace ZL {
if (id == this->clientId) continue; // Ïðîïóñêàåì ñåáÿ if (id == this->clientId) continue; // Ïðîïóñêàåì ñåáÿ
// Ëîãèêà îáíîâëåíèÿ èëè ñîçäàíèÿ RemotePlayer // Ëîãèêà îáíîâëåíèÿ èëè ñîçäàíèÿ RemotePlayer
updateRemotePlayer(id, vals, serverTime); updateRemotePlayer(id, vals, serverTime, now_ms);
} }
} }
void WebSocketClient::updateRemotePlayer(int id, const std::vector<std::string>& vals, uint64_t serverTime) { void WebSocketClient::updateRemotePlayer(int id, const std::vector<std::string>& vals, uint64_t serverTime, std::chrono::system_clock::time_point now_ms) {
// Èñïîëüçóåì ìüþòåêñ, òàê êàê ýòîò ìåòîä âûçûâàåòñÿ èç ñåòåâîãî ïîòîêà (TaskManager)
std::lock_guard<std::mutex> lock(playersMutex);
auto& rp = remotePlayers[id]; auto& rp = remotePlayers[id];
rp.id = id; rp.id = id;
@ -168,6 +225,7 @@ namespace ZL {
std::cout << "PING Received discreteMag=" << rp.discreteMag << std::endl; std::cout << "PING Received discreteMag=" << rp.discreteMag << std::endl;
rp.lastUpdateServerTime = uptime_timepoint; rp.lastUpdateServerTime = uptime_timepoint;
rp.apply_lag_compensation(now_ms);
} }

View File

@ -40,8 +40,8 @@ namespace ZL {
void Connect(const std::string& host, uint16_t port) override; void Connect(const std::string& host, uint16_t port) override;
void Poll() override; void Poll() override;
void parseWorldUpdate(const std::string& msg); void parseWorldUpdate(const std::string& msg, std::chrono::system_clock::time_point now_ms);
void updateRemotePlayer(int id, const std::vector<std::string>& vals, uint64_t serverTime); void updateRemotePlayer(int id, const std::vector<std::string>& vals, uint64_t serverTime, std::chrono::system_clock::time_point now_ms);
void Send(const std::string& message) override; void Send(const std::string& message) override;
void doWrite(); void doWrite();