Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Feb 14, 2009, 10:17:35 PM (15 years ago)
Author:
rgrieder
Message:

Merged presentation branch back to trunk.

Location:
code/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/network/packet/Gamestate.cc

    r2171 r2662  
    2828
    2929#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"
    3234#include "core/CoreIncludes.h"
    3335#include "core/Iterator.h"
    3436
    3537#include <zlib.h>
    36 #include <assert.h>
     38#include <cassert>
    3739
    3840
     
    4244namespace packet {
    4345
    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())
    4847
    4948#define PACKET_FLAG_GAMESTATE  ENET_PACKET_FLAG_RELIABLE
    5049
     50// Gamestate::Gamestate()
     51// {
     52//   flags_ = flags_ | PACKET_FLAG_GAMESTATE;
     53// }
     54
    5155Gamestate::Gamestate()
    5256{
    5357  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
     58  header_ = 0;
    5459}
    5560
     
    5863{
    5964  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
     65  header_ = new GamestateHeader(data_);
    6066}
    6167
     
    6470  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
    6571  data_=data;
     72  header_ = new GamestateHeader(data_);
     73}
     74
     75Gamestate::Gamestate(const Gamestate& g) :
     76    Packet( *(Packet*)&g )
     77{
     78  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
     79  header_ = new GamestateHeader(data_);
    6680}
    6781
     
    7387bool Gamestate::collectData(int id, uint8_t mode)
    7488{
    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;
    7691  assert(data_==0);
    77   unsigned int size = calcGamestateSize(id, mode);
     92  uint32_t size = calcGamestateSize(id, mode);
    7893
    7994  COUT(4) << "G.ST.Man: producing gamestate with id: " << id << std::endl;
    8095  if(size==0)
    8196    return false;
    82   data_ = new unsigned char[size + sizeof(GamestateHeader)];
     97  data_ = new uint8_t[size + GamestateHeader::getSize()];
    8398  if(!data_){
    8499    COUT(2) << "GameStateManager: could not allocate memory" << std::endl;
    85100    return false;
    86101  }
     102 
     103  // create the header object
     104  header_ = new GamestateHeader(data_);
    87105
    88106  //start collect data synchronisable by synchronisable
    89107  uint8_t *mem=data_;
    90   mem+=sizeof(GamestateHeader);
     108  mem += GamestateHeader::getSize();
    91109  ObjectList<Synchronisable>::iterator it;
    92110  for(it = ObjectList<Synchronisable>::begin(); it; ++it){
     111   
     112#ifndef NDEBUG
    93113    tempsize=it->getSize(id, mode);
    94 
    95114    if(currentsize+tempsize > size){
    96115      assert(0); // if we don't use multithreading this part shouldn't be neccessary
     
    98117      COUT(3) << "G.St.Man: need additional memory" << std::endl;
    99118      ObjectList<Synchronisable>::iterator temp = it;
    100       int addsize=tempsize;
     119      uint32_t addsize=tempsize;
    101120      while(++temp)
    102121        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);
    104123      if(!data_)
    105124        return false;
    106125      size = currentsize+addsize;
    107126    }// stop allocate additional memory
    108 
     127#endif
    109128
    110129    //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
    112133    if(!it->getData(mem, id, mode))
    113134      return false; // mem pointer gets automatically increased because of call by reference
     
    118139
    119140  //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 );
    126146  //stop write gamestate header
    127147
     
    133153bool Gamestate::spreadData(uint8_t mode)
    134154{
    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();
    139160    // get the start of the Synchronisable list
    140161  //ObjectList<Synchronisable>::iterator it=ObjectList<Synchronisable>::begin();
     
    142163
    143164  // 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() );
    148169    if(!s)
    149170    {
    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;
    151182    }
    152183    else
     
    157188  }
    158189
     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
    159216  return true;
    160217}
    161218
    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);
     219uint32_t Gamestate::getSize() const
     220{
     221  assert(data_);
     222  if(header_->isCompressed())
     223    return header_->getCompSize()+GamestateHeader::getSize();
    173224  else
    174225  {
    175     return HEADER->datasize+sizeof(GamestateHeader);
     226    return header_->getDataSize()+GamestateHeader::getSize();
    176227  }
    177228}
    178229
    179230bool 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();
    182233  assert(!isCompressed());
    183234  assert(!gs.isCompressed());
    184   while(d1<data_+HEADER->datasize)
     235  while(d1<data_+header_->getDataSize())
    185236  {
    186237    if(*d1!=*d2)
     
    201252bool Gamestate::compressData()
    202253{
    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);
    206257  if(buffer==0)
    207258    return false;
    208259
    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();
    211262  //unsigned char *dest = new unsigned char[buffer];
    212   uint8_t *source = GAMESTATE_START(data_);
     263  uint8_t *source = data_ + GamestateHeader::getSize();
    213264  int retval;
    214   retval = compress( dest, &buffer, source, (uLong)(HEADER->datasize) );
     265  retval = compress( dest, &buffer, source, (uLong)(header_->getDataSize()) );
    215266  switch ( retval ) {
    216267    case Z_OK: COUT(5) << "G.St.Man: compress: successfully compressed" << std::endl; break;
     
    219270    case Z_DATA_ERROR: COUT(2) << "G.St.Man: compress: data corrupted in gamestate.compress" << std::endl; return false;
    220271  }
    221 #ifndef NDEBUG
    222   //decompress and compare the start and the decompressed data
    223   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 #endif
    232272
    233273  //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;
    238277  //delete old data
    239278  delete[] data_;
    240279  //save new data
    241280  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;
    246284  return true;
    247285}
    248286bool Gamestate::decompressData()
    249287{
    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   unsigned int datasize = HEADER->datasize;
    254   unsigned int compsize = HEADER->compsize;
    255   unsigned 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;
    256294//  assert(compsize<=datasize);
    257295  bufsize = datasize;
    258296  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();
    262300  int retval;
    263301  uLongf length=bufsize;
     
    269307    case Z_DATA_ERROR: COUT(2) << "data corrupted (zlib)" << std::endl; return false;
    270308  }
    271 #ifndef NDEBUG
    272   assert(HEADER->crc32==calcCRC(ndata+sizeof(GamestateHeader), HEADER->datasize));
    273 #endif
    274309
    275310  //copy over the header
    276   *GAMESTATE_HEADER(ndata) = *HEADER;
     311  GamestateHeader *temp = header_;
     312  header_ = new GamestateHeader( data_, header_ );
     313  delete temp;
    277314
    278315  if (this->bDataENetAllocated_){
     
    289326  //set new pointers
    290327  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);
    294331  return true;
    295332}
     
    297334Gamestate *Gamestate::diff(Gamestate *base)
    298335{
    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_);
    302340  //unsigned char *basep = base->getGs()/*, *gs = getGs()*/;
    303341  uint8_t *basep = GAMESTATE_START(base->data_), *gs = GAMESTATE_START(this->data_);
    304   unsigned int of=0; // pointers offset
    305   unsigned 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();
    307345  if(dest_length==0)
    308346    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()){
    312350    *(dest+of)=*(basep+of)^*(gs+of); // do the xor
    313351    ++of;
    314352  }
    315   if(GAMESTATE_HEADER(base->data_)->datasize!=HEADER->datasize){
     353  if(diffHeader.getDataSize()!=header_->getDataSize()){
    316354    uint8_t n=0;
    317     if(GAMESTATE_HEADER(base->data_)->datasize < HEADER->datasize){
     355    if(diffHeader.getDataSize() < header_->getDataSize()){
    318356      while(of<dest_length){
    319357        *(dest+of)=n^*(gs+of);
     
    323361  }
    324362
    325   *GAMESTATE_HEADER(ndata) = *HEADER;
    326   GAMESTATE_HEADER(ndata)->diffed = true;
    327   GAMESTATE_HEADER(ndata)->base_id = base->getID();
    328363  Gamestate *g = new Gamestate(ndata, getClientID());
     364  *(g->header_) = *header_;
     365  g->header_->setDiffed( true );
     366  g->header_->setBaseID( base->getID() );
    329367  g->flags_=flags_;
    330368  g->packetDirection_ = packetDirection_;
     
    332370}
    333371
    334 Gamestate* Gamestate::doSelection(unsigned int clientID){
    335   assert(data_);
    336   std::map<unsigned int, Synchronisable *>::iterator it;
     372Gamestate* Gamestate::doSelection(unsigned int clientID, unsigned int targetSize){
     373  assert(data_);
     374  std::list<obj>::iterator it;
    337375
    338376  // 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()];
    340378  // create a gamestate out of it
    341379  Gamestate *gs = new Gamestate(gdata);
    342   uint8_t *newdata = gdata + sizeof(GamestateHeader);
     380  uint8_t *newdata = gdata + GamestateHeader::getSize();
    343381  uint8_t *origdata = GAMESTATE_START(data_);
    344382
    345383  //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_ );
    350394
    351395  //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;
    362416    }else{
    363       newobjectheader->dataAvailable=false;
     417      newobjectheader = oldobjectheader;
     418      newobjectheader.setDataAvailable(false);
    364419      memset(newdata+objectOffset, 0, objectsize-objectOffset);
    365       assert(objectOffset==objectsize);
    366420    }
    367421    newdata += objectsize;
    368422    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 );
    370438  return gs;
    371439}
    372440
    373441
    374 Gamestate* Gamestate::intelligentDiff(Gamestate *base, unsigned int clientID){
    375   // asserts
    376   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   //preparations
    384   std::map<unsigned int, Synchronisable *>::iterator it;
    385   uint8_t *origdata, *basedata, *destdata, *ndata;
    386   unsigned int objectOffset, streamOffset=0;    //data offset
    387   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 diff
    397   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 header
    404     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 zeros
    418     while(objectOffset<origheader->size ){
    419 
    420       if(sendData && streamOffset<minsize)
    421         *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor
    422       else if(sendData)
    423         *(destdata+objectOffset)=((uint8_t)0)^*(origdata+objectOffset); // xor with 0 (basestream is too short)
    424       else
    425         *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered
    426 
    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 flag
    436   *(GamestateHeader *)ndata = *HEADER; //copy over the header
    437   Gamestate *gs = new Gamestate(ndata);
    438   GAMESTATE_HEADER(ndata)->diffed=true;
    439   return gs;
    440 }
    441 
    442 Gamestate* Gamestate::intelligentUnDiff(Gamestate *base){
    443   // asserts
    444   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   //preparations
    452   std::map<unsigned int, Synchronisable *>::iterator it;
    453   uint8_t *origdata, *basedata, *destdata, *ndata;
    454   unsigned int objectOffset, streamOffset=0;    //data offset
    455   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 undiff
    465   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 header
    472     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 zeros
    487     while(objectOffset<origheader->size ){
    488 
    489       if(sendData && streamOffset<minsize)
    490         *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor
    491       else if(sendData)
    492         *(destdata+objectOffset)=((unsigned char)0)^*(origdata+objectOffset); // xor with 0 (basestream is too short)
    493       else
    494         *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered
    495 
    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 flag
    505   *(GamestateHeader *)ndata = *HEADER; //copy over the header
    506   Gamestate *gs = new Gamestate(ndata);
    507   GAMESTATE_HEADER(ndata)->diffed=false;
    508   return gs;
    509 }
    510 
    511442Gamestate *Gamestate::undiff(Gamestate *base)
    512443{
    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());
    516447  //unsigned char *basep = base->getGs()/*, *gs = getGs()*/;
    517448  uint8_t *basep = GAMESTATE_START(base->data_);
    518449  uint8_t *gs = GAMESTATE_START(this->data_);
    519   unsigned int of=0; // pointers offset
    520   unsigned 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();
    522453  if(dest_length==0)
    523454    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()){
    527458    *(dest+of)=*(basep+of)^*(gs+of); // do the xor
    528459    ++of;
    529460  }
    530   if(GAMESTATE_HEADER(base->data_)->datasize!=HEADER->datasize){
     461  if(base->header_->getDataSize()!=header_->getDataSize()){
    531462    uint8_t n=0;
    532     if(GAMESTATE_HEADER(base->data_)->datasize < HEADER->datasize){
     463    if(base->header_->getDataSize() < header_->getDataSize()){
    533464      while(of < dest_length){
    534465        *(dest+of)=n^*(gs+of);
     
    537468    }
    538469  }
    539   *GAMESTATE_HEADER(ndata) = *HEADER;
    540   GAMESTATE_HEADER(ndata)->diffed = false;
    541470  Gamestate *g = new Gamestate(ndata, getClientID());
     471  assert(g->header_);
     472  *(g->header_) = *header_;
     473  g->header_->setDiffed( false );
    542474  g->flags_=flags_;
    543475  g->packetDirection_ = packetDirection_;
     
    548480
    549481
    550 unsigned int Gamestate::calcGamestateSize(unsigned int id, uint8_t mode)
    551 {
    552   unsigned int size=0;
     482uint32_t Gamestate::calcGamestateSize(int32_t id, uint8_t mode)
     483{
     484  uint32_t size=0;
    553485    // get the start of the Synchronisable list
    554486  ObjectList<Synchronisable>::iterator it;
     
    556488  for(it = ObjectList<Synchronisable>::begin(); it; ++it)
    557489    size+=it->getSize(id, mode); // size of the actual data of the synchronisable
    558 //  size+=sizeof(GamestateHeader);
    559490  return size;
    560491}
    561492
    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
Note: See TracChangeset for help on using the changeset viewer.