Skip to content

Commit 35513e0

Browse files
authored
fix player disconnect (#3104)
1 parent 1805288 commit 35513e0

7 files changed

Lines changed: 53 additions & 4 deletions

File tree

gframe/netserver.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ namespace{
1919

2020
unsigned char NetServer::net_server_write[SIZE_NETWORK_BUFFER]{};
2121
size_t NetServer::last_sent{};
22+
bufferevent* NetServer::disconnecting_bev = nullptr;
2223

2324
bool NetServer::StartServer(unsigned short port) {
2425
if(net_evbase)
@@ -146,10 +147,13 @@ void NetServer::ServerEchoEvent(bufferevent* bev, short events, void* ctx) {
146147
if (events & (BEV_EVENT_EOF | BEV_EVENT_ERROR)) {
147148
DuelPlayer* dp = &users[bev];
148149
DuelMode* dm = dp->game;
150+
auto* prev_disconnect = disconnecting_bev;
151+
disconnecting_bev = bev;
149152
if(dm)
150153
dm->LeaveGame(dp);
151154
else
152155
DisconnectPlayer(dp);
156+
disconnecting_bev = prev_disconnect;
153157
}
154158
}
155159
void NetServer::ServerThread() {
@@ -179,9 +183,14 @@ void NetServer::ServerThread() {
179183
void NetServer::DisconnectPlayer(DuelPlayer* dp) {
180184
auto bit = users.find(dp->bev);
181185
if(bit != users.end()) {
186+
if(dp->game) {
187+
dp->game->OnPlayerDisconnected(dp);
188+
dp->game = nullptr;
189+
}
182190
bufferevent_flush(dp->bev, EV_WRITE, BEV_FLUSH);
183191
bufferevent_disable(dp->bev, EV_READ);
184192
bufferevent_free(dp->bev);
193+
dp->bev = nullptr;
185194
users.erase(bit);
186195
}
187196
}

gframe/netserver.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ class NetServer {
1010
private:
1111
static unsigned char net_server_write[SIZE_NETWORK_BUFFER];
1212
static size_t last_sent;
13+
static bufferevent* disconnecting_bev;
14+
15+
static bool CanWriteToPlayer(DuelPlayer* dp) {
16+
return dp && dp->bev && dp->bev != disconnecting_bev;
17+
}
1318

1419
public:
1520
static bool StartServer(unsigned short port);
@@ -42,7 +47,7 @@ class NetServer {
4247
BufferIO::Write<uint16_t>(p, 1);
4348
BufferIO::Write<uint8_t>(p, proto);
4449
last_sent = 3;
45-
if (dp)
50+
if (CanWriteToPlayer(dp))
4651
bufferevent_write(dp->bev, net_server_write, 3);
4752
}
4853
template<typename ST>
@@ -53,7 +58,7 @@ class NetServer {
5358
BufferIO::Write<uint8_t>(p, proto);
5459
std::memcpy(p, &st, sizeof(ST));
5560
last_sent = sizeof(ST) + 3;
56-
if (dp)
61+
if (CanWriteToPlayer(dp))
5762
bufferevent_write(dp->bev, net_server_write, sizeof(ST) + 3);
5863
}
5964
static void SendBufferToPlayer(DuelPlayer* dp, unsigned char proto, void* buffer, size_t len) {
@@ -64,11 +69,11 @@ class NetServer {
6469
BufferIO::Write<uint8_t>(p, proto);
6570
std::memcpy(p, buffer, len);
6671
last_sent = len + 3;
67-
if (dp)
72+
if (CanWriteToPlayer(dp))
6873
bufferevent_write(dp->bev, net_server_write, len + 3);
6974
}
7075
static void ReSendToPlayer(DuelPlayer* dp) {
71-
if(dp)
76+
if (CanWriteToPlayer(dp))
7277
bufferevent_write(dp->bev, net_server_write, last_sent);
7378
}
7479
};

gframe/network.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ class DuelMode {
224224
virtual void GetResponse(DuelPlayer* dp, unsigned char* pdata, unsigned int len) = 0;
225225
virtual void TimeConfirm(DuelPlayer* dp) = 0;
226226
virtual void EndDuel() = 0;
227+
virtual void OnPlayerDisconnected(DuelPlayer* dp) = 0;
227228

228229
public:
229230
event* etimer { nullptr };

gframe/single_duel.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ void SingleDuel::LeaveGame(DuelPlayer* dp) {
172172
wbuf[0] = MSG_WIN;
173173
wbuf[1] = 1 - dp->type;
174174
wbuf[2] = 0x4;
175+
duel_stage = DUEL_STAGE_END;
175176
NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, wbuf, 3);
176177
NetServer::ReSendToPlayer(players[1]);
177178
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
@@ -1455,6 +1456,19 @@ void SingleDuel::EndDuel() {
14551456
event_del(etimer);
14561457
pduel = 0;
14571458
}
1459+
void SingleDuel::OnPlayerDisconnected(DuelPlayer* dp) {
1460+
if(host_player == dp)
1461+
host_player = nullptr;
1462+
for(int i = 0; i < 2; ++i) {
1463+
if(players[i] == dp) {
1464+
players[i] = nullptr;
1465+
ready[i] = false;
1466+
}
1467+
if(pplayer[i] == dp)
1468+
pplayer[i] = nullptr;
1469+
}
1470+
observers.erase(dp);
1471+
}
14581472
void SingleDuel::WaitforResponse(int playerid) {
14591473
last_response = playerid;
14601474
unsigned char msg = MSG_WAITING;

gframe/single_duel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class SingleDuel: public DuelMode {
2929
void GetResponse(DuelPlayer* dp, unsigned char* pdata, unsigned int len) override;
3030
void TimeConfirm(DuelPlayer* dp) override;
3131
void EndDuel() override;
32+
void OnPlayerDisconnected(DuelPlayer* dp) override;
3233

3334
void DuelEndProc();
3435
void WaitforResponse(int playerid);

gframe/tag_duel.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1564,6 +1564,24 @@ void TagDuel::EndDuel() {
15641564
event_del(etimer);
15651565
pduel = 0;
15661566
}
1567+
void TagDuel::OnPlayerDisconnected(DuelPlayer* dp) {
1568+
if(host_player == dp)
1569+
host_player = nullptr;
1570+
for(int i = 0; i < 4; ++i) {
1571+
if(players[i] == dp) {
1572+
players[i] = nullptr;
1573+
ready[i] = false;
1574+
surrender[i] = false;
1575+
}
1576+
if(pplayer[i] == dp)
1577+
pplayer[i] = nullptr;
1578+
}
1579+
for(int i = 0; i < 2; ++i) {
1580+
if(cur_player[i] == dp)
1581+
cur_player[i] = nullptr;
1582+
}
1583+
observers.erase(dp);
1584+
}
15671585
void TagDuel::WaitforResponse(int playerid) {
15681586
last_response = playerid;
15691587
unsigned char msg = MSG_WAITING;

gframe/tag_duel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class TagDuel: public DuelMode {
2929
void GetResponse(DuelPlayer* dp, unsigned char* pdata, unsigned int len) override;
3030
void TimeConfirm(DuelPlayer* dp) override;
3131
void EndDuel() override;
32+
void OnPlayerDisconnected(DuelPlayer* dp) override;
3233

3334
void DuelEndProc();
3435
void WaitforResponse(int playerid);

0 commit comments

Comments
 (0)