Changeset 2662 for code/trunk/src/network/packet
- Timestamp:
- Feb 14, 2009, 10:17:35 PM (16 years ago)
- Location:
- code/trunk
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
-
code/trunk/src/network/packet/Acknowledgement.cc
r2171 r2662 64 64 65 65 bool Acknowledgement::process(){ 66 COUT(0) << "processing ACK with ID: " << getAckID() << endl; 66 67 bool b = GamestateHandler::ackGamestate(getAckID(), clientID_); 67 68 delete this; -
code/trunk/src/network/packet/Acknowledgement.h
r2171 r2662 32 32 #include "Packet.h" 33 33 34 const unsigned int ACKID_NACK = 0; 34 35 35 36 namespace orxonox { -
code/trunk/src/network/packet/DeleteObjects.cc
r2171 r2662 30 30 #include "DeleteObjects.h" 31 31 #include <enet/enet.h> 32 #include "network/ Synchronisable.h"32 #include "network/synchronisable/Synchronisable.h" 33 33 #include "core/CoreIncludes.h" 34 34 #include <assert.h> … … 61 61 if(number==0) 62 62 return false; 63 COUT( 3) << "sending DeleteObjects: ";63 COUT(4) << "sending DeleteObjects: "; 64 64 unsigned int size = sizeof(ENUM::Type) + sizeof(uint32_t)*(number+1); 65 65 data_ = new uint8_t[size]; 66 66 uint8_t *tdata = data_; 67 * (ENUM::Type *)(tdata) = ENUM::DeleteObjects;67 *reinterpret_cast<ENUM::Type*>(tdata) = ENUM::DeleteObjects; 68 68 tdata += sizeof(ENUM::Type); 69 69 *(uint32_t *)tdata = number; … … 72 72 unsigned int temp = Synchronisable::popDeletedObject(); 73 73 // assert(temp<10000); //ugly hack 74 * (uint32_t *)(tdata) = temp;75 COUT( 3) << temp << " ";74 *reinterpret_cast<uint32_t*>(tdata) = temp; 75 COUT(4) << temp << " "; 76 76 tdata += sizeof(uint32_t); 77 77 } 78 COUT( 3) << std::endl;78 COUT(4) << std::endl; 79 79 return true; 80 80 } … … 87 87 bool DeleteObjects::process(){ 88 88 for(unsigned int i=0; i<*(unsigned int *)(data_+_QUANTITY); i++){ 89 COUT( 3) << "deleting object with id: " << *(uint32_t*)(data_+_OBJECTIDS+i*sizeof(uint32_t)) << std::endl;89 COUT(4) << "deleting object with id: " << *(uint32_t*)(data_+_OBJECTIDS+i*sizeof(uint32_t)) << std::endl; 90 90 Synchronisable::deleteObject( *(uint32_t*)(data_+_OBJECTIDS+i*sizeof(uint32_t)) ); 91 91 } -
code/trunk/src/network/packet/Gamestate.cc
r2171 r2662 28 28 29 29 #include "Gamestate.h" 30 #include "network/ClientInformation.h" 31 #include "network/GamestateHandler.h" 30 #include "../GamestateHandler.h" 31 #include "../synchronisable/Synchronisable.h" 32 #include "../TrafficControl.h" 33 #include "core/Core.h" 32 34 #include "core/CoreIncludes.h" 33 35 #include "core/Iterator.h" 34 36 35 37 #include <zlib.h> 36 #include < assert.h>38 #include <cassert> 37 39 38 40 … … 42 44 namespace packet { 43 45 44 #define GAMESTATE_START(data) (data + sizeof(GamestateHeader)) 45 #define GAMESTATE_HEADER(data) ((GamestateHeader *)data) 46 #define HEADER GAMESTATE_HEADER(data_) 47 46 #define GAMESTATE_START(data) (data + GamestateHeader::getSize()) 48 47 49 48 #define PACKET_FLAG_GAMESTATE ENET_PACKET_FLAG_RELIABLE 50 49 50 // Gamestate::Gamestate() 51 // { 52 // flags_ = flags_ | PACKET_FLAG_GAMESTATE; 53 // } 54 51 55 Gamestate::Gamestate() 52 56 { 53 57 flags_ = flags_ | PACKET_FLAG_GAMESTATE; 58 header_ = 0; 54 59 } 55 60 … … 58 63 { 59 64 flags_ = flags_ | PACKET_FLAG_GAMESTATE; 65 header_ = new GamestateHeader(data_); 60 66 } 61 67 … … 64 70 flags_ = flags_ | PACKET_FLAG_GAMESTATE; 65 71 data_=data; 72 header_ = new GamestateHeader(data_); 73 } 74 75 Gamestate::Gamestate(const Gamestate& g) : 76 Packet( *(Packet*)&g ) 77 { 78 flags_ = flags_ | PACKET_FLAG_GAMESTATE; 79 header_ = new GamestateHeader(data_); 66 80 } 67 81 … … 73 87 bool Gamestate::collectData(int id, uint8_t mode) 74 88 { 75 unsigned int tempsize=0, currentsize=0; 89 assert(this->header_==0); // make sure the header didn't exist before 90 uint32_t tempsize=0, currentsize=0; 76 91 assert(data_==0); 77 u nsigned int size = calcGamestateSize(id, mode);92 uint32_t size = calcGamestateSize(id, mode); 78 93 79 94 COUT(4) << "G.ST.Man: producing gamestate with id: " << id << std::endl; 80 95 if(size==0) 81 96 return false; 82 data_ = new u nsigned char[size + sizeof(GamestateHeader)];97 data_ = new uint8_t[size + GamestateHeader::getSize()]; 83 98 if(!data_){ 84 99 COUT(2) << "GameStateManager: could not allocate memory" << std::endl; 85 100 return false; 86 101 } 102 103 // create the header object 104 header_ = new GamestateHeader(data_); 87 105 88 106 //start collect data synchronisable by synchronisable 89 107 uint8_t *mem=data_; 90 mem +=sizeof(GamestateHeader);108 mem += GamestateHeader::getSize(); 91 109 ObjectList<Synchronisable>::iterator it; 92 110 for(it = ObjectList<Synchronisable>::begin(); it; ++it){ 111 112 #ifndef NDEBUG 93 113 tempsize=it->getSize(id, mode); 94 95 114 if(currentsize+tempsize > size){ 96 115 assert(0); // if we don't use multithreading this part shouldn't be neccessary … … 98 117 COUT(3) << "G.St.Man: need additional memory" << std::endl; 99 118 ObjectList<Synchronisable>::iterator temp = it; 100 int addsize=tempsize;119 uint32_t addsize=tempsize; 101 120 while(++temp) 102 121 addsize+=temp->getSize(id, mode); 103 data_ = (uint8_t *)realloc(data_, sizeof(GamestateHeader) + currentsize + addsize);122 data_ = (uint8_t *)realloc(data_, GamestateHeader::getSize() + currentsize + addsize); 104 123 if(!data_) 105 124 return false; 106 125 size = currentsize+addsize; 107 126 }// stop allocate additional memory 108 127 #endif 109 128 110 129 //if(it->doSelection(id)) 111 dataMap_[mem-data_]=(*it); // save the mem location of the synchronisable data 130 if ( it->doSync( id, mode ) ) 131 dataMap_.push_back( obj(it->getObjectID(), it->getCreatorID(), tempsize, mem-data_) ); 132 // dataMap_[mem-data_]=(*it); // save the mem location of the synchronisable data 112 133 if(!it->getData(mem, id, mode)) 113 134 return false; // mem pointer gets automatically increased because of call by reference … … 118 139 119 140 //start write gamestate header 120 HEADER->packetType = ENUM::Gamestate; 121 HEADER->datasize = currentsize; 122 HEADER->id = id; 123 HEADER->diffed = false; 124 HEADER->complete = true; 125 HEADER->compressed = false; 141 header_->setDataSize( currentsize ); 142 header_->setID( id ); 143 header_->setDiffed( false ); 144 header_->setComplete( true ); 145 header_->setCompressed( false ); 126 146 //stop write gamestate header 127 147 … … 133 153 bool Gamestate::spreadData(uint8_t mode) 134 154 { 135 assert(data_); 136 assert(!HEADER->compressed); 137 assert(!HEADER->diffed); 138 uint8_t *mem=data_+sizeof(GamestateHeader); 155 COUT(4) << "processing gamestate with id " << header_->getID() << endl; 156 assert(data_); 157 assert(!header_->isCompressed()); 158 assert(!header_->isDiffed()); 159 uint8_t *mem=data_+GamestateHeader::getSize(); 139 160 // get the start of the Synchronisable list 140 161 //ObjectList<Synchronisable>::iterator it=ObjectList<Synchronisable>::begin(); … … 142 163 143 164 // update the data of the objects we received 144 while(mem < data_+ sizeof(GamestateHeader)+HEADER->datasize){145 synchronisableHeader *objectheader = (synchronisableHeader*)mem;146 147 s = Synchronisable::getSynchronisable( objectheader ->objectID);165 while(mem < data_+GamestateHeader::getSize()+header_->getDataSize()){ 166 SynchronisableHeader objectheader(mem); 167 168 s = Synchronisable::getSynchronisable( objectheader.getObjectID() ); 148 169 if(!s) 149 170 { 150 Synchronisable::fabricate(mem, mode); 171 if (!Core::isMaster()) 172 { 173 Synchronisable::fabricate(mem, mode); 174 } 175 else 176 { 177 mem += objectheader.getDataSize(); 178 } 179 // COUT(0) << "could not fabricate synchronisable: " << objectheader->objectID << " classid: " << objectheader->classID << " creator: " << objectheader->creatorID << endl; 180 // else 181 // COUT(0) << "fabricated: " << objectheader->objectID << " classid: " << objectheader->classID << " creator: " << objectheader->creatorID << endl; 151 182 } 152 183 else … … 157 188 } 158 189 190 // In debug mode, check first, whether there are no duplicate objectIDs 191 #ifndef NDEBUG 192 ObjectList<Synchronisable>::iterator it; 193 for (it = ObjectList<Synchronisable>::begin(); it != ObjectList<Synchronisable>::end(); ++it) { 194 if (it->getObjectID() == OBJECTID_UNKNOWN) { 195 if (it->objectMode_ != 0x0) { 196 COUT(0) << "Found object with OBJECTID_UNKNOWN on the client with objectMode != 0x0!" << std::endl; 197 COUT(0) << "Possible reason for this error: Client created a synchronized object without the Server's approval." << std::endl; 198 COUT(0) << "Objects class: " << it->getIdentifier()->getName() << std::endl; 199 assert(false); 200 } 201 } 202 else { 203 ObjectList<Synchronisable>::iterator it2; 204 for (it2 = ObjectList<Synchronisable>::begin(); it2 != ObjectList<Synchronisable>::end(); ++it2) { 205 if (it->getObjectID() == it2->getObjectID() && *it != *it2) { 206 COUT(0) << "Found duplicate objectIDs on the client!" << std::endl 207 << "Are you sure you don't create a Sychnronisable objcect with 'new' \ 208 that doesn't have objectMode = 0x0?" << std::endl; 209 assert(false); 210 } 211 } 212 } 213 } 214 #endif 215 159 216 return true; 160 217 } 161 218 162 163 164 int Gamestate::getID(){ 165 return HEADER->id; 166 } 167 168 unsigned int Gamestate::getSize() const 169 { 170 assert(data_); 171 if(HEADER->compressed) 172 return HEADER->compsize+sizeof(GamestateHeader); 219 uint32_t Gamestate::getSize() const 220 { 221 assert(data_); 222 if(header_->isCompressed()) 223 return header_->getCompSize()+GamestateHeader::getSize(); 173 224 else 174 225 { 175 return HEADER->datasize+sizeof(GamestateHeader);226 return header_->getDataSize()+GamestateHeader::getSize(); 176 227 } 177 228 } 178 229 179 230 bool Gamestate::operator==(packet::Gamestate gs){ 180 uint8_t *d1 = data_+ sizeof(GamestateHeader);181 uint8_t *d2 = gs.data_+ sizeof(GamestateHeader);231 uint8_t *d1 = data_+GamestateHeader::getSize(); 232 uint8_t *d2 = gs.data_+GamestateHeader::getSize(); 182 233 assert(!isCompressed()); 183 234 assert(!gs.isCompressed()); 184 while(d1<data_+ HEADER->datasize)235 while(d1<data_+header_->getDataSize()) 185 236 { 186 237 if(*d1!=*d2) … … 201 252 bool Gamestate::compressData() 202 253 { 203 assert( HEADER);204 assert(! HEADER->compressed);205 uLongf buffer = (uLongf)((( HEADER->datasize+ 12)*1.01)+1);254 assert(data_); 255 assert(!header_->isCompressed()); 256 uLongf buffer = (uLongf)(((header_->getDataSize() + 12)*1.01)+1); 206 257 if(buffer==0) 207 258 return false; 208 259 209 uint8_t *ndata = new uint8_t[buffer+ sizeof(GamestateHeader)];210 uint8_t *dest = GAMESTATE_START(ndata);260 uint8_t *ndata = new uint8_t[buffer+GamestateHeader::getSize()]; 261 uint8_t *dest = ndata + GamestateHeader::getSize(); 211 262 //unsigned char *dest = new unsigned char[buffer]; 212 uint8_t *source = GAMESTATE_START(data_);263 uint8_t *source = data_ + GamestateHeader::getSize(); 213 264 int retval; 214 retval = compress( dest, &buffer, source, (uLong)( HEADER->datasize) );265 retval = compress( dest, &buffer, source, (uLong)(header_->getDataSize()) ); 215 266 switch ( retval ) { 216 267 case Z_OK: COUT(5) << "G.St.Man: compress: successfully compressed" << std::endl; break; … … 219 270 case Z_DATA_ERROR: COUT(2) << "G.St.Man: compress: data corrupted in gamestate.compress" << std::endl; return false; 220 271 } 221 #ifndef NDEBUG222 //decompress and compare the start and the decompressed data223 uint8_t *rdata = new uint8_t[HEADER->datasize+sizeof(GamestateHeader)];224 uint8_t *d2 = GAMESTATE_START(rdata);225 uLongf length2 = HEADER->datasize;226 uncompress(d2, &length2, dest, buffer);227 for(unsigned int i=0; i<HEADER->datasize; i++){228 assert(*(source+i)==*(d2+i));229 }230 delete[] rdata;231 #endif232 272 233 273 //copy and modify header 234 #ifndef NDEBUG 235 HEADER->crc32 = calcCRC(data_+sizeof(GamestateHeader), HEADER->datasize); 236 #endif 237 *GAMESTATE_HEADER(ndata) = *HEADER; 274 GamestateHeader *temp = header_; 275 header_ = new GamestateHeader(ndata, temp); 276 delete temp; 238 277 //delete old data 239 278 delete[] data_; 240 279 //save new data 241 280 data_ = ndata; 242 HEADER->compsize = buffer; 243 HEADER->compressed = true; 244 assert(HEADER->compressed); 245 COUT(4) << "gamestate compress datasize: " << HEADER->datasize << " compsize: " << HEADER->compsize << std::endl; 281 header_->setCompSize( buffer ); 282 header_->setCompressed( true ); 283 COUT(5) << "gamestate compress datasize: " << header_->getDataSize() << " compsize: " << header_->getCompSize() << std::endl; 246 284 return true; 247 285 } 248 286 bool Gamestate::decompressData() 249 287 { 250 assert( HEADER);251 assert( HEADER->compressed);252 COUT(4) << "GameStateClient: uncompressing gamestate. id: " << HEADER->id << ", baseid: " << HEADER->base_id << ", datasize: " << HEADER->datasize << ", compsize: " << HEADER->compsize<< std::endl;253 u nsigned int datasize = HEADER->datasize;254 u nsigned int compsize = HEADER->compsize;255 u nsigned int bufsize;288 assert(data_); 289 assert(header_->isCompressed()); 290 COUT(4) << "GameStateClient: uncompressing gamestate. id: " << header_->getID() << ", baseid: " << header_->getBaseID() << ", datasize: " << header_->getDataSize() << ", compsize: " << header_->getCompSize() << std::endl; 291 uint32_t datasize = header_->getDataSize(); 292 uint32_t compsize = header_->getCompSize(); 293 uint32_t bufsize; 256 294 // assert(compsize<=datasize); 257 295 bufsize = datasize; 258 296 assert(bufsize!=0); 259 uint8_t *ndata = new uint8_t[bufsize + sizeof(GamestateHeader)];260 uint8_t *dest = ndata + sizeof(GamestateHeader);261 uint8_t *source = data_ + sizeof(GamestateHeader);297 uint8_t *ndata = new uint8_t[bufsize + GamestateHeader::getSize()]; 298 uint8_t *dest = ndata + GamestateHeader::getSize(); 299 uint8_t *source = data_ + GamestateHeader::getSize(); 262 300 int retval; 263 301 uLongf length=bufsize; … … 269 307 case Z_DATA_ERROR: COUT(2) << "data corrupted (zlib)" << std::endl; return false; 270 308 } 271 #ifndef NDEBUG272 assert(HEADER->crc32==calcCRC(ndata+sizeof(GamestateHeader), HEADER->datasize));273 #endif274 309 275 310 //copy over the header 276 *GAMESTATE_HEADER(ndata) = *HEADER; 311 GamestateHeader *temp = header_; 312 header_ = new GamestateHeader( data_, header_ ); 313 delete temp; 277 314 278 315 if (this->bDataENetAllocated_){ … … 289 326 //set new pointers 290 327 data_ = ndata; 291 HEADER->compressed = false;292 assert( HEADER->datasize==datasize);293 assert( HEADER->compsize==compsize);328 header_->setCompressed( false ); 329 assert(header_->getDataSize()==datasize); 330 assert(header_->getCompSize()==compsize); 294 331 return true; 295 332 } … … 297 334 Gamestate *Gamestate::diff(Gamestate *base) 298 335 { 299 assert(HEADER); 300 assert(!HEADER->compressed); 301 assert(!HEADER->diffed); 336 assert(data_); 337 assert(!header_->isCompressed()); 338 assert(!header_->isDiffed()); 339 GamestateHeader diffHeader(base->data_); 302 340 //unsigned char *basep = base->getGs()/*, *gs = getGs()*/; 303 341 uint8_t *basep = GAMESTATE_START(base->data_), *gs = GAMESTATE_START(this->data_); 304 u nsigned int of=0; // pointers offset305 u nsigned int dest_length=0;306 dest_length= HEADER->datasize;342 uint32_t of=0; // pointers offset 343 uint32_t dest_length=0; 344 dest_length=header_->getDataSize(); 307 345 if(dest_length==0) 308 346 return NULL; 309 uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+ sizeof(GamestateHeader)];310 uint8_t *dest = ndata + sizeof(GamestateHeader);311 while(of < GAMESTATE_HEADER(base->data_)->datasize && of < HEADER->datasize){347 uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()]; 348 uint8_t *dest = ndata + GamestateHeader::getSize(); 349 while(of < diffHeader.getDataSize() && of < header_->getDataSize()){ 312 350 *(dest+of)=*(basep+of)^*(gs+of); // do the xor 313 351 ++of; 314 352 } 315 if( GAMESTATE_HEADER(base->data_)->datasize!=HEADER->datasize){353 if(diffHeader.getDataSize()!=header_->getDataSize()){ 316 354 uint8_t n=0; 317 if( GAMESTATE_HEADER(base->data_)->datasize < HEADER->datasize){355 if(diffHeader.getDataSize() < header_->getDataSize()){ 318 356 while(of<dest_length){ 319 357 *(dest+of)=n^*(gs+of); … … 323 361 } 324 362 325 *GAMESTATE_HEADER(ndata) = *HEADER;326 GAMESTATE_HEADER(ndata)->diffed = true;327 GAMESTATE_HEADER(ndata)->base_id = base->getID();328 363 Gamestate *g = new Gamestate(ndata, getClientID()); 364 *(g->header_) = *header_; 365 g->header_->setDiffed( true ); 366 g->header_->setBaseID( base->getID() ); 329 367 g->flags_=flags_; 330 368 g->packetDirection_ = packetDirection_; … … 332 370 } 333 371 334 Gamestate* Gamestate::doSelection(unsigned int clientID ){335 assert(data_); 336 std:: map<unsigned int, Synchronisable *>::iterator it;372 Gamestate* Gamestate::doSelection(unsigned int clientID, unsigned int targetSize){ 373 assert(data_); 374 std::list<obj>::iterator it; 337 375 338 376 // allocate memory for new data 339 uint8_t *gdata = new uint8_t[ HEADER->datasize+sizeof(GamestateHeader)];377 uint8_t *gdata = new uint8_t[header_->getDataSize()+GamestateHeader::getSize()]; 340 378 // create a gamestate out of it 341 379 Gamestate *gs = new Gamestate(gdata); 342 uint8_t *newdata = gdata + sizeof(GamestateHeader);380 uint8_t *newdata = gdata + GamestateHeader::getSize(); 343 381 uint8_t *origdata = GAMESTATE_START(data_); 344 382 345 383 //copy the GamestateHeader 346 *(GamestateHeader*)gdata = *HEADER; 347 348 synchronisableHeader *oldobjectheader, *newobjectheader; 349 unsigned int objectOffset; 384 assert(gs->header_); 385 *(gs->header_) = *header_; 386 387 uint32_t objectOffset; 388 unsigned int objectsize, destsize=0; 389 // TODO: Why is this variable not used? 390 //Synchronisable *object; 391 392 //call TrafficControl 393 TrafficControl::getInstance()->processObjectList( clientID, header_->getID(), &dataMap_ ); 350 394 351 395 //copy in the zeros 352 for(it=dataMap_.begin(); it!=dataMap_.end(); it++){ 353 oldobjectheader = (synchronisableHeader*)origdata; 354 newobjectheader = (synchronisableHeader*)newdata; 355 unsigned int objectsize = oldobjectheader->size; 356 assert(it->second->objectID==oldobjectheader->objectID); 357 *newobjectheader = *oldobjectheader; 358 objectOffset=sizeof(synchronisableHeader); //skip the size and the availableData variables in the objectheader 359 if(it->second->doSelection(HEADER->id)){ 360 assert(newobjectheader->dataAvailable==true); 361 memcpy(newdata+objectOffset, origdata+objectOffset, objectsize-objectOffset); 396 for(it=dataMap_.begin(); it!=dataMap_.end();){ 397 // if((*it).objSize==0) 398 // continue; 399 // if(it->second->getSize(HEADER->id)==0) // merged from objecthierarchy2, doesn't work anymore; TODO: change this 400 // continue; // merged from objecthierarchy2, doesn't work anymore; TODO: change this 401 SynchronisableHeader oldobjectheader(origdata); 402 SynchronisableHeader newobjectheader(newdata); 403 if ( (*it).objSize == 0 ) 404 { 405 ++it; 406 continue; 407 } 408 // object = Synchronisable::getSynchronisable( (*it).objID ); 409 // assert(object->objectID == oldobjectheader->objectID); 410 objectsize = oldobjectheader.getDataSize(); 411 objectOffset=SynchronisableHeader::getSize(); //skip the size and the availableData variables in the objectheader 412 if ( (*it).objID == oldobjectheader.getObjectID() ){ 413 memcpy(newdata, origdata, objectsize); 414 assert(newobjectheader.isDataAvailable()==true); 415 ++it; 362 416 }else{ 363 newobjectheader->dataAvailable=false; 417 newobjectheader = oldobjectheader; 418 newobjectheader.setDataAvailable(false); 364 419 memset(newdata+objectOffset, 0, objectsize-objectOffset); 365 assert(objectOffset==objectsize);366 420 } 367 421 newdata += objectsize; 368 422 origdata += objectsize; 369 } 423 destsize += objectsize; 424 } 425 #ifndef NDEBUG 426 uint32_t origsize = destsize; 427 while ( origsize < header_->getDataSize() ) 428 { 429 SynchronisableHeader oldobjectheader(origdata); 430 objectsize = oldobjectheader.getDataSize(); 431 origdata += objectsize; 432 origsize += objectsize; 433 } 434 assert(origsize==header_->getDataSize()); 435 assert(destsize!=0); 436 #endif 437 gs->header_->setDataSize( destsize ); 370 438 return gs; 371 439 } 372 440 373 441 374 Gamestate* Gamestate::intelligentDiff(Gamestate *base, unsigned int clientID){375 // asserts376 assert(data_);377 assert(base->data_);378 assert(!GAMESTATE_HEADER(base->data_)->diffed);379 assert(!GAMESTATE_HEADER(base->data_)->compressed);380 assert(!HEADER->compressed);381 assert(!HEADER->diffed);382 383 //preparations384 std::map<unsigned int, Synchronisable *>::iterator it;385 uint8_t *origdata, *basedata, *destdata, *ndata;386 unsigned int objectOffset, streamOffset=0; //data offset387 unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize;388 synchronisableHeader *origheader;389 synchronisableHeader *destheader;390 391 origdata = GAMESTATE_START(this->data_);392 basedata = GAMESTATE_START(base->data_);393 ndata = new uint8_t[HEADER->datasize + sizeof(GamestateHeader)];394 destdata = ndata + sizeof(GamestateHeader);395 396 // do the diff397 for(it=dataMap_.begin(); it!=dataMap_.end(); it++){398 assert(streamOffset<HEADER->datasize);399 bool sendData = it->second->doSelection(HEADER->id);400 origheader = (synchronisableHeader *)(origdata+streamOffset);401 destheader = (synchronisableHeader *)(destdata+streamOffset);402 403 //copy and partially diff the object header404 assert(sizeof(synchronisableHeader)==3*sizeof(unsigned int)+sizeof(bool));405 *(uint32_t*)destdata = *(uint32_t*)origdata; //size (do not diff)406 *(bool*)(destdata+sizeof(uint32_t)) = sendData;407 if(sendData){408 *(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)409 *(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)410 }else{411 *(uint32_t*)(destdata+sizeof(uint32_t)+sizeof(bool)) = 0;412 *(uint32_t*)(destdata+2*sizeof(uint32_t)+sizeof(bool)) = 0;413 }414 objectOffset=sizeof(synchronisableHeader);415 streamOffset+=sizeof(synchronisableHeader);416 417 //now handle the object data or fill with zeros418 while(objectOffset<origheader->size ){419 420 if(sendData && streamOffset<minsize)421 *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor422 else if(sendData)423 *(destdata+objectOffset)=((uint8_t)0)^*(origdata+objectOffset); // xor with 0 (basestream is too short)424 else425 *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered426 427 objectOffset++;428 streamOffset++;429 }430 destdata+=objectOffset;431 origdata+=objectOffset;432 basedata+=objectOffset;433 }434 435 //copy over the gamestate header and set the diffed flag436 *(GamestateHeader *)ndata = *HEADER; //copy over the header437 Gamestate *gs = new Gamestate(ndata);438 GAMESTATE_HEADER(ndata)->diffed=true;439 return gs;440 }441 442 Gamestate* Gamestate::intelligentUnDiff(Gamestate *base){443 // asserts444 assert(data_);445 assert(base->data_);446 assert(!GAMESTATE_HEADER(base->data_)->diffed);447 assert(!GAMESTATE_HEADER(base->data_)->compressed);448 assert(!HEADER->compressed);449 assert(HEADER->diffed);450 451 //preparations452 std::map<unsigned int, Synchronisable *>::iterator it;453 uint8_t *origdata, *basedata, *destdata, *ndata;454 unsigned int objectOffset, streamOffset=0; //data offset455 unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize;456 synchronisableHeader *origheader;457 synchronisableHeader *destheader;458 459 origdata = GAMESTATE_START(this->data_);460 basedata = GAMESTATE_START(base->data_);461 ndata = new uint8_t[HEADER->datasize + sizeof(GamestateHeader)];462 destdata = ndata + sizeof(GamestateHeader);463 464 // do the undiff465 for(it=dataMap_.begin(); it!=dataMap_.end(); it++){466 assert(streamOffset<HEADER->datasize);467 origheader = (synchronisableHeader *)(origdata+streamOffset);468 destheader = (synchronisableHeader *)(destdata+streamOffset);469 bool sendData;470 471 //copy and partially diff the object header472 assert(sizeof(synchronisableHeader)==3*sizeof(unsigned int)+sizeof(bool));473 *(unsigned int*)destdata = *(unsigned int*)origdata; //size (do not diff)474 *(bool*)(destdata+sizeof(unsigned int)) = *(bool*)(origdata+sizeof(unsigned int));475 sendData = *(bool*)(origdata+sizeof(unsigned int));476 if(sendData){477 *(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)478 *(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)479 }else{480 *(unsigned int*)(destdata+sizeof(unsigned int)+sizeof(bool)) = 0;481 *(unsigned int*)(destdata+2*sizeof(unsigned int)+sizeof(bool)) = 0;482 }483 objectOffset=sizeof(synchronisableHeader);484 streamOffset+=sizeof(synchronisableHeader);485 486 //now handle the object data or fill with zeros487 while(objectOffset<origheader->size ){488 489 if(sendData && streamOffset<minsize)490 *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor491 else if(sendData)492 *(destdata+objectOffset)=((unsigned char)0)^*(origdata+objectOffset); // xor with 0 (basestream is too short)493 else494 *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered495 496 objectOffset++;497 streamOffset++;498 }499 destdata+=objectOffset;500 origdata+=objectOffset;501 basedata+=objectOffset;502 }503 504 //copy over the gamestate header and set the diffed flag505 *(GamestateHeader *)ndata = *HEADER; //copy over the header506 Gamestate *gs = new Gamestate(ndata);507 GAMESTATE_HEADER(ndata)->diffed=false;508 return gs;509 }510 511 442 Gamestate *Gamestate::undiff(Gamestate *base) 512 443 { 513 assert(this && base);assert( HEADER);514 assert( HEADER->diffed);515 assert(! HEADER->compressed && !GAMESTATE_HEADER(base->data_)->compressed);444 assert(this && base);assert(data_); 445 assert(header_->isDiffed()); 446 assert(!header_->isCompressed() && !base->header_->isCompressed()); 516 447 //unsigned char *basep = base->getGs()/*, *gs = getGs()*/; 517 448 uint8_t *basep = GAMESTATE_START(base->data_); 518 449 uint8_t *gs = GAMESTATE_START(this->data_); 519 u nsigned int of=0; // pointers offset520 u nsigned int dest_length=0;521 dest_length= HEADER->datasize;450 uint32_t of=0; // pointers offset 451 uint32_t dest_length=0; 452 dest_length=header_->getDataSize(); 522 453 if(dest_length==0) 523 454 return NULL; 524 uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+ sizeof(GamestateHeader)];525 uint8_t *dest = ndata + sizeof(GamestateHeader);526 while(of < GAMESTATE_HEADER(base->data_)->datasize && of < HEADER->datasize){455 uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()]; 456 uint8_t *dest = ndata + GamestateHeader::getSize(); 457 while(of < base->header_->getDataSize() && of < header_->getDataSize()){ 527 458 *(dest+of)=*(basep+of)^*(gs+of); // do the xor 528 459 ++of; 529 460 } 530 if( GAMESTATE_HEADER(base->data_)->datasize!=HEADER->datasize){461 if(base->header_->getDataSize()!=header_->getDataSize()){ 531 462 uint8_t n=0; 532 if( GAMESTATE_HEADER(base->data_)->datasize < HEADER->datasize){463 if(base->header_->getDataSize() < header_->getDataSize()){ 533 464 while(of < dest_length){ 534 465 *(dest+of)=n^*(gs+of); … … 537 468 } 538 469 } 539 *GAMESTATE_HEADER(ndata) = *HEADER;540 GAMESTATE_HEADER(ndata)->diffed = false;541 470 Gamestate *g = new Gamestate(ndata, getClientID()); 471 assert(g->header_); 472 *(g->header_) = *header_; 473 g->header_->setDiffed( false ); 542 474 g->flags_=flags_; 543 475 g->packetDirection_ = packetDirection_; … … 548 480 549 481 550 u nsigned int Gamestate::calcGamestateSize(unsigned int id, uint8_t mode)551 { 552 u nsigned int size=0;482 uint32_t Gamestate::calcGamestateSize(int32_t id, uint8_t mode) 483 { 484 uint32_t size=0; 553 485 // get the start of the Synchronisable list 554 486 ObjectList<Synchronisable>::iterator it; … … 556 488 for(it = ObjectList<Synchronisable>::begin(); it; ++it) 557 489 size+=it->getSize(id, mode); // size of the actual data of the synchronisable 558 // size+=sizeof(GamestateHeader);559 490 return size; 560 491 } 561 492 562 /** 563 * This function removes a Synchronisable out of the universe 564 * @param it iterator of the list pointing to the object 565 * @return iterator pointing to the next object in the list 566 */ 567 void Gamestate::removeObject(ObjectList<Synchronisable>::iterator &it) { 568 ObjectList<Synchronisable>::iterator temp=it; 569 ++it; 570 delete *temp; 571 } 572 573 bool Gamestate::isDiffed(){ 574 return HEADER->diffed; 575 } 576 577 bool Gamestate::isCompressed(){ 578 return HEADER->compressed; 579 } 580 581 int Gamestate::getBaseID(){ 582 return HEADER->base_id; 583 } 584 } 585 586 } 493 } //namespace packet 494 } //namespace orxonox -
code/trunk/src/network/packet/Gamestate.h
r2171 r2662 31 31 #define NETWORK_PACKETGAMESTATE_H 32 32 33 #include " ../NetworkPrereqs.h"33 #include "network/NetworkPrereqs.h" 34 34 35 35 #include "Packet.h" 36 #include "network/Synchronisable.h" 36 #include "network/TrafficControl.h" 37 #include "core/CoreIncludes.h" 37 38 #include <map> 39 #include <list> 38 40 #ifndef NDEBUG 39 41 #include "util/CRC32.h" … … 44 46 namespace packet { 45 47 46 struct _NetworkExport GamestateHeader{ 47 ENUM::Type packetType; 48 int32_t id; // id of the gamestate 49 uint32_t compsize; 50 uint32_t datasize; 51 int32_t base_id; // id of the base-gamestate diffed from 52 bool diffed:1; // wheter diffed or not 53 bool complete:1; // wheter it is a complete gamestate or only partial 54 bool compressed:1; 55 #ifndef NDEBUG 56 uint32_t crc32; 57 #endif 48 class _NetworkExport GamestateHeader{ 49 public: 50 GamestateHeader(uint8_t *data){ assert(data); data_ = data; *(uint32_t*)data_ = ENUM::Gamestate; } 51 GamestateHeader(uint8_t *data, GamestateHeader* h) 52 { assert(data); data_=data; memcpy(data_, h->data_, getSize()); } 53 static inline uint32_t getSize() 54 { return 21; } 55 56 inline int32_t getID() const 57 { assert(data_); return *(int32_t*)(data_+4); } 58 inline void setID(int32_t id) 59 { assert(data_); *(int32_t*)(data_+4) = id; } 60 61 inline int32_t getBaseID() const 62 { assert(data_); return *(int32_t*)(data_+8); } 63 inline void setBaseID(int32_t id) 64 { assert(data_); *(int32_t*)(data_+8) = id; } 65 66 inline uint32_t getDataSize() const 67 { assert(data_); return *(uint32_t*)(data_+12); } 68 inline void setDataSize(uint32_t size) 69 { assert(data_); *(uint32_t*)(data_+12) = size; } 70 71 inline uint32_t getCompSize() const 72 { assert(data_); return *(uint32_t*)(data_+16); } 73 inline void setCompSize(uint32_t size) 74 { assert(data_); *(uint32_t*)(data_+16) = size; } 75 76 inline bool isDiffed() const 77 { assert(data_); return *(int8_t*)(data_+20) & 0x1; } 78 inline void setDiffed(bool b) 79 { assert(data_); *(int8_t*)(data_+20) = (b<<0) | (*(int8_t*)(data_+20) & 0x6 ); } 80 81 inline bool isComplete() const 82 { assert(data_); return *(int8_t*)(data_+20) & 0x2; } 83 inline void setComplete(bool b) 84 { assert(data_); *(int8_t*)(data_+20) = (b<<1) | (*(int8_t*)(data_+20) & 0x5 ); } 85 86 inline bool isCompressed() const 87 { assert(data_); return *(int8_t*)(data_+20) & 0x4; } 88 inline void setCompressed(bool b) 89 { assert(data_); *(int8_t*)(data_+20) = (b<<2) | (*(int8_t*)(data_+20) & 0x3 ); } 90 91 inline void operator=(GamestateHeader& h) 92 { assert(data_); assert(h.data_); memcpy( data_, h.data_, getSize()); } 93 private: 94 uint8_t *data_; 95 //#define GAMESTATE_START(data) (data + sizeof(GamestateHeader)) 96 //#define GAMESTATE_HEADER(data) ((GamestateHeader *)data) 97 //#define HEADER GAMESTATE_HEADER(data_) 98 58 99 }; 59 100 … … 66 107 Gamestate(uint8_t *data, unsigned int clientID); 67 108 Gamestate(uint8_t *data); 109 Gamestate(const Gamestate& g); 68 110 69 111 ~Gamestate(); … … 71 113 bool collectData(int id, uint8_t mode=0x0); 72 114 bool spreadData( uint8_t mode=0x0); 73 in t getID();74 bool isDiffed();75 bool isCompressed();76 in t getBaseID();115 inline int32_t getID() const { return header_->getID(); } 116 inline bool isDiffed() const { return header_->isDiffed(); } 117 inline bool isCompressed() const { return header_->isCompressed(); } 118 inline int32_t getBaseID() const { return header_->getBaseID(); } 77 119 Gamestate *diff(Gamestate *base); 78 Gamestate* intelligentDiff(Gamestate *base, unsigned int clientID);79 120 Gamestate *undiff(Gamestate *base); 80 Gamestate* intelligentUnDiff(Gamestate *base); 81 Gamestate* doSelection(unsigned int clientID); 121 Gamestate* doSelection(unsigned int clientID, unsigned int targetSize); 82 122 bool compressData(); 83 123 bool decompressData(); … … 85 125 // Packet functions 86 126 private: 87 virtual u nsigned int getSize() const;88 virtual bool process();127 virtual uint32_t getSize() const; 128 virtual inline bool process(); 89 129 90 130 bool operator ==(packet::Gamestate gs); 91 131 private: 92 u nsigned int calcGamestateSize(unsigned int id, uint8_t mode=0x0);93 void removeObject(ObjectListIterator<Synchronisable> &it);94 std::map<unsigned int, Synchronisable*> dataMap_;132 uint32_t calcGamestateSize(int32_t id, uint8_t mode=0x0); 133 std::list<obj> dataMap_; 134 GamestateHeader* header_; 95 135 }; 96 136 -
code/trunk/src/network/packet/Packet.cc
r2171 r2662 129 129 return false; 130 130 } 131 // Assures we don't create a packet and destroy it right after in another thread132 // without having a reference in the packetMap_133 boost::recursive_mutex::scoped_lock lock(Packet::packetMap_mutex);134 131 // We deliver ENet the data address so that it doesn't memcpy everything again. 135 132 // --> We have to delete data_ ourselves! … … 138 135 // Add the packet to a global list so we can access it again once enet calls our 139 136 // deletePacket method. We can of course only give a one argument function to the ENet C library. 140 packetMap_[(size_t)(void*)enetPacket_] = this; 137 { 138 // Assures we don't create a packet and destroy it right after in another thread 139 // without having a reference in the packetMap_ 140 boost::recursive_mutex::scoped_lock lock(Packet::packetMap_mutex); 141 packetMap_[(size_t)(void*)enetPacket_] = this; 142 } 141 143 } 142 144 #ifndef NDEBUG -
code/trunk/src/network/packet/Welcome.cc
r2171 r2662 32 32 #include "Welcome.h" 33 33 #include "network/Host.h" 34 #include "network/ Synchronisable.h"34 #include "network/synchronisable/Synchronisable.h" 35 35 #include "core/CoreIncludes.h" 36 36 #include <assert.h> … … 42 42 #define _PACKETID 0 43 43 #define _CLIENTID _PACKETID + sizeof(ENUM::Type) 44 #define _ SHIPID_CLIENTID + sizeof(uint32_t)45 46 Welcome::Welcome( u nsigned int clientID, unsigned int shipID )44 #define _ENDIANTEST _CLIENTID + sizeof(uint32_t) 45 46 Welcome::Welcome( uint32_t clientID, uint32_t shipID ) 47 47 : Packet() 48 48 { … … 52 52 assert(data_); 53 53 *(packet::ENUM::Type *)(data_ + _PACKETID ) = packet::ENUM::Welcome; 54 *(uint32_t *) &data_[ _CLIENTID ] = clientID;55 *(uint32_t *) &data_[ _SHIPID ] = shipID;54 *(uint32_t *)(data_ + _CLIENTID ) = static_cast<uint32_t>(clientID); 55 *(uint32_t *)(data_ + _ENDIANTEST ) = 0xFEDC4321; 56 56 } 57 57 58 Welcome::Welcome( uint8_t* data, u nsigned int clientID )58 Welcome::Welcome( uint8_t* data, uint32_t clientID ) 59 59 : Packet(data, clientID) 60 60 { … … 74 74 75 75 bool Welcome::process(){ 76 u nsigned int shipID,clientID;77 clientID = *(uint32_t *) &data_[ _CLIENTID ];78 shipID = *(uint32_t *)&data_[ _SHIPID ];76 uint32_t clientID; 77 clientID = *(uint32_t *)(data_ + _CLIENTID ); 78 assert(*(uint32_t *)(data_ + _ENDIANTEST ) == 0xFEDC4321); 79 79 Host::setClientID(clientID); 80 Host::setShipID(shipID); 81 COUT(3) << "Welcome set clientId: " << clientID << " shipID: " << shipID << std::endl; 80 COUT(3) << "Welcome set clientId: " << clientID << endl; 82 81 Synchronisable::setClient(true); 83 82 delete this; -
code/trunk/src/network/packet/Welcome.h
r2171 r2662 42 42 { 43 43 public: 44 Welcome( u nsigned int clientID, unsigned int shipID );45 Welcome( uint8_t* data, u nsigned int clientID );44 Welcome( uint32_t clientID, uint32_t shipID ); 45 Welcome( uint8_t* data, uint32_t clientID ); 46 46 virtual ~Welcome(); 47 47
Note: See TracChangeset
for help on using the changeset viewer.