Index: code/branches/network3/src/network/Client.cc
===================================================================
--- code/branches/network3/src/network/Client.cc	(revision 1191)
+++ code/branches/network3/src/network/Client.cc	(revision 1199)
@@ -230,8 +230,9 @@
     int id = data->id;
     COUT(5) << "received gamestate id: " << data->id << std::endl;
-    gamestate.pushGameState(data);
-    client_connection.addPacket(pck_gen.acknowledgement(id));
-    client_connection.sendPackets();
-    return;
+    if(gamestate.pushGameState(data)){
+      client_connection.addPacket(pck_gen.acknowledgement(id));
+      if(!client_connection.sendPackets())
+        COUT(2) << "Could not send acknowledgment" << std::endl;
+    }
   }
 
Index: code/branches/network3/src/network/GameStateClient.cc
===================================================================
--- code/branches/network3/src/network/GameStateClient.cc	(revision 1191)
+++ code/branches/network3/src/network/GameStateClient.cc	(revision 1199)
@@ -34,4 +34,6 @@
 #include "core/BaseObject.h"
 #include "Synchronisable.h"
+
+#define GAMESTATEID_INITIAL -1
 
 namespace network
@@ -44,4 +46,5 @@
   GameStateClient::GameStateClient() {
     COUT(5) << "this: " << this << std::endl;
+    last_diff_=0;
   }
 
@@ -50,23 +53,34 @@
 
   bool GameStateClient::pushGameState(GameStateCompressed *compstate) {
-    GameState *gs;
-    if(compstate->diffed){
-      while(compstate->base_id > gameStateList.front()->id){
-        // clean up old gamestates
-        free(gameStateList.front()->data);
-        // TODO: critical section
-        delete gameStateList.front();
-        gameStateList.pop();
-      }
-      if(compstate->base_id!=gameStateList.front()->id){
+    cleanup();
+    printGameStateMap();
+    GameState *gs, *reference;
+    if(compstate->diffed && compstate->base_id!=GAMESTATEID_INITIAL){
+      std::map<int, GameState*>::iterator it = gameStateMap.find(compstate->base_id);
+      if(it!=gameStateMap.end())
+        reference = (it)->second;
+      else
+        reference = NULL;
+      if(!reference){
         COUT(4) << "pushGameState: no reference found to diff" << std::endl;
         return false;
       }
-      gs = decode(gameStateList.front(), compstate);
+      gs = decode(reference, compstate);
     }
     else
       gs = decode(compstate);
-    if(gs)
-      return loadSnapshot(gs);
+    if(gs){
+      if (loadSnapshot(gs)){
+        gameStateMap.insert(std::pair<int, GameState*>(gs->id, gs));
+        COUT(4) << "adding decoded gs with id: " << gs->id << " diffed from: " << gs->base_id << std::endl;
+        last_diff_=gs->base_id;
+        return true;
+      }else{
+        COUT(4) << "could not decode gs with id: " << gs->id << " diffed from: " << gs->base_id << std::endl;
+        delete[] gs->data;
+        delete gs;
+        return false;
+      }
+    }
     COUT(4) << "could not use gamestate sent by server" << std::endl;
     return false;
@@ -117,5 +131,10 @@
           ///sigsegv may happen here again for some reason
           ///sigsegv is receved after the COUT(4) above
-          Synchronisable *no = dynamic_cast<Synchronisable *>(ID((unsigned int) sync.classID)->fabricate());
+          orxonox::Identifier* id = ID((unsigned int)sync.classID);
+          if(!id){
+            COUT(4) << "We could not identify a new object" << std::endl;
+            continue;
+          }
+          Synchronisable *no = dynamic_cast<Synchronisable *>(id->fabricate());
           COUT(4) << "loadsnapshort: classid: " << sync.classID << " objectID: " << sync.objectID << " length: " << sync.length << std::endl;
           no->objectID=sync.objectID;
@@ -140,20 +159,21 @@
   }
 
-  GameState *GameStateClient::undiff(GameState *a, GameState *b) {
-    unsigned char *ap = a->data, *bp = b->data;
+  GameState *GameStateClient::undiff(GameState *old, GameState *diff) {
+    unsigned char *ap = old->data, *bp = diff->data;
     int of=0; // pointers offset
     int dest_length=0;
-    if(a->size>=b->size)
-      dest_length=a->size;
+    if(old->size>=diff->size)
+      dest_length=old->size;
     else
-      dest_length=b->size;
-    unsigned char *dp = (unsigned char *)malloc(dest_length*sizeof(unsigned char));
-    while(of<a->size && of<b->size){
+      dest_length=diff->size;
+//     unsigned char *dp = (unsigned char *)malloc(dest_length*sizeof(unsigned char));
+    unsigned char *dp = new unsigned char[dest_length*sizeof(unsigned char)];
+    while(of<old->size && of<diff->size){
       *(dp+of)=*(ap+of)^*(bp+of); // do the xor
       ++of;
     }
-    if(a->size!=b->size){ // do we have to fill up ?
+    if(old->size!=diff->size){ // do we have to fill up ?
       unsigned char n=0;
-      if(a->size<b->size){
+      if(old->size<diff->size){
         while(of<dest_length){
           *(dp+of)=n^*(bp+of);
@@ -170,6 +190,7 @@
     // FIXME: is it true or false now? (struct has changed, producing warnings)
     GameState *r = new GameState;
-    r->id = b->id;
+    r->id = diff->id;
     r->size = dest_length;
+    r->base_id = diff->base_id;
     r->diffed = false;
     r->data = dp;
@@ -196,5 +217,6 @@
     else
       bufsize = normsize;
-    unsigned char* dest = (unsigned char*)malloc( bufsize );
+//     unsigned char* dest = (unsigned char*)malloc( bufsize );
+    unsigned char *dest = new unsigned char[bufsize];
     int retval;
     uLongf length=normsize;
@@ -216,5 +238,5 @@
     gamestate->diffed = a->diffed;
 
-    delete a->data; //delete compressed data
+    delete[] a->data; //delete compressed data
     delete a; //we do not need the old (struct) gamestate anymore
 
@@ -222,9 +244,9 @@
   }
 
-  GameState *GameStateClient::decode(GameState *a, GameStateCompressed *x) {
-    GameState *t = decode(x);
-    gameStateList.push(t);
-    //return undiff(a, t);
-    return t;
+  GameState *GameStateClient::decode(GameState *old, GameStateCompressed *diff) {
+    COUT(4) << "using diffed gamestate" << std::endl;
+    GameState *t = decode(diff);
+    return undiff(old, t);
+//     return t;
   }
 
@@ -237,7 +259,29 @@
     t->data = x->data;
     t->size = x->normsize;
-    gameStateList.push(t);
     return t;
   }
-
+  
+  void GameStateClient::cleanup(){
+    std::map<int, GameState*>::iterator temp, it = gameStateMap.begin();
+    while(it!=gameStateMap.end()){
+      if(it->first>=last_diff_)
+        break;
+      // otherwise delete that stuff
+      delete[] (*it).second->data;
+      delete (*it).second;
+      temp=it++;
+      gameStateMap.erase(temp);
+    }
+  }
+
+  void GameStateClient::printGameStateMap(){
+    std::map<int, GameState*>::iterator it;
+    COUT(4) << "gamestates: ";
+    for(it=gameStateMap.begin(); it!=gameStateMap.end(); it++){
+      COUT(4) << it->first << ":" << it->second << "|";
+    }
+    COUT(4) << std::endl;
+    
+  }
+  
 }
Index: code/branches/network3/src/network/GameStateClient.h
===================================================================
--- code/branches/network3/src/network/GameStateClient.h	(revision 1191)
+++ code/branches/network3/src/network/GameStateClient.h	(revision 1199)
@@ -41,5 +41,5 @@
 #define _GameStateClient_H__
 
-#include <queue>
+#include <map>
 
 #include "NetworkPrereqs.h"
@@ -61,12 +61,15 @@
   private:
     bool loadSnapshot(GameState *state);
-    GameState *undiff(GameState *a, GameState *b);
+    void cleanup();
+    GameState *undiff(GameState *old, GameState *diff);
     GameState *decompress(GameStateCompressed *a);
-    GameState *decode(GameState *a, GameStateCompressed *x);
+    GameState *decode(GameState *old, GameStateCompressed *diff);
     GameState *decode(GameStateCompressed *x);
     void removeObject(orxonox::Iterator<Synchronisable> &it);
+    void printGameStateMap();
 
     GameState     *reference;
-    std::queue<GameState *> gameStateList;
+    int           last_diff_;
+    std::map<int, GameState *> gameStateMap;
   };
 
Index: code/branches/network3/src/network/GameStateManager.cc
===================================================================
--- code/branches/network3/src/network/GameStateManager.cc	(revision 1191)
+++ code/branches/network3/src/network/GameStateManager.cc	(revision 1199)
@@ -52,5 +52,5 @@
 {
   GameStateManager::GameStateManager(ClientInformation *head) {
-    id=0;
+    id_=0;
     head_=head;
   }
@@ -61,8 +61,9 @@
   void GameStateManager::update(){
     cleanup();
-    reference = getSnapshot(id);
-    gameStateMap.insert(std::pair<int, GameState*>(id, reference));
-    gameStateUsed[id]=0;
-    ++id;
+    reference = getSnapshot();
+    COUT(4) << "inserting gamestate: " << reference << std::endl;
+    gameStateMap.insert(std::pair<int, GameState*>(id_, reference));
+    gameStateUsed[id_]=0;
+    printGameStates();
     return;
   }
@@ -79,10 +80,15 @@
     while(it!=gameStateUsed.end()){
       if( (*it).second <= 0 ){
-        free(gameStateMap[(*it).first]->data);
+        COUT(4) << "GameStateManager: deleting gamestate with id: " << (*it).first << ", uses: " << (*it).second << std::endl;
+        delete[] gameStateMap[(*it).first]->data;
         delete gameStateMap[(*it).first];
         gameStateMap.erase((*it).first);
         gameStateUsed.erase(it++);
-      }else  //as soon as we got a used gamestate break here because we could use newer gamestates in future
+        continue;
+      }else if(id_-it->first<=KEEP_GAMESTATES){  //as soon as we got a used gamestate break here because we could use newer gamestates in future but only if we do not exceed KEEP_GAMESTATES # of gamestates in cache
+        COUT(4) << "breaking " << std::endl;
         break;
+      }
+      it++;
     }
   }
@@ -92,14 +98,21 @@
     //Server::sendGameState?
     int gID = head_->findClient(clientID)->getGamestateID();
-    COUT(4) << "G.St.Man: popgamestate: sending gstate_id: " << id << " diffed from: " << gID << " (not diffed yet)" << std::endl;
-    
+    COUT(4) << "G.St.Man: popgamestate: sending gstate_id: " << id_ << " diffed from: " << gID << " (not diffed yet)" << std::endl;
+//     COUT(3) << "gamestatemap: " << &gameStateMap << std::endl;
     //chose wheather the next gamestate is the first or not
     if(gID != GAMESTATEID_INITIAL){
-      GameState *client = gameStateMap[gID];
+      // TODO something with the gamestatemap is wrong
+      GameState *client = gameStateMap.find(gID)->second;
       GameState *server = reference;
       //head_->findClient(clientID)->setGamestateID(id);
-      return encode(client, server);
+      COUT(3) << "client: " << client << " server: " << server << " gamestatemap: " << &gameStateMap << std::endl;
+      if(client)
+        return encode(client, server);
+      else
+        return encode(server);
     } else {
+      COUT(4) << "we got a GAMESTATEID_INITIAL for clientID: " << clientID << std::endl;
       GameState *server = reference;
+      ackGameState(clientID, reference->id);
       //head_->findClient(clientID)->setGamestateID(id);
       return encode(server);
@@ -113,10 +126,10 @@
   * @return struct of type gamestate containing the size of the whole gamestate and a pointer linking to the flat list
   */
-  GameState *GameStateManager::getSnapshot(int id)
+  GameState *GameStateManager::getSnapshot()
   {
     //std::cout << "begin getSnapshot" << std::endl;
     //the size of the gamestate
     int totalsize=0;
-    int memsize=1000;
+    int memsize=0;
     //the size of one specific synchronisable
     int tempsize=0;
@@ -127,5 +140,5 @@
 
     GameState *retval=new GameState; //return value
-    retval->id=id++;
+    retval->id=++id_;
     COUT(4) << "G.ST.Man: producing gamestate with id: " << retval->id << std::endl;
     // offset of memory functions
@@ -133,8 +146,9 @@
     // get total size of gamestate
     for(it = orxonox::ObjectList<Synchronisable>::start(); it; ++it){
-      size+=it->getSize();
-      size+=3*sizeof(int);
-    }
-    retval->data = (unsigned char*)malloc(size);
+      size+=it->getSize(); // size of the actual data of the synchronisable
+      size+=3*sizeof(int); // size of datasize, classID and objectID
+    }
+    //retval->data = (unsigned char*)malloc(size);
+    retval->data = new unsigned char[size];
     if(!retval->data){
       COUT(2) << "GameStateManager: could not allocate memory" << std::endl;
@@ -148,7 +162,7 @@
       // add place for data and 3 ints (length,classid,objectid)
       totalsize+=tempsize+3*sizeof(int);
-      // allocate additional space
-      if((totalsize+tempsize) > memsize){
-        COUT(5) << "G.St.Man: need additional memory" << std::endl;
+      // allocate+tempsize additional space
+      if(totalsize > size){
+        COUT(3) << "G.St.Man: need additional memory" << std::endl;
 //         if(tempsize < 1000){
 //           retval->data = (unsigned char *)realloc((void *)retval->data, totalsize+1000);
@@ -190,16 +204,16 @@
   GameStateCompressed *GameStateManager::encode(GameState *a, GameState *b) {
     COUT(5) << "G.St.Man: this will be a DIFFED gamestate" << std::endl;
-    //GameState r = diff(a,b);
+    GameState *r = diff(a,b);
     //r.diffed = true;
-    GameState *r = b;
-    r->diffed = false;
+//     GameState *r = b;
+//     r->diffed = false;
     //return compress_(r);
     GameStateCompressed *g = new GameStateCompressed;
-    g->base_id = b->base_id;
-    g->id = b->id;
-    g->diffed = b->diffed;
-    g->data = b->data;
-    g->normsize = b->size;
-    g->compsize = b->size;
+    g->base_id = r->base_id;
+    g->id = r->id;
+    g->diffed = r->diffed;
+    g->data = r->data;
+    g->normsize = r->size;
+    g->compsize = r->size;
     return g;
   }
@@ -226,5 +240,6 @@
     else
       dest_length=b->size;
-    unsigned char *dp = (unsigned char *)malloc(dest_length*sizeof(unsigned char));
+    //unsigned char *dp = (unsigned char *)malloc(dest_length*sizeof(unsigned char));
+    unsigned char *dp = new unsigned char[dest_length*sizeof(unsigned char)];
     while(of<a->size && of<b->size){
       *(dp+of)=*(ap+of)^*(bp+of); // do the xor
@@ -263,5 +278,6 @@
     uLongf buffer = (uLongf)((a->size + 12)*1.01)+1;
     //COUT(4) << "size: " << size << ", buffer: " << buffer << std::endl;
-    unsigned char* dest = (unsigned char*)malloc( buffer );
+    //unsigned char* dest = (unsigned char*)malloc( buffer );
+    unsigned char *dest = new unsigned char[buffer];
     //COUT(4) << "dest: " << dest << std::endl;
     int retval;
@@ -296,9 +312,11 @@
   void GameStateManager::ackGameState(int clientID, int gamestateID) {
     ClientInformation *temp = head_->findClient(clientID);
-    int curid = temp->getID();
+    int curid = temp->getGamestateID();
+    COUT(4) << "acking gamestate " << gamestateID << " for clientid: " << clientID << " curid: " << curid << std::endl;
     // decrease usage of gamestate and save it
-    deleteUnusedGameState(curid);
+//     deleteUnusedGameState(curid);
     //increase gamestateused
-    ++gameStateUsed.find(gamestateID)->second;
+    --(gameStateUsed.find(curid)->second);
+    ++(gameStateUsed.find(gamestateID)->second);
     temp->setGamestateID(gamestateID);
     /*
@@ -308,13 +326,11 @@
   }
 
-  bool GameStateManager::deleteUnusedGameState(int gamestateID) {
-    int used = --(gameStateUsed.find(gamestateID)->second);
-    if(id-gamestateID>KEEP_GAMESTATES && used==0){
-      // delete gamestate
-      delete gameStateMap.find(gamestateID)->second;
-      gameStateMap.erase(gamestateID);
-      return true;
-    }
-    return false;
+  bool GameStateManager::printGameStates() {
+    std::map<int, GameState*>::iterator it;
+    COUT(4) << "gamestates: ";
+    for(it = gameStateMap.begin(); it!=gameStateMap.end(); it++){
+      COUT(4) << (*it).first << ":" << (*it).second << " | ";
+    }
+    COUT(4) << std::endl;
   }
 
Index: code/branches/network3/src/network/GameStateManager.h
===================================================================
--- code/branches/network3/src/network/GameStateManager.h	(revision 1191)
+++ code/branches/network3/src/network/GameStateManager.h	(revision 1199)
@@ -50,5 +50,5 @@
 {
 
-#define KEEP_GAMESTATES 20
+#define KEEP_GAMESTATES 100
 
   /**
@@ -78,13 +78,12 @@
     GameStateCompressed *popGameState(int clientID);
     void ackGameState(int clientID, int gamestateID);
-    int id;
   private:
     void cleanup(); // "garbage handler"
-    GameState *getSnapshot(int id);
+    GameState *getSnapshot();
     GameStateCompressed *encode(GameState *a, GameState *b);
     GameStateCompressed *encode(GameState *a);
     GameState *diff(GameState *a, GameState *b);
     GameStateCompressed *compress_(GameState *a);
-    bool deleteUnusedGameState(int gamestateID);
+    bool printGameStates();
 
     std::map<int, GameState*> gameStateMap; //map gsID to gamestate*
@@ -92,4 +91,5 @@
     GameState *reference;
     ClientInformation *head_;
+    int id_;
   };
 
Index: code/branches/network3/src/network/PacketDecoder.cc
===================================================================
--- code/branches/network3/src/network/PacketDecoder.cc	(revision 1191)
+++ code/branches/network3/src/network/PacketDecoder.cc	(revision 1199)
@@ -97,8 +97,8 @@
   {
     ack* a = new ack;
-    *a = *(ack*)packet->data; //press pattern of ack on new data
-
-
-    COUT(5) << "PacketDecoder: got ack id: " << a->id << std::endl;
+    *a = *(ack*)(packet->data); //press pattern of ack on new data
+
+
+    COUT(4) << "PacketDecoder: got ack id: " << a->a << std::endl;
     processAck( a, clientId ); //debug info
 
Index: code/branches/network3/src/network/Server.cc
===================================================================
--- code/branches/network3/src/network/Server.cc	(revision 1191)
+++ code/branches/network3/src/network/Server.cc	(revision 1199)
@@ -143,5 +143,5 @@
     updateGamestate();
 
-    //sleep(1); // TODO remove
+    usleep(200000); // TODO remove
     return;
   }
@@ -220,6 +220,6 @@
 
   void Server::processAck( ack *data, int clientID) {
-    COUT(5) << "Server: processing ack from client: " << clientID << "; ack-id: " << data->id << std::endl;
-    clients->findClient(clientID)->setGamestateID(data->a);
+    COUT(4) << "Server: processing ack from client: " << clientID << "; ack-id: " << data->a << std::endl;
+    gamestates->ackGameState(clientID, data->a);
   }
 
Index: code/branches/network3/src/network/Synchronisable.cc
===================================================================
--- code/branches/network3/src/network/Synchronisable.cc	(revision 1191)
+++ code/branches/network3/src/network/Synchronisable.cc	(revision 1199)
@@ -147,5 +147,5 @@
     retVal.classID=this->classID;
     retVal.length=getSize();
-    COUT(4) << "Synchronisable getting data from objectID: " << retVal.objectID << " classID: " << retVal.classID << " length: " << retVal.length << std::endl;
+    COUT(5) << "Synchronisable getting data from objectID: " << retVal.objectID << " classID: " << retVal.classID << " length: " << retVal.length << std::endl;
     retVal.data=mem;
     // copy to location
@@ -163,5 +163,5 @@
         const char *data = ( ( *(std::string *) (*i)->var).c_str());
         std::memcpy( retVal.data+n, (void*)data, (*i)->size);
-        COUT(4) << "synchronisable: char: " << (const char *)(retVal.data+n) << " data: " << data << " string: " << *(std::string *)((*i)->var) << std::endl;
+        COUT(5) << "synchronisable: char: " << (const char *)(retVal.data+n) << " data: " << data << " string: " << *(std::string *)((*i)->var) << std::endl;
         n+=(*i)->size;
         break;
@@ -193,8 +193,8 @@
       case STRING:
         (*i)->size = *(int *)data;
-        COUT(4) << "string size: " << (*i)->size << std::endl;
+        COUT(5) << "string size: " << (*i)->size << std::endl;
         data+=sizeof(int);
         *((std::string *)((*i)->var)) = std::string((const char*)data);
-        COUT(4) << "synchronisable: char: " << (const char*)data << " string: " << std::string((const char*)data) << std::endl;
+        COUT(5) << "synchronisable: char: " << (const char*)data << " string: " << std::string((const char*)data) << std::endl;
         data += (*i)->size;
         break;
@@ -219,5 +219,5 @@
         tsize+=sizeof(int);
         (*i)->size=((std::string *)(*i)->var)->length()+1;
-        COUT(4) << "String size: " << (*i)->size << std::endl;
+        COUT(5) << "String size: " << (*i)->size << std::endl;
         tsize+=(*i)->size;
         break;
