Fixing lag compensation and make more smooth

This commit is contained in:
Vladislav Khorev committed 2026-02-05 09:00:54 +03:00
1 parent 82ca994fac
commit 7b1d9363a0
6 files changed
+159 -54

No files matched your search

+67 -25
View File
@@ -146,6 +146,7 @@ class Session : public std::enable_shared_from_this<Session> {
}
}
void sendBoxesToClient() {
std::lock_guard<std::mutex> lock(g_boxes_mutex);
@@ -168,30 +169,6 @@ class Session : public std::enable_shared_from_this<Session> {
send_message(boxMsg);
}
void send_message(std::string msg) {
auto ss = std::make_shared<std::string>(std::move(msg));
if (is_writing_) {
ws_.async_write(net::buffer(*ss),
[self = shared_from_this(), ss](beast::error_code ec, std::size_t) {
if (ec) {
std::cerr << "Write error: " << ec.message() << std::endl;
}
});
}
else {
is_writing_ = true;
ws_.async_write(net::buffer(*ss),
[self = shared_from_this(), ss](beast::error_code ec, std::size_t) {
self->is_writing_ = false;
if (ec) {
std::cerr << "Write error: " << ec.message() << std::endl;
}
});
}
}
public:
explicit Session(tcp::socket&& socket, int id)
@@ -237,6 +214,46 @@ public:
return id_;
}
ClientState get_latest_state(std::chrono::system_clock::time_point now) {
if (timedClientStates.timedStates.empty()) {
return {};
}
// 1. Берем самое последнее известное состояние
ClientState latest = timedClientStates.timedStates.back();
// 3. Применяем компенсацию лага (экстраполяцию).
// Функция внутри использует simulate_physics, чтобы переместить объект
// из точки lastUpdateServerTime в точку now.
latest.apply_lag_compensation(now);
return latest;
}
void send_message(std::string msg) {
auto ss = std::make_shared<std::string>(std::move(msg));
if (is_writing_) {
ws_.async_write(net::buffer(*ss),
[self = shared_from_this(), ss](beast::error_code ec, std::size_t) {
if (ec) {
std::cerr << "Write error: " << ec.message() << std::endl;
}
});
}
else {
is_writing_ = true;
ws_.async_write(net::buffer(*ss),
[self = shared_from_this(), ss](beast::error_code ec, std::size_t) {
self->is_writing_ = false;
if (ec) {
std::cerr << "Write error: " << ec.message() << std::endl;
}
});
}
}
private:
void do_read() {
ws_.async_read(buffer_, [self = shared_from_this()](beast::error_code ec, std::size_t) {
@@ -260,8 +277,33 @@ private:
};
void update_world(net::steady_timer& timer, net::io_context& ioc) {
static auto last_snapshot_time = std::chrono::steady_clock::now();
auto now = std::chrono::steady_clock::now();
// TODO: Renew game state
// Рассылка Snapshot раз в 1000мс
/*
if (std::chrono::duration_cast<std::chrono::milliseconds>(now - last_snapshot_time).count() >= 1000) {
last_snapshot_time = now;
auto system_now = std::chrono::system_clock::now();
std::string snapshot_msg = "SNAPSHOT:" + std::to_string(
std::chrono::duration_cast<std::chrono::milliseconds>(
system_now.time_since_epoch()).count()
);
std::lock_guard<std::mutex> lock(g_sessions_mutex);
// Формируем общую строку состояний всех игроков
for (auto& session : g_sessions) {
ClientState st = session->get_latest_state(system_now);
snapshot_msg += "|" + std::to_string(session->get_id()) + ":" + st.formPingMessageContent();
}
for (auto& session : g_sessions) {
session->send_message(snapshot_msg);
}
}*/
timer.expires_after(std::chrono::milliseconds(50));
timer.async_wait([&](const boost::system::error_code& ec) {