mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
feat(client_world): implement server exit acknowledgment with timeout
This commit is contained in:
@@ -66,7 +66,8 @@ public:
|
|||||||
const std::vector<RemotePlayerRenderData>& render_player_data() const;
|
const std::vector<RemotePlayerRenderData>& render_player_data() const;
|
||||||
glm::vec3 sunlight_dir() const;
|
glm::vec3 sunlight_dir() const;
|
||||||
void receive_chunk(ChunkDataRsp data);
|
void receive_chunk(ChunkDataRsp data);
|
||||||
void exit();
|
void receive_exit();
|
||||||
|
void request_exit();
|
||||||
template <typename Fn>
|
template <typename Fn>
|
||||||
void register_timer(std::string_view id, TickType threshold, Fn&& f) {
|
void register_timer(std::string_view id, TickType threshold, Fn&& f) {
|
||||||
m_timers.emplace(std::piecewise_construct,
|
m_timers.emplace(std::piecewise_construct,
|
||||||
@@ -82,6 +83,9 @@ private:
|
|||||||
using ChunkPosVector = std::vector<ChunkPos>;
|
using ChunkPosVector = std::vector<ChunkPos>;
|
||||||
using OtherPlayerHashMap =
|
using OtherPlayerHashMap =
|
||||||
std::unordered_map<std::string, RemotePlayerInfo>;
|
std::unordered_map<std::string, RemotePlayerInfo>;
|
||||||
|
|
||||||
|
static constexpr int WORLD_EXIT_TIMEOUT = 200;
|
||||||
|
|
||||||
ClientPlayer m_player;
|
ClientPlayer m_player;
|
||||||
OtherPlayerHashMap m_other_players;
|
OtherPlayerHashMap m_other_players;
|
||||||
ChunkHashMap m_chunks;
|
ChunkHashMap m_chunks;
|
||||||
@@ -104,6 +108,7 @@ private:
|
|||||||
std::vector<RemotePlayerRenderData> m_render_player_data;
|
std::vector<RemotePlayerRenderData> m_render_player_data;
|
||||||
tbb::concurrent_unordered_map<std::string, Timer> m_timers;
|
tbb::concurrent_unordered_map<std::string, Timer> m_timers;
|
||||||
std::atomic<bool> m_game_running{false};
|
std::atomic<bool> m_game_running{false};
|
||||||
|
std::atomic<bool> m_receive_exit{false};
|
||||||
std::atomic<int> m_rendering_distance{24};
|
std::atomic<int> m_rendering_distance{24};
|
||||||
std::atomic<TickType> m_game_ticks{0};
|
std::atomic<TickType> m_game_ticks{0};
|
||||||
std::atomic<TickType> m_day_tick{6000};
|
std::atomic<TickType> m_day_tick{6000};
|
||||||
|
|||||||
@@ -305,7 +305,7 @@ void App::run() {
|
|||||||
update();
|
update();
|
||||||
render();
|
render();
|
||||||
}
|
}
|
||||||
m_client_world.exit();
|
m_client_world.request_exit();
|
||||||
}
|
}
|
||||||
static Gait player_gait = Gait::WALK;
|
static Gait player_gait = Gait::WALK;
|
||||||
void App::update() {
|
void App::update() {
|
||||||
|
|||||||
@@ -240,6 +240,9 @@ void ClientWorld::receive_player_logout(const LogoutRsp& rsp) {
|
|||||||
Logger::info("Player {} erase", rsp.uuid());
|
Logger::info("Player {} erase", rsp.uuid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (rsp.uuid() == m_player.get_uuid()) {
|
||||||
|
m_receive_exit = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientWorld::init(std::string_view player_name,
|
void ClientWorld::init(std::string_view player_name,
|
||||||
@@ -462,12 +465,25 @@ void ClientWorld::receive_chunk(ChunkDataRsp data) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
void ClientWorld::receive_exit() { m_receive_exit = true; }
|
||||||
|
|
||||||
void ClientWorld::exit() {
|
void ClientWorld::request_exit() {
|
||||||
|
if (m_receive_exit) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Arena arena;
|
Arena arena;
|
||||||
auto* req = Arena::Create<LogoutReq>(&arena);
|
auto* req = Arena::Create<LogoutReq>(&arena);
|
||||||
req->set_uuid(m_player.get_uuid());
|
req->set_uuid(m_player.get_uuid());
|
||||||
m_client->send(make_packet(*req));
|
m_client->send(make_packet(*req));
|
||||||
|
int cnt = 0;
|
||||||
|
while (!m_receive_exit) {
|
||||||
|
std::this_thread::sleep_for(milliseconds(DEFAULT_PER_TICK_TIME));
|
||||||
|
++cnt;
|
||||||
|
if (cnt >= WORLD_EXIT_TIMEOUT) {
|
||||||
|
Logger::warn("Can't Receive Server Exit Sign");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientWorld::update(float delta_time) {
|
void ClientWorld::update(float delta_time) {
|
||||||
|
|||||||
@@ -664,11 +664,13 @@ void ServerWorld::handle_player_login(const std::string& name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ServerWorld::handle_player_exit(const std::string& uuid) {
|
void ServerWorld::handle_player_exit(const std::string& uuid) {
|
||||||
|
std::shared_ptr<Session> exit_session;
|
||||||
{
|
{
|
||||||
std::lock_guard lock(m_player_mutex);
|
std::lock_guard lock(m_player_mutex);
|
||||||
auto it = m_players.find(uuid);
|
auto it = m_players.find(uuid);
|
||||||
if (it != m_players.end()) {
|
if (it != m_players.end()) {
|
||||||
Logger::info("Player {} Exit the Server", it->second.get_name());
|
Logger::info("Player {} Exit the Server", it->second.get_name());
|
||||||
|
exit_session = it->second.get_session();
|
||||||
m_players.erase(it);
|
m_players.erase(it);
|
||||||
} else {
|
} else {
|
||||||
Logger::error("Player {} isn't in Server", uuid);
|
Logger::error("Player {} isn't in Server", uuid);
|
||||||
@@ -678,6 +680,11 @@ void ServerWorld::handle_player_exit(const std::string& uuid) {
|
|||||||
|
|
||||||
m_uuid_to_name.erase(uuid);
|
m_uuid_to_name.erase(uuid);
|
||||||
|
|
||||||
|
Arena arena;
|
||||||
|
auto* rsp = Arena::Create<LogoutRsp>(&arena);
|
||||||
|
rsp->set_uuid(uuid);
|
||||||
|
exit_session->send(make_packet(*rsp));
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Session>> sessions;
|
std::vector<std::shared_ptr<Session>> sessions;
|
||||||
{
|
{
|
||||||
std::shared_lock lock(m_player_mutex);
|
std::shared_lock lock(m_player_mutex);
|
||||||
@@ -687,9 +694,6 @@ void ServerWorld::handle_player_exit(const std::string& uuid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto& s : sessions) {
|
for (auto& s : sessions) {
|
||||||
Arena arena;
|
|
||||||
auto* rsp = Arena::Create<LogoutRsp>(&arena);
|
|
||||||
rsp->set_uuid(uuid);
|
|
||||||
s->send(make_packet(*rsp));
|
s->send(make_packet(*rsp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user