|
@@ -141,13 +141,17 @@ bool ClientNetworkCoordinatorSocketHandl
|
|
|
_settings_client.network.server_game_type = SERVER_GAME_TYPE_LOCAL;
|
|
|
|
|
|
this->CloseConnection();
|
|
|
return false;
|
|
|
|
|
|
case NETWORK_COORDINATOR_ERROR_INVALID_INVITE_CODE: {
|
|
|
this->CloseToken(detail);
|
|
|
auto connecter_pre_it = this->connecter_pre.find(detail);
|
|
|
if (connecter_pre_it != this->connecter_pre.end()) {
|
|
|
connecter_pre_it->second->SetFailure();
|
|
|
this->connecter_pre.erase(connecter_pre_it);
|
|
|
}
|
|
|
|
|
|
/* Mark the server as offline. */
|
|
|
NetworkGameList *item = NetworkGameListAddItem(detail);
|
|
|
item->online = false;
|
|
|
|
|
|
UpdateNetworkGameWindow();
|
|
@@ -255,36 +259,28 @@ bool ClientNetworkCoordinatorSocketHandl
|
|
|
bool ClientNetworkCoordinatorSocketHandler::Receive_GC_CONNECTING(Packet *p)
|
|
|
{
|
|
|
std::string token = p->Recv_string(NETWORK_TOKEN_LENGTH);
|
|
|
std::string invite_code = p->Recv_string(NETWORK_INVITE_CODE_LENGTH);
|
|
|
|
|
|
/* Find the connecter based on the invite code. */
|
|
|
auto connecter_it = this->connecter_pre.find(invite_code);
|
|
|
if (connecter_it == this->connecter_pre.end()) {
|
|
|
auto connecter_pre_it = this->connecter_pre.find(invite_code);
|
|
|
if (connecter_pre_it == this->connecter_pre.end()) {
|
|
|
this->CloseConnection();
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
/* Now store it based on the token. */
|
|
|
this->connecter[token] = connecter_it->second;
|
|
|
this->connecter_pre.erase(connecter_it);
|
|
|
this->connecter[token] = connecter_pre_it->second;
|
|
|
this->connecter_pre.erase(connecter_pre_it);
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool ClientNetworkCoordinatorSocketHandler::Receive_GC_CONNECT_FAILED(Packet *p)
|
|
|
{
|
|
|
std::string token = p->Recv_string(NETWORK_TOKEN_LENGTH);
|
|
|
|
|
|
auto connecter_it = this->connecter.find(token);
|
|
|
if (connecter_it != this->connecter.end()) {
|
|
|
connecter_it->second->SetFailure();
|
|
|
this->connecter.erase(connecter_it);
|
|
|
}
|
|
|
|
|
|
/* Close all remaining connections. */
|
|
|
this->CloseToken(token);
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool ClientNetworkCoordinatorSocketHandler::Receive_GC_DIRECT_CONNECT(Packet *p)
|
|
@@ -379,13 +375,13 @@ NetworkRecvStatus ClientNetworkCoordinat
|
|
|
this->CloseSocket();
|
|
|
this->connecting = false;
|
|
|
|
|
|
_network_server_connection_type = CONNECTION_TYPE_UNKNOWN;
|
|
|
this->next_update = {};
|
|
|
|
|
|
this->CloseAllTokens();
|
|
|
this->CloseAllConnections();
|
|
|
|
|
|
SetWindowDirty(WC_CLIENT_LIST, 0);
|
|
|
|
|
|
return NETWORK_RECV_STATUS_OKAY;
|
|
|
}
|
|
|
|
|
@@ -521,17 +517,20 @@ void ClientNetworkCoordinatorSocketHandl
|
|
|
* doesn't have to, as it is implied by the client telling. */
|
|
|
Packet *p = new Packet(PACKET_COORDINATOR_CLIENT_CONNECTED);
|
|
|
p->Send_uint8(NETWORK_COORDINATOR_VERSION);
|
|
|
p->Send_string(token);
|
|
|
this->SendPacket(p);
|
|
|
|
|
|
/* Find the connecter; it can happen it no longer exist, in cases where
|
|
|
* we aborted the connect but the Game Coordinator was already in the
|
|
|
* processes of connecting us. */
|
|
|
auto connecter_it = this->connecter.find(token);
|
|
|
assert(connecter_it != this->connecter.end());
|
|
|
|
|
|
connecter_it->second->SetConnected(sock);
|
|
|
this->connecter.erase(connecter_it);
|
|
|
if (connecter_it != this->connecter.end()) {
|
|
|
connecter_it->second->SetConnected(sock);
|
|
|
this->connecter.erase(connecter_it);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* Close all remaining connections. */
|
|
|
this->CloseToken(token);
|
|
|
}
|
|
|
|
|
@@ -549,12 +548,17 @@ void ClientNetworkCoordinatorSocketHandl
|
|
|
p->Send_string(token);
|
|
|
p->Send_uint8(family);
|
|
|
p->Send_bool(result);
|
|
|
this->SendPacket(p);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Close the STUN handler.
|
|
|
* @param token The token used for the STUN handlers.
|
|
|
* @param family The family of STUN handlers to close. AF_UNSPEC to close all STUN handlers for this token.
|
|
|
*/
|
|
|
void ClientNetworkCoordinatorSocketHandler::CloseStunHandler(const std::string &token, uint8 family)
|
|
|
{
|
|
|
auto stun_it = this->stun_handlers.find(token);
|
|
|
if (stun_it == this->stun_handlers.end()) return;
|
|
|
|
|
|
if (family == AF_UNSPEC) {
|
|
@@ -578,54 +582,49 @@ void ClientNetworkCoordinatorSocketHandl
|
|
|
/**
|
|
|
* Close everything related to this connection token.
|
|
|
* @param token The connection token to close.
|
|
|
*/
|
|
|
void ClientNetworkCoordinatorSocketHandler::CloseToken(const std::string &token)
|
|
|
{
|
|
|
/* Ensure all other pending connection attempts are also killed. */
|
|
|
if (this->game_connecter != nullptr) {
|
|
|
this->game_connecter->Kill();
|
|
|
this->game_connecter = nullptr;
|
|
|
}
|
|
|
|
|
|
/* Close all remaining STUN connections. */
|
|
|
this->CloseStunHandler(token);
|
|
|
|
|
|
/* Close the caller of the connection attempt. */
|
|
|
auto connecter_it = this->connecter.find(token);
|
|
|
if (connecter_it != this->connecter.end()) {
|
|
|
connecter_it->second->SetFailure();
|
|
|
this->connecter.erase(connecter_it);
|
|
|
}
|
|
|
auto connecter_pre_it = this->connecter_pre.find(token);
|
|
|
if (connecter_pre_it != this->connecter_pre.end()) {
|
|
|
connecter_pre_it->second->SetFailure();
|
|
|
this->connecter_pre.erase(connecter_pre_it);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Close all pending connection tokens.
|
|
|
*/
|
|
|
void ClientNetworkCoordinatorSocketHandler::CloseAllTokens()
|
|
|
void ClientNetworkCoordinatorSocketHandler::CloseAllConnections()
|
|
|
{
|
|
|
/* Ensure all other pending connection attempts are also killed. */
|
|
|
if (this->game_connecter != nullptr) {
|
|
|
this->game_connecter->Kill();
|
|
|
this->game_connecter = nullptr;
|
|
|
}
|
|
|
|
|
|
/* Mark any pending connecters as failed. */
|
|
|
for (auto &[token, it] : this->connecter) {
|
|
|
this->CloseStunHandler(token);
|
|
|
it->SetFailure();
|
|
|
|
|
|
/* Inform the Game Coordinator he can stop trying to connect us to the server. */
|
|
|
this->ConnectFailure(token, 0);
|
|
|
}
|
|
|
this->stun_handlers.clear();
|
|
|
this->connecter.clear();
|
|
|
|
|
|
/* Also close any pending invite-code requests. */
|
|
|
for (auto &[invite_code, it] : this->connecter_pre) {
|
|
|
it->SetFailure();
|
|
|
}
|
|
|
this->connecter.clear();
|
|
|
this->connecter_pre.clear();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Check whether we received/can send some data from/to the Game Coordinator server and
|
|
|
* when that's the case handle it appropriately.
|