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:
9 edited

Legend:

Unmodified
Added
Removed
  • code/trunk

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

    r2171 r2662  
    6464
    6565bool Acknowledgement::process(){
     66COUT(0) << "processing ACK with ID: " << getAckID() << endl;
    6667  bool b = GamestateHandler::ackGamestate(getAckID(), clientID_);
    6768  delete this;
  • code/trunk/src/network/packet/Acknowledgement.h

    r2171 r2662  
    3232#include "Packet.h"
    3333
     34const unsigned int ACKID_NACK = 0;
    3435
    3536namespace orxonox {
  • code/trunk/src/network/packet/DeleteObjects.cc

    r2171 r2662  
    3030#include "DeleteObjects.h"
    3131#include <enet/enet.h>
    32 #include "network/Synchronisable.h"
     32#include "network/synchronisable/Synchronisable.h"
    3333#include "core/CoreIncludes.h"
    3434#include <assert.h>
     
    6161  if(number==0)
    6262    return false;
    63   COUT(3) << "sending DeleteObjects: ";
     63  COUT(4) << "sending DeleteObjects: ";
    6464  unsigned int size = sizeof(ENUM::Type) + sizeof(uint32_t)*(number+1);
    6565  data_ = new uint8_t[size];
    6666  uint8_t *tdata = data_;
    67   *(ENUM::Type *)(tdata) = ENUM::DeleteObjects;
     67  *reinterpret_cast<ENUM::Type*>(tdata) = ENUM::DeleteObjects;
    6868  tdata += sizeof(ENUM::Type);
    6969  *(uint32_t *)tdata = number;
     
    7272    unsigned int temp = Synchronisable::popDeletedObject();
    7373//     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 << " ";
    7676    tdata += sizeof(uint32_t);
    7777  }
    78   COUT(3) << std::endl;
     78  COUT(4) << std::endl;
    7979  return true;
    8080}
     
    8787bool DeleteObjects::process(){
    8888  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;
    9090    Synchronisable::deleteObject( *(uint32_t*)(data_+_OBJECTIDS+i*sizeof(uint32_t)) );
    9191  }
  • 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
  • code/trunk/src/network/packet/Gamestate.h

    r2171 r2662  
    3131#define NETWORK_PACKETGAMESTATE_H
    3232
    33 #include "../NetworkPrereqs.h"
     33#include "network/NetworkPrereqs.h"
    3434
    3535#include "Packet.h"
    36 #include "network/Synchronisable.h"
     36#include "network/TrafficControl.h"
     37#include "core/CoreIncludes.h"
    3738#include <map>
     39#include <list>
    3840#ifndef NDEBUG
    3941#include "util/CRC32.h"
     
    4446namespace packet {
    4547
    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
     48class _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
    5899};
    59100
     
    66107    Gamestate(uint8_t *data, unsigned int clientID);
    67108    Gamestate(uint8_t *data);
     109    Gamestate(const Gamestate& g);
    68110
    69111    ~Gamestate();
     
    71113    bool collectData(int id, uint8_t mode=0x0);
    72114    bool spreadData( uint8_t mode=0x0);
    73     int getID();
    74     bool isDiffed();
    75     bool isCompressed();
    76     int 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(); }
    77119    Gamestate *diff(Gamestate *base);
    78     Gamestate* intelligentDiff(Gamestate *base, unsigned int clientID);
    79120    Gamestate *undiff(Gamestate *base);
    80     Gamestate* intelligentUnDiff(Gamestate *base);
    81     Gamestate* doSelection(unsigned int clientID);
     121    Gamestate* doSelection(unsigned int clientID, unsigned int targetSize);
    82122    bool compressData();
    83123    bool decompressData();
     
    85125    // Packet functions
    86126  private:
    87     virtual unsigned int getSize() const;
    88     virtual bool process();
     127    virtual uint32_t getSize() const;
     128    virtual inline bool process();
    89129
    90130    bool operator ==(packet::Gamestate gs);
    91131  private:
    92     unsigned 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_;
    95135};
    96136
  • code/trunk/src/network/packet/Packet.cc

    r2171 r2662  
    129129      return false;
    130130    }
    131     // Assures we don't create a packet and destroy it right after in another thread
    132     // without having a reference in the packetMap_
    133     boost::recursive_mutex::scoped_lock lock(Packet::packetMap_mutex);
    134131    // We deliver ENet the data address so that it doesn't memcpy everything again.
    135132    // --> We have to delete data_ ourselves!
     
    138135    // Add the packet to a global list so we can access it again once enet calls our
    139136    // 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    }
    141143  }
    142144#ifndef NDEBUG
  • code/trunk/src/network/packet/Welcome.cc

    r2171 r2662  
    3232#include "Welcome.h"
    3333#include "network/Host.h"
    34 #include "network/Synchronisable.h"
     34#include "network/synchronisable/Synchronisable.h"
    3535#include "core/CoreIncludes.h"
    3636#include <assert.h>
     
    4242#define _PACKETID             0
    4343#define _CLIENTID             _PACKETID + sizeof(ENUM::Type)
    44 #define _SHIPID               _CLIENTID + sizeof(uint32_t)
    45  
    46   Welcome::Welcome( unsigned int clientID, unsigned int shipID )
     44#define _ENDIANTEST           _CLIENTID + sizeof(uint32_t)
     45
     46  Welcome::Welcome( uint32_t clientID, uint32_t shipID )
    4747 : Packet()
    4848{
     
    5252  assert(data_);
    5353  *(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;
    5656}
    5757
    58 Welcome::Welcome( uint8_t* data, unsigned int clientID )
     58Welcome::Welcome( uint8_t* data, uint32_t clientID )
    5959  : Packet(data, clientID)
    6060{
     
    7474
    7575bool Welcome::process(){
    76   unsigned 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);
    7979  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;
    8281  Synchronisable::setClient(true);
    8382  delete this;
  • code/trunk/src/network/packet/Welcome.h

    r2171 r2662  
    4242{
    4343public:
    44   Welcome( unsigned int clientID, unsigned int shipID );
    45   Welcome( uint8_t* data, unsigned int clientID );
     44  Welcome( uint32_t clientID, uint32_t shipID );
     45  Welcome( uint8_t* data, uint32_t clientID );
    4646  virtual ~Welcome();
    4747
Note: See TracChangeset for help on using the changeset viewer.