Changeset 9406 in orxonox.OLD for trunk/src/lib/network/synchronizeable.cc
- Timestamp:
- Jul 24, 2006, 11:09:47 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/network/synchronizeable.cc
r9110 r9406 11 11 12 12 ### File Specific: 13 main-programmer: Silvan Nellen14 co-programmer: Benjamin Wuest13 main-programmer: Christoph Renner (rennerc@ee.ethz.ch) 14 co-programmer: Patrick Boenzli (patrick@orxonox.ethz.ch) 15 15 */ 16 16 … … 29 29 #include "synchronizeable.h" 30 30 31 #include "converter.h" 32 31 33 32 34 … … 38 40 this->setClassID(CL_SYNCHRONIZEABLE, "Synchronizeable"); 39 41 this->owner = 0; 40 this->setIsServer(SharedNetworkData::getInstance()->getHostID() == 0);42 // this->setIsServer(SharedNetworkData::getInstance()->getHostID() == 0); 41 43 this->uniqueID = NET_UID_UNASSIGNED; 42 44 this->networkStream = NULL; 43 45 this->bSynchronize = false; 44 46 45 47 if( State::isOnline()) 46 48 { … … 54 56 assert( syncVarList.size() == 0 ); 55 57 mLeafClassId = this->registerVarId( new SynchronizeableInt( (int*)&this->getLeafClassID(), (int*)&this->getLeafClassID(), "leafClassId" ) ); 56 58 57 59 this->registerVar( new SynchronizeableInt( &this->owner, &this->owner, "owner" ) ); 58 60 this->registerVar( new SynchronizeableString( &this->objectName, &this->objectName, "objectName" ) ); … … 69 71 { 70 72 this->networkStream->disconnectSynchronizeable(*this); 71 72 if ( this->isServer() && this->beSynchronized() && this->getUniqueID() > 0 && !this->isA( CL_MESSAGE_MANAGER ) ) 73 74 if ( (SharedNetworkData::getInstance()->isMasterServer() || SharedNetworkData::getInstance()->isProxyServer() ) 75 && this->beSynchronized() && this->getUniqueID() > 0 && !this->isA( CL_MESSAGE_MANAGER ) ) 73 76 NetworkGameManager::getInstance()->removeSynchronizeable( this->getUniqueID() ); 74 77 } 75 78 76 79 for ( SyncVarList::iterator it = syncVarList.begin(); it != syncVarList.end(); it++ ) 77 80 { … … 79 82 } 80 83 syncVarList.clear(); 81 84 82 85 for ( UserStateHistory::iterator it = recvStates.begin(); it != recvStates.end(); it++ ) 83 86 { … … 93 96 94 97 } 95 98 96 99 for ( UserStateHistory::iterator it = sentStates.begin(); it != sentStates.end(); it++ ) 97 100 { … … 105 108 delete *it2; 106 109 } 107 108 } 109 } 110 111 /** 112 * Sets the server flag to a given value 113 * @param isServer: the boolean value which the server flag is to set to 114 */ 115 void Synchronizeable::setIsServer(bool isServer) 116 { 117 if( isServer ) 118 this->state = this->state | STATE_SERVER; 119 else 120 this->state = this->state & (~STATE_SERVER); 121 } 122 123 124 /** 125 * Determines if the server flag is set 126 * @return true, if the server flag is true, false else 127 */ 128 bool Synchronizeable::isServer() 129 { 130 return (this->state & STATE_SERVER) >0; 131 } 132 133 134 110 } 111 } 112 113 114 115 /** 116 * creates a diff image from two states 117 * @param userId: the userid of the user where the image will be sent to 118 * @param data: the binary data array to write to 119 * @param maxLength: maximal length of the data written (length of available space in the array) 120 * @param stateId: the state id that this diff will represent 121 * @param priorityTH: the priority threshold: all syncs below this threshold won't be synchronized 122 * 123 * @todo check for permissions 124 */ 135 125 int Synchronizeable::getStateDiff( int userId, byte* data, int maxLength, int stateId, int fromStateId, int priorityTH ) 136 126 { … … 169 159 (*it2)->data = NULL; 170 160 } 171 161 172 162 delete *it2; 173 163 } … … 181 171 while ( it != sentStates[userId].end() && (*it)->stateId != fromStateId ) 182 172 it++; 183 184 // if ( getLeafClassID() == CL_SPACE_SHIP )185 // {186 // PRINTF(0)("getStateDiff:SpaceShip from: %d stateId: %d\n", (it == sentStates[userId].end())?-1:fromStateId, stateId);187 // }188 173 189 174 if ( it == sentStates[userId].end() ) … … 196 181 197 182 stateFrom = initialEntry; 198 183 199 184 sentStates[userId].push_back( stateFrom ); 200 185 } … … 205 190 206 191 sentStates[userId].push_back( stateTo ); 207 192 208 193 stateTo->stateId = stateId; 209 194 stateTo->dataLength = neededSize; … … 214 199 int i = 0; 215 200 int n; 216 217 bool hasPermission ;201 202 bool hasPermission = false; 218 203 bool sizeChanged = false; 219 204 … … 221 206 for ( SyncVarList::iterator it = syncVarList.begin(); it != syncVarList.end(); it++ ) 222 207 { 223 hasPermission = ( 224 this->isServer() && (*it)->checkPermission( PERMISSION_SERVER ) || 225 this->owner == SharedNetworkData::getInstance()->getHostID() && (*it)->checkPermission( PERMISSION_OWNER ) || 226 this->isServer() && this->owner != userId && (*it)->checkPermission( PERMISSION_OWNER ) || 227 (*it)->checkPermission( PERMISSION_ALL ) 228 ); 229 230 if ( sizeIter == stateFrom->sizeList.end() || *sizeIter != (*it)->getSize() ) 208 // DATA PERMISSIONS 209 // check if this synchronizeable has the permissions to write the data 210 211 // first check MASTER_SERVER permissions 212 if( SharedNetworkData::getInstance()->isMasterServer() && (*it)->checkPermission( PERMISSION_MASTER_SERVER )) 213 hasPermission = true; 214 // now check PROXY_SERVER permissions 215 else if( SharedNetworkData::getInstance()->isProxyServer() && (*it)->checkPermission( PERMISSION_MASTER_SERVER )) 216 hasPermission = true; 217 // now check OWNER permissions 218 else if( this->owner == SharedNetworkData::getInstance()->getHostID() && (*it)->checkPermission( PERMISSION_OWNER )) 219 hasPermission = true; 220 // now check ALL permissions 221 else if( (*it)->checkPermission( PERMISSION_ALL )) 222 hasPermission = true; 223 // SPECIAL: get write permissions if i am master server and i am able to overwrite the client stuff 224 else if( SharedNetworkData::getInstance()->isMasterServer() && this->owner != userId && (*it)->checkPermission( PERMISSION_OWNER )) 225 hasPermission = true; 226 // SPECIAL: get write permissions if i am proxy server and i am able to overwrite the client stuff 227 else if( SharedNetworkData::getInstance()->isProxyServer() && this->owner != userId && (*it)->checkPermission( PERMISSION_OWNER )) 228 hasPermission = true; 229 else 230 hasPermission = false; 231 232 233 if ( sizeIter == stateFrom->sizeList.end() || *sizeIter != (*it)->getSize() ) 231 234 sizeChanged = true; 232 235 233 236 if ( ( hasPermission && (*it)->getPriority() >= priorityTH ) || sizeChanged ) 234 237 { 235 238 n = (*it)->writeToBuf( stateTo->data+i, stateTo->dataLength - i ); 236 239 //NETPRINTF(0)("getvar %s %d\n", (*it)->getName().c_str(), n); 240 //PRINTF(0)("getvar %s %d\n", (*it)->getName().c_str(), n); 237 241 stateTo->sizeList.push_back( n ); 238 //(*it)->debug(); 242 // this is only for very hardcore debug sessions 243 // (*it)->debug(); 239 244 i += n; 240 245 } … … 257 262 if ( i != neededSize ) 258 263 { 259 PRINTF(0)("strange error: (%s) %d != %d\n", this->getClass Name(), i, neededSize);264 PRINTF(0)("strange error: (%s) %d != %d\n", this->getClassCName(), i, neededSize); 260 265 assert(false); 261 266 } … … 281 286 * @param fromStateId id of the base state id 282 287 * @return number bytes read 288 * 283 289 * @todo check for permissions 284 290 */ … … 299 305 StateHistoryEntry * stateFrom = NULL; 300 306 307 // search the state from wich the diff is made of 301 308 StateHistory::iterator it = recvStates[userId].begin(); 302 309 while ( it != recvStates[userId].end() && (*it)->stateId != fromStateId ) 303 310 it++; 304 311 305 306 // if ( getLeafClassID() == CL_SPACE_SHIP ) 307 // { 308 // PRINTF(0)("setStateDiff:SpaceShip from: %d stateId: %d\n", (it == recvStates[userId].end())?-1:fromStateId, stateId); 309 // } 310 312 // if this is the first state to receive 311 313 if ( it == recvStates[userId].end() ) 312 314 { … … 318 320 319 321 stateFrom = initialEntry; 320 322 321 323 recvStates[userId].push_back( stateFrom ); 322 324 } 323 325 else 324 326 stateFrom = (*it); 325 326 //apply diff 327 328 329 // apply diff 327 330 for ( int i = 0; i<length; i++ ) 328 331 { … … 331 334 else 332 335 stateTo->data[i] = data[i]; 333 334 } 335 336 } 337 336 338 //add state to state history 337 339 recvStates[userId].push_back( stateTo ); 338 340 339 341 int i = 0; 340 342 int n = 0; 341 343 std::list<int> changes; 342 344 bool hasPermission = false; 345 346 // extract the new state for every client 343 347 for ( SyncVarList::iterator it = syncVarList.begin(); it != syncVarList.end(); it++ ) 344 348 { 345 if ( 346 (*it)->checkPermission( PERMISSION_SERVER ) && networkStream->isUserServer( userId ) || 347 (*it)->checkPermission( PERMISSION_OWNER ) && this->owner == userId || 348 networkStream->isUserServer( userId ) && this->owner != SharedNetworkData::getInstance()->getHostID() && (*it)->checkPermission( PERMISSION_OWNER ) || 349 (*it)->checkPermission( PERMISSION_ALL ) 350 ) 349 // DATA PERMISSIONS 350 // check if this synchronizeable has the permissions to write the data 351 352 // first check MASTER_SERVER permissions 353 if( this->networkStream->isUserMasterServer( userId ) && (*it)->checkPermission( PERMISSION_MASTER_SERVER )) 354 hasPermission = true; 355 // now check PROXY_SERVER permissions 356 else if( this->networkStream->isUserProxyServer( userId ) && (*it)->checkPermission( PERMISSION_MASTER_SERVER )) 357 hasPermission = true; 358 // now check OWNER permissions 359 else if( this->owner == userId && (*it)->checkPermission( PERMISSION_OWNER )) 360 hasPermission = true; 361 // now check ALL permissions 362 else if( (*it)->checkPermission( PERMISSION_ALL )) 363 hasPermission = true; 364 // SPECIAL: get write permissions if im sending to a master server that does not own this sync 365 else if( this->networkStream->isUserMasterServer( userId ) && this->owner != SharedNetworkData::getInstance()->getHostID() && (*it)->checkPermission( PERMISSION_OWNER )) 366 hasPermission = true; 367 // SPECIAL: get write permissions if im sending to a proxy server that does not own this sync 368 else if( this->networkStream->isUserProxyServer( userId ) && this->owner != SharedNetworkData::getInstance()->getHostID() && (*it)->checkPermission( PERMISSION_OWNER )) 369 hasPermission = true; 370 else 371 hasPermission = false; 372 373 374 375 // if it has the permission to write do it 376 if( hasPermission) 351 377 { 352 378 n = (*it)->readFromBuf( stateTo->data + i, stateTo->dataLength - i ); 353 379 i += n; 354 //NETPRINTF(0)("%s::setvar %s %d\n", getClassName(), (*it)->getName().c_str(), n); 380 //NETPRINTF(0)("%s::setvar %s %d\n", getClassCName(), (*it)->getName().c_str(), n); 381 //PRINTF(0)("%s::setvar %s %d\n", getClassCName(), (*it)->getName().c_str(), n); 355 382 //(*it)->debug(); 356 383 if ( (*it)->getHasChanged() ) … … 361 388 else 362 389 { 363 // PRINTF(0)("DONT SET VAR BECAUSE OF PERMISSION: %s %d %d %d %d %d %d\n", (*it)->getName().c_str(), (*it)->checkPermission( PERMISSION_ SERVER ), (*it)->checkPermission( PERMISSION_OWNER ), (*it)->checkPermission( PERMISSION_ALL ), networkStream->isUserServer( userId ), this->owner, userId );390 // PRINTF(0)("DONT SET VAR BECAUSE OF PERMISSION: %s %d %d %d %d %d %d\n", (*it)->getName().c_str(), (*it)->checkPermission( PERMISSION_MASTER_SERVER ), (*it)->checkPermission( PERMISSION_OWNER ), (*it)->checkPermission( PERMISSION_ALL ), networkStream->isUserServer( userId ), this->owner, userId ); 364 391 n = (*it)->getSizeFromBuf( stateTo->data + i, stateTo->dataLength - i ); 365 //NETPRINTF(0)("%s::setvar %s %d\n", getClass Name(), (*it)->getName().c_str(), n);392 //NETPRINTF(0)("%s::setvar %s %d\n", getClassCName(), (*it)->getName().c_str(), n); 366 393 //(*it)->debug(); 367 394 i += n; … … 370 397 371 398 this->varChangeHandler( changes ); 372 399 373 400 return i; 374 401 } … … 423 450 (*it)->data = NULL; 424 451 } 425 452 426 453 delete *it; 427 454 } 428 455 recvStates[userId].clear(); 429 456 } 430 457 431 458 if ( sentStates.size() > userId ) 432 459 { 433 460 434 461 for ( std::list<StateHistoryEntry*>::iterator it = sentStates[userId].begin(); it != sentStates[userId].end(); it++ ) 435 462 { … … 439 466 (*it)->data = NULL; 440 467 } 441 468 442 469 delete *it; 443 470 } … … 448 475 /** 449 476 * this function is called after recieving a state. 450 * @param userId 451 * @param stateId 452 * @param fromStateId 477 * @param userId 478 * @param stateId 479 * @param fromStateId 453 480 */ 454 481 void Synchronizeable::handleRecvState( int userId, int stateId, int fromStateId ) … … 457 484 if ( recvStates.size() <= userId ) 458 485 recvStates.resize( userId+1 ); 459 486 460 487 //remove old states 461 488 StateHistory::iterator it = recvStates[userId].begin(); … … 485 512 StateHistory::iterator delIt = it; 486 513 it ++; 487 514 488 515 if ( (*delIt)->data ) 489 516 { … … 493 520 delete *delIt; 494 521 recvStates[userId].erase( delIt ); 495 522 496 523 continue; 497 524 } 498 525 it++; 499 526 } 500 527 501 528 StateHistory::iterator fromState = recvStates[userId].end(); 502 529 StateHistory::iterator toState = recvStates[userId].end(); 503 530 504 531 for ( it = recvStates[userId].begin(); it != recvStates[userId].end(); it++ ) 505 532 { … … 508 535 if ( (*it)->stateId == fromStateId ) 509 536 fromState = it; 510 537 511 538 if ( fromState != recvStates[userId].end() && toState != recvStates[userId].end() ) 512 539 break; 513 540 } 514 541 515 542 // setStateDiff was not called and i know fromStateId 516 543 if ( fromState != recvStates[userId].end() && toState == recvStates[userId].end() ) 517 544 { 518 545 StateHistoryEntry * entry = new StateHistoryEntry; 519 546 520 547 entry->dataLength = (*fromState)->dataLength; 521 548 if ( entry->dataLength > 0 ) 522 549 { 523 550 entry->data = new byte[entry->dataLength]; 524 551 525 552 assert( (*fromState)->data ); 526 553 memcpy( entry->data, (*fromState)->data, entry->dataLength ); … … 528 555 else 529 556 entry->data = NULL; 530 557 531 558 entry->sizeList = (*fromState)->sizeList; 532 559 entry->stateId = stateId; 533 560 534 561 recvStates[userId].push_back(entry); 535 562 } … … 538 565 /** 539 566 * this function is called after sending a state 540 * @param userId 541 * @param stateId 542 * @param fromStateId 567 * @param userId 568 * @param stateId 569 * @param fromStateId 543 570 */ 544 571 void Synchronizeable::handleSentState( int userId, int stateId, int fromStateId ) … … 557 584 StateHistory::iterator delIt = it; 558 585 it ++; 559 586 560 587 if ( (*delIt)->data ) 561 588 { … … 565 592 delete *delIt; 566 593 sentStates[userId].erase( delIt ); 567 594 568 595 continue; 569 596 } … … 571 598 } 572 599 573 600 574 601 StateHistory::iterator fromState = sentStates[userId].end(); 575 602 StateHistory::iterator toState = sentStates[userId].end(); 576 603 577 604 for ( it = sentStates[userId].begin(); it != sentStates[userId].end(); it++ ) 578 605 { … … 581 608 if ( (*it)->stateId == fromStateId ) 582 609 fromState = it; 583 610 584 611 if ( fromState != sentStates[userId].end() && toState != sentStates[userId].end() ) 585 612 break; 586 613 } 587 614 588 615 589 616 // getStateDiff was not called and i know fromStateId 590 617 if ( fromState != sentStates[userId].end() && toState == sentStates[userId].end() ) 591 618 { 592 619 StateHistoryEntry * entry = new StateHistoryEntry; 593 620 594 621 entry->dataLength = (*fromState)->dataLength; 595 622 if ( entry->dataLength > 0 ) 596 623 { 597 624 entry->data = new byte[entry->dataLength]; 598 625 599 626 assert( (*fromState)->data ); 600 627 memcpy( entry->data, (*fromState)->data, entry->dataLength ); … … 602 629 else 603 630 entry->data = NULL; 604 631 605 632 entry->sizeList = (*fromState)->sizeList; 606 633 entry->stateId = stateId; 607 634 608 635 sentStates[userId].push_back(entry); 609 636 } 610 611 } 612 613 614 637 638 } 639 640 641
Note: See TracChangeset
for help on using the changeset viewer.