void Directory::Write ( ostream &output ) const
{
    // 
    // Start marker

    output.write( DIRECTORY_MARKERSTART, DIRECTORY_MARKERSIZE );
    
    //
    // Our own information

    WriteDynamicString( output, m_name );
    
    //
    // Our data
    // Indexes are not important and can be forgotten
    
    int numUsed = m_data.NumUsed();
    WritePackedInt(output, numUsed);
    
    for ( int d = 0; d < m_data.Size(); ++d )
    {
        if ( m_data.ValidIndex(d) ) 
        {
            DirectoryData *data = m_data[d];
            AppAssert( data );
            data->Write( output );
        }
    }
    

    // 
    // Our subdirectories
    // Indexes are not important and can be forgotten

    int numSubDirs = m_subDirectories.NumUsed();
    WritePackedInt(output, numSubDirs);

    for ( int s = 0; s < m_subDirectories.Size(); ++s )
    {
        if ( m_subDirectories.ValidIndex(s) )
        {
            Directory *subDir = m_subDirectories[s];
            AppAssert( subDir );
            subDir->Write( output );
        }
    }

    //
    // End marker

    output.write( DIRECTORY_MARKEREND, DIRECTORY_MARKERSIZE );
}
Esempio n. 2
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;
}