1
0
Fork 0

(svn r22308) -Fix [FS#4574]: waiting on a server could kick the client, or rather the client would kick itself due to an unexpected packet

release/1.2
rubidium 2011-04-09 21:52:38 +00:00
parent 6ce83c0aaa
commit d1a50a01b4
2 changed files with 34 additions and 32 deletions

View File

@ -719,17 +719,14 @@ DEF_GAME_RECEIVE_COMMAND(Client, PACKET_SERVER_WELCOME)
DEF_GAME_RECEIVE_COMMAND(Client, PACKET_SERVER_WAIT) DEF_GAME_RECEIVE_COMMAND(Client, PACKET_SERVER_WAIT)
{ {
if (this->status != STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET; /* We set the internal wait state when requesting the map. */
this->status = STATUS_MAP_WAIT; if (this->status != STATUS_MAP_WAIT) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
/* But... only now we set the join status to waiting, instead of requesting. */
_network_join_status = NETWORK_JOIN_STATUS_WAITING; _network_join_status = NETWORK_JOIN_STATUS_WAITING;
_network_join_waiting = p->Recv_uint8(); _network_join_waiting = p->Recv_uint8();
SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0); SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0);
/* We are put on hold for receiving the map.. we need GUI for this ;) */
DEBUG(net, 1, "The server is currently busy sending the map to someone else, please wait..." );
DEBUG(net, 1, "There are %d clients in front of you", _network_join_waiting);
return NETWORK_RECV_STATUS_OKAY; return NETWORK_RECV_STATUS_OKAY;
} }

View File

@ -539,9 +539,11 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap()
if (this->status == STATUS_MAP) { if (this->status == STATUS_MAP) {
if (this->savegame_mutex != NULL) this->savegame_mutex->BeginCritical(); if (this->savegame_mutex != NULL) this->savegame_mutex->BeginCritical();
bool last_packet = false;
for (uint i = 0; i < sent_packets && this->savegame_packets != NULL; i++) { for (uint i = 0; i < sent_packets && this->savegame_packets != NULL; i++) {
Packet *p = this->savegame_packets; Packet *p = this->savegame_packets;
bool last_packet = p->buffer[2] == PACKET_SERVER_MAP_DONE; last_packet = p->buffer[2] == PACKET_SERVER_MAP_DONE;
/* Remove the packet from the savegame queue and put it in the real queue. */ /* Remove the packet from the savegame queue and put it in the real queue. */
this->savegame_packets = p->next; this->savegame_packets = p->next;
@ -549,31 +551,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap()
this->NetworkTCPSocketHandler::SendPacket(p); this->NetworkTCPSocketHandler::SendPacket(p);
if (last_packet) { if (last_packet) {
/* Done reading! */
/* Set the status to DONE_MAP, no we will wait for the client
* to send it is ready (maybe that happens like never ;)) */
this->status = STATUS_DONE_MAP;
NetworkClientSocket *new_cs;
bool new_map_client = false;
/* Check if there is a client waiting for receiving the map
* and start sending him the map */
FOR_ALL_CLIENT_SOCKETS(new_cs) {
if (new_cs->status == STATUS_MAP_WAIT) {
/* Check if we already have a new client to send the map to */
if (!new_map_client) {
/* If not, this client will get the map */
new_cs->status = STATUS_AUTHORIZED;
new_map_client = true;
new_cs->SendMap();
} else {
/* Else, send the other clients how many clients are in front of them */
new_cs->SendWait();
}
}
}
/* There is no more data, so break the for */ /* There is no more data, so break the for */
break; break;
} }
@ -581,6 +558,34 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap()
if (this->savegame_mutex != NULL) this->savegame_mutex->EndCritical(); if (this->savegame_mutex != NULL) this->savegame_mutex->EndCritical();
if (last_packet) {
/* Done reading, make sure saving is done as well */
WaitTillSaved();
/* Set the status to DONE_MAP, no we will wait for the client
* to send it is ready (maybe that happens like never ;)) */
this->status = STATUS_DONE_MAP;
NetworkClientSocket *new_cs;
bool new_map_client = false;
/* Check if there is a client waiting for receiving the map
* and start sending him the map */
FOR_ALL_CLIENT_SOCKETS(new_cs) {
if (new_cs->status == STATUS_MAP_WAIT) {
/* Check if we already have a new client to send the map to */
if (!new_map_client) {
/* If not, this client will get the map */
new_cs->status = STATUS_AUTHORIZED;
new_map_client = true;
new_cs->SendMap();
} else {
/* Else, send the other clients how many clients are in front of them */
new_cs->SendWait();
}
}
}
}
switch (this->SendPackets()) { switch (this->SendPackets()) {
case SPS_CLOSED: case SPS_CLOSED:
return NETWORK_RECV_STATUS_CONN_LOST; return NETWORK_RECV_STATUS_CONN_LOST;