Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
May 27, 2015, 10:45:56 AM (9 years ago)
Author:
maxima
Message:

multiplayer branch merged to presentation

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/branches/presentationFS15/src/libraries/network/MasterServer.cc

    r8952 r10497  
    3434#include "util/Output.h"
    3535
    36 namespace orxonox 
     36namespace orxonox
    3737{
    3838  /*** MACROS ***/
     
    4545  MasterServer *MasterServer::instance = NULL;
    4646
    47 
    48 
    49 
    5047  /* command: list servers */
    51   void 
     48  void
    5249  MasterServer::listServers( void )
    5350  {
     
    5956
    6057    /* loop through list elements */
    61     for( i = MasterServer::getInstance()->mainlist.serverlist.begin(); 
    62       i != MasterServer::getInstance()->mainlist.serverlist.end(); ++i ) 
     58    for( i = MasterServer::getInstance()->mainlist.serverlist.begin();
     59      i != MasterServer::getInstance()->mainlist.serverlist.end(); ++i )
    6360    {
    6461      orxout(user_info) << "  " << (*i).ServerInfo.getServerIP() << std::endl;
     
    7067  }
    7168
    72   void 
     69  void
    7370  MasterServer::delServer( std::string todeladdr )
    7471  {
    7572    /* tell the user we're now removing the entry from the server list */
    76     orxout(user_info) << "MS: Deleting server \"" << todeladdr << "\"..." 
     73    orxout(user_info) << "MS: Deleting server \"" << todeladdr << "\"..."
    7774      << std::endl;
    7875
    7976    /* see if we actually have that server on our list */
    80     ServerListSearchResult shandle = 
     77    ServerListSearchResult shandle =
    8178      MasterServer::getInstance()->mainlist.findServerByAddress(todeladdr);
    8279
     
    8683    }
    8784
    88     /* force-disconnect the server */ 
     85    /* force-disconnect the server */
    8986    enet_peer_disconnect( shandle.result.peer, 0 );
    9087
     
    9895
    9996  /* helpers */
    100   static void 
     97  static void
    10198  helper_output_debug( ENetEvent *event, char *addrconv )
    10299  {
    103100    orxout(verbose, context::master_server)
    104       << "A packet of length" 
     101      << "A packet of length"
    105102      << event->packet->dataLength
    106103      << " containing "
    107104      << (const char*)event->packet->data
    108105      << " was received from "
    109       << addrconv 
     106      << addrconv
    110107      << " on channel "
    111108      << event->channelID << endl;
     
    122119
    123120    /* loop through list elements */
    124     for( i = mainlist.serverlist.begin(); i 
    125         != mainlist.serverlist.end(); ++i ) 
     121    for( i = mainlist.serverlist.begin(); i
     122        != mainlist.serverlist.end(); ++i )
    126123    {
    127124      /* send this particular server */
    128125      /* build reply string */
    129       char *tosend = (char *)calloc( (*i).ServerInfo.getServerIP().length()
    130           + MSPROTO_SERVERLIST_ITEM_LEN + 2,1 );
    131       if( !tosend ) 
     126      int packetlen = MSPROTO_SERVERLIST_ITEM_LEN + 1 + (*i).ServerInfo.getServerIP().length() + 1 + (*i).ServerInfo.getServerName().length() + 1 + sizeof((*i).ServerInfo.getClientNumber()) + 1;
     127      char *tosend = (char *)calloc(packetlen ,1 );
     128      if( !tosend )
    132129      { orxout(internal_warning, context::master_server) << "Masterserver.cc: Memory allocation failed." << endl;
    133130        continue;
    134       } 
    135       sprintf( tosend, "%s %s", MSPROTO_SERVERLIST_ITEM,
    136           (*i).ServerInfo.getServerIP().c_str() );
     131      }
     132      sprintf( tosend, "%s %s %s %u", MSPROTO_SERVERLIST_ITEM,
     133          (*i).ServerInfo.getServerIP().c_str(), (*i).ServerInfo.getServerName().c_str(), (*i).ServerInfo.getClientNumber());
    137134
    138135      /* create packet from it */
    139136      reply = enet_packet_create( tosend,
    140           strlen( tosend ) + 1, 
     137          strlen( tosend ) + 1,
    141138          ENET_PACKET_FLAG_RELIABLE);
    142139
     
    149146      /* free the tosend buffer */
    150147      free( tosend );
    151     } 
     148    }
    152149
    153150    /* create end-of-list packet */
     
    163160  }
    164161
    165   /* maybe the two methods below can be merged into one and 
    166    * made to use ENet's RTT functionality to check for disconnected 
     162  /* maybe the two methods below can be merged into one and
     163   * made to use ENet's RTT functionality to check for disconnected
    167164   * servers.
    168165   */
    169   void 
     166  void
    170167  MasterServer::helper_cleanupServers( void )
    171168  {
    172169    /* get an iterator */
    173170    std::list<ServerListElem>::iterator i;
    174      
     171
    175172    if( mainlist.serverlist.size() == 0 )
    176173      return;
    177174
    178175    /* loop through list elements */
    179     for( i = mainlist.serverlist.begin(); i 
    180         != mainlist.serverlist.end(); ++i ) 
     176    for( i = mainlist.serverlist.begin(); i
     177        != mainlist.serverlist.end(); ++i )
    181178    { /* see if we have a disconnected peer */
    182       if( (*i).peer && 
     179      if( (*i).peer &&
    183180         ((*i).peer->state == ENET_PEER_STATE_DISCONNECTED ||
    184181          (*i).peer->state == ENET_PEER_STATE_ZOMBIE ))
    185       { 
     182      {
    186183        /* Remove it from the list */
    187184        orxout(internal_warning) << (char*)(*i).peer->data << " timed out.\n";
     
    190187        /* stop iterating, we manipulated the list */
    191188        /* TODO note: this only removes one dead server per loop
    192          * iteration. not beautiful, but one iteration is ~100ms, 
     189         * iteration. not beautiful, but one iteration is ~100ms,
    193190         * so not really relevant for the moment.
    194191         */
     
    196193      }
    197194    }
    198  
     195
    199196  }
    200197
     
    204201  /***** EVENTS *****/
    205202  /* connect event */
    206   int 
     203  int
    207204  MasterServer::eventConnect( ENetEvent *event )
    208205  { /* check for bad parameters */
     
    217214
    218215    /* output debug info */
    219     orxout(verbose, context::master_server) << "A new client connected from " 
    220       << addrconv 
    221       << " on port " 
     216    orxout(verbose, context::master_server) << "A new client connected from "
     217      << addrconv
     218      << " on port "
    222219      << event->peer->address.port << endl;
    223220
    224221    /* store string form of address here */
    225     event->peer->data = addrconv; 
     222    event->peer->data = addrconv;
    226223
    227224    /* all fine. */
     
    230227
    231228  /* disconnect event */
    232   int 
     229  int
    233230  MasterServer::eventDisconnect( ENetEvent *event )
    234231  { /* check for bad parameters */
     
    255252
    256253  /* data event */
    257   int 
     254  int
    258255  MasterServer::eventData( ENetEvent *event )
    259256  { /* validate packet */
     
    262259      return -1;
    263260    }
    264      
     261
    265262    /* generate address in readable form */
    266263    char *addrconv = (char *) calloc( 50, 1 );
    267264    enet_address_get_host_ip( &(event->peer->address), addrconv, 49 );
     265    /* convert to string */
     266    std::string ip = std::string( addrconv );
     267    /* delete addrconv */
     268    if( addrconv ) free( addrconv );
     269
     270    /* pointer to full packet data */
     271    char * packetdata = (char *)event->packet->data;
    268272
    269273    /* output debug info about the data that has come */
     
    271275
    272276    /* GAME SERVER OR CLIENT CONNECTION? */
    273     if( !strncmp( (char *)event->packet->data, MSPROTO_GAME_SERVER,
    274       MSPROTO_GAME_SERVER_LEN ) )
     277    if( !strncmp(packetdata, MSPROTO_GAME_SERVER, MSPROTO_GAME_SERVER_LEN ) )
    275278    { /* Game server */
    276279
    277       if( !strncmp( (char *)event->packet->data
    278         + MSPROTO_GAME_SERVER_LEN+1,
    279         MSPROTO_REGISTER_SERVER, MSPROTO_REGISTER_SERVER_LEN ) )
     280      if( !strncmp( packetdata + MSPROTO_GAME_SERVER_LEN+1, MSPROTO_REGISTER_SERVER, MSPROTO_REGISTER_SERVER_LEN ) )
    280281      { /* register new server */
    281         mainlist.addServer( packet::ServerInformation( event ),
    282           event->peer );
    283        
     282        mainlist.addServer( packet::ServerInformation( event ), event->peer );
     283
    284284        /* tell people we did so */
    285         orxout(internal_info, context::master_server) << "Added new server to list: " << 
     285        orxout(internal_info, context::master_server) << "Added new server to list: " <<
    286286          packet::ServerInformation( event ).getServerIP() << endl;
    287287      }
    288288
    289       else if( !strncmp( (char *)event->packet->data
    290         + MSPROTO_GAME_SERVER_LEN+1,
    291         MSPROTO_SERVERDC, MSPROTO_SERVERDC_LEN ) )
    292       {
     289      else if( !strncmp( packetdata + MSPROTO_GAME_SERVER_LEN+1, MSPROTO_SERVERDC, MSPROTO_SERVERDC_LEN ) )
     290      { /* disconnect server */
     291
     292        /* remove the server from the list it belongs to */
     293        this->mainlist.delServerByAddress( ip );
     294
     295        /* tell the user */
     296        orxout(internal_info, context::master_server) << "Removed server " << ip << " from list." << endl;
     297      }
     298      /* TODO add hook for disconnect here */
     299
     300      else if( !strncmp( packetdata + MSPROTO_GAME_SERVER_LEN+1, MSPROTO_SET_NAME, MSPROTO_SET_NAME_LEN ) )
     301      { /* save server name */
    293302        /* create string from peer data */
    294         std::string name = std::string( addrconv );
     303        std::string data (event->packet->data,event->packet->data + event->packet->dataLength );
     304        std::string name = data.substr(MSPROTO_GAME_SERVER_LEN+1 + MSPROTO_SET_NAME_LEN + 1);
    295305
    296306        /* remove the server from the list it belongs to */
    297         this->mainlist.delServerByAddress( name );
     307        this->mainlist.setNameByAddress( ip, name );
    298308
    299309        /* tell the user */
    300         orxout(internal_info, context::master_server) << "Removed server " << name << " from list." << endl;
    301       }
    302 
    303       /* TODO add hook for disconnect here */
    304     }
    305     else if( !strncmp( (char *)event->packet->data, MSPROTO_CLIENT,
    306       MSPROTO_CLIENT_LEN) )
     310        orxout(internal_info, context::master_server) << "Updated server " << ip << " with new name " << name << endl;
     311      }
     312
     313      else if( !strncmp( packetdata + MSPROTO_GAME_SERVER_LEN+1, MSPROTO_SET_CLIENTS, MSPROTO_SET_CLIENTS_LEN ) )
     314      { /* save client count from server */
     315        /* create string from peer data */
     316        std::string data (event->packet->data,event->packet->data + event->packet->dataLength );
     317        std::string textform= data.substr(MSPROTO_GAME_SERVER_LEN + 1 + MSPROTO_SET_CLIENTS_LEN + 1);
     318        int clientNumber = Ogre::StringConverter::parseInt(textform);
     319
     320        this->mainlist.setClientsByAddress( ip, clientNumber);
     321
     322        /* tell the user */
     323        orxout(internal_info, context::master_server) << "Updated server " << ip << " with new client number " << clientNumber << endl;
     324      }
     325    }
     326    else if( !strncmp( packetdata, MSPROTO_CLIENT, MSPROTO_CLIENT_LEN) )
    307327    { /* client */
    308       if( !strncmp( (char *)event->packet->data + MSPROTO_CLIENT_LEN+1,
    309         MSPROTO_REQ_LIST, MSPROTO_REQ_LIST_LEN ) )
     328      if( !strncmp( packetdata + MSPROTO_CLIENT_LEN+1, MSPROTO_REQ_LIST, MSPROTO_REQ_LIST_LEN ) )
    310329        /* send server list */
    311330        helper_sendlist( event );
    312331    }
    313332    else
    314     { /* bad message, don't do anything. */ }
    315 
    316     /* delete addrconv */
    317     if( addrconv ) free( addrconv );
     333    { /* bad message, don't do anything. */ }
    318334
    319335    /* Clean up the packet now that we're done using it. */
     
    324340
    325341  /**** MAIN ROUTINE *****/
    326   int 
     342  int
    327343  MasterServer::run()
    328344  {
     
    330346    ENetEvent *event = (ENetEvent *)calloc(sizeof(ENetEvent), sizeof(char));
    331347    if( event == NULL )
    332     { 
     348    {
    333349      orxout(user_error, context::master_server) << "Could not create ENetEvent structure, exiting." << endl;
    334350      exit( EXIT_FAILURE );
     
    345361    switch (event->type)
    346362    { /* new connection */
    347       case ENET_EVENT_TYPE_CONNECT: 
     363      case ENET_EVENT_TYPE_CONNECT:
    348364        eventConnect( event ); break;
    349365
    350366        /* disconnect */
    351       case ENET_EVENT_TYPE_DISCONNECT: 
     367      case ENET_EVENT_TYPE_DISCONNECT:
    352368        eventDisconnect( event ); break;
    353369
     
    358374
    359375    /* done */
     376    free(event);
    360377    return 0;
    361   } 
     378  }
    362379
    363380  /* constructor */
     
    380397    this->address.port = ORX_MSERVER_PORT;
    381398
    382     /* create a host with the above settings (the last two 0 mean: accept 
     399    /* create a host with the above settings (the last two 0 mean: accept
    383400     * any input/output bandwidth */
    384     this->server = enet_host_create( &this->address, ORX_MSERVER_MAXCONNS, 
     401    this->server = enet_host_create( &this->address, ORX_MSERVER_MAXCONNS,
    385402        ORX_MSERVER_MAXCHANS, 0, 0 );
    386403    assert(this->server);
     
    388405    /* see if creation worked */
    389406    if( !this->server )
    390     { orxout(user_error, context::master_server) << 
     407    { orxout(user_error, context::master_server) <<
    391408        "An error occurred while trying to create an ENet server host." << endl;
    392409      exit( EXIT_FAILURE );
Note: See TracChangeset for help on using the changeset viewer.