Working on server optimization
This commit is contained in:
parent
e8f1786a2a
commit
be2aa76f8b
@ -323,7 +323,6 @@ private:
|
|||||||
receivedState.shipType = this->shipType;
|
receivedState.shipType = this->shipType;
|
||||||
timedClientStates.add_state(receivedState);
|
timedClientStates.add_state(receivedState);
|
||||||
|
|
||||||
retranslateMessage(cleanMessage);
|
|
||||||
}
|
}
|
||||||
else if (type == "RESPAWN") {
|
else if (type == "RESPAWN") {
|
||||||
{
|
{
|
||||||
@ -433,16 +432,6 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void retranslateMessage(const std::string& msg) {
|
|
||||||
std::string event_msg = "EVENT:" + std::to_string(id_) + ":" + msg;
|
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(g_sessions_mutex);
|
|
||||||
for (auto& session : g_sessions) {
|
|
||||||
if (session->get_id() != id_) {
|
|
||||||
session->send_message(event_msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void broadcastToAll(const std::string& message) {
|
void broadcastToAll(const std::string& message) {
|
||||||
@ -454,81 +443,61 @@ void broadcastToAll(const std::string& message) {
|
|||||||
|
|
||||||
void update_world(net::steady_timer& timer, net::io_context& ioc) {
|
void update_world(net::steady_timer& timer, net::io_context& ioc) {
|
||||||
|
|
||||||
static auto last_snapshot_time = std::chrono::steady_clock::now();
|
static auto last_snapshot_time = std::chrono::system_clock::now();
|
||||||
auto now = std::chrono::steady_clock::now();
|
|
||||||
/*static uint64_t lastTickCount = 0;
|
|
||||||
|
|
||||||
if (lastTickCount == 0) {
|
auto now = std::chrono::system_clock::now();
|
||||||
//lastTickCount = SDL_GetTicks64();
|
uint64_t now_ms = static_cast<uint64_t>(
|
||||||
lastTickCount = std::chrono::duration_cast<std::chrono::milliseconds>(
|
std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count());
|
||||||
std::chrono::system_clock::now().time_since_epoch()
|
|
||||||
).count();
|
|
||||||
|
|
||||||
lastTickCount = (lastTickCount / 50) * 50;
|
// --- Snapshot every 500ms ---
|
||||||
|
/*if (std::chrono::duration_cast<std::chrono::milliseconds>(now - last_snapshot_time).count() >= 500) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
auto newTickCount = std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
||||||
std::chrono::system_clock::now().time_since_epoch()
|
|
||||||
).count();
|
|
||||||
|
|
||||||
newTickCount = (newTickCount / 50) * 50;
|
|
||||||
|
|
||||||
int64_t deltaMs = static_cast<int64_t>(newTickCount - lastTickCount);
|
|
||||||
|
|
||||||
std::chrono::system_clock::time_point nowRounded = std::chrono::system_clock::time_point(std::chrono::milliseconds(newTickCount));
|
|
||||||
*/
|
|
||||||
// For each player
|
|
||||||
// Get letest state + add time (until newTickCount)
|
|
||||||
// Calculate if collisions with boxes
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Рассылка Snapshot раз в 1000мс
|
|
||||||
/*
|
|
||||||
if (std::chrono::duration_cast<std::chrono::milliseconds>(now - last_snapshot_time).count() >= 1000) {
|
|
||||||
last_snapshot_time = now;
|
last_snapshot_time = now;
|
||||||
|
|
||||||
auto system_now = std::chrono::system_clock::now();
|
std::string snapshot_msg = "SNAPSHOT:" + std::to_string(now_ms);
|
||||||
|
|
||||||
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);
|
std::lock_guard<std::mutex> lock(g_sessions_mutex);
|
||||||
|
|
||||||
// Формируем общую строку состояний всех игроков
|
|
||||||
for (auto& session : g_sessions) {
|
for (auto& session : g_sessions) {
|
||||||
ClientState st = session->get_latest_state(system_now);
|
ClientState st = session->get_latest_state(now);
|
||||||
snapshot_msg += "|" + std::to_string(session->get_id()) + ":" + st.formPingMessageContent();
|
snapshot_msg += "|" + std::to_string(session->get_id()) + ":" + st.formPingMessageContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& session : g_sessions) {
|
for (auto& session : g_sessions) {
|
||||||
session->send_message(snapshot_msg);
|
session->send_message(snapshot_msg);
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
const std::chrono::milliseconds interval(50);
|
// --- Tick: broadcast each player's latest state to all others (20Hz) ---
|
||||||
timer.expires_after(interval);
|
// Send the raw last-known state with its original timestamp, NOT an extrapolated one.
|
||||||
|
// Extrapolating here causes snap-back: if a player stops rotating, the server would
|
||||||
|
// keep sending over-rotated positions until the new state arrives, then B snaps back.
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(g_sessions_mutex);
|
||||||
|
for (auto& sender : g_sessions) {
|
||||||
|
if (sender->timedClientStates.timedStates.empty()) continue;
|
||||||
|
|
||||||
timer.async_wait([&](const boost::system::error_code& ec) {
|
const ClientState& st = sender->timedClientStates.timedStates.back();
|
||||||
if (ec) return;
|
uint64_t stateTime = static_cast<uint64_t>(
|
||||||
|
std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||||
|
st.lastUpdateServerTime.time_since_epoch()).count());
|
||||||
|
|
||||||
auto now = std::chrono::system_clock::now();
|
std::string event_msg = "EVENT:" + std::to_string(sender->get_id()) +
|
||||||
uint64_t now_ms = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count());
|
":UPD:" + std::to_string(stateTime) + ":" + st.formPingMessageContent();
|
||||||
|
|
||||||
|
for (auto& receiver : g_sessions) {
|
||||||
|
if (receiver->get_id() != sender->get_id()) {
|
||||||
|
receiver->send_message(event_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Tick: projectile movement and hit detection ---
|
||||||
|
const float dt = 50.0f / 1000.0f;
|
||||||
std::vector<DeathInfo> deathEvents;
|
std::vector<DeathInfo> deathEvents;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> pl(g_projectiles_mutex);
|
std::lock_guard<std::mutex> pl(g_projectiles_mutex);
|
||||||
std::vector<int> indicesToRemove;
|
std::vector<int> indicesToRemove;
|
||||||
|
|
||||||
float dt = 50.0f / 1000.0f;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < g_projectiles.size(); ++i) {
|
for (size_t i = 0; i < g_projectiles.size(); ++i) {
|
||||||
auto& pr = g_projectiles[i];
|
auto& pr = g_projectiles[i];
|
||||||
|
|
||||||
@ -593,9 +562,9 @@ void update_world(net::steady_timer& timer, net::io_context& ioc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Tick: box-projectile collisions ---
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> bm(g_boxes_mutex);
|
std::lock_guard<std::mutex> bm(g_boxes_mutex);
|
||||||
//const float projectileHitRadius = 1.5f;
|
|
||||||
const float projectileHitRadius = 5.0f;
|
const float projectileHitRadius = 5.0f;
|
||||||
const float boxCollisionRadius = 2.0f;
|
const float boxCollisionRadius = 2.0f;
|
||||||
|
|
||||||
@ -609,7 +578,6 @@ void update_world(net::steady_timer& timer, net::io_context& ioc) {
|
|||||||
for (size_t pi = 0; pi < g_projectiles.size(); ++pi) {
|
for (size_t pi = 0; pi < g_projectiles.size(); ++pi) {
|
||||||
const auto& pr = g_projectiles[pi];
|
const auto& pr = g_projectiles[pi];
|
||||||
Eigen::Vector3f diff = pr.pos - boxWorld;
|
Eigen::Vector3f diff = pr.pos - boxWorld;
|
||||||
//std::cout << "diff norm is " << diff.norm() << std::endl;
|
|
||||||
float thresh = boxCollisionRadius + projectileHitRadius;
|
float thresh = boxCollisionRadius + projectileHitRadius;
|
||||||
|
|
||||||
if (diff.squaredNorm() <= thresh * thresh) {
|
if (diff.squaredNorm() <= thresh * thresh) {
|
||||||
@ -639,6 +607,7 @@ void update_world(net::steady_timer& timer, net::io_context& ioc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Tick: box-ship collisions ---
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> bm(g_boxes_mutex);
|
std::lock_guard<std::mutex> bm(g_boxes_mutex);
|
||||||
std::lock_guard<std::mutex> lm(g_sessions_mutex);
|
std::lock_guard<std::mutex> lm(g_sessions_mutex);
|
||||||
@ -687,7 +656,7 @@ void update_world(net::steady_timer& timer, net::io_context& ioc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!deathEvents.empty()) {
|
// --- Broadcast deaths ---
|
||||||
for (const auto& death : deathEvents) {
|
for (const auto& death : deathEvents) {
|
||||||
std::string deadMsg = "DEAD:" +
|
std::string deadMsg = "DEAD:" +
|
||||||
std::to_string(death.serverTime) + ":" +
|
std::to_string(death.serverTime) + ":" +
|
||||||
@ -702,8 +671,8 @@ void update_world(net::steady_timer& timer, net::io_context& ioc) {
|
|||||||
std::cout << "Server: Sent DEAD event - Player " << death.targetId
|
std::cout << "Server: Sent DEAD event - Player " << death.targetId
|
||||||
<< " killed by " << death.killerId << std::endl;
|
<< " killed by " << death.killerId << std::endl;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
// --- Broadcast box destructions ---
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> dm(g_boxDestructions_mutex);
|
std::lock_guard<std::mutex> dm(g_boxDestructions_mutex);
|
||||||
for (const auto& destruction : g_boxDestructions) {
|
for (const auto& destruction : g_boxDestructions) {
|
||||||
@ -721,6 +690,10 @@ void update_world(net::steady_timer& timer, net::io_context& ioc) {
|
|||||||
g_boxDestructions.clear();
|
g_boxDestructions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Schedule next tick in 50ms ---
|
||||||
|
timer.expires_after(std::chrono::milliseconds(50));
|
||||||
|
timer.async_wait([&timer, &ioc](const boost::system::error_code& ec) {
|
||||||
|
if (ec) return;
|
||||||
update_world(timer, ioc);
|
update_world(timer, ioc);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -169,7 +169,7 @@ void ClientState::apply_lag_compensation(std::chrono::system_clock::time_point n
|
|||||||
|
|
||||||
while (deltaMsLeftover > 0)
|
while (deltaMsLeftover > 0)
|
||||||
{
|
{
|
||||||
long long miniDelta = 50;
|
long long miniDelta = std::min(50LL, deltaMsLeftover);
|
||||||
simulate_physics(miniDelta);
|
simulate_physics(miniDelta);
|
||||||
deltaMsLeftover -= miniDelta;
|
deltaMsLeftover -= miniDelta;
|
||||||
}
|
}
|
||||||
@ -207,7 +207,7 @@ void ClientState::handle_full_sync(const std::vector<std::string>& parts, int st
|
|||||||
discreteAngle = std::stoi(parts[startFrom + 13]);
|
discreteAngle = std::stoi(parts[startFrom + 13]);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ClientState::formPingMessageContent()
|
std::string ClientState::formPingMessageContent() const
|
||||||
{
|
{
|
||||||
Eigen::Quaternionf q(rotation);
|
Eigen::Quaternionf q(rotation);
|
||||||
|
|
||||||
|
|||||||
@ -50,7 +50,7 @@ struct ClientState {
|
|||||||
|
|
||||||
void handle_full_sync(const std::vector<std::string>& parts, int startFrom);
|
void handle_full_sync(const std::vector<std::string>& parts, int startFrom);
|
||||||
|
|
||||||
std::string formPingMessageContent();
|
std::string formPingMessageContent() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ClientStateInterval
|
struct ClientStateInterval
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user