Changeset 1907 for code/trunk/src/network/packet/Gamestate.cc
- Timestamp:
- Oct 12, 2008, 7:40:47 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk/src/network/packet/Gamestate.cc
r1767 r1907 46 46 #define HEADER GAMESTATE_HEADER(data_) 47 47 48 49 #define PACKET_FLAG_GAMESTATE ENET_PACKET_FLAG_RELIABLE 50 48 51 Gamestate::Gamestate() 49 52 { 50 } 51 52 Gamestate::Gamestate(unsigned char *data, int clientID): 53 flags_ = flags_ | PACKET_FLAG_GAMESTATE; 54 } 55 56 Gamestate::Gamestate(uint8_t *data, unsigned int clientID): 53 57 Packet(data, clientID) 54 58 { 59 flags_ = flags_ | PACKET_FLAG_GAMESTATE; 60 } 61 62 Gamestate::Gamestate(uint8_t *data) 63 { 64 flags_ = flags_ | PACKET_FLAG_GAMESTATE; 65 data_=data; 55 66 } 56 67 … … 74 85 return false; 75 86 } 76 87 88 #ifndef NDEBUG 89 std::list<Synchronisable*> slist; 90 std::list<Synchronisable*>::iterator iit; 91 #endif 77 92 //start collect data synchronisable by synchronisable 78 u nsigned char*mem=data_;93 uint8_t *mem=data_; 79 94 mem+=sizeof(GamestateHeader); 80 95 orxonox::ObjectList<Synchronisable>::iterator it; 81 96 for(it = orxonox::ObjectList<Synchronisable>::begin(); it; ++it){ 82 tempsize=it->getSize 2(id, mode);97 tempsize=it->getSize(id, mode); 83 98 84 99 if(currentsize+tempsize > size){ … … 88 103 int addsize=tempsize; 89 104 while(++temp) 90 addsize+=temp->getSize 2(id, mode);91 data_ = (u nsigned char*)realloc(data_, sizeof(GamestateHeader) + currentsize + addsize);105 addsize+=temp->getSize(id, mode); 106 data_ = (uint8_t *)realloc(data_, sizeof(GamestateHeader) + currentsize + addsize); 92 107 if(!data_) 93 108 return false; … … 95 110 }// stop allocate additional memory 96 111 112 #ifndef NDEBUG 113 for(iit=slist.begin(); iit!=slist.end(); iit++) 114 assert((*iit)!=*it); 115 slist.push_back(*it); 116 #endif 117 118 //if(it->doSelection(id)) 119 dataMap_[mem-data_]=(*it); // save the mem location of the synchronisable data 97 120 if(!it->getData(mem, id, mode)) 98 121 return false; // mem pointer gets automatically increased because of call by reference … … 105 128 HEADER->packetType = ENUM::Gamestate; 106 129 assert( *(ENUM::Type *)(data_) == ENUM::Gamestate); 107 HEADER-> normsize = currentsize;130 HEADER->datasize = currentsize; 108 131 HEADER->id = id; 109 132 HEADER->diffed = false; … … 122 145 assert(!HEADER->compressed); 123 146 assert(!HEADER->diffed); 124 unsigned int size, objectID, classID; 125 unsigned char *mem=data_+sizeof(GamestateHeader); 147 uint8_t *mem=data_+sizeof(GamestateHeader); 126 148 // get the start of the Synchronisable list 127 orxonox::ObjectList<Synchronisable>::iterator it=orxonox::ObjectList<Synchronisable>::begin(); 128 129 while(mem < data_+sizeof(GamestateHeader)+HEADER->normsize){ 130 // extract synchronisable header 131 size = *(unsigned int *)mem; 132 objectID = *(unsigned int*)(mem+sizeof(unsigned int)); 133 classID = *(unsigned int*)(mem+2*sizeof(unsigned int)); 134 135 if(!it || it->objectID!=objectID || it->classID!=classID){ 136 // bad luck ;) 137 // delete the synchronisable (obviously seems to be deleted on the server) 138 while(it && it->objectID!=objectID) 139 removeObject(it); 140 141 if(!it){ 142 //fabricate the new synchronisable 143 if(!Synchronisable::fabricate(mem, mode)) 144 return false; 145 it=orxonox::ObjectList<Synchronisable>::end(); 146 }else{ 147 if(! it->updateData(mem, mode)) 148 { 149 COUT(1) << "We couldn't update objectID: " \ 150 << objectID << "; classID: " << classID << std::endl; 151 } 152 } 153 } else 149 //orxonox::ObjectList<Synchronisable>::iterator it=orxonox::ObjectList<Synchronisable>::begin(); 150 Synchronisable *s; 151 152 // update the data of the objects we received 153 while(mem < data_+sizeof(GamestateHeader)+HEADER->datasize){ 154 synchronisableHeader *objectheader = (synchronisableHeader*)mem; 155 156 s = Synchronisable::getSynchronisable( objectheader->objectID ); 157 if(!s) 154 158 { 155 // we have our object 156 if(! it->updateData(mem, mode)) 157 { 158 COUT(1) << "We couldn't update objectID: " \ 159 << objectID << "; classID: " << classID << std::endl; 160 } 161 } 162 ++it; 159 s = Synchronisable::fabricate(mem, mode); 160 assert(s); 161 // if(!s) 162 // return false; 163 } 164 else 165 { 166 bool b = s->updateData(mem, mode); 167 assert(b); 168 //if(!s->updateData(mem, mode)) 169 //return false; 170 } 163 171 } 164 172 165 173 return true; 166 174 } 175 176 167 177 168 178 int Gamestate::getID(){ … … 177 187 else 178 188 { 179 return HEADER-> normsize+sizeof(GamestateHeader);189 return HEADER->datasize+sizeof(GamestateHeader); 180 190 } 181 191 } 182 192 183 193 bool Gamestate::operator==(packet::Gamestate gs){ 184 u nsigned char*d1 = data_+sizeof(GamestateHeader);185 u nsigned char*d2 = gs.data_+sizeof(GamestateHeader);194 uint8_t *d1 = data_+sizeof(GamestateHeader); 195 uint8_t *d2 = gs.data_+sizeof(GamestateHeader); 186 196 assert(!isCompressed()); 187 197 assert(!gs.isCompressed()); 188 while(d1<data_+HEADER-> normsize)198 while(d1<data_+HEADER->datasize) 189 199 { 190 200 if(*d1!=*d2) … … 201 211 } 202 212 213 214 203 215 bool Gamestate::compressData() 204 216 { 205 217 assert(HEADER); 206 218 assert(!HEADER->compressed); 207 uLongf buffer = (uLongf)(((HEADER-> normsize + 12)*1.01)+1);219 uLongf buffer = (uLongf)(((HEADER->datasize + 12)*1.01)+1); 208 220 if(buffer==0) 209 221 return false; 210 222 211 u nsigned char *ndata = new unsigned char[buffer+sizeof(GamestateHeader)];212 u nsigned char*dest = GAMESTATE_START(ndata);223 uint8_t *ndata = new uint8_t[buffer+sizeof(GamestateHeader)]; 224 uint8_t *dest = GAMESTATE_START(ndata); 213 225 //unsigned char *dest = new unsigned char[buffer]; 214 u nsigned char*source = GAMESTATE_START(data_);226 uint8_t *source = GAMESTATE_START(data_); 215 227 int retval; 216 retval = compress( dest, &buffer, source, (uLong)(HEADER-> normsize) );228 retval = compress( dest, &buffer, source, (uLong)(HEADER->datasize) ); 217 229 switch ( retval ) { 218 230 case Z_OK: COUT(5) << "G.St.Man: compress: successfully compressed" << std::endl; break; … … 223 235 #ifndef NDEBUG 224 236 //decompress and compare the start and the decompressed data 225 u nsigned char *rdata = new unsigned char[HEADER->normsize+sizeof(GamestateHeader)];226 u nsigned char*d2 = GAMESTATE_START(rdata);227 uLongf length2 = HEADER-> normsize;237 uint8_t *rdata = new uint8_t[HEADER->datasize+sizeof(GamestateHeader)]; 238 uint8_t *d2 = GAMESTATE_START(rdata); 239 uLongf length2 = HEADER->datasize; 228 240 uncompress(d2, &length2, dest, buffer); 229 for(unsigned int i=0; i<HEADER-> normsize; i++){241 for(unsigned int i=0; i<HEADER->datasize; i++){ 230 242 assert(*(source+i)==*(d2+i)); 231 243 } … … 235 247 //copy and modify header 236 248 #ifndef NDEBUG 237 HEADER->crc32 = calcCRC(data_+sizeof(GamestateHeader), HEADER-> normsize);249 HEADER->crc32 = calcCRC(data_+sizeof(GamestateHeader), HEADER->datasize); 238 250 #endif 239 251 *GAMESTATE_HEADER(ndata) = *HEADER; … … 245 257 HEADER->compressed = true; 246 258 assert(HEADER->compressed); 247 COUT(3) << "gamestate compress normsize: " << HEADER->normsize << " compsize: " << HEADER->compsize << std::endl;259 COUT(3) << "gamestate compress datasize: " << HEADER->datasize << " compsize: " << HEADER->compsize << std::endl; 248 260 return true; 249 261 } … … 252 264 assert(HEADER); 253 265 assert(HEADER->compressed); 254 COUT(3) << "GameStateClient: uncompressing gamestate. id: " << HEADER->id << ", baseid: " << HEADER->base_id << ", normsize: " << HEADER->normsize << ", compsize: " << HEADER->compsize << std::endl;255 unsigned int normsize = HEADER->normsize;266 COUT(3) << "GameStateClient: uncompressing gamestate. id: " << HEADER->id << ", baseid: " << HEADER->base_id << ", datasize: " << HEADER->datasize << ", compsize: " << HEADER->compsize << std::endl; 267 unsigned int datasize = HEADER->datasize; 256 268 unsigned int compsize = HEADER->compsize; 257 269 unsigned int bufsize; 258 assert(compsize<= normsize);259 bufsize = normsize;270 assert(compsize<=datasize); 271 bufsize = datasize; 260 272 assert(bufsize!=0); 261 u nsigned char *ndata = new unsigned char[bufsize + sizeof(GamestateHeader)];262 u nsigned char*dest = ndata + sizeof(GamestateHeader);263 u nsigned char*source = data_ + sizeof(GamestateHeader);273 uint8_t *ndata = new uint8_t[bufsize + sizeof(GamestateHeader)]; 274 uint8_t *dest = ndata + sizeof(GamestateHeader); 275 uint8_t *source = data_ + sizeof(GamestateHeader); 264 276 int retval; 265 277 uLongf length=bufsize; … … 272 284 } 273 285 #ifndef NDEBUG 274 assert(HEADER->crc32==calcCRC(ndata+sizeof(GamestateHeader), HEADER-> normsize));286 assert(HEADER->crc32==calcCRC(ndata+sizeof(GamestateHeader), HEADER->datasize)); 275 287 #endif 276 288 … … 282 294 data_ = ndata; 283 295 HEADER->compressed = false; 284 assert(HEADER-> normsize==normsize);296 assert(HEADER->datasize==datasize); 285 297 assert(HEADER->compsize==compsize); 286 298 return true; … … 293 305 assert(!HEADER->diffed); 294 306 //unsigned char *basep = base->getGs()/*, *gs = getGs()*/; 295 u nsigned char*basep = GAMESTATE_START(base->data_), *gs = GAMESTATE_START(this->data_);307 uint8_t *basep = GAMESTATE_START(base->data_), *gs = GAMESTATE_START(this->data_); 296 308 unsigned int of=0; // pointers offset 297 309 unsigned int dest_length=0; 298 dest_length=HEADER-> normsize;310 dest_length=HEADER->datasize; 299 311 if(dest_length==0) 300 312 return NULL; 301 u nsigned char *ndata = new unsigned char[dest_length*sizeof(unsigned char)+sizeof(GamestateHeader)];302 u nsigned char*dest = ndata + sizeof(GamestateHeader);303 while(of < GAMESTATE_HEADER(base->data_)-> normsize && of < HEADER->normsize){313 uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+sizeof(GamestateHeader)]; 314 uint8_t *dest = ndata + sizeof(GamestateHeader); 315 while(of < GAMESTATE_HEADER(base->data_)->datasize && of < HEADER->datasize){ 304 316 *(dest+of)=*(basep+of)^*(gs+of); // do the xor 305 317 ++of; 306 318 } 307 if(GAMESTATE_HEADER(base->data_)-> normsize!=HEADER->normsize){308 u nsigned charn=0;309 if(GAMESTATE_HEADER(base->data_)-> normsize < HEADER->normsize){319 if(GAMESTATE_HEADER(base->data_)->datasize!=HEADER->datasize){ 320 uint8_t n=0; 321 if(GAMESTATE_HEADER(base->data_)->datasize < HEADER->datasize){ 310 322 while(of<dest_length){ 311 323 *(dest+of)=n^*(gs+of); … … 324 336 } 325 337 338 Gamestate* Gamestate::doSelection(unsigned int clientID){ 339 assert(data_); 340 std::map<unsigned int, Synchronisable *>::iterator it; 341 342 // allocate memory for new data 343 uint8_t *gdata = new uint8_t[HEADER->datasize+sizeof(GamestateHeader)]; 344 // create a gamestate out of it 345 Gamestate *gs = new Gamestate(gdata); 346 uint8_t *newdata = gdata + sizeof(GamestateHeader); 347 uint8_t *origdata = GAMESTATE_START(data_); 348 349 //copy the GamestateHeader 350 *(GamestateHeader*)gdata = *HEADER; 351 352 synchronisableHeader *oldobjectheader, *newobjectheader; 353 unsigned int objectOffset; 354 355 //copy in the zeros 356 for(it=dataMap_.begin(); it!=dataMap_.end(); it++){ 357 oldobjectheader = (synchronisableHeader*)origdata; 358 newobjectheader = (synchronisableHeader*)newdata; 359 unsigned int objectsize = oldobjectheader->size; 360 assert(it->second->objectID==oldobjectheader->objectID); 361 *newobjectheader = *oldobjectheader; 362 objectOffset=sizeof(uint8_t)+sizeof(bool); //skip the size and the availableDate variables in the objectheader 363 if(it->second->doSelection(HEADER->id)){ 364 newobjectheader->dataAvailable=true; //TODO: probably not neccessary 365 while(objectOffset<objectsize){ 366 *(newdata + objectOffset)=*(origdata + objectOffset); // copy the data 367 objectOffset++; 368 } 369 }else{ 370 newobjectheader->dataAvailable=false; 371 while(objectOffset<objectsize){ 372 *(newdata+objectOffset)=0; // set to 0 373 objectOffset++; 374 } 375 assert(objectOffset==objectsize); 376 } 377 newdata += objectsize; 378 origdata += objectsize; 379 } 380 return gs; 381 } 382 383 384 Gamestate* Gamestate::intelligentDiff(Gamestate *base, unsigned int clientID){ 385 // asserts 386 assert(data_); 387 assert(base->data_); 388 assert(!GAMESTATE_HEADER(base->data_)->diffed); 389 assert(!GAMESTATE_HEADER(base->data_)->compressed); 390 assert(!HEADER->compressed); 391 assert(!HEADER->diffed); 392 393 //preparations 394 std::map<unsigned int, Synchronisable *>::iterator it; 395 uint8_t *origdata, *basedata, *destdata, *ndata; 396 unsigned int objectOffset, streamOffset=0; //data offset 397 unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize; 398 synchronisableHeader *origheader; 399 synchronisableHeader *destheader; 400 401 origdata = GAMESTATE_START(this->data_); 402 basedata = GAMESTATE_START(base->data_); 403 ndata = new uint8_t[HEADER->datasize + sizeof(GamestateHeader)]; 404 destdata = ndata + sizeof(GamestateHeader); 405 406 // do the diff 407 for(it=dataMap_.begin(); it!=dataMap_.end(); it++){ 408 assert(streamOffset<HEADER->datasize); 409 bool sendData = it->second->doSelection(HEADER->id); 410 origheader = (synchronisableHeader *)(origdata+streamOffset); 411 destheader = (synchronisableHeader *)(destdata+streamOffset); 412 413 //copy and partially diff the object header 414 assert(sizeof(synchronisableHeader)==3*sizeof(unsigned int)+sizeof(bool)); 415 *(uint32_t*)destdata = *(uint32_t*)origdata; //size (do not diff) 416 *(bool*)(destdata+sizeof(uint32_t)) = sendData; 417 if(sendData){ 418 *(uint32_t*)(destdata+sizeof(uint32_t)+sizeof(bool)) = *(uint32_t*)(basedata+sizeof(uint32_t)+sizeof(bool)) ^ *(uint32_t*)(origdata+sizeof(uint32_t)+sizeof(bool)); //objectid (diff it) 419 *(uint32_t*)(destdata+2*sizeof(uint32_t)+sizeof(bool)) = *(uint32_t*)(basedata+2*sizeof(uint32_t)+sizeof(bool)) ^ *(uint32_t*)(origdata+2*sizeof(uint32_t)+sizeof(bool)); //classid (diff it) 420 }else{ 421 *(uint32_t*)(destdata+sizeof(uint32_t)+sizeof(bool)) = 0; 422 *(uint32_t*)(destdata+2*sizeof(uint32_t)+sizeof(bool)) = 0; 423 } 424 objectOffset=sizeof(synchronisableHeader); 425 streamOffset+=sizeof(synchronisableHeader); 426 427 //now handle the object data or fill with zeros 428 while(objectOffset<origheader->size ){ 429 430 if(sendData && streamOffset<minsize) 431 *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor 432 else if(sendData) 433 *(destdata+objectOffset)=((uint8_t)0)^*(origdata+objectOffset); // xor with 0 (basestream is too short) 434 else 435 *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered 436 437 objectOffset++; 438 streamOffset++; 439 } 440 destdata+=objectOffset; 441 origdata+=objectOffset; 442 basedata+=objectOffset; 443 } 444 445 //copy over the gamestate header and set the diffed flag 446 *(GamestateHeader *)ndata = *HEADER; //copy over the header 447 Gamestate *gs = new Gamestate(ndata); 448 GAMESTATE_HEADER(ndata)->diffed=true; 449 return gs; 450 } 451 452 Gamestate* Gamestate::intelligentUnDiff(Gamestate *base){ 453 // asserts 454 assert(data_); 455 assert(base->data_); 456 assert(!GAMESTATE_HEADER(base->data_)->diffed); 457 assert(!GAMESTATE_HEADER(base->data_)->compressed); 458 assert(!HEADER->compressed); 459 assert(HEADER->diffed); 460 461 //preparations 462 std::map<unsigned int, Synchronisable *>::iterator it; 463 uint8_t *origdata, *basedata, *destdata, *ndata; 464 unsigned int objectOffset, streamOffset=0; //data offset 465 unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize; 466 synchronisableHeader *origheader; 467 synchronisableHeader *destheader; 468 469 origdata = GAMESTATE_START(this->data_); 470 basedata = GAMESTATE_START(base->data_); 471 ndata = new uint8_t[HEADER->datasize + sizeof(GamestateHeader)]; 472 destdata = ndata + sizeof(GamestateHeader); 473 474 // do the undiff 475 for(it=dataMap_.begin(); it!=dataMap_.end(); it++){ 476 assert(streamOffset<HEADER->datasize); 477 origheader = (synchronisableHeader *)(origdata+streamOffset); 478 destheader = (synchronisableHeader *)(destdata+streamOffset); 479 bool sendData; 480 481 //copy and partially diff the object header 482 assert(sizeof(synchronisableHeader)==3*sizeof(unsigned int)+sizeof(bool)); 483 *(unsigned int*)destdata = *(unsigned int*)origdata; //size (do not diff) 484 *(bool*)(destdata+sizeof(unsigned int)) = *(bool*)(origdata+sizeof(unsigned int)); 485 sendData = *(bool*)(origdata+sizeof(unsigned int)); 486 if(sendData){ 487 *(unsigned int*)(destdata+sizeof(unsigned int)+sizeof(bool)) = *(unsigned int*)(basedata+sizeof(unsigned int)+sizeof(bool)) ^ *(unsigned int*)(origdata+sizeof(unsigned int)+sizeof(bool)); //objectid (diff it) 488 *(unsigned int*)(destdata+2*sizeof(unsigned int)+sizeof(bool)) = *(unsigned int*)(basedata+2*sizeof(unsigned int)+sizeof(bool)) ^ *(unsigned int*)(origdata+2*sizeof(unsigned int)+sizeof(bool)); //classid (diff it) 489 }else{ 490 *(unsigned int*)(destdata+sizeof(unsigned int)+sizeof(bool)) = 0; 491 *(unsigned int*)(destdata+2*sizeof(unsigned int)+sizeof(bool)) = 0; 492 } 493 objectOffset=sizeof(synchronisableHeader); 494 streamOffset+=sizeof(synchronisableHeader); 495 496 //now handle the object data or fill with zeros 497 while(objectOffset<origheader->size ){ 498 499 if(sendData && streamOffset<minsize) 500 *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor 501 else if(sendData) 502 *(destdata+objectOffset)=((unsigned char)0)^*(origdata+objectOffset); // xor with 0 (basestream is too short) 503 else 504 *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered 505 506 objectOffset++; 507 streamOffset++; 508 } 509 destdata+=objectOffset; 510 origdata+=objectOffset; 511 basedata+=objectOffset; 512 } 513 514 //copy over the gamestate header and set the diffed flag 515 *(GamestateHeader *)ndata = *HEADER; //copy over the header 516 Gamestate *gs = new Gamestate(ndata); 517 GAMESTATE_HEADER(ndata)->diffed=false; 518 return gs; 519 } 520 326 521 Gamestate *Gamestate::undiff(Gamestate *base) 327 522 { … … 330 525 assert(!HEADER->compressed && !GAMESTATE_HEADER(base->data_)->compressed); 331 526 //unsigned char *basep = base->getGs()/*, *gs = getGs()*/; 332 u nsigned char*basep = GAMESTATE_START(base->data_);333 u nsigned char*gs = GAMESTATE_START(this->data_);527 uint8_t *basep = GAMESTATE_START(base->data_); 528 uint8_t *gs = GAMESTATE_START(this->data_); 334 529 unsigned int of=0; // pointers offset 335 530 unsigned int dest_length=0; 336 dest_length=HEADER-> normsize;531 dest_length=HEADER->datasize; 337 532 if(dest_length==0) 338 533 return NULL; 339 u nsigned char *ndata = new unsigned char[dest_length*sizeof(unsigned char)+sizeof(GamestateHeader)];340 u nsigned char*dest = ndata + sizeof(GamestateHeader);341 while(of < GAMESTATE_HEADER(base->data_)-> normsize && of < HEADER->normsize){534 uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+sizeof(GamestateHeader)]; 535 uint8_t *dest = ndata + sizeof(GamestateHeader); 536 while(of < GAMESTATE_HEADER(base->data_)->datasize && of < HEADER->datasize){ 342 537 *(dest+of)=*(basep+of)^*(gs+of); // do the xor 343 538 ++of; 344 539 } 345 if(GAMESTATE_HEADER(base->data_)-> normsize!=HEADER->normsize){346 u nsigned charn=0;347 if(GAMESTATE_HEADER(base->data_)-> normsize < HEADER->normsize){540 if(GAMESTATE_HEADER(base->data_)->datasize!=HEADER->datasize){ 541 uint8_t n=0; 542 if(GAMESTATE_HEADER(base->data_)->datasize < HEADER->datasize){ 348 543 while(of < dest_length){ 349 544 *(dest+of)=n^*(gs+of); … … 370 565 // get total size of gamestate 371 566 for(it = orxonox::ObjectList<Synchronisable>::begin(); it; ++it) 372 size+=it->getSize 2(id, mode); // size of the actual data of the synchronisable567 size+=it->getSize(id, mode); // size of the actual data of the synchronisable 373 568 // size+=sizeof(GamestateHeader); 374 569 return size;
Note: See TracChangeset
for help on using the changeset viewer.