Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/console/src/network/GameStateClient.cc @ 1438

Last change on this file since 1438 was 1438, checked in by landauf, 16 years ago

removed some other (potential) bugs or dangerous code lines

File size: 6.3 KB
RevLine 
[1056]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      ...
24 *   Co-authors:
25 *      ...
26 *
27 */
[1062]28
29#include "GameStateClient.h"
[1056]30
[777]31#include <zlib.h>
[514]32
[777]33#include "core/CoreIncludes.h"
34#include "Synchronisable.h"
[416]35
[777]36namespace network
[416]37{
[777]38  GameStateClient::GameStateClient() {
39  }
[416]40
[777]41  GameStateClient::~GameStateClient() {
42  }
[416]43
[777]44  bool GameStateClient::pushGameState(GameStateCompressed *compstate) {
[1021]45    GameState *gs;
[777]46    if(compstate->diffed)
[1021]47      gs = decode(reference, compstate);
[777]48    else
[1021]49      gs = decode(compstate);
50    if(gs)
51      return loadSnapshot(gs);
52    COUT(4) << "could not use gamestate sent by server" << std::endl;
53    return false;
[777]54  }
[416]55
[777]56  /**
57  * This function removes a Synchronisable out of the universe
58  * @param it iterator of the list pointing to the object
59  * @return iterator pointing to the next object in the list
60  */
61  void GameStateClient::removeObject(orxonox::Iterator<Synchronisable> &it) {
62    orxonox::Iterator<Synchronisable> temp=it;
63    ++it;
64    delete  *temp;
65  }
[416]66
[777]67  /**
68  * This function loads a Snapshort of the gamestate into the universe
69  * @param state a GameState struct containing the size of the gamestate and a pointer linking to a flat list (returned by getSnapshot)
70  */
[1021]71  bool GameStateClient::loadSnapshot(GameState *state) {
72    unsigned char *data=state->data;
73    COUT(4) << "loadSnapshot: loading gs: " << state->id << std::endl;
[777]74    // get the start of the Synchronisable list
75    orxonox::Iterator<Synchronisable> it=orxonox::ObjectList<Synchronisable>::start();
76    syncData sync;
77    // loop as long as we have some data ;)
[1021]78    while(data < state->data+state->size){
[777]79      // prepare the syncData struct
80      sync.length = (int)*data;
81      data+=sizeof(int);
82      sync.objectID = (int)*data;
83      data+=sizeof(int);
84      sync.classID = (int)*data;
85      data+=sizeof(int);
86      sync.data = data;
87      data+=sync.length;
[416]88
[777]89      if(it->objectID!=sync.objectID){
90        // bad luck ;)
91        // delete the synchronisable (obviously seems to be deleted on the server)
[1021]92        while(it && it->objectID!=sync.objectID)
[777]93          removeObject(it);
[1056]94
95
[1021]96        if(!it){
97          COUT(5) << "classid: " << sync.classID << ", name: " << ID((unsigned int) sync.classID)->getName() << std::endl;
98          Synchronisable *no = (Synchronisable*)(ID((unsigned int) sync.classID)->fabricate());
[777]99          no->objectID=sync.objectID;
100          no->classID=sync.classID;
101          it=orxonox::ObjectList<Synchronisable>::end();
102          // update data and create object/entity...
[1438]103          if( !no->updateData(sync) && !no->create() )
104          {
105            COUT(1) << "We couldn't create/update the object: " << sync.objectID << std::endl;
106          }
[777]107          ++it;
108        }
109      } else {
110        // we have our object
[1438]111        if(! it->updateData(sync))
112        {
[1021]113          COUT(1) << "We couldn't update objectID: " \
[1438]114          << sync.objectID << "; classID: " << sync.classID << std::endl;
115        }
[416]116      }
[777]117      ++it;
[416]118    }
[777]119
120    return true;
[416]121  }
[514]122
[1021]123  GameState *GameStateClient::undiff(GameState *a, GameState *b) {
124    unsigned char *ap = a->data, *bp = b->data;
[777]125    int of=0; // pointers offset
126    int dest_length=0;
[1021]127    if(a->size>=b->size)
128      dest_length=a->size;
[777]129    else
[1021]130      dest_length=b->size;
[777]131    unsigned char *dp = (unsigned char *)malloc(dest_length*sizeof(unsigned char));
[1021]132    while(of<a->size && of<b->size){
[777]133      *(dp+of)=*(ap+of)^*(bp+of); // do the xor
134      ++of;
135    }
[1021]136    if(a->size!=b->size){ // do we have to fill up ?
[777]137      unsigned char n=0;
[1021]138      if(a->size<b->size){
[777]139        while(of<dest_length){
140          *(dp+of)=n^*(bp+of);
141          of++;
142        }
143      } else{
144        while(of<dest_length){
145          *(dp+of)=*(ap+of)^n;
146          of++;
147        }
[416]148      }
149    }
[777]150    // should be finished now
[782]151    // FIXME: is it true or false now? (struct has changed, producing warnings)
[1021]152    GameState *r = new GameState;
153    r->id = b->id;
154    r->size = dest_length;
155    r->diffed = false;
156    r->data = dp;
[777]157    return r;
[416]158  }
159
[1021]160  GameState *GameStateClient::decompress(GameStateCompressed *a) {
161    int normsize = a->normsize;
162    int compsize = a->compsize;
[777]163    int bufsize;
164    if(normsize < compsize)
165      bufsize = compsize;
166    else
167      bufsize = normsize;
168    unsigned char* dest = (unsigned char*)malloc( bufsize );
169    int retval;
170    uLongf length=normsize;
171    //std::cout << "gamestateclient" << std::endl;
172    //std::cout << "normsize " << a.normsize << " compsize " << a.compsize << " " << bufsize << std::endl;
[1021]173    retval = uncompress( dest, &length, a->data, (uLong)compsize );
[777]174    //std::cout << "length " << length << std::endl;
175    switch ( retval ) {
[1021]176      case Z_OK: COUT(4) << "successfully decompressed" << std::endl; break;
177      case Z_MEM_ERROR: COUT(1) << "not enough memory available" << std::endl; return NULL;
178      case Z_BUF_ERROR: COUT(2) << "not enough memory available in the buffer" << std::endl; return NULL;
179      case Z_DATA_ERROR: COUT(2) << "data corrupted" << std::endl; return NULL;
[777]180    }
[416]181
[1021]182    GameState *gamestate = new GameState;
183    gamestate->id = a->id;
184    gamestate->size = normsize;
185    gamestate->data = dest;
186    gamestate->diffed = a->diffed;
[1056]187
[1021]188    delete a->data; //delete compressed data
189    delete a; //we do not need the old (struct) gamestate anymore
[777]190
191    return gamestate;
[416]192  }
[514]193
[1021]194  GameState *GameStateClient::decode(GameState *a, GameStateCompressed *x) {
195    GameState *t = decompress(x);
196    return undiff(a, t);
[777]197  }
[416]198
[1021]199  GameState *GameStateClient::decode(GameStateCompressed *x) {
200    GameState *t = decompress(x);
[777]201    return t;
202  }
[416]203
204}
Note: See TracBrowser for help on using the repository browser.