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 );
        }
    }
}
Beispiel #3
0
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;
}
Beispiel #4
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;
}
Beispiel #5
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;
}