Changeset 6341 in orxonox.OLD for trunk/src/lib/network/network_game_manager.cc
- Timestamp:
- Dec 30, 2005, 1:57:12 AM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/network/network_game_manager.cc
r6139 r6341 20 20 #define DEBUG_MODULE_NETWORK 21 21 22 #include "factory.h" 23 #include "network_stream.h" 24 #include "converter.h" 25 22 26 /* include your own header */ 23 27 #include "network_game_manager.h" … … 27 31 using namespace std; 28 32 33 NetworkGameManager* NetworkGameManager::singletonRef = NULL; 34 29 35 /*! 30 36 * Standard constructor … … 32 38 NetworkGameManager::NetworkGameManager() 33 39 { 40 PRINTF(0)("START\n"); 41 34 42 /* set the class id for the base object */ 35 this->setClassID(CL_ENTITY_MANAGER, "EntityManager"); 43 this->setClassID(CL_NETWORK_GAME_MANAGER, "NetworkGameManager"); 44 45 allOutBuffer.length = 0; 46 47 allOutBuffer.maxLength = 10*1024; 48 49 allOutBuffer.buffer = new byte[10*1024]; 50 51 newUniqueID = MAX_CONNECTIONS + 2; 52 53 hasRequestedWorld = false; 36 54 } 37 55 … … 41 59 NetworkGameManager::~NetworkGameManager() 42 60 { 43 } 44 45 46 void NetworkGameManager::writeBytes(const byte* data, int length) 47 { 61 for ( int i = 0; i<outBuffer.size(); i++) 62 { 63 if ( outBuffer[i].buffer ) 64 delete outBuffer[i].buffer; 65 } 66 67 if ( allOutBuffer.buffer ) 68 delete allOutBuffer.buffer; 69 } 70 71 72 int NetworkGameManager::writeBytes(const byte* data, int length, int sender) 73 { 74 int i = 0; 75 byte b; 76 77 while ( i<length ) 78 { 79 b = data[i++]; 80 81 PRINTF(0)("WriteBytes: b = %d\n", b); 82 83 if ( isServer() ) 84 { 85 if ( b == REQUEST_CREATE ) 86 { 87 if ( !handleRequestCreate( i, data, length, sender ) ) 88 return i; 89 continue; 90 } 91 if ( b == REQUEST_REMOVE ) 92 { 93 if ( !handleRequestRemove( i, data, length, sender ) ) 94 return i; 95 continue; 96 } 97 } 98 else 99 { 100 if ( b == CREATE_ENTITY ) 101 { 102 if ( !handleCreateEntity( i, data, length, sender ) ) 103 return i; 104 continue; 105 } 106 if ( b == REMOVE_ENTITY ) 107 { 108 if ( !handleRemoveEntity( i, data, length, sender ) ) 109 return i; 110 continue; 111 } 112 if ( b == CREATE_ENTITY_LIST ) 113 { 114 if ( !handleCreateEntityList( i, data, length, sender ) ) 115 return i; 116 continue; 117 } 118 if ( b == REMOVE_ENTITY_LIST ) 119 { 120 if ( !handleRemoveEntityList( i, data, length, sender ) ) 121 return i; 122 continue; 123 } 124 if ( b == YOU_ARE_ENTITY ) 125 { 126 if ( !handleYouAreEntity( i, data, length, sender ) ) 127 return i; 128 continue; 129 } 130 } 131 132 if ( b == REQUEST_SYNC ) 133 { 134 if ( !handleRequestSync( i, data, length, sender ) ) 135 return i; 136 continue; 137 } 138 139 if ( b == REQUEST_ENTITY_LIST ) 140 { 141 PRINTF(0)("sending THE list\n"); 142 sendEntityList( sender ); 143 continue; 144 } 145 146 //if we get her something with data is wrong 147 PRINTF(1)("Data is not in the right format! i=%d\n", i); 148 return i; 149 } 150 151 return i; 48 152 } 49 153 50 154 int NetworkGameManager::readBytes(byte* data, int maxLength, int * reciever) 51 155 { 156 if ( !isServer() && !hasRequestedWorld ) 157 { 158 SYNCHELP_WRITE_BEGIN(); 159 byte b = REQUEST_ENTITY_LIST; 160 SYNCHELP_WRITE_BYTE( b ); 161 hasRequestedWorld = true; 162 PRINTF(0)("the world is enough! id=%d\n", this->getUniqueID()); 163 return SYNCHELP_WRITE_N; 164 } 165 for ( int i = 0; i<outBuffer.size(); i++ ) 166 { 167 *reciever = i; 168 if ( outBuffer[i].length>0 ) 169 { 170 int nbytes = outBuffer[i].length; 171 outBuffer[i].length = 0; 172 173 if ( nbytes > maxLength ) 174 { 175 PRINTF(1)("OutBuffer.length (%d) > (%d) networkStreamBuffer.maxLength\n", nbytes, maxLength); 176 return 0; 177 } 178 179 memcpy(data, outBuffer[i].buffer, nbytes); 180 return nbytes; 181 } 182 } 183 184 *reciever = 0; 185 int nbytes = allOutBuffer.length; 186 allOutBuffer.length = 0; 187 188 if ( nbytes <=0 ) 189 return 0; 190 191 if ( nbytes > maxLength ) 192 { 193 PRINTF(1)("OutBuffer.length (%d) > (%d) networkStreamBuffer.length\n", nbytes, maxLength); 194 return 0; 195 } 196 197 memcpy( data, allOutBuffer.buffer, nbytes ); 198 return nbytes; 52 199 } 53 200 … … 63 210 /*! 64 211 * Checks whether this is connected to a server or a client 65 * and afterwards creates the needed entity if possible212 * and afterwards creates the needed entity 66 213 * @param classID: The ID of the class of which an entity should be created 67 214 */ 68 void NetworkGameManager::createEntity(int classID) 69 { 70 } 215 void NetworkGameManager::createEntity( ClassID classID, int owner ) 216 { 217 if ( this->isServer() ) 218 { 219 if ( newUniqueID < 0 ) 220 { 221 PRINTF(1)("Cannot create entity! There are no more uniqueIDs left!\n"); 222 return; 223 } 224 225 this->executeCreateEntity( classID, newUniqueID++, owner ); 226 } 227 else 228 { 229 this->requestCreateEntity( classID ); 230 } 231 } 232 233 234 /*! 235 * Checks whether this is connected to a server or a client 236 * and afterwards creates the needed entity 237 * @param classID: The ID of the class of which an entity should be created 238 */ 239 BaseObject* NetworkGameManager::createEntity( TiXmlElement* element) 240 { 241 if ( this->isServer() ) 242 { 243 if ( newUniqueID < 0 ) 244 { 245 PRINTF(1)("Cannot create entity! There are no more uniqueIDs left!\n"); 246 return NULL; 247 } 248 newUniqueID++; 249 250 BaseObject * b = Factory::fabricate( element ); 251 252 if ( !b ) 253 { 254 PRINTF(1)("Could not fabricate Object with classID %x\n", element->Value() ); 255 return NULL; 256 } 257 258 259 if ( b->isA(CL_SYNCHRONIZEABLE) ) 260 { 261 Synchronizeable * s = dynamic_cast<Synchronizeable*>(b); 262 s->setUniqueID( newUniqueID ); 263 s->setOwner( 0 ); 264 this->networkStream->connectSynchronizeable( *s ); 265 return b; 266 } 267 else 268 { 269 PRINTF(1)("Class %s is not a synchronizeable!\n", b->getClassName() ); 270 delete b; 271 } 272 } 273 else 274 { 275 PRINTF(1)("This node is not a server and cannot create id %x\n", element->Value()); 276 } 277 return NULL; 278 } 279 71 280 72 281 /*! … … 77 286 void NetworkGameManager::removeEntity(int uniqueID) 78 287 { 288 if ( this->isServer() ) 289 { 290 this->executeRemoveEntity( uniqueID ); 291 } 292 else 293 { 294 this->requestRemoveEntity( uniqueID ); 295 } 79 296 } 80 297 … … 85 302 * @param classID: The ID of the class of which an entity should be created 86 303 */ 87 void NetworkGameManager::requestCreateEntity(int classID) 88 { 304 void NetworkGameManager::requestCreateEntity(ClassID classID) 305 { 306 if ( !writeToClientBuffer( allOutBuffer, (byte)REQUEST_CREATE ) ) 307 return; 308 if ( !writeToClientBuffer( allOutBuffer, (int)classID ) ) 309 return; 89 310 } 90 311 … … 95 316 void NetworkGameManager::requestRemoveEntity(int uniqueID) 96 317 { 318 if ( !writeToClientBuffer( allOutBuffer, (byte)REQUEST_REMOVE ) ) 319 return; 320 if ( !writeToClientBuffer( allOutBuffer, uniqueID ) ) 321 return; 97 322 } 98 323 … … 102 327 * @param classID: The ID of the class of which an entity should be created 103 328 */ 104 void NetworkGameManager::executeCreateEntity(int classID) 105 { 329 void NetworkGameManager::executeCreateEntity(ClassID classID, int uniqueID, int owner) 330 { 331 if ( !writeToClientBuffer( allOutBuffer, (byte)CREATE_ENTITY ) ) 332 return; 333 if ( !writeToClientBuffer( allOutBuffer, (int)classID ) ) 334 return; 335 if ( !writeToClientBuffer( allOutBuffer, uniqueID ) ) 336 return; 337 if ( !writeToClientBuffer( allOutBuffer, owner ) ) 338 return; 339 340 doCreateEntity( classID, uniqueID, owner ); 106 341 } 107 342 … … 113 348 void NetworkGameManager::executeRemoveEntity(int uniqueID) 114 349 { 350 if ( !writeToClientBuffer( allOutBuffer, (byte)REMOVE_ENTITY ) ) 351 return; 352 if ( !writeToClientBuffer( allOutBuffer, uniqueID ) ) 353 return; 354 355 doRemoveEntity(uniqueID); 115 356 } 116 357 … … 119 360 * @return: true if the entity can be created, false otherwise 120 361 */ 121 bool NetworkGameManager::canCreateEntity(int classID) 122 { 123 } 362 bool NetworkGameManager::canCreateEntity(ClassID classID) 363 { 364 return true; 365 } 366 367 /*! 368 * Sends the Entities to the new connected client 369 * @param userID: The ID of the user 370 */ 371 void NetworkGameManager::sendEntityList( int userID ) 372 { 373 if ( !isServer() ) 374 return; 375 376 if ( userID >= outBuffer.size() ) 377 resizeBufferVector( userID ); 378 379 SynchronizeableList::const_iterator it, e; 380 381 it = this->networkStream->getSyncBegin(); 382 e = this->networkStream->getSyncEnd(); 383 384 if ( !writeToClientBuffer( outBuffer[userID], (byte)CREATE_ENTITY_LIST ) ) 385 return; 386 387 // -2 because you must not send network_game_manager and handshake 388 if ( !writeToClientBuffer( outBuffer[userID], networkStream->getSyncCount() ) ) 389 return; 390 391 //PRINTF(0)("SendEntityList: n = %d\n", networkStream->getSyncCount()-2 ); 392 393 while ( it != e ) 394 { 395 396 if ( !writeToClientBuffer( outBuffer[userID], (int)((*it)->getLeafClassID()) ) ) 397 return; 398 //PRINTF(0)("SendEntityList: ClassID = %x\n", (*it)->getRealClassID()); 399 400 if ( !writeToClientBuffer( outBuffer[userID], (int)((*it)->getUniqueID()) ) ) 401 return; 402 403 if ( !writeToClientBuffer( outBuffer[userID], (int)((*it)->getOwner()) ) ) 404 return; 405 406 it++; 407 } 408 409 410 } 411 412 /** 413 * Creates a buffer for user n 414 * @param n The ID of the user 415 */ 416 void NetworkGameManager::resizeBufferVector( int n ) 417 { 418 for ( int i = outBuffer.size(); i<=n; i++) 419 { 420 clientBuffer outBuf; 421 422 outBuf.length = 0; 423 424 outBuf.maxLength = 5*1024; 425 426 outBuf.buffer = new byte[5*1014]; 427 428 outBuffer.push_back(outBuf); 429 } 430 } 431 432 /** 433 * Creates the entity on this host 434 * @param classID: ClassID of the entity to create 435 * @param uniqueID: Unique ID to assign to the synchronizeable 436 * @param owner: owner of this synchronizealbe 437 */ 438 void NetworkGameManager::doCreateEntity( ClassID classID, int uniqueID, int owner ) 439 { 440 BaseObject * b = Factory::fabricate( classID ); 441 442 if ( !b ) 443 { 444 PRINTF(1)("Could not fabricate Object with classID %x\n", classID); 445 return; 446 } 447 448 if ( b->isA(CL_SYNCHRONIZEABLE) ) 449 { 450 Synchronizeable * s = dynamic_cast<Synchronizeable*>(b); 451 s->setUniqueID( uniqueID ); 452 s->setOwner( owner ); 453 this->networkStream->connectSynchronizeable( *s ); 454 if ( !isServer() ) 455 s->setIsOutOfSync( true ); 456 PRINTF(0)("Fabricated %s with id %d\n", s->getClassName(), s->getUniqueID()); 457 } 458 else 459 { 460 PRINTF(1)("Class with ID %x is not a synchronizeable!", (int)classID); 461 delete b; 462 } 463 } 464 465 /** 466 * Removes a entity on this host 467 * @param uniqueID: unique ID assigned with the entity to remove 468 */ 469 void NetworkGameManager::doRemoveEntity( int uniqueID ) 470 { 471 SynchronizeableList::const_iterator it,e; 472 it = this->networkStream->getSyncBegin(); 473 e = this->networkStream->getSyncEnd(); 474 475 while ( it != e ) 476 { 477 if ( (*it)->getUniqueID() == uniqueID ) 478 { 479 delete *it; 480 break; 481 } 482 it++; 483 } 484 } 485 486 /** 487 * Tell the synchronizeable that a user's synchronizeable is out of sync 488 * @param uniqueID: unique ID assigned with the entity which is out of sync 489 * @param userID: user ID who's synchronizeable is out of sync 490 */ 491 void NetworkGameManager::doRequestSync( int uniqueID, int userID ) 492 { 493 SynchronizeableList::const_iterator it,e; 494 it = this->networkStream->getSyncBegin(); 495 e = this->networkStream->getSyncEnd(); 496 497 while ( it != e ) 498 { 499 if ( (*it)->getUniqueID() == uniqueID ) 500 { 501 (*it)->requestSync( userID ); 502 break; 503 } 504 it++; 505 } 506 } 507 508 /** 509 * Copies length bytes to the clientBuffer with error checking 510 * @param clientBuffer: the clientBuffer to write to 511 * @param data: buffer to the data 512 * @param length: length of data 513 * @return false on error true else 514 */ 515 bool NetworkGameManager::writeToClientBuffer( clientBuffer &cb, byte * data, int length ) 516 { 517 if ( length > cb.maxLength-cb.length ) 518 { 519 PRINTF(1)("No space left in clientBuffer\n"); 520 return false; 521 } 522 523 memcpy( cb.buffer+cb.length, data, length ); 524 return true; 525 } 526 527 /** 528 * Reads data from clientBuffer with error checking 529 * @param clientBuffer: the clientBuffer to read from 530 * @param data: pointer to the buffer 531 * @param length: 532 * @return 533 */ 534 bool NetworkGameManager::readFromClientBuffer( clientBuffer &cb, byte * data, int length ) 535 { 536 if ( cb.length < length ) 537 { 538 PRINTF(0)("There is not enough data in clientBuffer\n"); 539 return 0; 540 } 541 542 memcpy( data, cb.buffer+cb.length-length, length ); 543 return true; 544 } 545 546 /** 547 * Tells this client that he has to control this entity 548 * @param uniqueID: the entity's uniqeID 549 */ 550 void NetworkGameManager::doYouAre( int uniqueID ) 551 { 552 //TODO: what has to be done 553 } 554 555 /** 556 * Tells a remote client that he has to control this entity 557 * @param uniqueID: the entity's uniqeID 558 * @param userID: the users ID 559 */ 560 void NetworkGameManager::sendYouAre( int uniqueID, int userID ) 561 { 562 if ( !isServer() ) 563 return; 564 565 if ( userID != 0 ) 566 { 567 if ( !writeToClientBuffer( outBuffer[userID], (byte)YOU_ARE_ENTITY ) ) 568 return; 569 570 if ( !writeToClientBuffer( outBuffer[userID], uniqueID ) ) 571 return; 572 } 573 else 574 { 575 doYouAre(uniqueID); 576 } 577 } 578 579 bool NetworkGameManager::handleRequestCreate( int & i, const byte * data, int length, int sender ) 580 { 581 if ( INTSIZE > length-i ) 582 { 583 PRINTF(1)("Cannot read classID from buffer! Not enough data left!\n"); 584 return false; 585 } 586 int classID; 587 i += Converter::byteArrayToInt( &data[i], &classID ); 588 589 createEntity( (ClassID)classID ); 590 591 return true; 592 } 593 594 bool NetworkGameManager::handleRequestRemove( int & i, const byte * data, int length, int sender ) 595 { 596 if ( INTSIZE > length-i ) 597 { 598 PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n"); 599 return false; 600 } 601 int uniqueID; 602 i += Converter::byteArrayToInt( &data[i], &uniqueID ); 603 604 removeEntity( uniqueID ); 605 606 return true; 607 } 608 609 bool NetworkGameManager::handleCreateEntity( int & i, const byte * data, int length, int sender ) 610 { 611 if ( INTSIZE > length-i ) 612 { 613 PRINTF(1)("Cannot read classID from buffer! Not enough data left!\n"); 614 return false; 615 } 616 int classID; 617 i += Converter::byteArrayToInt( &data[i], &classID ); 618 619 if ( INTSIZE > length-i ) 620 { 621 PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n"); 622 return false; 623 } 624 int uniqueID; 625 i += Converter::byteArrayToInt( &data[i], &uniqueID ); 626 627 if ( INTSIZE > length-i ) 628 { 629 PRINTF(1)("Cannot read owner from buffer! Not enough data left!\n"); 630 return false; 631 } 632 int owner; 633 i += Converter::byteArrayToInt( &data[i], &owner ); 634 635 doCreateEntity( (ClassID)classID, uniqueID, owner ); 636 637 return true; 638 } 639 640 bool NetworkGameManager::handleRemoveEntity( int & i, const byte * data, int length, int sender ) 641 { 642 if ( INTSIZE > length-i ) 643 { 644 PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n"); 645 return false; 646 } 647 int uniqueID; 648 i += Converter::byteArrayToInt( &data[i], &uniqueID ); 649 650 doRemoveEntity( uniqueID ); 651 652 return true; 653 } 654 655 bool NetworkGameManager::handleCreateEntityList( int & i, const byte * data, int length, int sender ) 656 { 657 if ( INTSIZE > length-i ) 658 { 659 PRINTF(1)("Cannot read n from buffer! Not enough data left!\n"); 660 return false; 661 } 662 663 PRINTF(0)("HandleCreateEntityList: data[i..i+3] = %d %d %d %d\n", data[i], data[i+1], data[i+2], data[i+3]); 664 665 int n; 666 i += Converter::byteArrayToInt( &data[i], &n ); 667 668 669 PRINTF(0)("HandleCreateEntityList: n = %d\n", n); 670 671 int classID, uniqueID, owner; 672 673 for ( int j = 0; j<n; j++ ) 674 { 675 676 if ( INTSIZE > length-i ) 677 { 678 PRINTF(1)("Cannot read classID from buffer! Not enough data left!\n"); 679 return false; 680 } 681 i += Converter::byteArrayToInt( &data[i], &classID ); 682 683 if ( INTSIZE > length-i ) 684 { 685 PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n"); 686 return false; 687 } 688 i += Converter::byteArrayToInt( &data[i], &uniqueID ); 689 690 if ( INTSIZE > length-i ) 691 { 692 PRINTF(1)("Cannot read owner from buffer! Not enough data left!\n"); 693 return false; 694 } 695 i += Converter::byteArrayToInt( &data[i], &owner ); 696 697 if ( classID != CL_NETWORK_GAME_MANAGER && classID != CL_HANDSHAKE ) 698 doCreateEntity( (ClassID)classID, uniqueID, owner ); 699 700 } 701 return true; 702 } 703 704 bool NetworkGameManager::handleRemoveEntityList( int & i, const byte * data, int length, int sender ) 705 { 706 if ( INTSIZE > length-i ) 707 { 708 PRINTF(1)("Cannot read n from buffer! Not enough data left!\n"); 709 return false; 710 } 711 int n; 712 i += Converter::byteArrayToInt( &data[i], &n ); 713 714 int uniqueID; 715 716 for ( int j = 0; j<n; j++ ) 717 { 718 719 if ( INTSIZE > length-i ) 720 { 721 PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n"); 722 return false; 723 } 724 i += Converter::byteArrayToInt( &data[i], &uniqueID ); 725 726 doRemoveEntity( uniqueID ); 727 } 728 729 return true; 730 } 731 732 bool NetworkGameManager::handleYouAreEntity( int & i, const byte * data, int length, int sender ) 733 { 734 if ( INTSIZE > length-i ) 735 { 736 PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n"); 737 return false; 738 } 739 740 int uniqueID; 741 i += Converter::byteArrayToInt( &data[i], &uniqueID ); 742 743 doYouAre( uniqueID ); 744 745 return true; 746 } 747 748 bool NetworkGameManager::handleRequestSync( int & i, const byte * data, int length, int sender ) 749 { 750 if ( INTSIZE > length-i ) 751 { 752 PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n"); 753 return false; 754 } 755 int uniqueID; 756 i += Converter::byteArrayToInt( &data[i], &uniqueID ); 757 758 doRequestSync( uniqueID, sender ); 759 760 return true; 761 } 762 763 bool NetworkGameManager::writeToClientBuffer( clientBuffer & cb, byte b ) 764 { 765 if ( cb.maxLength-cb.length < 1 ) 766 { 767 PRINTF(1)("Cannot write to clientBuffer! Not enough space for 1 byte\n"); 768 return false; 769 } 770 771 cb.buffer[cb.length++] = b; 772 773 return true; 774 } 775 776 bool NetworkGameManager::writeToClientBuffer( clientBuffer & cb, int i ) 777 { 778 int n = Converter::intToByteArray( i, cb.buffer+cb.length, cb.maxLength-cb.length ); 779 cb.length += n; 780 781 if ( n <= 0 ) 782 { 783 PRINTF(1)("Cannot write to clientBuffer! Not enough space for 1 int\n"); 784 return false; 785 } 786 787 return true; 788 } 789 790 void NetworkGameManager::sync( int uniqueID, int owner ) 791 { 792 if ( owner==this->getHostID() ) 793 return; 794 795 if ( !isServer() ) 796 executeRequestSync( uniqueID, 0 ); 797 else 798 executeRequestSync( uniqueID, owner ); 799 } 800 801 void NetworkGameManager::executeRequestSync( int uniqueID, int user ) 802 { 803 if ( user >= outBuffer.size() ) 804 resizeBufferVector( user ); 805 806 if ( !writeToClientBuffer( outBuffer[user], (byte)REQUEST_SYNC ) ) 807 return; 808 if ( !writeToClientBuffer( outBuffer[user], uniqueID ) ) 809 return; 810 } 811
Note: See TracChangeset
for help on using the changeset viewer.