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

View File

@ -245,6 +245,7 @@ namespace ZL
std::chrono::system_clock::now().time_since_epoch()
).count();
std::string msg = "VEL:" + std::to_string(now_ms) + ":" + std::to_string(Environment::shipSelectedVelocity);
msg = msg + ":" + formPingMessageContent();
networkClient->Send(msg);
}
});
@ -583,6 +584,18 @@ namespace ZL
renderer.PushMatrix();
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. Камера и вид игрока
renderer.TranslateMatrix({ 0, 0, -1.0f * Environment::zoom });
renderer.RotateMatrix(Environment::inverseShipMatrix);
@ -601,6 +614,8 @@ namespace ZL
// В твоем drawShip() есть: renderer.TranslateMatrix({ 0, -6.f, 0 });
renderer.TranslateMatrix({ 0, -6.f, 0 });
*/
renderer.DrawVertexRenderStruct(spaceship);
renderer.PopMatrix();
}
@ -638,6 +653,7 @@ namespace ZL
).count();
// 1. Извлекаем кватернион из матрицы поворота
/*
Eigen::Quaternionf q(Environment::shipMatrix);
// 2. Формируем строку PING согласно протоколу сервера
@ -657,6 +673,8 @@ namespace ZL
+ std::to_string(Environment::shipSelectedVelocity) + ":"
+ std::to_string(Environment::lastSentMagnitude) + ":" // Используем те же static переменные из блока ROT
+ std::to_string(Environment::lastSentAngle);
*/
std::string pingMsg = "PING:" + std::to_string(now_ms) + ":" + formPingMessageContent();
networkClient->Send(pingMsg);
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);
msg = msg + ":" + formPingMessageContent();
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);
msg = msg + ":" + formPingMessageContent();
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

View File

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

View File

@ -14,7 +14,7 @@ constexpr float SHIP_ACCEL = 1.0f * 1000.0f;
constexpr float ROTATION_SENSITIVITY = 0.002f;
struct ClientState {
int id;
int id = 0;
Eigen::Vector3f position = { 0, 0, 45000.0f };
Eigen::Matrix3f rotation = Eigen::Matrix3f::Identity();
Eigen::Vector3f currentAngularVelocity = Eigen::Vector3f::Zero();
@ -201,19 +201,26 @@ struct ClientState {
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 значения кватерниона для экономии:
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();
currentAngularVelocity = Eigen::Vector3f{ std::stof(parts[9]), std::stof(parts[10]), std::stof(parts[11]) };
velocity = std::stof(parts[12]);
selectedVelocity = std::stoi(parts[13]);
discreteMag = std::stof(parts[14]);
discreteAngle = std::stoi(parts[15]);
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[startFrom+13]);
}
};

View File

@ -69,13 +69,14 @@ namespace ZL {
void WebSocketClient::Poll() {
std::lock_guard<std::mutex> lock(queueMutex);
while (!messageQueue.empty()) {
auto nowTime = std::chrono::system_clock::now();
auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
nowTime.time_since_epoch()
).count();
while (!messageQueue.empty()) {
std::string msg = messageQueue.front();
messageQueue.pop();
@ -93,10 +94,65 @@ namespace ZL {
if (subType == "VEL") {
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") {
rp.discreteAngle = std::stoi(parts[4]);
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;
@ -121,12 +177,15 @@ namespace ZL {
}
}
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;...
auto parts = split(msg, '|');
if (parts.size() < 4) return;
@ -143,13 +202,11 @@ namespace ZL {
if (id == this->clientId) continue; // Ïðîïóñêàåì ñåáÿ
// Ëîãèêà îáíîâëåíèÿ èëè ñîçäàíèÿ 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) {
// Èñïîëüçóåì ìüþòåêñ, òàê êàê ýòîò ìåòîä âûçûâàåòñÿ èç ñåòåâîãî ïîòîêà (TaskManager)
std::lock_guard<std::mutex> lock(playersMutex);
void WebSocketClient::updateRemotePlayer(int id, const std::vector<std::string>& vals, uint64_t serverTime, std::chrono::system_clock::time_point now_ms) {
auto& rp = remotePlayers[id];
rp.id = id;
@ -168,6 +225,7 @@ namespace ZL {
std::cout << "PING Received discreteMag=" << rp.discreteMag << std::endl;
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 Poll() override;
void parseWorldUpdate(const std::string& msg);
void updateRemotePlayer(int id, const std::vector<std::string>& vals, uint64_t serverTime);
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, std::chrono::system_clock::time_point now_ms);
void Send(const std::string& message) override;
void doWrite();