Added force disconnect from server

This commit is contained in:
Vladislav Khorev committed 2026-03-06 20:05:55 +03:00
1 parent 8528b4dc90
commit ac551122d9
9 files changed
+93 -3

No files matched your search

+37 -2
View File
@@ -20,7 +20,19 @@ std::vector<std::string> split(const std::string& s, char delimiter) {
Session::Session(Server& server, tcp::socket&& socket, int id)
: server_(server)
, ws_(std::move(socket))
, id_(id) {
, id_(id)
, lastReceivedTime_(std::chrono::system_clock::now()) {
}
bool Session::is_timed_out(std::chrono::system_clock::time_point now) const {
if (!joined_) return false;
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - lastReceivedTime_).count();
return elapsed > PLAYER_TIMEOUT_MS;
}
void Session::force_disconnect() {
ws_.async_close(websocket::close_code::normal,
[self = shared_from_this()](beast::error_code) {});
}
int Session::get_id() const { return id_; }
@@ -166,12 +178,16 @@ void Session::doWrite() {
void Session::do_read() {
ws_.async_read(buffer_, [self = shared_from_this()](beast::error_code ec, std::size_t) {
if (ec) {
if (self->joined_) {
self->server_.broadcastToAllExceptId("PLAYER_LEFT:" + std::to_string(self->id_), self->id_);
std::cout << "Client " << self->id_ << " disconnected, broadcasting PLAYER_LEFT\n";
}
std::lock_guard<std::mutex> lock(self->server_.g_sessions_mutex);
self->server_.g_sessions.erase(std::remove_if(self->server_.g_sessions.begin(), self->server_.g_sessions.end(),
[self](const std::shared_ptr<Session>& session) {
return session.get() == self.get();
}), self->server_.g_sessions.end());
std::cout << "Client " << self->id_ << " disconnected\n";
std::cout << "Client " << self->id_ << " removed from session list\n";
return;
}
@@ -188,6 +204,7 @@ void Session::process_message(const std::string& msg) {
std::cout << "[Security] Invalid packet hash. Dropping message: " << msg << std::endl;
return;
}
lastReceivedTime_ = std::chrono::system_clock::now();
std::string cleanMessage = msg.substr(0, msg.find("#hash:"));
std::cout << "Received from player " << id_ << ": " << cleanMessage << std::endl;
@@ -480,6 +497,24 @@ void Server::update_world() {
uint64_t now_ms = static_cast<uint64_t>(
std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count());
// --- Detect and force-disconnect timed-out players ---
{
std::vector<std::shared_ptr<Session>> timedOut;
{
std::lock_guard<std::mutex> lock(g_sessions_mutex);
for (auto& session : g_sessions) {
if (session->is_timed_out(now)) {
timedOut.push_back(session);
}
}
}
for (auto& session : timedOut) {
std::cout << "Server: Player " << session->get_id()
<< " timed out after " << PLAYER_TIMEOUT_MS << "ms, forcing disconnect\n";
session->force_disconnect();
}
}
{
std::lock_guard<std::mutex> lock(g_sessions_mutex);
for (auto& sender : g_sessions) {
+3
View File
@@ -72,6 +72,7 @@ class Session : public std::enable_shared_from_this<Session> {
public:
ClientStateInterval timedClientStates;
bool joined_ = false;
std::chrono::system_clock::time_point lastReceivedTime_;
bool hasReservedSpawn_ = false;
Eigen::Vector3f reservedSpawn_ = Eigen::Vector3f(0.0f, 0.0f, kWorldZOffset);
@@ -87,6 +88,8 @@ public:
void send_message(const std::string& msg);
void run();
bool IsMessageValid(const std::string& fullMessage);
bool is_timed_out(std::chrono::system_clock::time_point now) const;
void force_disconnect();
private:
void sendBoxesToClient();