bool ServerThread::handShake(StreamSocket* socket, UserNetworkIdentification* otherID, UInt32& tag) { NetMessage message; bool success; UInt32 tempTag; printd(INFO, "ServerThread::handShake(): receiving ID of client!\n"); // ID exchange try { Network::receiveNetMessage(socket, &message); message.getUInt32(tempTag); tag = tempTag; internalNetwork->decodeId(otherID, &message); } // try catch (...) { printd(ERROR, "ServerThread::handShake(): error at receiving client's ID!\n"); return false; } // catch printd(INFO, "ServerThread::handShake(): client has ip %s and userId %u\n", internalNetwork->ipAddressToString(otherID->netId.address.ipAddress).c_str(), otherID->userId); // Check if client is already connected, send connectionDenied-Message if so if (internalNetwork->checkClientConnected(&otherID->netId)) { printd(WARNING, "ServerThread::handShake(): Client already connected!\n"); message.clear(); message.putUInt32(internalNetwork->connectionRequestDenyTag); try { Network::sendNetMessage(socket, &message); } catch (...) { } return false; } // if if (tag != internalNetwork->quickConnectTag) success = handleNormalConnect(socket, message); else success = handleQuickConnect(socket, message, otherID); if (!success) return false; // internalNetwork->mapUserToNetworkId[otherID->userId] = otherID->netId; return true; } // handShake
// ---------------------------------------------------------------------------- void ConnectToServer::asynchronousUpdate() { switch(m_state) { case NONE: { Log::info("ConnectToServer", "Protocol starting"); // This protocol will write the public address of this // instance to STKHost. m_current_protocol = new GetPublicAddress(this); m_current_protocol->requestStart(); // This protocol will be unpaused in the callback from // GetPublicAddress requestPause(); m_state = GETTING_SELF_ADDRESS; break; } case GETTING_SELF_ADDRESS: { delete m_current_protocol; // delete GetPublicAddress m_current_protocol = NULL; registerWithSTKServer(); // Register us with STK server if (m_quick_join) { handleQuickConnect(); // Quick connect will give us the server details, // so we can immediately try to connect to the server m_state = REQUESTING_CONNECTION; } else { m_state = GOT_SERVER_ADDRESS; } } break; case GOT_SERVER_ADDRESS: { assert(!m_quick_join); delete m_current_protocol; m_current_protocol = NULL; Log::info("ConnectToServer", "Server's address known"); // we're in the same lan (same public ip address) !! if (m_server_address.getIP() == NetworkConfig::get()->getMyAddress().getIP()) { Log::info("ConnectToServer", "Server appears to be in the same LAN."); } m_state = REQUESTING_CONNECTION; m_current_protocol = new RequestConnection(m_server_id); m_current_protocol->requestStart(); break; } case REQUESTING_CONNECTION: // In case of a LAN server, m_crrent_protocol is NULL if (!m_current_protocol || m_current_protocol->getState() == PROTOCOL_STATE_TERMINATED) { delete m_current_protocol; m_current_protocol = NULL; // Server knows we want to connect Log::info("ConnectToServer", "Connection request made"); if (m_server_address.getIP() == 0 || m_server_address.getPort() == 0 ) { // server data not correct, hide address and stop m_state = HIDING_ADDRESS; Log::error("ConnectToServer", "Server address is %s", m_server_address.toString().c_str()); m_current_protocol = new HidePublicAddress(); m_current_protocol->requestStart(); return; } if (m_server_address.getIP() == NetworkConfig::get()->getMyAddress().getIP() || NetworkConfig::get()->isLAN()) { // We're in the same lan (same public ip address). // The state will change to CONNECTING handleSameLAN(); } else { m_state = CONNECTING; m_current_protocol = new PingProtocol(m_server_address, 2.0); m_current_protocol->requestStart(); } } break; case CONNECTING: // waiting the server to answer our connection { static double timer = 0; if (StkTime::getRealTime() > timer+5.0) // every 5 seconds { STKHost::get()->connect(m_server_address); timer = StkTime::getRealTime(); Log::info("ConnectToServer", "Trying to connect to %s", m_server_address.toString().c_str()); } break; } case CONNECTED: { Log::info("ConnectToServer", "Connected"); if(m_current_protocol) { // Kill the ping protocol because we're connected m_current_protocol->requestTerminate(); } delete m_current_protocol; m_current_protocol = NULL; // LAN networking does not use the stk server tables. if(NetworkConfig::get()->isWAN()) { m_current_protocol = new HidePublicAddress(); m_current_protocol->requestStart(); } m_state = HIDING_ADDRESS; break; } case HIDING_ADDRESS: // Wait till we have hidden our address if (!m_current_protocol || m_current_protocol->getState() == PROTOCOL_STATE_TERMINATED) { if(m_current_protocol) { delete m_current_protocol; m_current_protocol = NULL; Log::info("ConnectToServer", "Address hidden"); } m_state = DONE; // lobby room protocol if we're connected only if(STKHost::get()->getPeers()[0]->isConnected()) { Protocol *p = new ClientLobbyRoomProtocol(m_server_address); p->requestStart(); } } break; case DONE: requestTerminate(); m_state = EXITING; break; case EXITING: break; } } // asynchronousUpdate