Fixing bugs, more freq updated
This commit is contained in:
parent
e0a60dcd6f
commit
3c55b59c8d
@ -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;
|
||||
|
||||
43
src/Game.cpp
43
src/Game.cpp
@ -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
|
||||
|
||||
@ -52,6 +52,7 @@ namespace ZL {
|
||||
void handleMotion(int mx, int my);
|
||||
|
||||
void extrapolateRemotePlayers();
|
||||
std::string formPingMessageContent();
|
||||
|
||||
SDL_Window* window;
|
||||
SDL_GLContext glContext;
|
||||
|
||||
@ -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]);
|
||||
}
|
||||
};
|
||||
|
||||
@ -69,13 +69,14 @@ namespace ZL {
|
||||
void WebSocketClient::Poll() {
|
||||
std::lock_guard<std::mutex> lock(queueMutex);
|
||||
|
||||
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()) {
|
||||
|
||||
auto nowTime = std::chrono::system_clock::now();
|
||||
|
||||
auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
nowTime.time_since_epoch()
|
||||
).count();
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user