- Timestamp:
- May 27, 2015, 10:45:56 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/presentationFS15/src/libraries/network/MasterServer.cc
r8952 r10497 34 34 #include "util/Output.h" 35 35 36 namespace orxonox 36 namespace orxonox 37 37 { 38 38 /*** MACROS ***/ … … 45 45 MasterServer *MasterServer::instance = NULL; 46 46 47 48 49 50 47 /* command: list servers */ 51 void 48 void 52 49 MasterServer::listServers( void ) 53 50 { … … 59 56 60 57 /* 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 ) 63 60 { 64 61 orxout(user_info) << " " << (*i).ServerInfo.getServerIP() << std::endl; … … 70 67 } 71 68 72 void 69 void 73 70 MasterServer::delServer( std::string todeladdr ) 74 71 { 75 72 /* 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 << "\"..." 77 74 << std::endl; 78 75 79 76 /* see if we actually have that server on our list */ 80 ServerListSearchResult shandle = 77 ServerListSearchResult shandle = 81 78 MasterServer::getInstance()->mainlist.findServerByAddress(todeladdr); 82 79 … … 86 83 } 87 84 88 /* force-disconnect the server */ 85 /* force-disconnect the server */ 89 86 enet_peer_disconnect( shandle.result.peer, 0 ); 90 87 … … 98 95 99 96 /* helpers */ 100 static void 97 static void 101 98 helper_output_debug( ENetEvent *event, char *addrconv ) 102 99 { 103 100 orxout(verbose, context::master_server) 104 << "A packet of length" 101 << "A packet of length" 105 102 << event->packet->dataLength 106 103 << " containing " 107 104 << (const char*)event->packet->data 108 105 << " was received from " 109 << addrconv 106 << addrconv 110 107 << " on channel " 111 108 << event->channelID << endl; … … 122 119 123 120 /* 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 ) 126 123 { 127 124 /* send this particular server */ 128 125 /* 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 ) 132 129 { orxout(internal_warning, context::master_server) << "Masterserver.cc: Memory allocation failed." << endl; 133 130 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()); 137 134 138 135 /* create packet from it */ 139 136 reply = enet_packet_create( tosend, 140 strlen( tosend ) + 1, 137 strlen( tosend ) + 1, 141 138 ENET_PACKET_FLAG_RELIABLE); 142 139 … … 149 146 /* free the tosend buffer */ 150 147 free( tosend ); 151 } 148 } 152 149 153 150 /* create end-of-list packet */ … … 163 160 } 164 161 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 167 164 * servers. 168 165 */ 169 void 166 void 170 167 MasterServer::helper_cleanupServers( void ) 171 168 { 172 169 /* get an iterator */ 173 170 std::list<ServerListElem>::iterator i; 174 171 175 172 if( mainlist.serverlist.size() == 0 ) 176 173 return; 177 174 178 175 /* 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 ) 181 178 { /* see if we have a disconnected peer */ 182 if( (*i).peer && 179 if( (*i).peer && 183 180 ((*i).peer->state == ENET_PEER_STATE_DISCONNECTED || 184 181 (*i).peer->state == ENET_PEER_STATE_ZOMBIE )) 185 { 182 { 186 183 /* Remove it from the list */ 187 184 orxout(internal_warning) << (char*)(*i).peer->data << " timed out.\n"; … … 190 187 /* stop iterating, we manipulated the list */ 191 188 /* 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, 193 190 * so not really relevant for the moment. 194 191 */ … … 196 193 } 197 194 } 198 195 199 196 } 200 197 … … 204 201 /***** EVENTS *****/ 205 202 /* connect event */ 206 int 203 int 207 204 MasterServer::eventConnect( ENetEvent *event ) 208 205 { /* check for bad parameters */ … … 217 214 218 215 /* 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 " 222 219 << event->peer->address.port << endl; 223 220 224 221 /* store string form of address here */ 225 event->peer->data = addrconv; 222 event->peer->data = addrconv; 226 223 227 224 /* all fine. */ … … 230 227 231 228 /* disconnect event */ 232 int 229 int 233 230 MasterServer::eventDisconnect( ENetEvent *event ) 234 231 { /* check for bad parameters */ … … 255 252 256 253 /* data event */ 257 int 254 int 258 255 MasterServer::eventData( ENetEvent *event ) 259 256 { /* validate packet */ … … 262 259 return -1; 263 260 } 264 261 265 262 /* generate address in readable form */ 266 263 char *addrconv = (char *) calloc( 50, 1 ); 267 264 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; 268 272 269 273 /* output debug info about the data that has come */ … … 271 275 272 276 /* 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 ) ) 275 278 { /* Game server */ 276 279 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 ) ) 280 281 { /* register new server */ 281 mainlist.addServer( packet::ServerInformation( event ), 282 event->peer ); 283 282 mainlist.addServer( packet::ServerInformation( event ), event->peer ); 283 284 284 /* 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: " << 286 286 packet::ServerInformation( event ).getServerIP() << endl; 287 287 } 288 288 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 */ 293 302 /* 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); 295 305 296 306 /* remove the server from the list it belongs to */ 297 this->mainlist. delServerByAddress(name );307 this->mainlist.setNameByAddress( ip, name ); 298 308 299 309 /* 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) ) 307 327 { /* 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 ) ) 310 329 /* send server list */ 311 330 helper_sendlist( event ); 312 331 } 313 332 else 314 { /* bad message, don't do anything. */ } 315 316 /* delete addrconv */ 317 if( addrconv ) free( addrconv ); 333 { /* bad message, don't do anything. */ } 318 334 319 335 /* Clean up the packet now that we're done using it. */ … … 324 340 325 341 /**** MAIN ROUTINE *****/ 326 int 342 int 327 343 MasterServer::run() 328 344 { … … 330 346 ENetEvent *event = (ENetEvent *)calloc(sizeof(ENetEvent), sizeof(char)); 331 347 if( event == NULL ) 332 { 348 { 333 349 orxout(user_error, context::master_server) << "Could not create ENetEvent structure, exiting." << endl; 334 350 exit( EXIT_FAILURE ); … … 345 361 switch (event->type) 346 362 { /* new connection */ 347 case ENET_EVENT_TYPE_CONNECT: 363 case ENET_EVENT_TYPE_CONNECT: 348 364 eventConnect( event ); break; 349 365 350 366 /* disconnect */ 351 case ENET_EVENT_TYPE_DISCONNECT: 367 case ENET_EVENT_TYPE_DISCONNECT: 352 368 eventDisconnect( event ); break; 353 369 … … 358 374 359 375 /* done */ 376 free(event); 360 377 return 0; 361 } 378 } 362 379 363 380 /* constructor */ … … 380 397 this->address.port = ORX_MSERVER_PORT; 381 398 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 383 400 * 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, 385 402 ORX_MSERVER_MAXCHANS, 0, 0 ); 386 403 assert(this->server); … … 388 405 /* see if creation worked */ 389 406 if( !this->server ) 390 { orxout(user_error, context::master_server) << 407 { orxout(user_error, context::master_server) << 391 408 "An error occurred while trying to create an ENet server host." << endl; 392 409 exit( EXIT_FAILURE );
Note: See TracChangeset
for help on using the changeset viewer.