void Directory::CreateData ( const char *dataName, DArray <int> *darray ) { if ( GetData( dataName ) ) { AppReleaseAssert(false, "Attempted to create duplicate data %s at location\n%s", dataName, m_name); } else { Directory *directory = AddDirectory ( dataName ); AppAssert( directory ); directory->CreateData( "tID", "DArray<int>" ); directory->CreateData( "Size", darray->Size() ); for ( int i = 0; i < darray->Size(); ++i ) { char indexName[16]; sprintf ( indexName, "[i %d]", i ); Directory *thisDir = directory->AddDirectory( indexName ); if ( darray->ValidIndex(i) ) { thisDir->CreateData( "[Used]", true ); thisDir->CreateData( "[Data]", darray->GetData(i) ); } else { thisDir->CreateData( "[Used]", false ); } } } }
void Directory::CreateData ( const char *dataName, LList<int> *llist ) { if( GetData( dataName ) ) { AppReleaseAssert(false, "Attempted to create duplicate data %s at location\n%s", dataName, m_name); } else { Directory *directory = AddDirectory ( dataName ); AppAssert( directory ); directory->CreateData( "tID", "LList<int>" ); directory->CreateData( "Size", llist->Size() ); for ( int i = 0; i < llist->Size(); ++i ) { char indexName[16]; sprintf ( indexName, "[i %d]", i ); int data = llist->GetData(i); directory->CreateData( indexName, data ); } } }
static NetCallBackRetType AuthenticationThread(void *ignored) { #ifdef WAN_PLAY_ENABLED // // Every few seconds request the next key to be authenticated while( true ) { NetSleep( PERIOD_AUTHENTICATION_RETRY ); if( MetaServer_IsConnected() ) { char unknownKey[256]; char clientIp[256]; int keyId = -1; bool unknownKeyFound = false; // // Look for a key that isnt yet authenticated s_authResultsMutex.Lock(); for( int i = 0; i < s_authResults.Size(); ++i ) { AuthenticationResult *authResult = s_authResults[i]; if( authResult->m_authResult == AuthenticationUnknown && authResult->m_numTries < 5 ) { strcpy( unknownKey, authResult->m_authKey ); strcpy( clientIp, authResult->m_ip ); keyId = authResult->m_keyId; authResult->m_numTries++; unknownKeyFound = true; break; } } s_authResultsMutex.Unlock(); // // Check the key out if( unknownKeyFound ) { int basicResult = Authentication_SimpleKeyCheck(unknownKey); if( basicResult < 0 ) { // The key is in the wrong format Authentication_SetStatus( unknownKey, keyId, basicResult ); char *resultString = Authentication_GetStatusString(basicResult); AppDebugOut( "Key failed basic check : %s (result=%s)\n", unknownKey, resultString ); } else if( Authentication_IsDemoKey(unknownKey) ) { // This is a demo key, and has passed the simple check // Assume its valid from now on Authentication_SetStatus( unknownKey, -1, AuthenticationAccepted ); AppDebugOut( "Auth Key accepted as DEMOKEY : %s\n", unknownKey ); } else { // Request a proper auth check from the metaserver Directory directory; directory.SetName( NET_METASERVER_MESSAGE ); directory.CreateData( NET_METASERVER_COMMAND, NET_METASERVER_REQUEST_AUTH ); directory.CreateData( NET_METASERVER_AUTHKEY, unknownKey ); directory.CreateData( NET_METASERVER_AUTHKEYID, keyId ); directory.CreateData( NET_METASERVER_GAMENAME, APP_NAME ); directory.CreateData( NET_METASERVER_GAMEVERSION, APP_VERSION ); if( strcmp(clientIp, "unknown") != 0 ) { directory.CreateData( NET_METASERVER_IP, clientIp ); } MetaServer_SendToMetaServer( &directory ); AppDebugOut( "Requesting authentication of key %s\n", unknownKey ); } } } } #endif return 0; }
static NetCallBackRetType RequestIdentityThread(void *ignored) { #ifdef WAN_PLAY_ENABLED NetSocketListener *listener = (NetSocketListener *) ignored; int listenerIndex = GetListenerIndex(listener); AppAssert( listenerIndex > -1 ); s_listenersMutex.Lock(); MatchMakerListener *_listener = s_listeners[listenerIndex]; AppAssert(_listener); s_listenersMutex.Unlock(); // // Generate a uniqueID for this request // So we can tell the replies apart s_uniqueRequestMutex.Lock(); int uniqueId = s_uniqueRequestid; ++s_uniqueRequestid; s_uniqueRequestMutex.Unlock(); _listener->m_uniqueId = uniqueId; // // Build our request and convert to a byte stream // (only need to do this once and keep re-sending) Directory request; request.SetName( NET_MATCHMAKER_MESSAGE ); request.CreateData( NET_METASERVER_COMMAND, NET_MATCHMAKER_REQUEST_IDENTITY ); request.CreateData( NET_MATCHMAKER_UNIQUEID, uniqueId ); // // Open a connection to the MatchMaker service // Start sending requests for our ID every few seconds // to ensure the connection stays open in the NAT NetSocketSession socket( *listener, s_matchMakerIp, s_matchMakerPort ); while( true ) { // // Stop if We've been asked to if( _listener->m_shutDown ) { break; } // // Update the request with the latest auth data Directory *clientProps = MetaServer_GetClientProperties(); request.CreateData( NET_METASERVER_GAMENAME, clientProps->GetDataString(NET_METASERVER_GAMENAME) ); request.CreateData( NET_METASERVER_GAMEVERSION, clientProps->GetDataString(NET_METASERVER_GAMEVERSION) ); request.CreateData( NET_METASERVER_AUTHKEY, clientProps->GetDataString(NET_METASERVER_AUTHKEY) ); delete clientProps; int requestSize = 0; char *requestByteStream = request.Write(requestSize); // // Send the request int numBytesWritten = 0; NetRetCode result = socket.WriteData( requestByteStream, requestSize, &numBytesWritten ); delete [] requestByteStream; if( result != NetOk || numBytesWritten != requestSize ) { AppDebugOut( "MatchMaker encountered error sending data\n" ); break; } NetSleep( PERIOD_MATCHMAKER_REQUESTID ); } // // Shut down the request s_listenersMutex.Lock(); if( s_listeners.ValidIndex(listenerIndex) && s_listeners[listenerIndex] == _listener ) { s_listeners.RemoveData(listenerIndex); } s_listenersMutex.Unlock(); delete _listener; #endif return 0; }
bool MatchMaker_ReceiveMessage( NetSocketListener *_listener, Directory *_message ) { AppAssert( _message ); AppAssert( strcmp(_message->m_name, NET_MATCHMAKER_MESSAGE) == 0 ); AppAssert( _message->HasData( NET_METASERVER_COMMAND, DIRECTORY_TYPE_STRING ) ); char *cmd = _message->GetDataString( NET_METASERVER_COMMAND ); if( strcmp( cmd, NET_MATCHMAKER_IDENTIFY ) == 0 ) { // // This message contains the external IP and port of one of our connections if( !_message->HasData( NET_MATCHMAKER_UNIQUEID, DIRECTORY_TYPE_INT ) || !_message->HasData( NET_MATCHMAKER_YOURIP, DIRECTORY_TYPE_STRING ) || !_message->HasData( NET_MATCHMAKER_YOURPORT, DIRECTORY_TYPE_INT ) ) { AppDebugOut( "MatchMaker : Received badly formed identity message, discarded\n" ); } else { int uniqueId = _message->GetDataInt( NET_MATCHMAKER_UNIQUEID ); s_listenersMutex.Lock(); for( int i = 0; i < s_listeners.Size(); ++i ) { if( s_listeners.ValidIndex(i) ) { MatchMakerListener *listener = s_listeners[i]; if( listener->m_uniqueId == uniqueId ) { if( !listener->m_identified ) { listener->m_ip = strdup( _message->GetDataString(NET_MATCHMAKER_YOURIP) ); listener->m_port = _message->GetDataInt(NET_MATCHMAKER_YOURPORT); listener->m_identified = true; AppDebugOut( "Socket %d identified as public IP %s:%d\n", listener->m_listener->GetBoundSocketHandle(), listener->m_ip, listener->m_port ); } break; } } } s_listenersMutex.Unlock(); } } else if( strcmp( cmd, NET_MATCHMAKER_REQUEST_CONNECT ) == 0 ) { // // This is a request from a client for the server to set up a UDP hole punch if( !_message->HasData( NET_METASERVER_IP, DIRECTORY_TYPE_STRING ) || !_message->HasData( NET_METASERVER_PORT, DIRECTORY_TYPE_INT ) ) { AppDebugOut( "MatchMaker : Received badly formed connection request, discarded\n" ); } else { char *ip = _message->GetDataString( NET_METASERVER_IP ); int port = _message->GetDataInt( NET_METASERVER_PORT ); AppDebugOut( "MatchMaker : SERVER Received request to allow client to join from %s:%d\n", ip, port ); Directory dir; dir.SetName( NET_MATCHMAKER_MESSAGE ); dir.CreateData( NET_METASERVER_COMMAND, NET_MATCHMAKER_RECEIVED_CONNECT ); NetSocketSession session( *_listener, ip, port ); MetaServer_SendDirectory( &dir, &session ); } } else if( strcmp( cmd, NET_MATCHMAKER_RECEIVED_CONNECT ) == 0 ) { AppDebugOut( "MatchMaker : CLIENT received confirmation from Server that Hole Punch is set up\n" ); } else { AppAbort( "unrecognised matchmaker message" ); } return true; }