Index: /code/trunk/src/core/ConfigFileManager.cc
===================================================================
--- /code/trunk/src/core/ConfigFileManager.cc	(revision 3197)
+++ /code/trunk/src/core/ConfigFileManager.cc	(revision 3198)
@@ -40,5 +40,4 @@
 namespace orxonox
 {
-    const int CONFIG_FILE_MAX_LINELENGHT  = 1024;
     const char* const DEFAULT_CONFIG_FILE = "default.ini";
 
@@ -244,14 +243,10 @@
         if (file.is_open())
         {
-
-            char linearray[CONFIG_FILE_MAX_LINELENGHT];
-
             ConfigFileSection* newsection = 0;
 
             while (file.good() && !file.eof())
             {
-                file.getline(linearray, CONFIG_FILE_MAX_LINELENGHT);
-
-                std::string line = std::string(linearray);
+                std::string line;
+                std::getline(file, line);
 
                 std::string temp = getStripped(line);
Index: /code/trunk/src/core/ConsoleCommandCompilation.cc
===================================================================
--- /code/trunk/src/core/ConsoleCommandCompilation.cc	(revision 3197)
+++ /code/trunk/src/core/ConsoleCommandCompilation.cc	(revision 3198)
@@ -73,8 +73,8 @@
 
         // Iterate through the file and put the lines into the CommandExecutor
-        char line[1024];
         while (file.good() && !file.eof())
         {
-            file.getline(line, 1024);
+            std::string line;
+            std::getline(file, line);
             CommandExecutor::execute(line);
         }
@@ -144,8 +144,8 @@
 
         std::string output = "";
-        char line[1024];
         while (file.good() && !file.eof())
         {
-            file.getline(line, 1024);
+            std::string line;
+            std::getline(file, line);
             output += line;
             output += "\n";
Index: /code/trunk/src/core/Language.cc
===================================================================
--- /code/trunk/src/core/Language.cc	(revision 3197)
+++ /code/trunk/src/core/Language.cc	(revision 3198)
@@ -224,11 +224,9 @@
         }
 
-        char line[1024];
-
         // Iterate through the file and create the LanguageEntries
         while (file.good() && !file.eof())
         {
-            file.getline(line, 1024);
-            std::string lineString = std::string(line);
+            std::string lineString;
+            std::getline(file, lineString);
 
             // Check if the line is empty
@@ -272,11 +270,9 @@
         }
 
-        char line[1024];
-
         // Iterate through the file and create the LanguageEntries
         while (file.good() && !file.eof())
         {
-            file.getline(line, 1024);
-            std::string lineString = std::string(line);
+            std::string lineString;
+            std::getline(file, lineString);
 
             // Check if the line is empty
Index: /code/trunk/src/core/LuaBind.cc
===================================================================
--- /code/trunk/src/core/LuaBind.cc	(revision 3197)
+++ /code/trunk/src/core/LuaBind.cc	(revision 3198)
@@ -95,10 +95,10 @@
     }
 
-    char line[1024*32];
     std::string levelString = "";
 
     while (file.good() && !file.eof())
     {
-      file.getline(line, 1024*32);
+      std::string line;
+      std::getline(file, line);
       levelString += line;
       levelString += "\n";
Index: /code/trunk/src/network/Client.cc
===================================================================
--- /code/trunk/src/network/Client.cc	(revision 3197)
+++ /code/trunk/src/network/Client.cc	(revision 3198)
@@ -169,4 +169,5 @@
       bool b = packet->process();
       assert(b);
+      delete event;
     }
     if(gamestate.processGamestates())
Index: /code/trunk/src/network/ClientConnection.cc
===================================================================
--- /code/trunk/src/network/ClientConnection.cc	(revision 3197)
+++ /code/trunk/src/network/ClientConnection.cc	(revision 3198)
@@ -169,6 +169,6 @@
 // 	        assert(0);
           printf("ClientConnection: ENet returned with an error!\n");
-          quit_=true;
-          break;
+//           quit_=true;
+          continue;
           // add some error handling here ========================
         }
@@ -197,10 +197,16 @@
       }
     }
+    delete event;
     // now disconnect
 
     if(!disconnectConnection())
+    {
+      printf("could not disconnect properly\n");
       // if disconnecting failed destroy conn.
       boost::recursive_mutex::scoped_lock lock(enet_mutex_g);
       enet_peer_reset(server);
+    }
+    else
+      printf("properly disconnected\n");
     return;
   }
@@ -221,4 +227,5 @@
         break;
       case ENET_EVENT_TYPE_DISCONNECT:
+        printf("received disconnect confirmation from server");
         return true;
       }
Index: /code/trunk/src/network/ClientInformation.h
===================================================================
--- /code/trunk/src/network/ClientInformation.h	(revision 3197)
+++ /code/trunk/src/network/ClientInformation.h	(revision 3198)
@@ -91,5 +91,4 @@
     bool getSynched();
 
-
   private:
     static ClientInformation *head_;
Index: /code/trunk/src/network/ConnectionManager.cc
===================================================================
--- /code/trunk/src/network/ConnectionManager.cc	(revision 3197)
+++ /code/trunk/src/network/ConnectionManager.cc	(revision 3198)
@@ -132,4 +132,5 @@
     quit_=true;
     receiverThread_->join();
+    delete receiverThread_;
     return true;
   }
@@ -206,6 +207,6 @@
           // we should never reach this point
           printf("ConnectionManager: ENet returned with an error\n");
-          quit_=true;
-          printf("waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahhhhhhhhhhhhhhhh\n");
+//           quit_=true;
+//           printf("waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahhhhhhhhhhhhhhhh\n");
           continue;
           // add some error handling here ========================
@@ -218,11 +219,12 @@
 //             printf("====================================================================");
         case ENET_EVENT_TYPE_DISCONNECT:
+//           printf("====================================================================");
         case ENET_EVENT_TYPE_RECEIVE:
-            processData(event);
-            event = new ENetEvent;
+          processData(event);
+          event = new ENetEvent;
           break;
         case ENET_EVENT_TYPE_NONE:
           //receiverThread_->yield();
-          msleep(10);
+          msleep(1);
           break;
       }
Index: /code/trunk/src/network/ConnectionManager.h
===================================================================
--- /code/trunk/src/network/ConnectionManager.h	(revision 3197)
+++ /code/trunk/src/network/ConnectionManager.h	(revision 3198)
@@ -55,5 +55,5 @@
     const int NETWORK_PORT = 55556;
     const int NETWORK_MAX_CONNECTIONS = 50;
-    const int NETWORK_WAIT_TIMEOUT = 10;
+    const int NETWORK_WAIT_TIMEOUT = 1;
     const int NETWORK_DEFAULT_CHANNEL = 0;
 
Index: /code/trunk/src/network/GamestateManager.cc
===================================================================
--- /code/trunk/src/network/GamestateManager.cc	(revision 3197)
+++ /code/trunk/src/network/GamestateManager.cc	(revision 3198)
@@ -63,4 +63,8 @@
   GamestateManager::~GamestateManager()
   {
+    if( this->reference )
+      delete this->reference;
+    for( std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateQueue.begin(); it != gamestateQueue.end(); it++ )
+      delete (*it).second;
     delete trafficControl_;
   }
@@ -133,5 +137,8 @@
 //       COUT(3) << "diffing" << std::endl;
 //       packet::Gamestate* gs1  = gs;
-      gs = gs->diff(client);
+      packet::Gamestate *diffed = gs->diff(client);
+      //packet::Gamestate *gs2 = diffed->undiff(gs);
+//       assert(*gs == *gs2);
+      gs = diffed;
 //       packet::Gamestate* gs2 = gs->undiff(client);
 //       gs = new packet::Gamestate(*gs);
Index: /code/trunk/src/network/Server.cc
===================================================================
--- /code/trunk/src/network/Server.cc	(revision 3197)
+++ /code/trunk/src/network/Server.cc	(revision 3198)
@@ -128,4 +128,13 @@
   */
   void Server::close() {
+    ClientInformation *temp = ClientInformation::getBegin();
+    ClientInformation *temp2;
+    // disconnect all connected clients
+    while( temp )
+    {
+      temp2 = temp;
+      temp = temp->next();
+      disconnectClient( temp2 );
+    }
     connection->quitListener();
     return;
@@ -198,5 +207,5 @@
       switch( event->type ) {
       case ENET_EVENT_TYPE_CONNECT:
-        COUT(3) << "processing event_Type_connect" << std::endl;
+        COUT(4) << "processing event_Type_connect" << std::endl;
         addClient(event);
         break;
@@ -304,4 +313,5 @@
       // gs gets automatically deleted by enet callback
     }
+    delete del;
     return true;
   }
@@ -381,24 +391,25 @@
     if(!client)
       return false;
+    else
+      disconnectClient( client );
+    return true;
+  }
+
+  void Server::disconnectClient(int clientID){
+    ClientInformation *client = ClientInformation::findClient(clientID);
+    if(client)
+      disconnectClient(client);
+  }
+  
+  void Server::disconnectClient( ClientInformation *client){
+    connection->disconnectClient(client);
     gamestates_->removeClient(client);
-
 // inform all the listeners
     ObjectList<ClientConnectionListener>::iterator listener = ObjectList<ClientConnectionListener>::begin();
     while(listener){
       listener->clientDisconnected(client->getID());
-      listener++;
-    }
-
-    return ClientInformation::removeClient(event->peer);
-  }
-
-  void Server::disconnectClient(int clientID){
-    ClientInformation *client = ClientInformation::findClient(clientID);
-    if(client)
-      disconnectClient(client);
-  }
-  void Server::disconnectClient( ClientInformation *client){
-    connection->disconnectClient(client);
-    gamestates_->removeClient(client);
+      ++listener;
+    }
+    delete client; //remove client from list
   }
 
Index: /code/trunk/src/network/TrafficControl.cc
===================================================================
--- /code/trunk/src/network/TrafficControl.cc	(revision 3197)
+++ /code/trunk/src/network/TrafficControl.cc	(revision 3198)
@@ -137,4 +137,6 @@
 	void TrafficControl::ack(unsigned int clientID, unsigned int gamestateID)
 	{
+    if ( !this->bActive_ )
+      return;
 	  std::list<obj>::iterator itvec;  // iterator to iterate through the acked objects
 
@@ -189,5 +191,5 @@
   void TrafficControl::updateClientListTemp(std::list<obj>& list)
   {
-    clientListTemp_[currentClientID][currentGamestateID] = std::list<obj>(list);
+    clientListTemp_[currentClientID][currentGamestateID] = list;
   }
 
@@ -227,32 +229,32 @@
 	{
 
-	  //now the sorting
-
-	  //compare listToProcess vs clientListPerm
-    //if listToProcess contains new Objects, add them to clientListPerm
-    std::list<obj>::iterator itvec;
+    if( bActive_ )
+    {
+      //now the sorting
+
+      //compare listToProcess vs clientListPerm
+      //if listToProcess contains new Objects, add them to clientListPerm
+      std::list<obj>::iterator itvec;
     
-    std::map<unsigned int, objInfo >& objectListPerm = clientListPerm_[clientID];
+      std::map<unsigned int, objInfo >& objectListPerm = clientListPerm_[clientID];
     
-	  for( itvec=list.begin(); itvec != list.end(); itvec++)
-	  {
-	    if ( objectListPerm.find( (*itvec).objID) != objectListPerm.end() )
-      {
+      for( itvec=list.begin(); itvec != list.end(); itvec++)
+      {
+        if ( objectListPerm.find( (*itvec).objID) != objectListPerm.end() )
+        {
         // we already have the object in our map
         //obj bleibt in liste und permanente prio wird berechnet
-        objectListPerm[(*itvec).objID].objDiffGS = currentGamestateID - objectListPerm[(*itvec).objID].objCurGS;
-        continue;//check next objId
-      }
-      else
-      {
+          objectListPerm[(*itvec).objID].objDiffGS = currentGamestateID - objectListPerm[(*itvec).objID].objCurGS;
+          continue;//check next objId
+        }
+        else
+        {
         // insert the object into clientListPerm
-        insertinClientListPerm(clientID,*itvec);
-        continue;//check next objId
-      }
-    }
-	  //end compare listToProcess vs clientListPerm
-
-    if( bActive_ )
-    {
+          insertinClientListPerm(clientID,*itvec);
+          continue;//check next objId
+        }
+      }
+    //end compare listToProcess vs clientListPerm
+      
       //sort copied list according to priorities
       // use boost bind here because we need to pass a memberfunction to stl sort
@@ -275,8 +277,9 @@
 //       sort(list.begin(), list.end(), boost::bind(&TrafficControl::dataSort, this, _1, _2) );
       list.sort( boost::bind(&TrafficControl::dataSort, this, _1, _2) );
+      
+      //diese Funktion updateClientList muss noch gemacht werden
+      updateClientListTemp(list);
+      //end of sorting
     }
-    //diese Funktion updateClientList muss noch gemacht werden
-    updateClientListTemp(list);
-    //end of sorting
   }
 
Index: /code/trunk/src/network/packet/Acknowledgement.cc
===================================================================
--- /code/trunk/src/network/packet/Acknowledgement.cc	(revision 3197)
+++ /code/trunk/src/network/packet/Acknowledgement.cc	(revision 3198)
@@ -64,5 +64,5 @@
 
 bool Acknowledgement::process(){
-COUT(6) << "processing ACK with ID: " << getAckID() << endl;
+  COUT(5) << "processing ACK with ID: " << getAckID() << endl;
   bool b = GamestateHandler::ackGamestate(getAckID(), clientID_);
   delete this;
Index: /code/trunk/src/network/packet/Gamestate.cc
===================================================================
--- /code/trunk/src/network/packet/Gamestate.cc	(revision 3197)
+++ /code/trunk/src/network/packet/Gamestate.cc	(revision 3198)
@@ -79,4 +79,6 @@
 Gamestate::~Gamestate()
 {
+  if( header_ )
+    delete header_;
 }
 
@@ -98,4 +100,5 @@
   
   // create the header object
+  assert( header_ == 0 );
   header_ = new GamestateHeader(data_);
 
@@ -137,4 +140,5 @@
   header_->setDataSize( currentsize );
   header_->setID( id );
+  header_->setBaseID( GAMESTATEID_INITIAL );
   header_->setDiffed( false );
   header_->setComplete( true );
@@ -207,5 +211,4 @@
   }
 #endif
-
   return true;
 }
@@ -320,5 +323,5 @@
 }
 
-Gamestate *Gamestate::diff(Gamestate *base)
+/*Gamestate *Gamestate::diff(Gamestate *base)
 {
   assert(data_);
@@ -355,5 +358,70 @@
   g->packetDirection_ = packetDirection_;
   return g;
-}
+}*/
+
+Gamestate *Gamestate::diff(Gamestate *base)
+{
+  assert(this && base); assert(data_ && base->data_);
+  assert(!header_->isCompressed() && !base->header_->isCompressed());
+  assert(!header_->isDiffed());
+  
+  uint8_t *basep = GAMESTATE_START(base->data_);
+  uint8_t *gs = GAMESTATE_START(this->data_);
+  uint32_t dest_length = header_->getDataSize();
+  
+  if(dest_length==0)
+    return NULL;
+  
+  uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
+  uint8_t *dest = GAMESTATE_START(ndata);
+  
+  rawDiff( dest, gs, basep, header_->getDataSize(), base->header_->getDataSize() );
+#ifndef NDEBUG
+  uint8_t *dest2 = new uint8_t[dest_length];
+  rawDiff( dest2, dest, basep, header_->getDataSize(), base->header_->getDataSize() );
+  assert( memcmp( dest2, gs, dest_length) == 0 );
+#endif
+
+  Gamestate *g = new Gamestate(ndata, getClientID());
+  assert(g->header_);
+  *(g->header_) = *header_;
+  g->header_->setDiffed( true );
+  g->header_->setBaseID( base->getID() );
+  g->flags_=flags_;
+  g->packetDirection_ = packetDirection_;
+  assert(g->isDiffed());
+  assert(!g->isCompressed());
+  return g;
+}
+
+Gamestate *Gamestate::undiff(Gamestate *base)
+{
+  assert(this && base); assert(data_ && base->data_);
+  assert(!header_->isCompressed() && !base->header_->isCompressed());
+  assert(header_->isDiffed());
+  
+  uint8_t *basep = GAMESTATE_START(base->data_);
+  uint8_t *gs = GAMESTATE_START(this->data_);
+  uint32_t dest_length = header_->getDataSize();
+  
+  if(dest_length==0)
+    return NULL;
+  
+  uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
+  uint8_t *dest = ndata + GamestateHeader::getSize();
+  
+  rawDiff( dest, gs, basep, header_->getDataSize(), base->header_->getDataSize() );
+  
+  Gamestate *g = new Gamestate(ndata, getClientID());
+  assert(g->header_);
+  *(g->header_) = *header_;
+  g->header_->setDiffed( false );
+  g->flags_=flags_;
+  g->packetDirection_ = packetDirection_;
+  assert(!g->isDiffed());
+  assert(!g->isCompressed());
+  return g;
+}
+
 
 // Gamestate *Gamestate::diff(Gamestate *base)
@@ -409,4 +477,31 @@
 // }
 
+
+void Gamestate::rawDiff( uint8_t* newdata, uint8_t* data, uint8_t* basedata, uint32_t datalength, uint32_t baselength)
+{
+  uint64_t* gd = (uint64_t*)data;
+  uint64_t* bd = (uint64_t*)basedata;
+  uint64_t* nd = (uint64_t*)newdata;
+  
+  unsigned int i;
+  for( i=0; i<datalength/8; i++ )
+  {
+    if( i<baselength/8 )
+      *(nd+i) = *(gd+i) ^ *(bd+i);  // xor the data
+    else
+      *(nd+i) = *(gd+i); // just copy over the data
+  }
+  unsigned int j;
+  // now process the rest (when datalength isn't a multiple of 4)
+  for( j = 8*(datalength/8); j<datalength; j++ )
+  {
+    if( j<baselength )
+      *(newdata+j) = *(data+j) ^ *(basedata+j); // xor
+    else
+      *(newdata+j) = *(data+j); // just copy
+  }
+  assert(j==datalength);
+}
+
 Gamestate* Gamestate::doSelection(unsigned int clientID, unsigned int targetSize){
   assert(data_);
@@ -478,5 +573,5 @@
 
 
-Gamestate *Gamestate::undiff(Gamestate *base)
+/*Gamestate *Gamestate::undiff(Gamestate *base)
 {
   assert(this && base);assert(data_);
@@ -514,6 +609,5 @@
   assert(!g->isCompressed());
   return g;
-}
-
+}*/
 
 uint32_t Gamestate::calcGamestateSize(int32_t id, uint8_t mode)
Index: /code/trunk/src/network/packet/Gamestate.h
===================================================================
--- /code/trunk/src/network/packet/Gamestate.h	(revision 3197)
+++ /code/trunk/src/network/packet/Gamestate.h	(revision 3198)
@@ -124,4 +124,5 @@
     // Packet functions
   private:
+    void rawDiff( uint8_t* newdata, uint8_t* data, uint8_t* basedata, uint32_t datalength, uint32_t baselength);
     virtual uint32_t getSize() const;
     virtual inline bool process();
Index: /code/trunk/src/network/synchronisable/Synchronisable.cc
===================================================================
--- /code/trunk/src/network/synchronisable/Synchronisable.cc	(revision 3197)
+++ /code/trunk/src/network/synchronisable/Synchronisable.cc	(revision 3198)
@@ -98,8 +98,12 @@
     // delete callback function objects
     if(!Identifier::isCreatingHierarchy()){
+      // remove object from the static objectMap
+      if (this->objectMode_ != 0x0 && (Host::running() && Host::isServer()))
+        deletedObjects_.push(objectID);
+      // delete all Synchronisable Variables from syncList ( which are also in stringList )
       for(std::vector<SynchronisableVariableBase*>::iterator it = syncList.begin(); it!=syncList.end(); it++)
         delete (*it);
-      if (this->objectMode_ != 0x0 && (Host::running() && Host::isServer()))
-        deletedObjects_.push(objectID);
+      syncList.clear();
+      stringList.clear();
     }
     std::map<uint32_t, Synchronisable*>::iterator it;
@@ -174,4 +178,6 @@
     COUT(4) << "fabricate objectID: " << no->objectID << " classID: " << no->classID << std::endl;
           // update data and create object/entity...
+    assert( Synchronisable::objectMap_.find(header.getObjectID()) == Synchronisable::objectMap_.end() );
+    Synchronisable::objectMap_[header.getObjectID()] = no;
     bool b = no->updateData(mem, mode, true);
     assert(b);
@@ -213,11 +219,12 @@
       return it1->second;
 
-    ObjectList<Synchronisable>::iterator it;
-    for(it = ObjectList<Synchronisable>::begin(); it; ++it){
-      if( it->getObjectID()==objectID ){
-        objectMap_[objectID] = *it;
-        return *it;
-      }
-    }
+//     ObjectList<Synchronisable>::iterator it;
+//     for(it = ObjectList<Synchronisable>::begin(); it; ++it){
+//       if( it->getObjectID()==objectID ){
+//         objectMap_[objectID] = *it;
+//         return *it;
+//       }
+//     }
+    // if the objects not in the map it should'nt exist at all anymore
     return NULL;
   }
Index: /code/trunk/src/orxonox/gamestates/GSDedicated.cc
===================================================================
--- /code/trunk/src/orxonox/gamestates/GSDedicated.cc	(revision 3197)
+++ /code/trunk/src/orxonox/gamestates/GSDedicated.cc	(revision 3198)
@@ -33,11 +33,25 @@
 #include "core/Clock.h"
 #include "core/CommandLine.h"
+#include "core/CommandExecutor.h"
 #include "core/Game.h"
 #include "core/GameMode.h"
 #include "network/Server.h"
 
+#include <iostream>
+#include <iomanip>
+#include <boost/bind.hpp>
+
+#ifndef ORXONOX_PLATFORM_WINDOWS
+#include <termios.h>
+#endif
+
+
 namespace orxonox
 {
+    const unsigned int MAX_COMMAND_LENGTH = 255;
+    
     AddGameState(GSDedicated, "dedicated");
+    
+    termios* GSDedicated::originalTerminalSettings_;
 
     GSDedicated::GSDedicated(const std::string& name)
@@ -45,5 +59,12 @@
         , server_(0)
         , timeSinceLastUpdate_(0)
-    {
+        , closeThread_(false)
+        , inputIterator_(0)
+        , cleanLine_(true)
+        , cursorX_(0)
+        , cursorY_(0)
+    {
+        this->commandLine_ = new unsigned char[MAX_COMMAND_LENGTH];
+//         memset( this->commandLine_, 0, MAX_COMMAND_LENGTH );
     }
 
@@ -55,4 +76,11 @@
     {
         GameMode::setHasServer(true);
+        
+        this->inputThread_ = new boost::thread(boost::bind(&GSDedicated::inputThread, this));
+        
+#ifndef ORXONOX_PLATFORM_WINDOWS
+        this->originalTerminalSettings_ = new termios;
+        this->setTerminalMode();
+#endif
 
         this->server_ = new Server(CommandLine::getValue("port"));
@@ -66,4 +94,13 @@
         this->server_->close();
         delete this->server_;
+        
+        closeThread_ = true;
+#ifndef ORXONOX_PLATFORM_WINDOWS
+        std::cout << "\033[0G\033[K";
+        std::cout.flush();
+        resetTerminalMode();
+        delete this->originalTerminalSettings_;
+#endif
+        //inputThread_->join();
 
         GameMode::setHasServer(false);
@@ -72,11 +109,7 @@
     void GSDedicated::update(const Clock& time)
     {
-//        static float startTime = time.getSecondsPrecise();
-//        static int nrOfTicks = 0;
         timeSinceLastUpdate_ += time.getDeltaTime();
         if (timeSinceLastUpdate_ >= NETWORK_PERIOD)
         {
-//            ++nrOfTicks;
-//            COUT(0) << "estimated ticks/sec: " << nrOfTicks/(time.getSecondsPrecise()-startTime) << endl;
             timeSinceLastUpdate_ -= static_cast<unsigned int>(timeSinceLastUpdate_ / NETWORK_PERIOD) * NETWORK_PERIOD;
             server_->update(time);
@@ -84,7 +117,186 @@
         else
         {
-            usleep((int)((NETWORK_PERIOD - timeSinceLastUpdate_) * 1000 * 1000));
+            usleep((unsigned int)((NETWORK_PERIOD - timeSinceLastUpdate_)*1000*1000 ));
+            usleep(NETWORK_PERIOD*1000*1000); // NOTE: this is to throttle the non-network framerate
 //            COUT(0) << "sleeping for " << (int)((NETWORK_PERIOD - timeSinceLastUpdate_) * 1000 * 1000) << " usec" << endl;
         }
-    }
+        processQueue();
+        printLine();
+    }
+    
+    void GSDedicated::inputThread()
+    {
+        unsigned char c;
+        unsigned int  escapeChar=0;
+        while(!closeThread_)
+        {
+            c = getchar();
+            {
+//                 boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+                if ( inputIterator_>=MAX_COMMAND_LENGTH-1 && c!='\n' )
+                    continue;
+                if( escapeChar > 0 )
+                {
+                    if( c == '[' )
+                    {
+                        escapeChar = 2;
+                        continue;
+                    }
+                    else if ( escapeChar == 2 )
+                    {
+                        switch (c)
+                        {
+                            case 'A': //keyup
+                                
+                                break;
+                            case 'B': //keydown
+                                
+                                break;
+                            case 'C': //keyright
+                                if(cursorX_<inputIterator_)
+                                    ++cursorX_;
+                                break;
+                            case 'D': //keyleft
+                                if(cursorX_>0)
+                                    --cursorX_;
+                                break;
+                            default: //not supported...
+//                                 std::cout << endl << c << endl;
+                                break;
+                        }
+                        escapeChar = 0;
+                    }
+                }
+                else // not in escape sequence mode
+                {
+                    switch (c)
+                    {
+                        case '\n':
+                            this->cleanLine_ = true;
+                            {
+                                boost::recursive_mutex::scoped_lock(this->inputQueueMutex_);
+                                boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+                                this->commandQueue_.push( std::string((const char*)this->commandLine_,inputIterator_) );
+                            }
+                            memset( this->commandLine_, 0, inputIterator_ );
+                            inputIterator_ = 0;
+                            this->cursorX_ = 0;
+                            this->cursorY_ = 0;
+                            std::cout << endl;
+                            break;
+                        case 127: // backspace
+                        case '\b':
+                            deleteCharacter( this->cursorX_ );
+                            break;
+                        case '\t':
+                        {
+//                             boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+                            std::cout << endl << CommandExecutor::hint( std::string((const char*)this->commandLine_,inputIterator_) ) << endl;
+                            strncpy((char*)this->commandLine_, CommandExecutor::complete( std::string((const char*)this->commandLine_,inputIterator_) ).c_str(), MAX_COMMAND_LENGTH);
+                            inputIterator_ = strlen((const char*)this->commandLine_);
+                            break;
+                        }
+                        case '\033': // 1. escape character
+                            escapeChar = 1;
+                            break;
+                        default:
+                            insertCharacter( this->cursorX_, c );
+                            break;
+                    }
+                }
+            }
+        }
+    }
+    
+    void GSDedicated::printLine()
+    {
+#ifndef ORXONOX_PLATFORM_WINDOWS
+        // set cursor to the begining of the line and erase the line
+        std::cout << "\033[0G\033[K";
+//         boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+        // print status line
+        std::cout << std::fixed << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgFPS() << " fps, " << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgTickTime() << " ms avg ticktime # ";
+        //save cursor position
+        std::cout << "\033[s";
+        //print commandLine buffer
+        std::cout << std::string((const char*)this->commandLine_, inputIterator_);
+        //restore cursor position and move it cursorX_ to the right
+        std::cout << "\033[u";
+        if( this->cursorX_ > 0 )
+            std::cout << "\033[" << this->cursorX_ << "C";
+        std::cout.flush();
+#endif
+    }
+    
+    void GSDedicated::processQueue()
+    {
+        std::string tempstr;
+        {
+            boost::recursive_mutex::scoped_lock lock1(this->inputQueueMutex_);
+            while(true)
+            {
+                if ( !this->commandQueue_.empty() )
+                {
+                    tempstr = this->commandQueue_.front();
+                    this->commandQueue_.pop();
+                    lock1.unlock();
+                }
+                else
+                    break;
+                CommandExecutor::execute(tempstr, true);
+            }
+        }
+    }
+    
+    void GSDedicated::setTerminalMode()
+    {
+#ifndef ORXONOX_PLATFORM_WINDOWS
+        termios new_settings;
+     
+        tcgetattr(0,this->originalTerminalSettings_);
+        new_settings = *this->originalTerminalSettings_;
+        new_settings.c_lflag &= ~( ICANON | ECHO );
+//         new_settings.c_lflag |= ( ISIG | IEXTEN );
+        new_settings.c_cc[VTIME] = 0;
+        new_settings.c_cc[VMIN] = 1;
+        tcsetattr(0,TCSANOW,&new_settings);
+        COUT(0) << endl;
+//       atexit(&GSDedicated::resetTerminalMode);
+#endif
+    }
+    
+    void GSDedicated::resetTerminalMode()
+    {
+#ifndef ORXONOX_PLATFORM_WINDOWS
+        tcsetattr(0, TCSANOW, GSDedicated::originalTerminalSettings_);
+#endif
+    }
+    
+    void GSDedicated::insertCharacter( unsigned int position, char c )
+    {
+//         std::cout << endl << (unsigned int)c << endl;
+        // check that we do not exceed MAX_COMMAND_LENGTH
+        if( inputIterator_+1 < MAX_COMMAND_LENGTH )
+        {
+            // if cursor not at end of line then move the rest of the line
+            if( position != this->inputIterator_ )
+                    memmove( this->commandLine_+position+1, this->commandLine_+position, this->inputIterator_-position);
+//             boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+            this->commandLine_[position] = c;
+            ++this->cursorX_;
+            ++this->inputIterator_;
+        }
+    }
+    void GSDedicated::deleteCharacter( unsigned int position )
+    {
+//         boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+        if ( this->inputIterator_>0 && position>0 )
+        {
+            if ( position != this->inputIterator_ )
+                memmove( this->commandLine_+position-1, this->commandLine_+position, this->inputIterator_-position);
+            --this->cursorX_;
+            --this->inputIterator_;
+        }
+    }
+    
 }
Index: /code/trunk/src/orxonox/gamestates/GSDedicated.h
===================================================================
--- /code/trunk/src/orxonox/gamestates/GSDedicated.h	(revision 3197)
+++ /code/trunk/src/orxonox/gamestates/GSDedicated.h	(revision 3198)
@@ -34,7 +34,15 @@
 #include "core/GameState.h"
 #include "network/NetworkPrereqs.h"
+#include <queue>
+#include <cstring>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+
+struct termios;
 
 namespace orxonox
 {
+    
     class _OrxonoxExport GSDedicated : public GameState
     {
@@ -48,6 +56,28 @@
 
     private:
-        Server* server_;
-        float   timeSinceLastUpdate_;
+        void inputThread();
+        void printLine();
+        void processQueue();
+        void setTerminalMode();
+        static void resetTerminalMode();
+        
+        void insertCharacter( unsigned int position, char c );
+        void deleteCharacter( unsigned int position );
+        
+        Server*                 server_;
+        float                   timeSinceLastUpdate_;
+        
+        boost::thread           *inputThread_;
+        boost::recursive_mutex  inputLineMutex_;
+        boost::recursive_mutex  inputQueueMutex_;
+        bool                    closeThread_;
+        bool                    cleanLine_;
+        unsigned char*          commandLine_;
+        unsigned int            inputIterator_;
+        std::queue<std::string> commandQueue_;
+        static termios*         originalTerminalSettings_;
+        
+        unsigned int            cursorX_;
+        unsigned int            cursorY_;
     };
 }
Index: /code/trunk/src/util/OutputBuffer.cc
===================================================================
--- /code/trunk/src/util/OutputBuffer.cc	(revision 3197)
+++ /code/trunk/src/util/OutputBuffer.cc	(revision 3198)
@@ -36,6 +36,4 @@
 namespace orxonox
 {
-    const int OUTPUTBUFFER_MAX_LINE_LENGTH = 16384; //! The maximal number of lines that can be stored within the OutputBuffer.
-
     /**
         @brief Adds a new listener to the list.
@@ -105,8 +103,5 @@
     bool OutputBuffer::getLine(std::string* output)
     {
-        char line[OUTPUTBUFFER_MAX_LINE_LENGTH];
-
-        this->stream_.getline(line, OUTPUTBUFFER_MAX_LINE_LENGTH);
-        (*output) = std::string(line);
+        std::getline(this->stream_, *output);
 
         bool eof = this->stream_.eof();
Index: /code/trunk/src/util/SignalHandler.cc
===================================================================
--- /code/trunk/src/util/SignalHandler.cc	(revision 3197)
+++ /code/trunk/src/util/SignalHandler.cc	(revision 3198)
@@ -107,9 +107,4 @@
     void SignalHandler::sigHandler( int sig )
     {
-      for ( SignalCallbackList::iterator it = SignalHandler::getInstance().callbackList.begin(); it != SignalHandler::getInstance().callbackList.end(); it++  )
-      {
-        (*(it->cb))( it->someData );
-      }
-
       std::string sigName = "UNKNOWN";
 
@@ -126,4 +121,16 @@
           break;
       }
+      // if the signalhandler has already been destroyed then don't do anything
+      if( SignalHandler::singletonRef_s == 0 )
+      {
+        COUT(0) << "recieved signal " << sigName.c_str() << std::endl << "can't write backtrace because SignalHandler already destroyed" << std::endl;
+        exit(EXIT_FAILURE);
+      }
+
+      for ( SignalCallbackList::iterator it = SignalHandler::getInstance().callbackList.begin(); it != SignalHandler::getInstance().callbackList.end(); it++  )
+      {
+        (*(it->cb))( it->someData );
+      }
+
 
       COUT(0) << "recieved signal " << sigName.c_str() << std::endl << "try to write backtrace to file orxonox_crash.log" << std::endl;
