Index: /trunk/configure.ac
===================================================================
--- /trunk/configure.ac	(revision 7953)
+++ /trunk/configure.ac	(revision 7954)
@@ -601,5 +601,5 @@
 # FIXME: Replace `main' with a function in `-lm':
  AC_CHECK_LIB([m], [main])
-
+ AX_CHECK_REQUIRED_HEADER_LIB([zlib.h], [z], [zlibVersion],,, [http://www.zlib.net])
 
 # Checks for header files.
Index: /trunk/src/defs/class_id.h
===================================================================
--- /trunk/src/defs/class_id.h	(revision 7953)
+++ /trunk/src/defs/class_id.h	(revision 7954)
@@ -366,4 +366,6 @@
   CL_HANDSHAKE                  =    0x00000d06,
   CL_NETWORK_GAME_MANAGER       =    0x00000d07,
+  CL_MESSAGE_MANAGER            =    0x00000d08,
+  CL_SIMPLE_SYNC                =    0x00000d09,
 
 
Index: /trunk/src/lib/BuildLibs.am
===================================================================
--- /trunk/src/lib/BuildLibs.am	(revision 7953)
+++ /trunk/src/lib/BuildLibs.am	(revision 7954)
@@ -11,5 +11,4 @@
                 $(LIB_PREFIX)/sound/libORXsound.a \
                 $(LIB_PREFIX)/event/libORXevent.a \
-                $(LIB_PREFIX)/physics/libORXphysics.a \
                 $(LIB_PREFIX)/particles/libORXparticles.a \
                 $(LIB_PREFIX)/collision_detection/libORXcd.a \
@@ -20,4 +19,6 @@
                 $(LIB_PREFIX)/parser/cmdline_parser/libCmdLineParser.a \
                 $(LIB_PREFIX)/parser/ini_parser/libIniParser.a \
+                $(LIB_PREFIX)/physics/libORXphysics.a \
+                $(LIB_PREFIX)/shell/libORXshell.a \
                 $(LIB_PREFIX)/math/libORXmath.a \
                 $(LIB_PREFIX)/libORXlibs.a
Index: /trunk/src/lib/coord/p_node.cc
===================================================================
--- /trunk/src/lib/coord/p_node.cc	(revision 7953)
+++ /trunk/src/lib/coord/p_node.cc	(revision 7954)
@@ -53,4 +53,7 @@
   if (parent != NULL)
     parent->addChild(this);
+
+  this->relCoordinate_handle = this->registerVarId( new SynchronizeableVector( &relCoordinate, &relCoordinate_write, "coordinate" ) );
+  this->relDirection_handle = this->registerVarId( new SynchronizeableQuaternion( &relDirection, &relDirection_write, "direction" ) );
 }
 
@@ -1077,256 +1080,19 @@
 
 /**
- * Writes data from network containing information about the state
- * @param data pointer to data
- * @param length length of data
- * @param sender hostID of sender
- */
-int PNode::writeState( const byte * data, int length, int sender )
-{
-  SYNCHELP_READ_BEGIN();
-
-  SYNCHELP_READ_FKT( BaseObject::writeState, NWT_PN_BO_WRITESTATE );
-
-  //   char * parentName = NULL;
-  //   SYNCHELP_READ_STRINGM( parentName );
-  //
-  //   if ( strcmp(parentName, "")==0 )
-  //   {
-  //     setParent( (char*)NULL );
-  //   }
-  //   else
-  //   {
-  //     setParent( parentName );
-  //   }
-  //
-  //  delete[] parentName;
-
-  int parentMode;
-  SYNCHELP_READ_INT( parentMode, NWT_PN_PARENTMODE );
-  this->setParentMode((PARENT_MODE)parentMode);
-
-  float f1, f2, f3, f4;
-
-  SYNCHELP_READ_FLOAT( f1, NWT_PN_COORX );
-  SYNCHELP_READ_FLOAT( f2, NWT_PN_COORY );
-  SYNCHELP_READ_FLOAT( f3, NWT_PN_COORZ );
-  this->setRelCoor( f1, f2, f3 );
-
-
-  SYNCHELP_READ_FLOAT( f1, NWT_PN_ROTV );
-  SYNCHELP_READ_FLOAT( f2, NWT_PN_ROTX );
-  SYNCHELP_READ_FLOAT( f3, NWT_PN_ROTY );
-  SYNCHELP_READ_FLOAT( f4, NWT_PN_ROTZ );
-  this->setRelDir( Quaternion( Vector(f2, f3, f4), f1 ) );
-
-  //   int n;
-  //   char * childName;
-  //
-  //   PRINTF(0)("JKLO %d %d %d %d\n", data[__synchelp_read_i], data[__synchelp_read_i+1], data[__synchelp_read_i+2], data[__synchelp_read_i+3]);
-  //   SYNCHELP_READ_INT( n );
-  //   PRINTF(0)("read %s:n=%d\n", this->getName(), n);
-  //
-  //   for (int i = 0; i<n; i++)
-  //   {
-  //     SYNCHELP_READ_STRINGM( childName );
-  //     PRINTF(0)("RCVD CHILD = %s\n", childName);
-  //     addChild( childName );
-  //     delete childName;
-  //     childName = NULL;
-  //   }
-
-  return SYNCHELP_READ_N;
-}
-
-/**
- * data copied in data will bee sent to another host
- * @param data pointer to data
- * @param maxLength max length of data
- * @return the number of bytes writen
- */
-int PNode::readState( byte * data, int maxLength )
-{
-  SYNCHELP_WRITE_BEGIN();
-
-  SYNCHELP_WRITE_FKT( BaseObject::readState, NWT_PN_BO_WRITESTATE );
-
-  //   if ( this->parent )
-  //   {
-  //     SYNCHELP_WRITE_STRING( parent->getName() );
-  //   }
-  //   else
-  //   {
-  //     SYNCHELP_WRITE_STRING( "" );
-  //   }
-
-  SYNCHELP_WRITE_INT( this->parentMode, NWT_PN_PARENTMODE );
-
-  SYNCHELP_WRITE_FLOAT( this->relCoordinate.x, NWT_PN_COORX );
-  SYNCHELP_WRITE_FLOAT( this->relCoordinate.y, NWT_PN_COORY );
-  SYNCHELP_WRITE_FLOAT( this->relCoordinate.z, NWT_PN_COORZ );
-
-  SYNCHELP_WRITE_FLOAT( this->relDirection.w, NWT_PN_ROTV );
-  SYNCHELP_WRITE_FLOAT( this->relDirection.v.x, NWT_PN_ROTX );
-  SYNCHELP_WRITE_FLOAT( this->relDirection.v.y, NWT_PN_ROTY );
-  SYNCHELP_WRITE_FLOAT( this->relDirection.v.z, NWT_PN_ROTZ );
-
-  //   int n = children.size();
-  //   //check if camera is in children
-  //   for (std::std::list<PNode*>::const_iterator it = children.begin(); it!=children.end(); it++)
-  //   {
-  //     if ( (*it)->isA(CL_CAMERA) )
-  //       n--;
-  //   }
-  //   PRINTF(0)("write %s:n=%d\n", this->getName(), n);
-  //   SYNCHELP_WRITE_INT( n );
-  //   PRINTF(0)("ASDF %d %d %d %d\n", data[__synchelp_write_i-4], data[__synchelp_write_i-3], data[__synchelp_write_i-2], data[__synchelp_write_i-1]);
-  //
-  //
-  //   for (std::list<PNode*>::const_iterator it = children.begin(); it!=children.end(); it++)
-  //   {
-  //     //dont add camera because there is only one camera attached to local player
-  //     if ( !(*it)->isA(CL_CAMERA) )
-  //     {
-  //       PRINTF(0)("SENDING CHILD: %s\n", (*it)->getName());
-  //       SYNCHELP_WRITE_STRING( (*it)->getName() );
-  //     }
-  //   }
-
-  return SYNCHELP_WRITE_N;
-}
-
-#define __FLAG_COOR 1
-#define __FLAG_ROT  2
-
-#define __OFFSET_POS 1
-#define __OFFSET_ROT 0.05
-
-/**
- * Writes data from network containing information about the state which has changed
- * @param data pointer to data
- * @param length length of data
- * @param sender hostID of sender
- */
-int PNode::writeSync( const byte * data, int length, int sender )
-{
-  SYNCHELP_READ_BEGIN();
-
-  if ( this->getHostID()==this->getOwner() )
-  {
-    return SYNCHELP_READ_N;
-  }
-
-  byte flags = 0;
-  SYNCHELP_READ_BYTE( flags, NWT_PN_FLAGS );
-  //PRINTF(0)("%s::FLAGS = %d\n", this->getName(), flags);
-
-  float f1, f2, f3, f4;
-
-  if ( flags & __FLAG_COOR )
-  {
-    SYNCHELP_READ_FLOAT( f1, NWT_PN_SCOORX );
-    SYNCHELP_READ_FLOAT( f2, NWT_PN_SCOORY );
-    SYNCHELP_READ_FLOAT( f3, NWT_PN_SCOORZ );
-    PRINTF(0)("RCVD COOR: %f %f %f\n", f1, f2, f3);
-    this->setRelCoor( f1, f2, f3 );
-  }
-
-  if ( flags & __FLAG_ROT )
-  {
-    SYNCHELP_READ_FLOAT( f1, NWT_PN_SROTV );
-    SYNCHELP_READ_FLOAT( f2, NWT_PN_SROTX );
-    SYNCHELP_READ_FLOAT( f3, NWT_PN_SROTY );
-    SYNCHELP_READ_FLOAT( f4, NWT_PN_SROTZ );
-    PRINTF(0)("RCVD QUAT: %f %f %f %f\n", f1, f2, f3, f4);
-    //this->setRelDir( Quaternion( Vector(f2, f3, f4), f1 ) );
-    Quaternion q;
-    q.w = f1;
-    q.v.x = f2;
-    q.v.y = f3;
-    q.v.z = f4;
-    this->setAbsDir( q );
-  }
-
-  return SYNCHELP_READ_N;
-}
-
-/**
- * data copied in data will bee sent to another host
- * @param data pointer to data
- * @param maxLength max length of data
- * @return the number of bytes writen
- */
-int PNode::readSync( byte * data, int maxLength )
-{
-  //WARNING: if you change this file make sure you also change needsReadSync
-  SYNCHELP_WRITE_BEGIN();
-
-  if ( this->getHostID()!=0 && this->getHostID()!=this->getOwner() )
-  {
-    return SYNCHELP_WRITE_N;
-  }
-
-  byte flags = 0;
-  if ( fabs( coorx - relCoordinate.x ) > __OFFSET_POS*0.05*this->velocity.len() ||
-       fabs( coory - relCoordinate.y ) > __OFFSET_POS*0.05*this->velocity.len() ||
-       fabs( coorz - relCoordinate.z ) > __OFFSET_POS*0.05*this->velocity.len() )
-    flags |= __FLAG_COOR;
-
-  if ( fabs( rotw - absDirection.w ) > __OFFSET_ROT ||
-       fabs( rotx - absDirection.v.x ) > __OFFSET_ROT ||
-       fabs( roty - absDirection.v.y ) > __OFFSET_ROT ||
-       fabs( rotz - absDirection.v.z ) > __OFFSET_ROT )
-    flags |= __FLAG_ROT;
-
-
-  SYNCHELP_WRITE_BYTE( flags, NWT_PN_FLAGS );
-  PRINTF(0)("FLAGS = %d\n", flags);
-
-  if ( flags & __FLAG_COOR )
-  {
-
-    PRINTF(0)("SEND COOR: %f %f %f\n", this->relCoordinate.x, this->relCoordinate.y, this->relCoordinate.z);
-
-    SYNCHELP_WRITE_FLOAT( this->relCoordinate.x, NWT_PN_SCOORX );
-    SYNCHELP_WRITE_FLOAT( this->relCoordinate.y, NWT_PN_SCOORY );
-    SYNCHELP_WRITE_FLOAT( this->relCoordinate.z, NWT_PN_SCOORZ );
-
-    coorx = relCoordinate.x;
-    coory = relCoordinate.y;
-    coorz = relCoordinate.z;
-  }
-
-  if ( flags & __FLAG_ROT )
-  {
-
-    PRINTF(0)("SEND QUAT: %f %f %f %f\n", this->absDirection.w, this->absDirection.v.x, this->absDirection.v.y, this->absDirection.v.z);
-
-    SYNCHELP_WRITE_FLOAT( this->absDirection.w, NWT_PN_SROTV );
-    SYNCHELP_WRITE_FLOAT( this->absDirection.v.x, NWT_PN_SROTX );
-    SYNCHELP_WRITE_FLOAT( this->absDirection.v.y, NWT_PN_SROTY );
-    SYNCHELP_WRITE_FLOAT( this->absDirection.v.z, NWT_PN_SROTZ );
-
-    rotw = absDirection.w;
-    rotx = absDirection.v.x;
-    roty = absDirection.v.y;
-    rotz = absDirection.v.z;
-  }
-
-  return SYNCHELP_WRITE_N;
-}
-
-bool PNode::needsReadSync( )
-{
-  if ( fabs( coorx - relCoordinate.x ) > __OFFSET_POS*0.05*this->velocity.len() ||
-       fabs( coory - relCoordinate.y ) > __OFFSET_POS*0.05*this->velocity.len() ||
-       fabs( coorz - relCoordinate.z ) > __OFFSET_POS*0.05*this->velocity.len() )
-    return true;
-
-  if ( fabs( rotw - absDirection.w ) > __OFFSET_ROT ||
-       fabs( rotx - absDirection.v.x ) > __OFFSET_ROT ||
-       fabs( roty - absDirection.v.y ) > __OFFSET_ROT ||
-       fabs( rotz - absDirection.v.z ) > __OFFSET_ROT )
-    return true;
-
-  return false;
-}
+ * handles changes in synchronizable variables
+ * @param id id's which changed
+ */
+void PNode::varChangeHandler( std::list< int > & id )
+{
+  if ( std::find( id.begin(), id.end(), relCoordinate_handle ) != id.end() )
+  {
+    setRelCoor( relCoordinate_write );
+  }
+
+  if ( std::find( id.begin(), id.end(), relDirection_handle ) != id.end() )
+  {
+    setRelDir( relDirection_write );
+  }
+}
+
+
Index: /trunk/src/lib/coord/p_node.h
===================================================================
--- /trunk/src/lib/coord/p_node.h	(revision 7953)
+++ /trunk/src/lib/coord/p_node.h	(revision 7954)
@@ -186,10 +186,4 @@
   float distance(const PNode* node) const { return (this->getAbsCoor() - node->getAbsCoor()).len(); };
 
-  int       writeState(const byte* data, int length, int sender);
-  int       readState(byte* data, int maxLength );
-  int       writeSync(const byte* data, int length, int sender);
-  int       readSync(byte* data, int maxLength );
-  bool      needsReadSync();
-
  private:
   /** tells the child that the parent's Coordinate has changed */
@@ -243,4 +237,13 @@
     float roty;
     float rotz;
+    
+  private:
+    int relCoordinate_handle;
+    int relDirection_handle;
+    Vector relCoordinate_write;
+    Quaternion relDirection_write;
+    
+  public:
+    virtual void varChangeHandler( std::list<int> & id );
 };
 
Index: /trunk/src/lib/graphics/importer/height_map.cc
===================================================================
--- /trunk/src/lib/graphics/importer/height_map.cc	(revision 7953)
+++ /trunk/src/lib/graphics/importer/height_map.cc	(revision 7954)
@@ -603,7 +603,9 @@
   PRINTF(0)("c: %f \n" ,c);
 
+
   height -= ( (a/c)*(x) + (b/c)*(y));
 
-  PRINTF(0)("height: %f \n" ,height );
+  // PRINTF(0)("height: %f \n" ,height );
   return (height + offsetZ);
-}
+
+}
Index: /trunk/src/lib/lang/base_object.cc
===================================================================
--- /trunk/src/lib/lang/base_object.cc	(revision 7953)
+++ /trunk/src/lib/lang/base_object.cc	(revision 7954)
@@ -82,4 +82,5 @@
   assert (!(this->classID & classID & !CL_MASK_SUBSUPER_CLASS_IDA ));
 
+  this->leafClassID = classID;
   this->classID |= (long)classID;
   this->className = className;
@@ -105,8 +106,7 @@
  * Factory::fabricate(Object->getLeafClassID());
  */
-ClassID BaseObject::getLeafClassID() const
+const ClassID& BaseObject::getLeafClassID() const
 {
-  assert (this->classList != NULL);
-  return this->classList->getLeafClassID();
+  return this->leafClassID;
 }
 
@@ -176,33 +176,2 @@
 
 }
-
-/**
- * Writes data from network containing information about the state
- * @param data pointer to data
- * @param length length of data
- * @param sender hostID of sender
- */
-int BaseObject::writeState( const byte * data, int length, int sender )
-{
-  SYNCHELP_READ_BEGIN();
-
-  SYNCHELP_READ_STRING( this->objectName, NWT_BO_NAME );
-
-  return SYNCHELP_READ_N;
-}
-
-/**
- * data copied in data will bee sent to another host
- * @param data pointer to data
- * @param maxLength max length of data
- * @return the number of bytes writen
- */
-int BaseObject::readState( byte * data, int maxLength )
-{
-  SYNCHELP_WRITE_BEGIN();
-
-  //PRINTF(0)("objectname = %s\n", this->objectName);
-  SYNCHELP_WRITE_STRING( this->objectName, NWT_BO_NAME );
-
-  return SYNCHELP_WRITE_N;
-}
Index: /trunk/src/lib/lang/base_object.h
===================================================================
--- /trunk/src/lib/lang/base_object.h	(revision 7953)
+++ /trunk/src/lib/lang/base_object.h	(revision 7954)
@@ -42,5 +42,5 @@
   /** @returns the classID of the corresponding Object */
   inline int getClassID() const { return this->classID; };
-  ClassID    getLeafClassID() const;
+  const ClassID& getLeafClassID() const;
 
   bool isA (ClassID classID) const;
@@ -52,14 +52,12 @@
   bool operator==(ClassID classID) { return this->isA(classID); };
 
-  int       writeState(const byte* data, int length, int sender);
-  int       readState(byte* data, int maxLength );
-
  protected:
    void setClassID(ClassID classID, const std::string& className);
+   std::string        objectName;        //!< The name of this object
 
  private:
     std::string        className;        //!< the name of the class
     long               classID;          //!< this is the id from the class_id.h enumeration
-    std::string        objectName;       //!< The name of this object
+    ClassID            leafClassID;      //!< The Leaf Class ID
 
     ClassList*         classList;        //!< Pointer to the ClassList this Object is inside of
Index: /trunk/src/lib/network/Makefile.am
===================================================================
--- /trunk/src/lib/network/Makefile.am	(revision 7953)
+++ /trunk/src/lib/network/Makefile.am	(revision 7954)
@@ -13,7 +13,23 @@
                       network_protocol.cc \
 		      server_socket.cc \
+		      tcp_server_socket.cc \
+		      tcp_socket.cc \
+		      udp_server_socket.cc \
+		      udp_socket.cc \
 		      handshake.cc \
 		      network_game_manager.cc \
-		      converter.cc
+		      converter.cc \
+		      message_manager.cc \
+		      network_log.cc \
+		      zip.cc \
+		      \
+		      synchronizeable_var/synchronizeable_var.cc \
+		      synchronizeable_var/synchronizeable_vector.cc \
+		      synchronizeable_var/synchronizeable_int.cc \
+		      synchronizeable_var/synchronizeable_quaternion.cc \
+		      synchronizeable_var/synchronizeable_string.cc \
+		      synchronizeable_var/synchronizeable_float.cc \
+		      synchronizeable_var/synchronizeable_bool.cc \
+		      synchronizeable_var/synchronizeable_uint.cc 
 
 
@@ -29,8 +45,24 @@
                  network_protocol.h \
 		 server_socket.h \
+		 tcp_server_socket.h \
+		 tcp_socket.h \
+		 udp_server_socket.h \
+		 udp_socket.h \
 		 handshake.h \
 		 network_game_manager.h \
 		 converter.h \
-		 netdefs.h
+		 netdefs.h \
+		 message_manager.h \
+		 network_log.h \
+		 zip.h \
+		 \
+		 synchronizeable_var/synchronizeable_var.h \
+		 synchronizeable_var/synchronizeable_vector.h \
+		 synchronizeable_var/synchronizeable_int.h \
+		 synchronizeable_var/synchronizeable_quaternion.h \
+		 synchronizeable_var/synchronizeable_string.h \
+		 synchronizeable_var/synchronizeable_float.h \
+		 synchronizeable_var/synchronizeable_bool.h \
+		 synchronizeable_var/synchronizeable_uint.h
 
 
Index: /trunk/src/lib/network/connection_monitor.cc
===================================================================
--- /trunk/src/lib/network/connection_monitor.cc	(revision 7953)
+++ /trunk/src/lib/network/connection_monitor.cc	(revision 7954)
@@ -10,9 +10,11 @@
 
 ### File Specific:
-   main-programmer: Silvan Nellen
+   main-programmer: Christoph Renner
    co-programmer: ...
 */
 
 #include "connection_monitor.h"
+#include "network_log.h"
+
 #include <debug.h>
 #include <SDL/SDL.h>
@@ -22,126 +24,218 @@
 using namespace std;
 
-ConnectionMonitor::ConnectionMonitor()
-{
-
+/**
+ * constructor
+ * @param userId user's id
+ */
+ConnectionMonitor::ConnectionMonitor( int userId )
+{
   /* set the class id for the base object and add ist to class list*/
   this->setClassID(CL_CONNECTION_MONITOR, "ConnectionMonitor");
-
-  /*initialize variables*/
-
-  /*Data of the lifetime of the ConnectionMonitor Object*/
-  packetToAverage = 100;
-  protocollType = "default(TCP)";
-
-  startTime= SDL_GetTicks();
-  totalReceivedPackets=0;
-  averageDatarate=0;
-  totalLostPackets=0;
-  totalPacketloss=0;
-
-  /*Data of the current packet*/
-  currentPacketID=0;
-  currentPacketTick=0;
-  lastPacketID=0;
-  lastPacketTick=0;
-  currentDelay=0;
-
-  /*Data of the last n packets (n is specified by paxketsToAverage)*/
-  sizeOfLastFewPackets=0;
-  currentDatarate=0;
-  lastFewDelays = new unsigned int [packetToAverage];
-  lastFewPackets = new byte* [packetToAverage];
-  packetCounter=0;
-
-
-}
-
-
-ConnectionMonitor::~ConnectionMonitor()
-{
-
-
-}
-
-
-
-void ConnectionMonitor::processPacket(byte* currentPacket, unsigned int packetLength)
-{
-  /*Process the current Packet*/
-  currentPacketTick = SDL_GetTicks();
-  currentDelay = currentPacketTick - lastPacketTick;
-
-  /*Do whats needed for Averaging*/
-
-  if(packetCounter == packetToAverage)
-    {
-      computeCurrentDatarate();
-      displayStatistic();
-      packetCounter = 0;
-      sizeOfLastFewPackets = 0;
-    }
-
-  lastFewDelays[packetCounter] = currentDelay;
-  lastFewPackets[packetCounter] = currentPacket;
-  sizeOfLastFewPackets += packetLength;
-
-  /*Update the lifetime Variables*/
-  totalReceivedPackets ++;
-  float timeDiff = this->currentPacketTick - this->startTime;
-  if( timeDiff != 0.0f )
-    averageDatarate = totalReceivedPackets/timeDiff;
-
-  /*Preparefor the next Packet*/
-  lastPacketTick = currentPacketTick;
-  packetCounter++;
-}
-
-
-/* Compute the value of current Datarate*/
-void ConnectionMonitor::computeCurrentDatarate()
-{
-  int timeForLastFewPackets=0;
-  for(int i=0;i < packetToAverage;i++)
-    timeForLastFewPackets += lastFewDelays[i];
-
-  if( timeForLastFewPackets != 0)
-    currentDatarate = sizeOfLastFewPackets/timeForLastFewPackets;
-}
-
-void doUDPRelatedStuff()
-{
-  /*  Do protocol related stuff
-
-  Only for Udp:
-  "currentPacketID = getID from package";
-
-  if(currentPacketID - lastPacketID > 1)
+  
+  this->userId = userId;
+  this->ping = 0;
+  this->incomingUnzippedBandWidth = 0;
+  this->outgoingUnzippedBandWidth = 0;
+  this->incomingZippedBandWidth = 0;
+  this->outgoingZippedBandWidth = 0;
+  this->nIncomingPackets = 0;
+  this->nOutgoingPackets = 0;
+  this->nZIncomingPackets = 0;
+  this->nZOutgoingPackets = 0;
+  
+  this->lastPacketTick = 0;
+  this->lastPrintTick = 0;
+}
+
+/**
+ * deconstructor
+ */
+ConnectionMonitor::~ConnectionMonitor( )
+{
+}
+
+/**
+ * process unzipped outgoing packet
+ * @param data pointer to packet data
+ * @param length length of packet
+ * @param stateId packet's state id
+ */
+void ConnectionMonitor::processUnzippedOutgoingPacket( byte * data, int length, int stateId )
+{
+  int tick = SDL_GetTicks();
+  
+  nOutgoingPackets++;
+  
+  // for ping calculation
+  sentStateTicks[stateId] = tick;
+  
+  // calculate bandwidth
+  outgoingUnzippedPacketHistory[tick] = length;
+  outgoingUnzippedBandWidth = calculateBandWidth( outgoingUnzippedPacketHistory, tick );
+  
+  //NETPRINTF(n)("UNZIPPED UPSTREAM: user: %d bandwidth %f\n", userId, outgoingUnzippedBandWidth );
+  
+  // count zero bytes
+  int nZeroBytes = 0;
+  
+  for ( int i = 0; i < length; i++ )
+    if ( data[i] == '\0' )
+      nZeroBytes++;
+  
+  //NETPRINTF(n)( "ZEROBYTES: %d (%f%%)\n", nZeroBytes, ((float)100)*nZeroBytes/length );
+}
+
+/**
+ * process unzipped incoming packet
+ * @param data pointer to packet data
+ * @param length length of packet
+ * @param stateId packet's state id
+ * @param ackedState state which was acked by this packet
+ */
+void ConnectionMonitor::processUnzippedIncomingPacket( byte * data, int length, int stateId, int ackedState )
+{
+  int tick = SDL_GetTicks();
+  
+  nIncomingPackets++;
+  
+  lastPacketTick = tick;
+  
+  // calculate ping
+  if ( sentStateTicks.find( ackedState ) != sentStateTicks.end() )
   {
-  totalLostPackets += currentPacketID - lastPacketID;
-}
-
-  totalPacketloss = (totalLostPackets/totalReceivedPackets)*100 ;
-  */
-}
-
-
-
-/* Display connectoin statistic*/
-void ConnectionMonitor::displayStatistic()
-{
-//   PRINT(0)("============================================\n");
-//   PRINT(0)("Connection Monitor Network Statistics:\n");
-//   PRINT(0)("Total received packets:",totalReceivedPackets);
-//   PRINT(0)("Average datarate :\n",averageDatarate);
-//   PRINT(0)("Total lost packets:",totalLostPackets);
-//   PRINT(0)("Packetloss [%] :\n",totalPacketloss);
-//
-//   PRINT(0)("Current datarate :\n",currentDatarate);
-//   PRINT(0)("Delays of the last few packets :\n");
-//   for(int i=1 ;i <= packetToAverage-1;i++)
-//     PRINT(0)("%i ",lastFewDelays[i]);
-//
-//   PRINT(0)("============================================\n");
-
-}
-
+    ackDelay.push_back( tick - sentStateTicks[ackedState] );
+  }
+  
+  while ( sentStateTicks.begin() != sentStateTicks.end() && sentStateTicks.begin()->first <= ackedState )
+    sentStateTicks.erase( sentStateTicks.begin() );
+      
+  while ( ackDelay.size() > N_PACKETS_FOR_PING )
+    ackDelay.erase( ackDelay.begin() );
+      
+  ping = 0;
+      
+  for ( std::list<int>::iterator it = ackDelay.begin(); it != ackDelay.end(); it++ )
+    ping += *it;
+      
+  if ( ackDelay.size() == 0 )
+    ping = -1;
+  else
+    ping /= ackDelay.size();
+      
+  //NETPRINTF(n)("PING: user: %d ping: %d\n", userId, ping );
+  
+  // calculate bandwidth
+  incomingUnzippedPacketHistory[tick] = length;
+  incomingUnzippedBandWidth = calculateBandWidth( incomingUnzippedPacketHistory, tick );
+  
+  //NETPRINTF(n)("UNZIPPED DOWNSTREAM: user: %d bandwidth %f\n", userId, incomingUnzippedBandWidth );
+  
+}
+
+/**
+ * calculate bandwidth out of packethistory
+ * @param packetHistory packet history
+ * @param tick current tick from SDL_GetTicks
+ * @return bandwidth in bytes/sec
+ */
+float ConnectionMonitor::calculateBandWidth( std::map< int, int > packetHistory, int tick )
+{
+  // delete old packets
+  while ( packetHistory.begin()->first < tick - MSECS_TO_CALC_BWIDTH )
+    packetHistory.erase( packetHistory.begin() );
+  
+  float res = 0.0f;
+  
+  for ( std::map<int,int>::iterator it = packetHistory.begin(); it != packetHistory.end(); it++ )
+  {
+    res += it->second;
+  }
+  
+  if ( packetHistory.size() <= 1 || tick - packetHistory.begin()->first == 0 )
+    res = 0.0f;
+  else
+    res /= (float)((tick - packetHistory.begin()->first)*( 1 + 1/((float)(packetHistory.size()-1)) ));
+  
+  res *= 1000.0f;
+  
+  return res;
+}
+
+
+/**
+ * process zipped outgoing packet
+ * @param data pointer to packet data
+ * @param length length of packet
+ * @param stateId packet's state id
+ */
+void ConnectionMonitor::processZippedOutgoingPacket( byte * data, int length, int stateId )
+{
+  int tick = SDL_GetTicks();
+  
+  nZOutgoingPackets++;
+  
+  // calculate bandwidth
+  outgoingZippedPacketHistory[tick] = length;
+  outgoingZippedBandWidth = calculateBandWidth( outgoingZippedPacketHistory, tick );
+  
+  //NETPRINTF(n)("UPSTREAM: user: %d bandwidth %f nOutgoingPackets %d\n", userId, outgoingZippedBandWidth, nOutgoingPackets );
+
+  if ( lastPrintTick < tick-1000 )
+  {
+    printStatis();
+    lastPrintTick = tick;
+  }
+}
+
+
+/**
+ * process zipped incoming packet
+ * @param data pointer to packet data
+ * @param length length of packet
+ * @param stateId packet's state id
+ * @param ackedState state which was acked by this packet
+ */
+void ConnectionMonitor::processZippedIncomingPacket( byte * data, int length, int stateId, int ackedState )
+{
+  int tick = SDL_GetTicks();
+  
+  nZIncomingPackets++;
+  
+  // calculate bandwidth
+  incomingZippedPacketHistory[tick] = length;
+  incomingZippedBandWidth = calculateBandWidth( incomingZippedPacketHistory, tick );
+  
+  //NETPRINTF(n)("DOWNSTREAM: user: %d bandwidth %f nIncomingPackets %d\n", userId, incomingZippedBandWidth, nIncomingPackets );
+  
+}
+
+
+/**
+ * check if client sent no packets for SECS_TO_TIMEOUT
+ * @return true if last packet recieved \< NOW() - SECS_TO_TIMEOUT
+ */
+bool ConnectionMonitor::hasTimedOut( )
+{
+  if ( lastPacketTick + SECS_TO_TIMEOUT*1000 < SDL_GetTicks() && nIncomingPackets > 0 )
+    return true;
+  
+  if ( nIncomingPackets == 0 && nOutgoingPackets >= NETWORK_FREQUENCY*SECS_TO_TIMEOUT )
+    return true;
+  
+  return false;
+}
+
+
+
+/**
+ * prints bandwith usage, ping and other important things to telnet-console
+ */
+void ConnectionMonitor::printStatis( )
+{
+  NETPRINT(n)("=========NETWORKSTATS FOR USER %d=========\n", userId);
+  NETPRINT(n)("PING = %d\n", ping);
+  NETPRINT(n)("BANDWIDTH: UP: %f (%f) DOWN %f (%f)\n", outgoingZippedBandWidth, outgoingUnzippedBandWidth, incomingZippedBandWidth, incomingUnzippedBandWidth);
+  NETPRINT(n)("==========================================");
+}
+
+
Index: /trunk/src/lib/network/connection_monitor.h
===================================================================
--- /trunk/src/lib/network/connection_monitor.h	(revision 7953)
+++ /trunk/src/lib/network/connection_monitor.h	(revision 7954)
@@ -10,44 +10,59 @@
 #include "netdefs.h"
 
+#include <map>
+
+#define N_PACKETS_FOR_PING 20
+#define MSECS_TO_CALC_BWIDTH 1000
+#define SECS_TO_TIMEOUT 10
+
 class ConnectionMonitor : virtual public BaseObject
-  {
+{
   public:
-    ConnectionMonitor();
+    ConnectionMonitor( int userId );
     virtual ~ConnectionMonitor();
 
-    void                processPacket(byte* packet, unsigned int packetLength);
+    void processUnzippedOutgoingPacket( byte * data, int length, int stateId );
+    void processUnzippedIncomingPacket( byte * data, int length, int stateId, int ackedState );
+    
+    void processZippedOutgoingPacket( byte * data, int length, int stateId );
+    void processZippedIncomingPacket( byte * data, int length, int stateId, int ackedState );
+    
+    void calculatePing();
+    
+    bool hasTimedOut();
+    
+    void printStatis();
+    
+  private:
+    float calculateBandWidth( std::map<int,int> packetHistory, int tick );
+    
+    int userId;       //!< user's id 
 
+    std::map<int,int>   sentStateTicks;
+    
+    std::map<int,int>   incomingUnzippedPacketHistory;
+    std::map<int,int>   outgoingUnzippedPacketHistory;
+    
+    std::map<int,int>   incomingZippedPacketHistory;
+    std::map<int,int>   outgoingZippedPacketHistory;
+    
+    std::list<int>      ackDelay;
+    int                 ping;
 
-  private:
-
-
-    void                displayStatistic();
-    void                computeCurrentDatarate();
-    void                doUDPRelatedStuff();
-
-    /*Data of the lifetime of the ConnectionMonitor Object*/
-    unsigned int        packetToAverage;
-    char*               protocollType;
-
-    unsigned int        totalReceivedPackets;
-    float               averageDatarate;
-    unsigned int        totalLostPackets;
-    float               totalPacketloss;
-    unsigned int        startTime;
-
-    /*Data of the current packet*/
-    unsigned int        currentPacketID;
-    unsigned int        currentPacketTick;
-    unsigned int        lastPacketID;
-    unsigned int        lastPacketTick;
-    unsigned int        currentDelay;
-
-    /*Data of the last n packets (n is specified by paxketsToAverage)*/
-    unsigned int        sizeOfLastFewPackets;
-    unsigned int        currentDatarate;
-    byte**              lastFewPackets;
-    unsigned int*       lastFewDelays;
-    unsigned int        packetCounter;
-
+    float               incomingUnzippedBandWidth;
+    float               outgoingUnzippedBandWidth;
+    
+    float               incomingZippedBandWidth;
+    float               outgoingZippedBandWidth;
+    
+    int                 nIncomingPackets;
+    int                 nOutgoingPackets;
+    
+    int                 nZIncomingPackets;
+    int                 nZOutgoingPackets;
+    
+    int                 lastPacketTick;
+    
+    int                 lastPrintTick;
   };
 
Index: /trunk/src/lib/network/converter.cc
===================================================================
--- /trunk/src/lib/network/converter.cc	(revision 7953)
+++ /trunk/src/lib/network/converter.cc	(revision 7954)
@@ -489,9 +489,20 @@
   {
     PRINTF(1)("something went wrong length > remaining bytes in buffer\n" );
+    
+    //TODO remove this
+    for ( int i = -1000; i < 1001; i++ )
+    {
+      if ( ( a[i] > 'a' && a[i] < 'z' ) || ( a[i] > 'A' && a[i] < 'Z' ) )
+        printf("%c", a[i]);
+      else
+        printf(".");
+    }
+    printf("\n");
+    
     s = "";
     return -1;
   }
 
-  s[0] = '\0';
+  s = "";
   s.append( (char*)a+n, length );
 
Index: /trunk/src/lib/network/data_stream.cc
===================================================================
--- /trunk/src/lib/network/data_stream.cc	(revision 7953)
+++ /trunk/src/lib/network/data_stream.cc	(revision 7954)
@@ -16,6 +16,4 @@
 /* include Data_stream Header */
 #include "data_stream.h"
-
-
 
 
Index: /trunk/src/lib/network/handshake.cc
===================================================================
--- /trunk/src/lib/network/handshake.cc	(revision 7953)
+++ /trunk/src/lib/network/handshake.cc	(revision 7954)
@@ -24,5 +24,5 @@
 #include <cassert>
 
-Handshake::Handshake( bool server, int clientId, int networkGameManagerId )
+Handshake::Handshake( bool server, int clientId, int networkGameManagerId, int messageManagerId )
   : Synchronizeable()
 {
@@ -31,175 +31,84 @@
 
   this->setIsServer(server);
-  this->clientId = clientId;
-  this->networkGameManagerId = networkGameManagerId;
-  this->state = 0;
-  this->isOk = false;
-  this->setOwner(0);
+ 
+  orxId_handler = registerVarId( new SynchronizeableInt( &localState.orxId, &remoteState.orxId, "orxonoxId", PERMISSION_ALL ) );
+  version_handler = registerVarId( new SynchronizeableInt( &localState.version, &remoteState.version, "version", PERMISSION_ALL ) );
+  netManId_handler = registerVarId( new SynchronizeableInt( &localState.networkManagerId, &remoteState.networkManagerId, "networkManagerId", PERMISSION_ALL ) );
+  msgManId_handler = registerVarId( new SynchronizeableInt( &localState.messageManagerId, &remoteState.messageManagerId, "messageManagerId", PERMISSION_ALL ) );
+  hostId_handler = registerVarId( new SynchronizeableInt( &localState.hostId, &remoteState.hostId, "hostId", PERMISSION_ALL ) );
+  completed_handler = registerVarId( new SynchronizeableInt( &localState.completed, &remoteState.completed, "completed", PERMISSION_ALL ) );
+  error_handler = registerVarId( new SynchronizeableInt( &localState.error, &remoteState.error, "error", PERMISSION_ALL ) );
+  errorString_handler = registerVarId( new SynchronizeableString( &localState.errorString, &remoteState.errorString, "errorString", PERMISSION_ALL ) );
+  
+  candel_id = registerVarId( new SynchronizeableInt( &localState.canDel, &remoteState.canDel, "canDel", PERMISSION_ALL ) );
+  
+  localState.completed = 0;
+  localState.error = 0;
+  localState.errorString = "";
+  localState.hostId = clientId;
+  localState.networkManagerId = networkGameManagerId;
+  this->localState.messageManagerId = messageManagerId;
+  localState.orxId = _ORXONOX_ID;
+  localState.version = _ORXONOX_VERSION;
+  localState.canDel = 0;
+  
+  remoteState.completed = 0;
+  remoteState.error = 0;
+  remoteState.errorString = "";
+  remoteState.hostId = -1;
+  remoteState.networkManagerId = -1;
+  remoteState.messageManagerId = -1;
+  remoteState.orxId = 0;
+  remoteState.version = 0;
+  remoteState.canDel = 0;
 
   this->setSynchronized(true);
-  PRINTF(5)("Handshake created clientId = %d\n", clientId);
+  PRINTF(0)("Handshake created clientId = %d\n", clientId);
 }
 
-int Handshake::writeBytes( const byte * data, int length, int sender)
+/**
+ * handler for changes in synced vars
+ * @param id id's which have changed
+ */
+void Handshake::varChangeHandler( std::list< int > & id )
 {
-  PRINTF(5)("Handshake::writeBytes states = %d %d %d %d (%d)\n", hasState( HS_RECVD_INIT ), hasState( HS_RECVD_VER ), hasState( HS_RECVD_HID ), hasState( HS_COMPLETED ), state);
+  for ( std::list<int>::iterator it = id.begin(); it != id.end(); it++ )
+  {
+    if ( *it == orxId_handler )
+    {
+      if ( remoteState.orxId != _ORXONOX_ID )
+      {
+        localState.error = 1;
+        localState.completed = 1;
+        localState.errorString = "Seems not to be orxonox!";
+        continue;
+      }
 
-  SYNCHELP_READ_BEGIN();
+    }
+     
+    if ( *it == version_handler )
+    {
+      if ( remoteState.version != _ORXONOX_VERSION )
+      {
+        localState.error = 2;
+        localState.completed = 1;
+        localState.errorString = "Versions of server and client do not match!";
+        continue;
+      }
 
-  if ( hasState( HS_COMPLETED ) )
-       return 0;
-
-  if ( !hasState( HS_RECVD_INIT ) )
-  {
-    if ( length != _INITIAL_DATA_LENGTH )
+    }
+    
+    if ( *it == candel_id )
     {
-      PRINTF(0)("initial packet has wrong size %d instead of %d\n", length, _INITIAL_DATA_LENGTH);
-      setState( HS_COMPLETED );
-      return 0;
+      PRINTF(0)("handshake finished candel changed\n");
     }
-
-    if ( strncmp((char*)data, _INITIAL_DATA, length) )
-    {
-      PRINTF(0)("initial packed does not match\n");
-      setState( HS_COMPLETED );
-      return length;
-    }
-
-    setState( HS_RECVD_INIT );
-    PRINTF(0)("got valid initial packet from client %d\n", clientId);
-    return length;
+    
   }
-
-  if ( hasState( HS_RECVD_INIT ) && !hasState( HS_RECVD_VER ) )
-  {
-    if ( length != _ORXONOX_VERSION_LENGTH )
-    {
-      PRINTF(0)("version number packet has wrong size %d instead of %d\n", length, _ORXONOX_VERSION_LENGTH);
-      setState( HS_COMPLETED );
-      return 0;
-    }
-
-    if ( strncmp((char*)data, _ORXONOX_VERSION, length) )
-    {
-      PRINTF(0)("versions do not match\n");
-      setState( HS_COMPLETED );
-      return length;
-    }
-
-    setState( HS_RECVD_VER );
-
-    PRINTF(0)("client %d's version does match\n", clientId);
-    return length;
-  }
-
-  if ( !isServer() && hasState( HS_RECVD_VER ) && !hasState( HS_RECVD_HID ) )
-  {
-    /*if ( length != INTSIZE+INTSIZE )
-    {
-      PRINTF(0)("hostID packet has wrong size %d instead of %d\n", length, INTSIZE+INTSIZE);
-      setState( HS_COMPLETED );
-      return 0;
-  }*/
-
-    setState( HS_COMPLETED );
-    setState( HS_RECVD_HID );
-    this->isOk = true;
-    SYNCHELP_READ_INT( this->newHostId, NWT_HS_HOST_ID );
-    SYNCHELP_READ_INT( this->newNetworkGameManagerId, NWT_HS_NGM_ID );
-
-    if ( newHostId == 0 )
-    {
-      setState( HS_WAS_REJECT );
-      isOk = false;
-      PRINTF(0)("Server did not accept handshake!\n");
-    }
-    else
-    {
-      PRINTF(0)("got my hostID: %d and networkGameManagerId: %d\n", newHostId, newNetworkGameManagerId);
-    }
-    return SYNCHELP_READ_N;
-  }
-
+  
+  if (
+      remoteState.orxId == _ORXONOX_ID &&
+      remoteState.version == _ORXONOX_VERSION
+     )
+    localState.completed = 1;
 }
 
-int Handshake::readBytes( byte * data, int maxLength, int * reciever )
-{
-  PRINTF(5)("Handshake::readBytes states = %d %d %d %d (%d)\n", hasState( HS_SENT_INIT ), hasState( HS_SENT_VER ), hasState( HS_SENT_HID ), hasState( HS_COMPLETED ), state);
-
-  SYNCHELP_WRITE_BEGIN();
-
-  if ( hasState( HS_COMPLETED ) )
-    return 0;
-
-  if ( !hasState( HS_SENT_INIT ) )
-  {
-    if ( maxLength < _INITIAL_DATA_LENGTH )
-    {
-      PRINTF(0)("buffer too small for _INITIAL_DATA");
-      setState( HS_COMPLETED );
-      return 0;
-    }
-
-    setState( HS_SENT_INIT );
-    memcpy(data, _INITIAL_DATA, _INITIAL_DATA_LENGTH);
-    if ( this->isServer() )
-      *reciever = clientId;
-    return _INITIAL_DATA_LENGTH;
-  }
-
-  if ( hasState( HS_RECVD_INIT ) && hasState( HS_SENT_INIT ) && !hasState( HS_SENT_VER ) )
-  {
-    if ( maxLength < _ORXONOX_VERSION_LENGTH )
-    {
-      PRINTF(0)("buffer too small for version number");
-      setState( HS_COMPLETED );
-      return 0;
-    }
-
-    setState( HS_SENT_VER );
-    memcpy(data, _ORXONOX_VERSION, _ORXONOX_VERSION_LENGTH);
-    if ( this->isServer() )
-      *reciever = clientId;
-    return _ORXONOX_VERSION_LENGTH;
-  }
-
-  if ( isServer() && hasState( HS_RECVD_VER) && hasState( HS_SENT_VER ) && !hasState( HS_SENT_HID ) )
-  {
-    if ( maxLength < 2 )
-    {
-      PRINTF(0)("buffer too small for ID");
-      setState( HS_COMPLETED );
-      return 0;
-    }
-
-    setState( HS_SENT_HID );
-    setState( HS_COMPLETED );
-
-    if ( hasState( HS_DO_REJECT ) )
-    {
-      isOk = false;
-      //memcpy(data, (byte*)0, 4);
-      SYNCHELP_WRITE_INT( 0, NWT_HS_HOST_ID);
-      SYNCHELP_WRITE_INT( 0, NWT_HS_NGM_ID);
-    }
-    else
-    {
-      isOk = true;
-      //memcpy(data, &clientId, 4);
-      SYNCHELP_WRITE_INT( clientId, NWT_HS_HOST_ID );
-      SYNCHELP_WRITE_INT( networkGameManagerId, NWT_HS_NGM_ID );
-    }
-    *reciever = clientId;
-    return SYNCHELP_WRITE_N;
-  }
-
-  return 0;
-}
-
-void Handshake::writeDebug( ) const
-{
-}
-
-void Handshake::readDebug( ) const
-{
-}
Index: /trunk/src/lib/network/handshake.h
===================================================================
--- /trunk/src/lib/network/handshake.h	(revision 7953)
+++ /trunk/src/lib/network/handshake.h	(revision 7954)
@@ -10,23 +10,22 @@
 #include "synchronizeable.h"
 
-#define _INITIAL_DATA "orxonox"
-#define _INITIAL_DATA_LENGTH 7
+#define _ORXONOX_ID 0xF91337A0
 
-#define _ORXONOX_VERSION "\x00\x00\x00\x01"
-#define _ORXONOX_VERSION_LENGTH 4
+#define _ORXONOX_VERSION 1
 
-typedef enum HandshakeState {
-  HS_SENT_INIT  = 0x00000001,
-  HS_RECVD_INIT = 0x00000002,
-  HS_SENT_VER   = 0x00000004,
-  HS_RECVD_VER  = 0x00000008,
-  HS_SENT_HID   = 0x00000010,
-  HS_RECVD_HID  = 0x00000020,
-  HS_COMPLETED  = 0x00000040,
-
-  HS_DO_REJECT  = 0x00010000,
-  HS_WAS_REJECT = 0x00020000,
-
-  NUM_STATES
+struct HandshakeState {
+  int orxId;
+  int version;
+  
+  int networkManagerId;
+  int messageManagerId;
+  int hostId;
+  
+  int completed;
+  int canDel;
+  
+  int error;
+  
+  std::string errorString;
 };
 
@@ -34,28 +33,30 @@
 {
   public:
-    Handshake(bool server, int clientId = 0, int networkGameManagerId = 0);
-    inline bool       completed(){ return hasState( HS_COMPLETED ); }
-    inline bool       ok(){ return isOk; }
-    inline int        getHostId(){ return newHostId; }
-    inline int        getNetworkGameManagerId(){ return newNetworkGameManagerId; }
-
-    inline void       doReject(){ setState(HS_DO_REJECT); }
-
-    virtual int       writeBytes(const byte* data, int length, int sender);
-    virtual int       readBytes(byte* data, int maxLength, int * reciever);
-    virtual void      writeDebug() const;
-    virtual void      readDebug() const;
+    Handshake( bool server, int clientId = 0, int networkGameManagerId = 0, int messageManagerId = 0 );
+    inline bool       completed(){ return localState.completed != 0 && remoteState.completed != 0; }
+    inline bool       ok(){ return localState.error == 0 && remoteState.error == 0; }
+    inline int        getHostId(){ return remoteState.hostId; }
+    inline int        getNetworkGameManagerId(){ return remoteState.networkManagerId; }
+    inline int        getMessageManagerId(){ return remoteState.messageManagerId; }
+    inline void       doReject( std::string reason ){ localState.error = 1; localState.errorString = "the server rejected your connection ["+ reason +"]"; }
+    inline bool       canDel(){ return localState.canDel == 1 && remoteState.canDel == 1; }
+    inline bool       allowDel(){ return localState.canDel == 1; }
+    inline void       del(){ localState.canDel = 1; }
+    
+    virtual void varChangeHandler( std::list<int> & id );
 
   private:
-    int               state;
-    int               clientId;
-    int               networkGameManagerId;
-    int               newHostId;
-    int               newNetworkGameManagerId;
-    bool              isOk;
-
-    inline bool       hasState( int a ){ return (state & a) == a; }
-    inline void       setState( int a ){ state = state | a; }
-    inline void       unsetState( int a ){ state = state & (~a); }
+    HandshakeState localState;
+    HandshakeState remoteState;
+    
+    int netManId_handler;
+    int msgManId_handler;
+    int hostId_handler;
+    int completed_handler;
+    int error_handler;
+    int errorString_handler;
+    int orxId_handler;
+    int version_handler;
+    int candel_id;
 
 };
Index: /trunk/src/lib/network/message_manager.cc
===================================================================
--- /trunk/src/lib/network/message_manager.cc	(revision 7954)
+++ /trunk/src/lib/network/message_manager.cc	(revision 7954)
@@ -0,0 +1,330 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "message_manager.h"
+
+using namespace std;
+
+MessageManager* MessageManager::singletonRef = NULL;
+
+
+/**
+ * standard constructor
+*/
+MessageManager::MessageManager ()
+{
+  this->setClassID( CL_MESSAGE_MANAGER, "MessageManager" );
+  newNumber = 1;
+  setSynchronized( true );
+}
+
+
+/**
+ * standard deconstructor
+*/
+MessageManager::~MessageManager ()
+{
+  for ( MessageQueue::iterator it = messageQueue.begin(); it != messageQueue.end(); it++ )
+  {
+    for ( std::list<NetworkMessage>::iterator it2 = it->second.messages.begin(); it2 != it->second.messages.end(); it2++ )
+    {
+      if ( it2->data )
+      {
+        delete it2->data;
+        it2->data = NULL;
+      }
+    }
+    
+    it->second.messages.clear();
+    it->second.toAck.clear();
+  }
+  
+  messageQueue.clear();
+}
+
+/**
+ * get the diff to last acked state of userId
+ *
+ * this class does not use the normal SynchronizeableVars for zynchronisation. instead
+ * it defines its own protocol
+ *
+ * @param userId user to create diff for
+ * @param data buffer to copy diff in
+ * @param maxLength max bytes to copy into data
+ * @param stateId id of current state
+ * @param fromStateId the reference state for the delta state
+ * @param priorityTH tells getStateDiff to not send element with priority \< priorityTH
+ * @return n bytes copied into data
+ */
+int MessageManager::getStateDiff( int userId, byte * data, int maxLength, int stateId, int fromStateId, int priorityTH )
+{
+  int i = 0;
+  int n;
+  
+  n = Converter::intToByteArray( messageQueue[userId].toAck.size(), data + i, maxLength );
+  i += n;
+  assert( n == INTSIZE );
+  
+  for ( std::list<int>::iterator it = messageQueue[userId].toAck.begin(); it != messageQueue[userId].toAck.end(); it++)
+  {
+    n = Converter::intToByteArray( *it, data + i, maxLength );
+    i += n;
+    assert( n == INTSIZE );
+  }
+  
+  messageQueue[userId].toAck.clear();
+  
+  n = Converter::intToByteArray( messageQueue[userId].messages.size(), data + i, maxLength );
+  i += n;
+  assert( n == INTSIZE );
+  
+  for ( std::list<NetworkMessage>::iterator it = messageQueue[userId].messages.begin(); it != messageQueue[userId].messages.end(); it++ )
+  {
+    n = Converter::intToByteArray( it->length, data + i, maxLength );
+    i += n;
+    assert( n == INTSIZE );
+    
+    n = Converter::intToByteArray( it->number, data + i, maxLength );
+    i += n;
+    assert( n == INTSIZE );
+    
+    n = Converter::intToByteArray( it->messageId, data + i, maxLength );
+    i += n;
+    assert( n == INTSIZE );
+    
+    assert( i + it->length <= maxLength );
+    memcpy( data + i, it->data, it->length );
+    i += it->length;
+  }
+  
+  return i;
+}
+
+/**
+ * sets a new state out of a diff created on another host
+ * @param userId hostId of user who send me that diff
+ * @param data pointer to diff
+ * @param length length of diff
+ * @param stateId id of current state
+ * @param fromStateId id of the base state id
+ * @return number bytes read
+ * @todo check for permissions
+ */
+int MessageManager::setStateDiff( int userId, byte * data, int length, int stateId, int fromStateId )
+{
+  int i = 0;
+  int n;
+  
+  int nAcks;
+  
+  assert( i + INTSIZE <= length );
+  n = Converter::byteArrayToInt( data + i, &nAcks );
+  assert( n == INTSIZE );
+  i += n;
+  
+  std::list<int> acks;
+  
+  int number;
+  
+  for ( int j = 0; j < nAcks; j++ )
+  {
+    assert( i + INTSIZE <= length );
+    n = Converter::byteArrayToInt( data + i, &number );
+    assert( n == INTSIZE );
+    i += n;
+    
+    acks.push_back( number );
+  }
+  
+  int nMessages;
+  
+  assert( i + INTSIZE <= length );
+  n = Converter::byteArrayToInt( data + i, &nMessages );
+  assert( n == INTSIZE );
+  i += n;
+
+  int messageLength, messageId;
+  
+  for ( int j = 0; j < nMessages; j++ )
+  {
+    assert( i + INTSIZE <= length );
+    n = Converter::byteArrayToInt( data + i, &messageLength );
+    assert( n == INTSIZE );
+    i += n;
+    
+    assert( i + INTSIZE <= length );
+    n = Converter::byteArrayToInt( data + i, &number );
+    assert( n == INTSIZE );
+    i += n;
+  
+    assert( i + INTSIZE <= length );
+    n = Converter::byteArrayToInt( data + i, &messageId );
+    assert( n == INTSIZE );
+    i += n;
+    
+    if ( number > 0 )
+      messageQueue[userId].toAck.push_back( number );
+    
+    assert( i + messageLength <= length );
+    assert( messageHandlerMap.find( (MessageId)messageId ) != messageHandlerMap.end() );
+    if ( std::find( messageQueue[userId].recievedMessages.begin(), messageQueue[userId].recievedMessages.end(), number )== messageQueue[userId].recievedMessages.end() )
+    {
+      if ( !(*(messageHandlerMap[(MessageId)messageId].cb))( (MessageId)messageId, data + i, messageLength, messageHandlerMap[(MessageId)messageId].someData, userId ) )
+      {
+        NetworkMessage msg;
+        
+        msg.data = new byte[messageLength];
+        memcpy( msg.data, data + i, messageLength );
+        msg.length = messageLength;
+        msg.messageId = (MessageId)messageId;
+        msg.number = userId;
+        
+        incomingMessabeBuffer.push_back( msg );
+      }
+      messageQueue[userId].recievedMessages.push_back( number );
+    }
+    i += messageLength;
+  }
+  
+  
+  for ( std::list<NetworkMessage>::iterator it = incomingMessabeBuffer.begin(); it != incomingMessabeBuffer.end();  )
+  {
+    if ( (*(messageHandlerMap[it->messageId].cb))( it->messageId, it->data, it->length, messageHandlerMap[it->messageId].someData, it->number ) )
+    {
+      std::list<NetworkMessage>::iterator delIt = it;
+      if ( it->data )
+        delete it->data;
+      it++;
+      incomingMessabeBuffer.erase( delIt );
+      continue;
+    }
+    it++;
+  }
+  
+  //walk throu message queue and remove acked messages
+  for ( std::list<NetworkMessage>::iterator it = messageQueue[userId].messages.begin(); it != messageQueue[userId].messages.end();  )
+  {
+    if ( std::find( acks.begin(), acks.end(), it->number) != acks.end() )
+    {
+      std::list<NetworkMessage>::iterator delIt = it;
+      it++;
+      messageQueue[userId].messages.erase( delIt );
+      continue;
+    }
+    it++;
+  }
+  
+  //TODO find bether way. maybe with timestamp
+  if ( messageQueue[userId].recievedMessages.size() > 1000 )
+  {
+    for ( int j = 0; j < messageQueue[userId].recievedMessages.size() - 1000; j++ )
+      messageQueue[userId].recievedMessages.erase( messageQueue[userId].recievedMessages.begin() );
+  }
+
+  return i;
+}
+
+/**
+ * clean up memory reserved for user
+ * @param userId userid
+ */
+void MessageManager::cleanUpUser( int userId )
+{
+  if ( messageQueue.find( userId ) == messageQueue.end() )
+    return;
+    
+  for ( std::list<NetworkMessage>::iterator it = messageQueue[userId].messages.begin(); it != messageQueue[userId].messages.end(); it++ )
+  {
+    if ( it->data )
+      delete it->data;
+    it->data = NULL;
+  }
+  
+  messageQueue[userId].toAck.clear();
+  
+  messageQueue.erase( userId );
+}
+
+/**
+ * registers function to handle messages with id messageId. someData is passed to callbackfuntion
+ * @param messageId message id to handle 
+ * @param cb function pointer to callback function
+ * @param someData this pointer is passed to callback function without modification
+ * @return true on success
+ */
+bool MessageManager::registerMessageHandler( MessageId messageId, MessageCallback cb, void * someData )
+{
+  MessageHandler messageHandler;
+  
+  messageHandler.cb = cb;
+  messageHandler.messageId = messageId;
+  messageHandler.someData = someData;
+  
+  messageHandlerMap[messageId] = messageHandler;
+  
+  return true;
+}
+
+/**
+ * initializes buffers for user
+ * @param userId userId
+ */
+void MessageManager::initUser( int userId )
+{
+  // just do something so map creates a new entry
+  messageQueue[userId].toAck.clear();
+  //assert( messageQueue[userId].messages.size() == 0 );
+}
+
+/**
+ * send a message to one or more clients
+ * recieverType:
+ *               RT_ALL send to all users. reciever is ignored
+ *               RT_USER send only to reciever
+ *               RT_NOT_USER send to all but reciever
+ *
+ * @param messageId message id
+ * @param data pointer to data
+ * @param dataLength length of data
+ * @param recieverType 
+ * @param reciever 
+ */
+void MessageManager::sendMessage( MessageId messageId, byte * data, int dataLength, RecieverType recieverType, int reciever, MessagePriority messagePriority )
+{
+  for ( MessageQueue::iterator it = messageQueue.begin(); it != messageQueue.end(); it++ )
+  {
+    if ( 
+         recieverType == RT_ALL ||
+         recieverType == RT_USER && it->first == reciever ||
+         recieverType == RT_NOT_USER && it->first != reciever
+       )
+    {
+      NetworkMessage msg;
+      
+      msg.data = new byte[dataLength];
+      memcpy( msg.data, data, dataLength );
+      msg.length = dataLength;
+      msg.messageId = messageId;
+      msg.number = newNumber++;
+      msg.priority = messagePriority;
+      
+      it->second.messages.push_back( msg );
+    }
+  }
+}
+
+
Index: /trunk/src/lib/network/message_manager.h
===================================================================
--- /trunk/src/lib/network/message_manager.h	(revision 7954)
+++ /trunk/src/lib/network/message_manager.h	(revision 7954)
@@ -0,0 +1,110 @@
+/*!
+ * @file message_manager.h
+ * @brief Definition of MessageManager
+*/
+
+#ifndef _MESSAGE_MANAGER_H
+#define _MESSAGE_MANAGER_H
+
+#include "synchronizeable.h"
+
+#include <map>
+#include <list>
+
+/*
+  Protocol:
+    int nacks
+    int acks[1..nacks]
+    int nmsg
+    (
+      int length
+      int number
+      int MessageId
+      byte * data
+    )[1..nmsg]
+*/
+
+
+enum MessageId 
+{
+  TESTMESSAGEID = 1,
+  MSGID_YOU_ARE
+};
+
+typedef bool (*MessageCallback)( MessageId messageId, byte * data, int dataLength, void * someData, int userId );
+
+enum RecieverType
+{
+  RT_ALL = 1,   //!< message is sent to all users
+  RT_USER,      //!< message is only sent to reciever
+  RT_NOT_USER   //!< message is sent to all but reciever
+};
+
+//TODO implement priority handling
+enum MessagePriority
+{
+  MP_HIGHBANDWIDTH = 1,  //!< fast and reliable but uses a lot of bandwidth
+  MP_LOWBANDWIDTH,       //!< may take a long time to arrive. reliable
+  MP_UNRELIABLE          //!< unreliable. low bandwidth 
+};
+
+struct NetworkMessage
+{
+  MessageId        messageId;
+  byte *           data;
+  int              length;
+  int              number;
+  MessagePriority  priority;
+};
+
+struct MessageUserQueue
+{
+  std::list<NetworkMessage> messages;
+  std::list<int>            toAck;
+  std::list<int>            recievedMessages;
+};
+
+typedef std::map<int,MessageUserQueue> MessageQueue;
+
+struct MessageHandler
+{
+  MessageCallback cb;
+  MessageId       messageId;
+  void *          someData;
+};
+
+typedef std::map<MessageId,MessageHandler> MessageHandlerMap;
+
+//! A class for sending messages over network
+class MessageManager : public Synchronizeable {
+ protected:
+   MessageManager();
+ public:
+   inline static MessageManager * getInstance(){ if (!singletonRef) singletonRef = new MessageManager();  return singletonRef; }
+   
+   virtual ~MessageManager();
+   
+   bool registerMessageHandler( MessageId messageId, MessageCallback cb, void * someData );
+   
+   void sendMessage( MessageId messageId, byte * data, int dataLength, RecieverType recieverType, int reciever, MessagePriority messagePriority );
+
+   virtual int getStateDiff( int userId, byte* data, int maxLength, int stateId, int fromStateId, int priorityTH );
+   virtual int setStateDiff( int userId, byte* data, int length, int stateId, int fromStateId );
+   virtual void cleanUpUser( int userId );
+   virtual void handleSentState( int userId, int stateId, int fromStateId ){}
+   virtual void handleRecvState( int userId, int stateId, int fromStateId ){}
+   
+   void initUser( int userId );
+
+
+ private:
+   static MessageManager *   singletonRef;
+   MessageQueue              messageQueue;           //!< stores messages to send
+   MessageHandlerMap         messageHandlerMap;      //!< contains handlers for messages
+
+   int                       newNumber;              //!< used to create unique message numbers
+   std::list<NetworkMessage> incomingMessabeBuffer; 
+
+};
+
+#endif /* _PROTO_CLASS_H */
Index: /trunk/src/lib/network/netdefs.h
===================================================================
--- /trunk/src/lib/network/netdefs.h	(revision 7953)
+++ /trunk/src/lib/network/netdefs.h	(revision 7954)
@@ -19,4 +19,6 @@
 #define MAX_CONNECTIONS 1000
 
+#define NETWORK_FREQUENCY 33
+
 
 typedef unsigned char byte;
@@ -28,4 +30,9 @@
 } NodeType;
 
+typedef enum ConnectionType {
+  NET_UDP = 0,
+  NET_TCP
+};
+
 
 typedef enum {
Index: /trunk/src/lib/network/network_game_manager.cc
===================================================================
--- /trunk/src/lib/network/network_game_manager.cc	(revision 7953)
+++ /trunk/src/lib/network/network_game_manager.cc	(revision 7954)
@@ -27,4 +27,5 @@
 #include "shared_network_data.h"
 #include "converter.h"
+#include "message_manager.h"
 
 #include "playable.h"
@@ -52,6 +53,7 @@
   this->setClassID(CL_NETWORK_GAME_MANAGER, "NetworkGameManager");
 
-  hasRequestedWorld = false;
   this->setSynchronized(true);
+  
+  MessageManager::getInstance()->registerMessageHandler( MSGID_YOU_ARE, youAreHandler, NULL );
 }
 
@@ -61,4 +63,5 @@
 NetworkGameManager::~NetworkGameManager()
 {
+#if 0
   for ( int i = 0; i<outBuffer.size(); i++)
   {
@@ -66,8 +69,9 @@
       delete outBuffer[i].buffer;
   }
-
-}
-
-
+#endif
+
+}
+
+#if 0
 int NetworkGameManager::writeBytes(const byte* data, int length, int sender)
 {
@@ -141,10 +145,4 @@
     {
       sendEntityList( sender );
-      continue;
-    }
-    else if ( b == NET_REQUEST_SYNC )
-    {
-      if ( !handleRequestSync( i, data, length, sender ) )
-        return i;
       continue;
     }
@@ -160,5 +158,7 @@
   return i;
 }
-
+#endif
+
+#if 0
 int NetworkGameManager::readBytes(byte* data, int maxLength, int * reciever)
 {
@@ -192,5 +192,7 @@
   return 0;
 }
-
+#endif
+
+#if 0
 void NetworkGameManager::writeDebug() const
 {
@@ -200,4 +202,5 @@
 {
 }
+#endif
 
 
@@ -211,14 +214,19 @@
   if ( this->isServer())
   {
-    if ( SharedNetworkData::getInstance()->getNewUniqueID() < 0 )
+    int res = this->executeCreateEntity( classID, SharedNetworkData::getInstance()->getNewUniqueID(), owner );
+    
+    if ( res < 0 )
     {
       PRINTF(1)("Cannot create entity! There are no more uniqueIDs left!\n");
       return -1;
     }
-    return this->executeCreateEntity( classID, SharedNetworkData::getInstance()->getNewUniqueID(), owner );
+    
+    return res;
   }
   else
   {
+#if 0
     this->requestCreateEntity( classID );
+#endif
     return -1;
   }
@@ -288,10 +296,12 @@
   else
   {
+#if 0
     this->requestRemoveEntity( uniqueID );
-  }
-}
-
-
-
+#endif
+  }
+}
+
+
+#if 0
 /*!
  * Creates the needed entity on the server if possible
@@ -311,5 +321,7 @@
   }
 }
-
+#endif
+
+#if 0
 /*!
  * Removes the specified entity on the server
@@ -329,4 +341,5 @@
   }
 }
+#endif
 
 /*!
@@ -337,4 +350,5 @@
 int NetworkGameManager::executeCreateEntity(ClassID classID, int uniqueID, int owner)
 {
+#if 0
   for ( int i = 0; i<outBuffer.size(); i++)
   {
@@ -351,5 +365,5 @@
       return -1;
   }
-
+#endif
   PRINTF(0)("ExecuteCreateEntity: server side: classID: %x, uniqueID: %i, owner: %i\n", classID, uniqueID, owner);
   doCreateEntity( classID, uniqueID, owner );
@@ -365,4 +379,5 @@
 void NetworkGameManager::executeRemoveEntity(int uniqueID)
 {
+#if 0
   for ( int i = 0; i<outBuffer.size(); i++)
   {
@@ -375,4 +390,5 @@
       return;
   }
+#endif
 
   doRemoveEntity(uniqueID);
@@ -388,4 +404,5 @@
 }
 
+#if 0
 /*!
  * Sends the Entities to the new connected client
@@ -443,4 +460,5 @@
   signalNewPlayer( userID );
 }
+#endif
 
 
@@ -448,7 +466,4 @@
 bool NetworkGameManager::signalNewPlayer(int userId)
 {
-  if ( userId >= outBuffer.size() )
-    resizeBufferVector( userId );
-
   /* create new playable for Player*/
   PRINTF(0)("Request for creation: %i\n", userId);
@@ -456,5 +471,4 @@
   PRINTF(0)("Request for creation: userid: %i, uniqueid: %i\n", userId, uniqueId);
   this->sendYouAre(uniqueId, userId);
-
 }
 
@@ -464,4 +478,8 @@
 {
   const std::list<BaseObject*>* playableList = ClassList::getList(CL_PLAYABLE);
+  
+  if ( !playableList )
+    return false;
+  
   std::list<BaseObject*>::const_iterator it = playableList->begin();
 
@@ -478,5 +496,5 @@
 }
 
-
+#if 0
 /**
  * Creates a buffer for user n
@@ -498,4 +516,5 @@
   }
 }
+#endif
 
 /**
@@ -532,6 +551,5 @@
     s->setSynchronized(true);
     //this->networkStream->connectSynchronizeable( *s );
-    if ( !isServer() )
-      s->setIsOutOfSync( true );
+
     PRINTF(0)("Fabricated %s with id %d\n", s->getClassName(), s->getUniqueID());
 
@@ -601,26 +619,5 @@
 }
 
-/**
- * Tell the synchronizeable that a user's synchronizeable is out of sync
- * @param uniqueID: unique ID assigned with the entity which is out of sync
- * @param userID: user ID who's synchronizeable is out of sync
- */
-void NetworkGameManager::doRequestSync( int uniqueID, int userID )
-{
-  SynchronizeableList::const_iterator it,e;
-  it = this->networkStream->getSyncBegin();
-  e = this->networkStream->getSyncEnd();
-
-  while ( it != e )
-  {
-    if ( (*it)->getUniqueID() == uniqueID )
-    {
-      (*it)->requestSync( userID );
-      break;
-    }
-    it++;
-  }
-}
-
+#if 0
 /**
  * Copies length bytes to the clientBuffer with error checking
@@ -641,5 +638,7 @@
   return true;
 }
-
+#endif
+
+#if 0
 /**
  * Reads data from clientBuffer with error checking
@@ -660,4 +659,5 @@
   return true;
 }
+#endif
 
 /**
@@ -687,5 +687,5 @@
       } else
       {
-        PRINTF(1)("UniqueID is not a Playable\n");
+        PRINTF(1)("UniqueID %d is not a Playable\n", uniqueID);
       }
     }
@@ -697,6 +697,4 @@
   assert(player != NULL);
 
-  s->setIsOutOfSync( true );
-
   PRINTF(0)("uniqueID = %d\n", s->getUniqueID());
 
@@ -715,17 +713,10 @@
   if ( !isServer() )
     return;
-
-  if ( userID != 0 )
-  {
-    if ( !writeToClientBuffer( outBuffer[userID], (byte)NET_YOU_ARE_ENTITY ) )
-      return;
-
-    if ( !writeToClientBuffer( outBuffer[userID], uniqueID ) )
-      return;
-  }
-  else
-  {
-    doYouAre(uniqueID);
-  }
+  
+  byte buf[INTSIZE];
+  
+  Converter::intToByteArray( uniqueID, buf, INTSIZE );
+  
+  MessageManager::getInstance()->sendMessage( MSGID_YOU_ARE, buf, INTSIZE, RT_USER, userID, MP_HIGHBANDWIDTH);
 }
 
@@ -902,21 +893,4 @@
   return true;
 }
-
-bool NetworkGameManager::handleRequestSync( int & i, const byte * data, int length, int sender )
-{
-  if ( INTSIZE > length-i )
-  {
-    PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n");
-    return false;
-  }
-  int uniqueID;
-  i += Converter::byteArrayToInt( &data[i], &uniqueID );
-
-  PRINTF(0)("handleRequestSync %d %d\n", uniqueID, sender);
-  doRequestSync( uniqueID, sender );
-
-  return true;
-}
-
 
 /**
@@ -958,5 +932,33 @@
 }
 
-
+bool NetworkGameManager::youAreHandler( MessageId messageId, byte * data, int dataLength, void * someData, int userId )
+{
+  assert( dataLength == INTSIZE );
+  int uniqueId;
+  
+  Converter::byteArrayToInt( data, &uniqueId );
+  
+  SynchronizeableList::const_iterator it = NetworkGameManager::getInstance()->networkStream->getSyncBegin();
+
+  Playable *p = NULL;
+  Synchronizeable *s = NULL;
+
+  for ( ; it !=NetworkGameManager::getInstance()->networkStream->getSyncEnd(); it++ )
+  {
+    if ( (*it)->getUniqueID()==uniqueId )
+    {
+      break;
+    }
+  }
+  
+  if ( it == NetworkGameManager::getInstance()->networkStream->getSyncEnd() )
+    return false;
+  
+  NetworkGameManager::getInstance()->doYouAre( uniqueId );
+  
+  return true;
+}
+
+#if 0
 bool NetworkGameManager::writeToClientBuffer( clientBuffer & cb, byte b )
 {
@@ -971,4 +973,5 @@
   return true;
 }
+
 
 bool NetworkGameManager::writeToClientBuffer( clientBuffer & cb, int i )
@@ -985,26 +988,5 @@
   return true;
 }
-
-void NetworkGameManager::sync( int uniqueID, int owner )
-{
-  /*if ( owner==this->getHostID() )
-  return;*/
-
-  if ( !isServer() )
-    executeRequestSync( uniqueID, 0 );
-  else
-    executeRequestSync( uniqueID, owner );
-}
-
-void NetworkGameManager::executeRequestSync( int uniqueID, int user )
-{
-  PRINTF(0)("executeRequestSync %d %d\n", uniqueID, user);
-  if ( user >= outBuffer.size() )
-    resizeBufferVector( user );
-
-  if ( !writeToClientBuffer( outBuffer[user], (byte)NET_REQUEST_SYNC ) )
-    return;
-  if ( !writeToClientBuffer( outBuffer[user], uniqueID ) )
-    return;
-}
-
+#endif
+
+
Index: /trunk/src/lib/network/network_game_manager.h
===================================================================
--- /trunk/src/lib/network/network_game_manager.h	(revision 7953)
+++ /trunk/src/lib/network/network_game_manager.h	(revision 7954)
@@ -12,38 +12,9 @@
 /* include base_object.h since all classes are derived from this one */
 #include "synchronizeable.h"
+#include "message_manager.h"
 
 
 class TiXmlElement;
 class PNode;
-
-/**
- * protocol definition
- *
- *  CREATE_ENTITY:       >> CLASS_ID, UNIQUE_ID, OWNER
- *  REMOVE_ENTITY:       >> UNIQUE_ID
- *
- *  CREATE_ENTITY_LIST:  >> NUMBER, [CLASS_ID, UNIQUE_ID, OWNER][0..NUMBER]
- *  REMOVE_ENTITY_LIST:  >> NUMBER, [UNIQUE_ID][0..NUMBER]
- *
- *  REQUEST_CREATE:      >> CLASS_ID
- *                       << [Sync Info]
- *  REQUEST_REMOVE:      >> UNIQUE_ID
- *                       << [Sync Info]
- *
- *  //REQUEST_CREATE_LIST: NUMBER, [CLASS_ID][0..NUMBER]
- *  //REQUEST_CREATE_LIST: NUMBER, [UNIQUE_ID][0..NUMBER]
- *
- *  REQUEST_ENTITY_LIST: //request the whole world :D
- *  REQUEST_SYNC:        >> UNIQUE_ID
- *                       << [Sync Info]
- *  //REQUEST_SYNC_LIST:   NUMBER, [UNIQUE_ID][0..NUMBER]
- *
- *  YOU_ARE_ENTITY:      >> UNIQUE_ID
- *
- *  REQUEST_PNODE_PATH   >> UNIQUE_ID_START   UNIQUE_ID_STOP
- *                       << UNIQUE_ID_1   UNIQUE_ID_2   UNIQUE_ID_3 ...   UNIQUE_ID_N
- *
- *  SEND_PNODE_PATH      >> UNIQUE_ID_START   UNIQUE_ID_STOP NUMBER [UNIQUE_ID][0..NUMBER]
- */
 
 typedef enum NetworkGameManagerProtocol {
@@ -54,5 +25,4 @@
   NET_REQUEST_CREATE,
   NET_REQUEST_REMOVE,
-  NET_REQUEST_SYNC,
   NET_YOU_ARE_ENTITY,
   NET_REQUEST_ENTITY_LIST,
@@ -81,8 +51,10 @@
     { if (!NetworkGameManager::singletonRef) NetworkGameManager::singletonRef = new NetworkGameManager(); return NetworkGameManager::singletonRef; }
 
+#if 0
     virtual int writeBytes(const byte* data, int length, int sender);
     virtual int readBytes(byte* data, int maxLength, int * reciever);
     virtual void writeDebug() const;
     virtual void readDebug() const;
+#endif
 
     int createEntity( ClassID classID, int owner = 0 );
@@ -91,7 +63,7 @@
     void sendYouAre( int uniqueID, int userID );
 
-    void sync(int uniqueID, int owner);
-
+#if 0
     void sendEntityList(int userID);
+#endif
 
     bool signalNewPlayer(int userId);
@@ -101,4 +73,6 @@
   private:
     NetworkGameManager();
+    
+    static bool youAreHandler(MessageId messageId, byte * data, int dataLength, void * someData, int userId );
 
 
@@ -111,5 +85,4 @@
     bool handleRemoveEntityList( int& i, const byte* data, int length, int sender );
     bool handleYouAreEntity( int& i, const byte* data, int length, int sender );
-    bool handleRequestSync( int& i, const byte* data, int length, int sender );
     bool handleRequestPNodePath(int& i, const byte* data, int length, int sender);
     bool handleSendPNodePath(int& i, const byte* data, int length, int sender);
@@ -117,24 +90,22 @@
 
     /* some network handlers helper functions */
-    void requestCreateEntity(ClassID classID);
+//    void requestCreateEntity(ClassID classID);
     int executeCreateEntity(ClassID classID, int uniqueID = 0, int owner = 0);
     BaseObject* doCreateEntity(ClassID classID, int uniqueID, int owner);
 
-    void requestRemoveEntity(int uniqueID);
+//    void requestRemoveEntity(int uniqueID);
     void executeRemoveEntity(int uniqueID);
     void doRemoveEntity(int uniqueID);
 
-    void executeRequestSync( int uniqueID, int user );
-    void doRequestSync(int uniqueID, int userID);
-
     void doYouAre( int uniqueID );
 
-    void requestPNodePath(const PNode* node1, const PNode* node2);
+//    void requestPNodePath(const PNode* node1, const PNode* node2);
     void executeRequestPNodePath(const PNode* node2, const PNode* node2);
     void doRequestPNodePath(const PNode* node1, const PNode* node2);
 
     bool canCreateEntity(ClassID classID);
+#if 0
+    void resizeBufferVector(int n);
 
-    void resizeBufferVector(int n);
 
     bool writeToClientBuffer( clientBuffer &cb, byte*data, int length );
@@ -142,11 +113,12 @@
     bool writeToClientBuffer( clientBuffer &cb, int i );
     bool readFromClientBuffer( clientBuffer &cb, byte*data, int length );
-
+#endif
 
   private:
+#if 0
     std::vector<clientBuffer>     outBuffer;
     //clientBuffer                  allOutBuffer;
+#endif
     static NetworkGameManager*    singletonRef;
-    bool                          hasRequestedWorld;
 };
 
Index: /trunk/src/lib/network/network_log.cc
===================================================================
--- /trunk/src/lib/network/network_log.cc	(revision 7954)
+++ /trunk/src/lib/network/network_log.cc	(revision 7954)
@@ -0,0 +1,218 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+#include "network_log.h"
+
+/**
+ *  the singleton reference to this class
+ */
+NetworkLog* NetworkLog::singletonRef = NULL;
+
+
+/**
+ * standard constructor
+ */
+NetworkLog::NetworkLog ()
+{
+  listensock = NULL;
+}
+
+
+/**
+   @brief standard deconstructor
+ */
+NetworkLog::~NetworkLog ()
+{
+  NetworkLog::singletonRef = NULL;
+}
+
+/**
+ * listens on port for connections
+ * @param port port number
+ * @return true on success
+ */
+bool NetworkLog::listen( int port )
+{
+  IPaddress ip;
+
+  if ( SDLNet_ResolveHost( &ip, NULL, port ) == -1 ) {
+    PRINT(1)( "SDLNet_ResolveHost: %s\n", SDLNet_GetError() );
+    listensock = NULL;
+    return false;
+  }
+  
+  listensock = SDLNet_TCP_Open( &ip );
+  
+  if( !listensock ) {
+    PRINT(1)( "SDLNet_TCP_Open: %s\n", SDLNet_GetError() );
+    return false;
+  } 
+
+  return true;
+}
+
+/**
+ * prints string to all connected sockets
+ */
+void NetworkLog::printfn( char * format, ... )
+{
+  va_list ap;
+  va_start( ap, format );
+  
+  assert( vsnprintf( buf, NETWORK_LOG_BUFLEN, format, ap ) < NETWORK_LOG_BUFLEN );
+  
+  va_end( ap );
+ 
+  printfnet();
+}
+
+/**
+ * accepts new connections
+ */
+void NetworkLog::acceptNewConnections( )
+{
+  TCPsocket newSock = SDLNet_TCP_Accept( listensock );
+  
+  if ( newSock )
+    sockets.push_back( newSock );
+}
+
+/**
+ * prints to all connected sockets and to PRINTF(0)
+ */
+void NetworkLog::printf0( char * format, ... )
+{
+  va_list ap;
+  va_start( ap, format );
+  
+  assert( vsnprintf( buf, NETWORK_LOG_BUFLEN, format, ap ) < NETWORK_LOG_BUFLEN );
+  
+  va_end( ap );
+  
+  PRINT(0)( buf );
+  printfnet();
+
+}
+
+/**
+ * prints to all connected sockets and to PRINTF(1)
+ */
+void NetworkLog::printf1( char * format, ... )
+{
+  va_list ap;
+  va_start( ap, format );
+  
+  assert( vsnprintf( buf, NETWORK_LOG_BUFLEN, format, ap ) < NETWORK_LOG_BUFLEN );
+  
+  va_end( ap );
+  
+  PRINT(1)( buf );
+  printfnet();
+
+}
+
+/**
+ * prints to all connected sockets and to PRINTF(2)
+ */
+void NetworkLog::printf2( char * format, ... )
+{
+  va_list ap;
+  va_start( ap, format );
+  
+  assert( vsnprintf( buf, NETWORK_LOG_BUFLEN, format, ap ) < NETWORK_LOG_BUFLEN );
+  
+  va_end( ap );
+  
+  PRINT(2)( buf );
+  printfnet();
+
+}
+
+/**
+ * prints to all connected sockets and to PRINTF(3)
+ */
+void NetworkLog::printf3( char * format, ... )
+{
+  va_list ap;
+  va_start( ap, format );
+  
+  assert( vsnprintf( buf, NETWORK_LOG_BUFLEN, format, ap ) < NETWORK_LOG_BUFLEN );
+  
+  va_end( ap );
+  
+  PRINT(3)( buf );
+  printfnet();
+
+}
+
+/**
+ * prints to all connected sockets and to PRINTF(4)
+ */
+void NetworkLog::printf4( char * format, ... )
+{
+  va_list ap;
+  va_start( ap, format );
+  
+  assert( vsnprintf( buf, NETWORK_LOG_BUFLEN, format, ap ) < NETWORK_LOG_BUFLEN );
+  
+  va_end( ap );
+  
+  PRINT(4)( buf );
+  printfnet();
+
+}
+
+/**
+ * prints to all connected sockets and to PRINTF(5)
+ */
+void NetworkLog::printf5( char * format, ... )
+{
+  va_list ap;
+  va_start( ap, format );
+  
+  assert( vsnprintf( buf, NETWORK_LOG_BUFLEN, format, ap ) < NETWORK_LOG_BUFLEN );
+  
+  va_end( ap );
+  
+  PRINT(5)( buf );
+  printfnet();
+
+}
+
+
+/**
+ * prints buf to network sockets
+ */
+void NetworkLog::printfnet()
+{
+  if ( !listensock )
+    return;
+  
+  acceptNewConnections();
+
+  for ( std::list<TCPsocket>::iterator it = sockets.begin(); it != sockets.end(); )
+  {
+    if ( SDLNet_TCP_Send( *it, buf, strlen( buf) ) < strlen( buf ) )
+    {
+      SDLNet_TCP_Close( *it );
+      std::list<TCPsocket>::iterator delIt = it;
+      it++;
+      sockets.erase( delIt );
+      continue;
+    }
+    
+    it++;
+  }
+}
Index: /trunk/src/lib/network/network_log.h
===================================================================
--- /trunk/src/lib/network/network_log.h	(revision 7954)
+++ /trunk/src/lib/network/network_log.h	(revision 7954)
@@ -0,0 +1,71 @@
+/*!
+ * @file network_log.h
+ * @brief Definition of the NetworkLog singleton Class
+ */
+
+#ifndef _NETWORK_LOG_H
+#define _NETWORK_LOG_H
+
+#include "netdefs.h"
+#include "debug.h"
+
+#include <string>
+#include <list>
+
+#define NETWORK_LOG_BUFLEN 1024
+
+/* macro definitions */
+#define NETPRINTF(x) NETPRINTF ## x
+#define NETPRINT(x) NETPRINT ## x
+
+#define NETPRINTFn NetworkLog::getInstance()->printfn("%s:%d:", __FILE__, __LINE__); NetworkLog::getInstance()->printfn
+#define NETPRINTF0 NetworkLog::getInstance()->printf0("%s:%d:", __FILE__, __LINE__); NetworkLog::getInstance()->printf0
+#define NETPRINTF1 NetworkLog::getInstance()->printf1("(EE)::%s:%d:", __FILE__, __LINE__); NetworkLog::getInstance()->printf1
+#define NETPRINTF2 NetworkLog::getInstance()->printf2("(WW)::%s:%d:", __FILE__, __LINE__); NetworkLog::getInstance()->printf2
+#define NETPRINTF3 NetworkLog::getInstance()->printf3("(II)::%s:%d:", __FILE__, __LINE__); NetworkLog::getInstance()->printf3
+#define NETPRINTF4 NetworkLog::getInstance()->printf4("(DD)::%s:%d:", __FILE__, __LINE__); NetworkLog::getInstance()->printf4
+#define NETPRINTF5 NetworkLog::getInstance()->printf5("(VD)::%s:%d:", __FILE__, __LINE__); NetworkLog::getInstance()->printf5
+
+#define NETPRINTn NetworkLog::getInstance()->printfn
+#define NETPRINT0 NetworkLog::getInstance()->printf0
+#define NETPRINT1 NetworkLog::getInstance()->printf1
+#define NETPRINT2 NetworkLog::getInstance()->printf2
+#define NETPRINT3 NetworkLog::getInstance()->printf3
+#define NETPRINT4 NetworkLog::getInstance()->printf4
+#define NETPRINT5 NetworkLog::getInstance()->printf5
+
+//! A default singleton class.
+class NetworkLog
+{
+
+  public:
+    virtual ~NetworkLog(void);
+    /** @returns a Pointer to the only object of this Class */
+    inline static NetworkLog* getInstance(void) { if (!singletonRef) singletonRef = new NetworkLog();  return singletonRef; };
+
+    bool listen( int port );
+
+    void printfnet( );
+
+    void printfn( char * format, ... );
+    void printf0( char * format, ... );
+    void printf1( char * format, ... );
+    void printf2( char * format, ... );
+    void printf3( char * format, ... );
+    void printf4( char * format, ... );
+    void printf5( char * format, ... );
+
+  private:
+    NetworkLog();
+
+    void acceptNewConnections();
+
+    static NetworkLog* singletonRef;
+
+    TCPsocket listensock;
+    std::list<TCPsocket> sockets;
+
+    char buf[NETWORK_LOG_BUFLEN];
+};
+
+#endif /* _NETWORK_LOG_H */
Index: /trunk/src/lib/network/network_manager.cc
===================================================================
--- /trunk/src/lib/network/network_manager.cc	(revision 7953)
+++ /trunk/src/lib/network/network_manager.cc	(revision 7954)
@@ -28,4 +28,6 @@
 #include "shared_network_data.h"
 #include "network_stream.h"
+#include "preferences.h"
+#include "network_log.h"
 
 
@@ -52,4 +54,11 @@
   this->defaultSyncStream = NULL;
   this->sharedNetworkData = SharedNetworkData::getInstance();
+  this->elapsedTime = 0.0f;
+  
+    
+  int port = Preferences::getInstance()->getInt( "network", "telnetport", 0 );
+  
+  if ( port > 0 )
+    NetworkLog::getInstance()->listen( port );
 
   PRINTF(0)("NetworkManager created\n");
@@ -72,4 +81,5 @@
   this->netStreamList = ClassList::getList(CL_SYNCHRONIZEABLE);
   PRINTF(0)("NetworkManager initzalized\n");
+
 }
 
@@ -90,12 +100,5 @@
 int NetworkManager::establishConnection(const std::string & name, unsigned int port)
 {
-  IPaddress ipAddress;
-  int error = SDLNet_ResolveHost(&ipAddress, name.c_str(), port);
-  if( error == -1) {
-    printf("\n\nerror on address resolution, program inconsistency\n\n");
-    return -1;
-  }
-
-  this->defaultSyncStream = new NetworkStream(ipAddress);
+  this->defaultSyncStream = new NetworkStream( name, port );
   this->sharedNetworkData->setDefaultSyncStream(this->defaultSyncStream);
   this->defaultSyncStream->startHandshake();
@@ -130,7 +133,13 @@
 /**
  *  sync the network
+ *  @param dtS: the seceonds elapsed since the last synchronize call
  */
-void NetworkManager::synchronize()
+void NetworkManager::synchronize( float dtS)
 {
+  this->elapsedTime += dtS;
+  if( likely(this->elapsedTime < 1.0f / NETWORK_FREQUENCY))
+    return;
+  this->elapsedTime = 0.0f;
+
   if (this->netStreamList != NULL || (this->netStreamList = ClassList::getList(CL_NETWORK_STREAM)) != NULL)
   {
Index: /trunk/src/lib/network/network_manager.h
===================================================================
--- /trunk/src/lib/network/network_manager.h	(revision 7953)
+++ /trunk/src/lib/network/network_manager.h	(revision 7954)
@@ -45,5 +45,5 @@
 
     void connectSynchronizeable(Synchronizeable& sync);
-    void synchronize();
+    void synchronize(float dtS);
 
     void debug();
@@ -61,4 +61,5 @@
 
     SharedNetworkData*               sharedNetworkData;       //!< reference to the shared data
+    float                            elapsedTime;             //!< elapsed time since the last network update
 };
 
Index: /trunk/src/lib/network/network_socket.cc
===================================================================
--- /trunk/src/lib/network/network_socket.cc	(revision 7953)
+++ /trunk/src/lib/network/network_socket.cc	(revision 7954)
@@ -21,6 +21,4 @@
 #define DEBUG_MODULE_NETWORK
 
-#include "converter.h"
-
 /* include your own header */
 #include "network_socket.h"
@@ -34,438 +32,11 @@
 NetworkSocket::NetworkSocket()
 {
-  this->init();
+  bOk = true;
 }
 
-/**
- * Constructor to connect directly
- */
-NetworkSocket::NetworkSocket(IPaddress ip)
+NetworkSocket::~ NetworkSocket( )
 {
-  this->init();
-  connectToServer(ip);
-}
-
-
-NetworkSocket::NetworkSocket( TCPsocket sock )
-{
-  this->init();
-  this->tcpSocket = sock;
-
-  readThread = SDL_CreateThread(thread_read, (void*)this);
-  writeThread = SDL_CreateThread(thread_write, (void*)this);
-}
-
-void NetworkSocket::init()
-{
-  /* set the class id for the base object */
-  this->setClassID(CL_NETWORK_SOCKET, "NetworkSocket");
-
-  tcpSocket = NULL;
-  incomingBufferLength = 0;
-  outgoingBufferLength = 0;
-
-  readThread = NULL;
-  writeThread = NULL;
-
-
-  thread_write_running = false;
-  thread_read_running = false;
-
-  incomingBufferMutex = SDL_CreateMutex();
-  outgoingBufferMutex = SDL_CreateMutex();
-
-
-  socketMutex = SDL_CreateMutex();
-  terminateThread = false;
-
-  /* Init SDL_net */
-  //NOTE: do we need to call SDLNet_Init for all instances?
-  if(SDLNet_Init()==-1)
-  {
-    PRINTF(1)("SDLNet_Init: %s\n", SDLNet_GetError());
-    return;
-  }
-  else
-    PRINTF(5)("SDL_net initialized\n");
-
-  PRINTF(0)("NetworkSocket created\n");
-
 }
 
 
 
-/**
- * Default destructor
- * dont use this from outside: use destroy() instead!!
- */
-NetworkSocket::~NetworkSocket( )
-{
-  this->terminateThread = true;
-  /* Quit SDL_net */
-  // NOTE: what if other instances of NetworkSocket running?
-  SDLNet_Quit();
-  PRINTF(5)("SDL_net shutdown\n");
-
-  SDL_DestroyMutex(incomingBufferMutex);
-  SDL_DestroyMutex(outgoingBufferMutex);
-  SDL_DestroyMutex(socketMutex);
-  SDL_DestroyMutex(threadTerminationMutex);
-}
-
-/**
- * This function establishes a TCP/UDP connection to a given server (function argument).
- * It is called by the NetworkStream. It creates a TCP/UDP socket for the connection.
- * @param ip
- */
-void NetworkSocket::connectToServer(IPaddress ip)
-{
-  //HACK this will cause segfault
-#warning remove this
-  int * a;
-  *a = 99;
-  //check if not already connected or listening
-  if (tcpSocket)
-  {
-    PRINTF(1)("NetworkSocket::listen: tcpSocket!=NULL! maybe you already called listen or connectToServer or did not call disconnectServer()!");
-  }
-
-  /* Connect to the host and port contained in ip using a TCP connection. */
-  tcpSocket = SDLNet_TCP_Open(&ip);
-  if(!tcpSocket)
-  {
-    PRINTF(1)("SDLNet_TCP_Open: %s\n", SDLNet_GetError());
-    return;
-  }
-
-  readThread = SDL_CreateThread(thread_read, (void*)this);
-  writeThread = SDL_CreateThread(thread_write, (void*)this);
-}
-
-
-/**
- * DTears down a TCP/UDP connection.
- */
-void NetworkSocket::disconnectServer( )
-{
-  terminateThread = true;
-  /* Close the connection */
-
-  SDL_mutexP(socketMutex);
-  SDLNet_TCP_Close(tcpSocket);
-  tcpSocket = NULL;
-  SDL_mutexV(socketMutex);
-}
-
-
-/**
- * This function writes some bytes (data) to the network connection (if the connection is already
- * estabilhed) otherwise it just does nothing (silently discarding the data). And writes some
- * warnings
- * @param data: pointer to the data to send
- * @param length: n bytes to send
- * @return the number successfully written bytes
- */
-int NetworkSocket::writeBytes(byte * data, int length)
-{
-  PRINTF(5)("NetworkSocket::writeBytes()\n");
-#ifdef _USE_OUTGOING_BUFFER
-
-#define min(a,b) (a<b)?a:b
-  int nbytes = min(_OUTGOING_BUFFER_SIZE - outgoingBufferLength, length);
-#undef min
-
-  if (!tcpSocket || data==NULL || nbytes<=0)
-  {
-    assert(_OUTGOING_BUFFER_SIZE - outgoingBufferLength > 0);
-    return 0;
-  }
-
-  SDL_mutexP(outgoingBufferMutex);
-
-  memcpy(outgoingBuffer + outgoingBufferLength, data, nbytes);
-  outgoingBufferLength += nbytes;
-
-  SDL_mutexV(outgoingBufferMutex);
-
-
-  return nbytes;
-#else
-  SDL_mutexP(socketMutex);
-
-  if (!tcpSocket || data==NULL)
-    return 0;
-
-  int res = SDLNet_TCP_Send(tcpSocket, data, length);
-
-  SDL_mutexV(socketMutex);
-
-  if (res<length)
-    PRINTF(1)("SDLNet_TCP_Send: %s\n", SDLNet_GetError());
-
-  return res;
-#endif
-}
-
-/**
- * Reads in the bytes from the network interface and passes it to the NetworkStream.
- * This function must internaly be implemented/connected as a thread, since the read
- * functions of many network libraries are blocking an would therefore block the whole
- * program.
- * From outside, the thread shouldn't be accessible at all.
- * @param data: pointer to memory, big enough to store length bytes
- * @param length: n bytes to read
- * @return the number successfully read bytes. -1 on error. may be less than length!
- */
-int NetworkSocket::readBytes(byte * data, int length)
-{
-  PRINTF(5)("NetworkSocket::readBytes()\n");
-  if (data==NULL)
-    return 0;
-
-  int nbytes = (length<incomingBufferLength) ? length : incomingBufferLength;
-
-
-  //printf("readBytes: nbytes = %d; length=%d; incomingBufferLength=%d\n", nbytes, length, incomingBufferLength);
-
-  // just in case ...
-  if (nbytes<0)
-    return -1;
-
-  if (nbytes==0)
-      return 0;
-
-  SDL_mutexP(incomingBufferMutex);
-
-  memcpy(data, incomingBuffer, nbytes);
-
-  //important: use memmove because the memory areas may overlap
-  memmove(incomingBuffer, incomingBuffer+nbytes, incomingBufferLength-nbytes);
-  incomingBufferLength -= nbytes;
-
-  SDL_mutexV(incomingBufferMutex);
-
-  return nbytes;
-}
-
-/**
- * Reads in the bytes form the network interface and passes it to the NetworkStream.
- * It only reads the bytes if there are enough bytes in our buffer.
- * @param data: pointer to memory, big enough to store length bytes
- * @param length: n bytes to read
- * @return the number successfully read bytes. -1 on error. 0 if there are not enough bytes in our buffer.
- */
-int NetworkSocket::readBlock(byte * data, int length)
-{
-  printf("NetworkSocket: got %i bytes, NetworkStream requested %i bytes\n", this->incomingBufferLength, length);
-  if (incomingBufferLength >= length)
-    return readBytes(data, length);
-  else return 0;
-}
-
-
-/**
- * used to create a thread to read from socket
- * @param data: pointer to NetworkSocket
- */
-int NetworkSocket::thread_read( void * data )
-{
-  int nbytesread = 0;
-  int nbytestoread = 0;
-  char buffer[_LOCAL_BUFFER_SIZE];
-  NetworkSocket * self = (NetworkSocket*)data;
-
-  self->thread_read_running = true;
-
-  while (!self->terminateThread)
-  {
-#define min(a,b) (a<b)?a:b
-    nbytestoread = min(_INCOMING_BUFFER_SIZE - self->incomingBufferLength, _LOCAL_BUFFER_SIZE);
-#undef min
-
-    //if buffer is full
-    if (nbytestoread<=0 || !self->tcpSocket)
-    {
-      SDL_Delay(_MSECONDS_SLEEP_FULL_BUFFER);
-      continue;
-    }
-
-    nbytesread = SDLNet_TCP_Recv(self->tcpSocket, buffer, nbytestoread);
-
-    SDL_mutexP(self->incomingBufferMutex);
-
-    if (nbytesread<=0)
-    {
-      if (nbytesread<0)
-        printf("SDLNet_TCP_Recv: %s\n", SDLNet_GetError());
-
-      SDL_mutexP(self->socketMutex);
-
-      SDLNet_TCP_Close(self->tcpSocket);
-      self->tcpSocket = NULL;
-
-      SDL_mutexV(self->socketMutex);
-      SDL_mutexV(self->incomingBufferMutex);
-      continue;
-    }
-
-    //printf("thread_read: nbytesread=%d\n", nbytesread);
-
-    memcpy(self->incomingBuffer+self->incomingBufferLength, buffer, nbytesread);
-    self->incomingBufferLength += nbytesread;
-
-    SDL_mutexV(self->incomingBufferMutex);
-  }
-
-  SDL_mutexP(self->threadTerminationMutex);
-  self->thread_read_running = false;
-
-  if ( !self->thread_write_running )
-  {
-    //delete self;
-    SDL_mutexV(self->threadTerminationMutex);
-  }
-  else
-  {
-    SDL_mutexV(self->threadTerminationMutex);
-  }
-
-
-#ifdef DONTEXITTHREADS
-  while ( true )
-  {
-    SDL_Delay(1000);
-  }
-#endif
-  
-  PRINTF(0)("QUIT READ THREAD\n");
-  
-  return 0;
-}
-
-int NetworkSocket::thread_write( void * data )
-{
-  int nbyteswrite = 0;
-  int nbytestowrite = 0;
-  char buffer[_LOCAL_BUFFER_SIZE];
-  NetworkSocket * self = (NetworkSocket*)data;
-
-  self->thread_write_running = true;
-
-  while (!self->terminateThread)
-  {
-#define min(a,b) (a<b)?a:b
-    nbytestowrite = min(self->outgoingBufferLength, _LOCAL_BUFFER_SIZE);
-#undef min
-
-//     printf("thread_write nbytes=%d listening=%d\n", nbytestowrite, (int)self->_isListening);
-
-    //if buffer is full
-    if (nbytestowrite<=0 || !self->tcpSocket)
-    {
-      SDL_Delay(_MSECONDS_SLEEP_EMPTY_BUFFER);
-      continue;
-    }
-
-    SDL_mutexP(self->outgoingBufferMutex);
-
-    //printf("a\n");
-
-    memcpy(buffer, self->outgoingBuffer, nbytestowrite);
-    self->outgoingBufferLength -= nbytestowrite;
-    memmove(self->outgoingBuffer, self->outgoingBuffer+nbytestowrite, self->outgoingBufferLength);
-
-    SDL_mutexV(self->outgoingBufferMutex);
-
-    nbyteswrite = SDLNet_TCP_Send(self->tcpSocket, buffer, nbytestowrite);
-
-    if (nbyteswrite<=0)
-    {
-      printf("SDLNet_TCP_Recv: %s\n", SDLNet_GetError());
-
-      SDL_mutexP(self->socketMutex);
-
-      SDLNet_TCP_Close(self->tcpSocket);
-      self->tcpSocket = NULL;
-
-      SDL_mutexV(self->socketMutex);
-      continue;
-    }
-
-  }
-
-  SDL_mutexP(self->threadTerminationMutex);
-  self->thread_write_running = false;
-
-  if ( !self->thread_read_running )
-  {
-    //delete self;
-    SDL_mutexV(self->threadTerminationMutex);
-  }
-  else
-  {
-    SDL_mutexV(self->threadTerminationMutex);
-  }
-
-#ifdef DONTEXITTHREADS
-  while ( true )
-  {
-  SDL_Delay(1000);
-  }
-#endif
-
-  PRINTF(0)("QUIT WRITE THREAD\n");
-
-  return 0;
-  
-}
-
-bool NetworkSocket::writePacket( byte * data, int length )
-{
-  PRINTF(5)("NetworkSocket::writePacket() size=%d\n", length);
-
-  if ( length > 1024 )
-  PRINTF(2)("WARNING SENDING BIG PACKET SIZE = %d\n", length);
-
-  byte blen[INTSIZE];
-
-  Converter::intToByteArray( length, blen, INTSIZE );
-
-  writeBytes(blen, INTSIZE);
-  writeBytes(data, length);
-}
-
-int NetworkSocket::readPacket( byte * data, int maxLength )
-{
-  PRINTF(5)("NetworkSocket::readPacket()\n");
-  if (incomingBufferLength<INTSIZE)
-  {
-    return 0;
-  }
-
-  int blen;
-  Converter::byteArrayToInt( incomingBuffer, &blen );
-
-  if (blen>maxLength)
-  {
-    PRINTF(1)("Buffersize is too small (%d) for packet (%d).\n", maxLength, blen);
-    assert(false);
-    return 0;
-  }
-
-  if (blen>incomingBufferLength)
-  {
-    return 0;
-  }
-
-  byte t[INTSIZE];
-  readBytes(t, INTSIZE);
-  int res = readBytes(data, blen);
-
-  if (res!=blen)
-    return -1;
-  else
-    return blen;
-
-}
-
-
Index: /trunk/src/lib/network/network_socket.h
===================================================================
--- /trunk/src/lib/network/network_socket.h	(revision 7953)
+++ /trunk/src/lib/network/network_socket.h	(revision 7954)
@@ -8,27 +8,4 @@
 #define _NETWORK_SOCKET
 
-//TODO HACK else gdb will not work on server
-#define DONTEXITTHREADS
-
-//if you want to use outgoing buffer define _USE_OUTGOING_BUFFER
-#define _USE_OUTGOING_BUFFER
-
-#define _INCOMING_BUFFER_SIZE 2024000
-#define _OUTGOING_BUFFER_SIZE 2024000
-#define _LOCAL_BUFFER_SIZE 1024
-//sleep if incoming buffer is full
-#define _MSECONDS_SLEEP_FULL_BUFFER 10
-//sleep if outgoing buffer is empty
-#define _MSECONDS_SLEEP_EMPTY_BUFFER 10
-
-
-/* contains memmove and memcpy */
-#include <string.h>
-
-#ifdef HAVE_SDL_H
- #include <SDL_thread.h>
-#else
- #include <SDL/SDL_thread.h>
-#endif
 /* include this file, it contains some default definitions */
 #include "netdefs.h"
@@ -38,66 +15,46 @@
 #include "base_object.h"
 
-/* using namespace std is default, this needs to be here */
-using namespace std;
-
 class NetworkSocket : public BaseObject
 {
+  public:
+    NetworkSocket();
+    virtual ~NetworkSocket();
 
-private:
-//  IPaddress serverAddress;
-//  unsigned int port;
-  TCPsocket tcpSocket;
-//  UDPsocket udpSocket;
+    /**
+     * connect to server on host with port port
+     * @param host hostname might be xxx.xxx.xxx.xxx or localhost ...
+     * @param port port to connect to
+     */
+    virtual void connectToServer( std::string host, int port ) = 0;
+    
+    /**
+     * disconnect from server
+     */
+    virtual void disconnectServer() = 0;
 
-  byte incomingBuffer[_INCOMING_BUFFER_SIZE];
-#ifdef _USE_OUTGOING_BUFFER
-  byte outgoingBuffer[_OUTGOING_BUFFER_SIZE];
-#endif
-  int incomingBufferLength;
-#ifdef _USE_OUTGOING_BUFFER
-  int outgoingBufferLength;
-#endif
+    /**
+     * send packet to connected socket. will be recieved as whole packet
+     * @param data pointer to data to send
+     * @param length lengt of packet to send
+     * @return true on success
+     */
+    virtual bool writePacket(byte * data, int length) = 0;
+    
+    /**
+     * read a packet sent by another NetworkSocket
+     * @param data data will be copied here
+     * @param maxLength readPacket will not read more than maxLength
+     * @return bytes read. on error less than zero
+     */
+    virtual int readPacket(byte * data, int maxLength) = 0;
 
-  SDL_mutex * incomingBufferMutex;
-#ifdef _USE_OUTGOING_BUFFER
-  SDL_mutex * outgoingBufferMutex;
-#endif
-  SDL_mutex * socketMutex;
-  bool terminateThread;
-
-  SDL_mutex* threadTerminationMutex;
-  static int thread_read(void * data);
-  bool thread_read_running;
-  bool thread_write_running;
-
-  SDL_Thread*            readThread;
-  SDL_Thread*            writeThread;
-
-#ifdef _USE_OUTGOING_BUFFER
-  static int thread_write(void * data);
-#endif
-
-  int writeBytes(byte * data, int length);
-  int readBytes(byte * data, int length);
-  int readBlock(byte * data, int length);
-
-  void init();
-
-public:
-
-  NetworkSocket();
-  virtual ~NetworkSocket();
-  NetworkSocket(IPaddress ip);
-  NetworkSocket(TCPsocket sock);
-  void destroy() { terminateThread = true; };
-
-
-  void connectToServer(IPaddress ip);
-  void disconnectServer();
-
-  bool writePacket(byte * data, int length);
-  int readPacket(byte * data, int maxLength);
-
-  inline bool isOk() { return tcpSocket!=NULL; }
+    /**
+     * check if socket is ok
+     * @return true if socket is ok
+     */
+    inline bool isOk() { return this->bOk; }
+  
+  protected:
+    bool bOk;            //!< check for socket status
 
 };
Index: /trunk/src/lib/network/network_stream.cc
===================================================================
--- /trunk/src/lib/network/network_stream.cc	(revision 7953)
+++ /trunk/src/lib/network/network_stream.cc	(revision 7954)
@@ -23,9 +23,20 @@
 #include "base_object.h"
 #include "network_protocol.h"
-#include "network_socket.h"
+#include "udp_socket.h"
+#include "udp_server_socket.h"
 #include "connection_monitor.h"
 #include "synchronizeable.h"
 #include "network_game_manager.h"
 #include "shared_network_data.h"
+#include "message_manager.h"
+#include "preferences.h"
+#include "zip.h"
+
+#include "src/lib/util/loading/resource_manager.h"
+
+#include "network_log.h"
+
+
+#include "lib/util/loading/factory.h"
 
 #include "debug.h"
@@ -49,30 +60,23 @@
   /* initialize the references */
   this->type = NET_CLIENT;
-  this->networkProtocol = new NetworkProtocol();
-  this->connectionMonitor = new ConnectionMonitor();
-}
-
-
-NetworkStream::NetworkStream(IPaddress& address)
+}
+
+
+NetworkStream::NetworkStream( std::string host, int port )
 {
   this->type = NET_CLIENT;
   this->init();
-  this->networkSockets.push_back(new NetworkSocket(address));
-  this->networkProtocol = new NetworkProtocol();
-  this->connectionMonitor = new ConnectionMonitor();
-  this->maxConnections = 1;
-}
-
-
-NetworkStream::NetworkStream(unsigned int port)
+  this->peers[0].socket = new UdpSocket( host, port );
+  this->peers[0].userId = 0;
+  this->peers[0].isServer = true;
+  this->peers[0].connectionMonitor = new ConnectionMonitor( 0 );
+}
+
+
+NetworkStream::NetworkStream( int port )
 {
   this->type = NET_SERVER;
   this->init();
-  this->serverSocket = new ServerSocket(port);
-  this->networkProtocol = new NetworkProtocol();
-  this->connectionMonitor = new ConnectionMonitor();
-  this->networkSockets.push_back( NULL );
-  this->networkSockets[0] = NULL; //TODO: remove this
-  this->handshakes.push_back( NULL );
+  this->serverSocket = new UdpServerSocket(port);
   this->bActive = true;
 }
@@ -87,4 +91,9 @@
   this->networkGameManager = NULL;
   myHostId = 0;
+  currentState = 0;
+  
+  remainingBytesToWriteToDict = Preferences::getInstance()->getInt( "compression", "writedict", 0 );
+  
+  assert( Zip::getInstance()->loadDictionary( "testdict" ) );
 }
 
@@ -98,23 +107,26 @@
   }
 
-  for (NetworkSocketVector::iterator i = networkSockets.begin(); i!=networkSockets.end(); i++)
-  {
-    if ( *i )
-    {
-      (*i)->disconnectServer();
-      (*i)->destroy();
-    }
-  }
-
-  for (HandshakeVector::iterator i = handshakes.begin(); i!=handshakes.end(); i++)
-  {
-    if ( *i )
-    {
-      delete (*i);
-    }
-  }
-
-  delete connectionMonitor;
-  delete networkProtocol;
+  for ( PeerList::iterator i = peers.begin(); i!=peers.end(); i++)
+  {
+    if ( i->second.socket )
+    {
+      i->second.socket->disconnectServer();
+      delete i->second.socket;
+      i->second.socket = NULL;
+    }
+    
+    if ( i->second.handshake )
+    {
+      delete i->second.handshake;
+      i->second.handshake = NULL;
+    }
+  }
+  
+  if ( serverSocket )
+  {
+    delete serverSocket;
+    serverSocket = NULL;
+  }
+
 }
 
@@ -125,7 +137,6 @@
   // setUniqueID( maxCon+2 ) because we need one id for every handshake
   // and one for handshake to reject client maxCon+1
-  this->networkGameManager->setUniqueID( this->maxConnections + 2 );
-  //this->connectSynchronizeable( *(this->networkGameManager) );
-  this->setMaxConnections( 10 );
+  this->networkGameManager->setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
+  MessageManager::getInstance()->setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
 }
 
@@ -135,7 +146,10 @@
   Handshake* hs = new Handshake(false);
   hs->setUniqueID( 0 );
-  this->handshakes.push_back(hs);
+  assert( peers[0].handshake == NULL );
+  peers[0].handshake = hs;
+//   peers[0].handshake->setSynchronized( true );
   //this->connectSynchronizeable(*hs);
-  PRINTF(0)("NetworkStream: %s\n", hs->getName());
+  //this->connectSynchronizeable(*hs);
+  PRINTF(0)("NetworkStream: Handshake created: %s\n", hs->getName());
 }
 
@@ -146,6 +160,5 @@
   sync.setNetworkStream( this );
 
-  if( this->networkSockets.size()>0 )
-    this->bActive = true;
+  this->bActive = true;
 }
 
@@ -157,7 +170,6 @@
   if (disconnectSynchro != this->synchronizeables.end())
     this->synchronizeables.erase(disconnectSynchro);
-
-  if( this->networkSockets.size()<=0 )
-    this->bActive = false;
+  
+  oldSynchronizeables[sync.getUniqueID()] = SDL_GetTicks();
 }
 
@@ -165,330 +177,587 @@
 void NetworkStream::processData()
 {
+  currentState++;
+  
   if ( this->type == NET_SERVER )
+  {
+    if ( serverSocket )
+      serverSocket->update();
+    
     this->updateConnectionList();
+  }
   else
   {
-    if ( networkSockets[0] && !networkSockets[0]->isOk() )
+    if ( peers[0].socket && ( !peers[0].socket->isOk() || peers[0].connectionMonitor->hasTimedOut() ) )
     {
       PRINTF(1)("lost connection to server\n");
 
-      //delete networkSockets[i];
-      networkSockets[0]->disconnectServer();
-      networkSockets[0]->destroy();
-      networkSockets[0] = NULL;
-
-      if ( handshakes[0] )
-        delete handshakes[0];
-      handshakes[0] = NULL;
-    }
-  }
-
-  for (int i = 0; i<handshakes.size(); i++)
-  {
-    if ( handshakes[i] )
-    {
-      if ( handshakes[i]->completed() )
+      peers[0].socket->disconnectServer();
+      delete peers[0].socket;
+      peers[0].socket = NULL;
+
+      if ( peers[0].handshake )
+        delete peers[0].handshake;
+      peers[0].handshake = NULL;
+    }
+  }
+
+  cleanUpOldSyncList();
+  handleHandshakes();
+  
+  // order of up/downstream is important!!!!
+  // don't change it
+  handleDownstream();
+  handleUpstream();
+
+}
+
+void NetworkStream::updateConnectionList( )
+{
+  //check for new connections
+
+  NetworkSocket* tempNetworkSocket = serverSocket->getNewSocket();
+
+  if ( tempNetworkSocket )
+  {
+    int clientId;
+    if ( freeSocketSlots.size() >0 )
+    {
+      clientId = freeSocketSlots.back();
+      freeSocketSlots.pop_back();
+      peers[clientId].socket = tempNetworkSocket;
+      peers[clientId].handshake = new Handshake(true, clientId, this->networkGameManager->getUniqueID(), MessageManager::getInstance()->getUniqueID() );
+      peers[clientId].connectionMonitor = new ConnectionMonitor( clientId );
+      peers[clientId].handshake->setUniqueID(clientId);
+      peers[clientId].userId = clientId;
+      peers[clientId].isServer = false;
+    } else
+    {
+      clientId = 1;
+      
+      for ( PeerList::iterator it = peers.begin(); it != peers.end(); it++ )
+        if ( it->first >= clientId )
+          clientId = it->first + 1;
+      
+      peers[clientId].socket = tempNetworkSocket;
+      peers[clientId].handshake = new Handshake(true, clientId, this->networkGameManager->getUniqueID(), MessageManager::getInstance()->getUniqueID());
+      peers[clientId].handshake->setUniqueID(clientId);
+      peers[clientId].connectionMonitor = new ConnectionMonitor( clientId );
+      peers[clientId].userId = clientId;
+      peers[clientId].isServer = false;
+      
+      PRINTF(0)("num sync: %d\n", synchronizeables.size());
+    }
+
+    if ( clientId > MAX_CONNECTIONS )
+    {
+      peers[clientId].handshake->doReject( "too many connections" );
+      PRINTF(0)("Will reject client %d because there are to many connections!\n", clientId);
+    }
+    else
+
+    PRINTF(0)("New Client: %d\n", clientId);
+
+    //this->connectSynchronizeable(*handshakes[clientId]);
+  }
+
+  //check if connections are ok else remove them
+  for ( PeerList::iterator it = peers.begin(); it != peers.end(); it++ )
+  {
+    if (  
+          it->second.socket &&
+          ( 
+            !it->second.socket->isOk()  ||
+            it->second.connectionMonitor->hasTimedOut()
+          )
+       )
+    {
+      std::string reason = "disconnected";
+      if ( it->second.connectionMonitor->hasTimedOut() )
+        reason = "timeout";
+      PRINTF(0)("Client is gone: %d (%s)\n", it->second.userId, reason.c_str());
+      
+      assert(false);
+
+      it->second.socket->disconnectServer();
+      delete it->second.socket;
+      it->second.socket = NULL;
+
+      if ( it->second.handshake )
+        delete it->second.handshake;
+      it->second.handshake = NULL;
+      
+      for ( SynchronizeableList::iterator it2 = synchronizeables.begin(); it2 != synchronizeables.end(); it2++ )
       {
-        if ( handshakes[i]->ok() )
+        (*it2)->cleanUpUser( it->second.userId );
+      }
+
+      NetworkGameManager::getInstance()->signalLeftPlayer(it->second.userId);
+
+      freeSocketSlots.push_back( it->second.userId );
+
+    }
+  }
+
+
+}
+
+void NetworkStream::debug()
+{
+  if( this->isServer())
+    PRINT(0)(" Host ist Server with ID: %i\n", this->myHostId);
+  else
+    PRINT(0)(" Host ist Client with ID: %i\n", this->myHostId);
+
+  PRINT(0)(" Got %i connected Synchronizeables, showing active Syncs:\n", this->synchronizeables.size());
+  for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
+  {
+    if( (*it)->beSynchronized() == true)
+      PRINT(0)("  Synchronizeable of class: %s::%s, with unique ID: %i, Synchronize: %i\n", (*it)->getClassName(), (*it)->getName(),
+               (*it)->getUniqueID(), (*it)->beSynchronized());
+  }
+  PRINT(0)(" Maximal Connections: %i\n", MAX_CONNECTIONS );
+
+}
+
+
+int NetworkStream::getSyncCount()
+{
+  int n = 0;
+  for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
+    if( (*it)->beSynchronized() == true)
+      ++n;
+
+  //return synchronizeables.size();
+  return n;
+}
+
+/**
+ * check if handshakes completed
+ */
+void NetworkStream::handleHandshakes( )
+{
+  for ( PeerList::iterator it = peers.begin(); it != peers.end(); it++ )
+  {
+    if ( it->second.handshake )
+    {
+      if ( it->second.handshake->completed() )
+      {
+        if ( it->second.handshake->ok() )
         {
-          if ( type != NET_SERVER )
-          {
-            SharedNetworkData::getInstance()->setHostID( handshakes[i]->getHostId() );
-            myHostId = SharedNetworkData::getInstance()->getHostID();
-
-            this->networkGameManager = NetworkGameManager::getInstance();
-            this->networkGameManager->setUniqueID( handshakes[i]->getNetworkGameManagerId() );
-            //this->connectSynchronizeable( *(this->networkGameManager) );
+          if ( !it->second.handshake->allowDel() )
+          {
+            if ( type != NET_SERVER )
+            {
+              SharedNetworkData::getInstance()->setHostID( it->second.handshake->getHostId() );
+              myHostId = SharedNetworkData::getInstance()->getHostID();
+
+              this->networkGameManager = NetworkGameManager::getInstance();
+              this->networkGameManager->setUniqueID( it->second.handshake->getNetworkGameManagerId() );
+              MessageManager::getInstance()->setUniqueID( it->second.handshake->getMessageManagerId() );
+            }
+              
+
+            PRINT(0)("handshake finished id=%d\n", it->second.handshake->getNetworkGameManagerId());
+
+            it->second.handshake->del();
           }
           else
           {
-
-          }
-          PRINT(0)("handshake finished id=%d\n", handshakes[i]->getNetworkGameManagerId());
-
-
-          delete handshakes[i];
-          handshakes[i] = NULL;
+            if ( it->second.handshake->canDel() )
+            {
+              if ( type == NET_SERVER )
+              {
+                handleNewClient( it->second.userId );
+              }
+              
+              PRINT(0)("handshake finished delete it\n");
+              delete it->second.handshake;
+              it->second.handshake = NULL;
+            }
+          }
+
         }
         else
         {
           PRINT(1)("handshake failed!\n");
-          networkSockets[i]->disconnectServer();
-          delete handshakes[i];
-          handshakes[i] = NULL;
-          //TODO: handle error
+          it->second.socket->disconnectServer();
         }
       }
     }
   }
-
-
-  /* DOWNSTREAM */
-
-
-
-  int dataLength;
-  int reciever;
-  Header header;
-  int counter;
-
-  for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
-  {
-    counter = 0;
-
-    if ( (*it)!=NULL && (*it)->beSynchronized() /*&& (*it)->getOwner() == myHostId*/ )
-    {
-      do {
-        counter++;
-
-        //check for endless loop
-        if ( counter > 50 )
+}
+
+/**
+ * handle upstream network traffic
+ */
+void NetworkStream::handleUpstream( )
+{
+  int offset;
+  int n;
+  
+  for ( PeerList::iterator peer = peers.begin(); peer != peers.end(); peer++ )
+  {
+    offset = INTSIZE; //make already space for length 
+    
+    if ( !peer->second.socket )
+      continue;
+    
+    n = Converter::intToByteArray( currentState, buf + offset, UDP_PACKET_SIZE - offset );
+    assert( n == INTSIZE );
+    offset += n;
+    
+    n = Converter::intToByteArray( peer->second.lastAckedState, buf + offset, UDP_PACKET_SIZE - offset );
+    assert( n == INTSIZE );
+    offset += n;
+    
+    n = Converter::intToByteArray( peer->second.lastRecvedState, buf + offset, UDP_PACKET_SIZE - offset );
+    assert( n == INTSIZE );
+    offset += n;
+    
+    for ( SynchronizeableList::iterator it = synchronizeables.begin(); it != synchronizeables.end(); it++ )
+    {
+      int oldOffset = offset;
+      Synchronizeable & sync = **it;
+      
+      if ( !sync.beSynchronized() || sync.getUniqueID() < 0 )
+        continue;
+
+      //if handshake not finished only sync handshake
+      if ( peer->second.handshake && sync.getLeafClassID() != CL_HANDSHAKE )
+        continue;
+      
+      if ( isServer() && sync.getLeafClassID() == CL_HANDSHAKE && sync.getUniqueID() != peer->second.userId )
+        continue;
+      
+      //do not sync null parent
+      if ( sync.getLeafClassID() == CL_NULL_PARENT )
+        continue;
+
+      assert( offset + INTSIZE <= UDP_PACKET_SIZE );
+      
+      //server fakes uniqueid=0 for handshake
+      if ( this->isServer() && sync.getUniqueID() < MAX_CONNECTIONS - 1 )
+        n = Converter::intToByteArray( 0, buf + offset, UDP_PACKET_SIZE - offset );
+      else
+        n = Converter::intToByteArray( sync.getUniqueID(), buf + offset, UDP_PACKET_SIZE - offset );
+      assert( n == INTSIZE );
+      offset += n;
+      
+      //make space for size
+      offset += INTSIZE;
+
+      n = sync.getStateDiff( peer->second.userId, buf + offset, UDP_PACKET_SIZE-offset, currentState, peer->second.lastAckedState, -1000 );
+      offset += n;
+      //NETPRINTF(0)("GGGGGEEEEETTTTT: %s (%d) %d\n",sync.getClassName(), sync.getUniqueID(), n);
+      
+      assert( Converter::intToByteArray( n, buf + offset - n - INTSIZE, INTSIZE ) == INTSIZE );
+      
+      //check if all bytes == 0 -> remove data 
+      //TODO not all synchronizeables like this maybe add Synchronizeable::canRemoveZeroDiff()
+      bool allZero = true; 
+      for ( int i = 0; i < n; i++ ) 
+      { 
+         if ( buf[i+oldOffset+2*INTSIZE] != 0 ) 
+           allZero = false; 
+      } 
+
+      if ( allZero ) 
+      { 
+        //NETPRINTF(n)("REMOVE ZERO DIFF: %s (%d)\n", sync.getClassName(), sync.getUniqueID()); 
+        offset = oldOffset; 
+      } 
+
+      
+    }
+    
+    for ( SynchronizeableList::iterator it = synchronizeables.begin(); it != synchronizeables.end(); it++ )
+    {
+      Synchronizeable & sync = **it;
+      
+      if ( !sync.beSynchronized() || sync.getUniqueID() < 0 )
+        continue;
+      
+      sync.handleSentState( peer->second.userId, currentState, peer->second.lastAckedState );
+    }
+    
+    assert( Converter::intToByteArray( offset, buf, INTSIZE ) == INTSIZE );
+    
+    int compLength = Zip::getInstance()->zip( buf, offset, compBuf, UDP_PACKET_SIZE );
+    
+    if ( compLength < 0 )
+    {
+      PRINTF(1)("compression failed!\n");
+      continue;
+    }
+    
+    assert( peer->second.socket->writePacket( compBuf, compLength ) );
+    
+    if ( this->remainingBytesToWriteToDict > 0 )
+      writeToNewDict( buf, offset );
+    
+    peer->second.connectionMonitor->processUnzippedOutgoingPacket( buf, offset, currentState );
+    peer->second.connectionMonitor->processZippedOutgoingPacket( compBuf, compLength, currentState );
+    
+    //NETPRINTF(n)("send packet: %d userId = %d\n", offset, peer->second.userId);
+  }
+}
+
+/**
+ * handle downstream network traffic
+ */
+void NetworkStream::handleDownstream( )
+{
+  int offset = 0;
+  
+  int length = 0;
+  int packetLength = 0;
+  int compLength = 0;
+  int uniqueId = 0;
+  int state = 0;
+  int ackedState = 0;
+  int fromState = 0;
+  int syncDataLength = 0;
+  
+  for ( PeerList::iterator peer = peers.begin(); peer != peers.end(); peer++ )
+  {
+    
+    if ( !peer->second.socket )
+      continue;
+
+    while ( 0 < (compLength = peer->second.socket->readPacket( compBuf, UDP_PACKET_SIZE )) )
+    {
+      //TODO tell monitor about zipped packet. because dropped packets dont count to bandwidth
+      //PRINTF(0)("GGGGGOOOOOOOOOOTTTTTTTT: %d\n", compLength);
+      packetLength = Zip::getInstance()->unZip( compBuf, compLength, buf, UDP_PACKET_SIZE );
+      
+      if ( packetLength < 4*INTSIZE )
+      {
+        if ( packetLength != 0 )
+          PRINTF(1)("got too small packet: %d\n", packetLength);
+        continue;
+      }
+      
+      if ( this->remainingBytesToWriteToDict > 0 )
+        writeToNewDict( buf, packetLength );
+    
+      assert( Converter::byteArrayToInt( buf, &length ) == INTSIZE );
+      assert( Converter::byteArrayToInt( buf + INTSIZE, &state ) == INTSIZE );
+      assert( Converter::byteArrayToInt( buf + 2*INTSIZE, &fromState ) == INTSIZE );
+      assert( Converter::byteArrayToInt( buf + 3*INTSIZE, &ackedState ) == INTSIZE );
+      //NETPRINTF(n)("ackedstate: %d\n", ackedState);
+      offset = 4*INTSIZE;
+
+      //NETPRINTF(n)("got packet: %d, %d\n", length, packetLength);
+    
+    //if this is an old state drop it
+      if ( state <= peer->second.lastRecvedState )
+        continue;
+    
+      if ( packetLength != length )
+      {
+        PRINTF(1)("real packet length (%d) and transmitted packet length (%d) do not match!\n", packetLength, length);
+        peer->second.socket->disconnectServer();
+        continue;
+      }
+      
+      while ( offset + 2*INTSIZE < length )
+      {
+        assert( offset > 0 );
+        assert( Converter::byteArrayToInt( buf + offset, &uniqueId ) == INTSIZE );
+        offset += INTSIZE;
+      
+        assert( Converter::byteArrayToInt( buf + offset, &syncDataLength ) == INTSIZE );
+        offset += INTSIZE;
+        
+        assert( syncDataLength > 0 );
+        assert( syncDataLength < 10000 );
+      
+        Synchronizeable * sync = NULL;
+        
+        for ( SynchronizeableList::iterator it = synchronizeables.begin(); it != synchronizeables.end(); it++ )
+        { 
+        //                                        client thinks his handshake has id 0!!!!!
+          if ( (*it)->getUniqueID() == uniqueId || ( uniqueId == 0 && (*it)->getUniqueID() == peer->second.userId ) )
+          {
+            sync = *it;
+            break;
+          }
+        }
+        
+        if ( sync == NULL )
         {
-          PRINTF(1)("there seems to be an error in readBytes of %s\n", (*it)->getClassName());
-          assert(false);
+          PRINTF(0)("could not find sync with id %d. try to create it\n", uniqueId);
+          if ( oldSynchronizeables.find( uniqueId ) != oldSynchronizeables.end() )
+          {
+            offset += syncDataLength;
+            continue;
+          }
+          
+          if ( !peers[peer->second.userId].isServer )
+          {
+            offset += syncDataLength;
+            continue;
+          }
+          
+          int leafClassId;
+          if ( INTSIZE > length - offset )
+          {
+            offset += syncDataLength;
+            continue;
+          }
+
+          Converter::byteArrayToInt( buf + offset, &leafClassId );
+          
+          assert( leafClassId != 0 );
+        
+          BaseObject * b = NULL;
+          /* These are some small exeptions in creation: Not all objects can/should be created via Factory */
+          /* Exception 1: NullParent */
+          if( leafClassId == CL_NULL_PARENT || leafClassId == CL_SYNCHRONIZEABLE || leafClassId == CL_NETWORK_GAME_MANAGER )
+          {
+            PRINTF(1)("Can not create Class with ID %x!\n", (int)leafClassId);
+            offset += syncDataLength;
+            continue;
+          }
+          else
+            b = Factory::fabricate( (ClassID)leafClassId );
+
+          if ( !b )
+          {
+            PRINTF(1)("Could not fabricate Object with classID %x\n", leafClassId);
+            offset += syncDataLength;
+            continue;
+          }
+
+          if ( b->isA(CL_SYNCHRONIZEABLE) )
+          {
+            sync = dynamic_cast<Synchronizeable*>(b);
+            sync->setUniqueID( uniqueId );
+            sync->setSynchronized(true);
+  
+            PRINTF(0)("Fabricated %s with id %d\n", sync->getClassName(), sync->getUniqueID());
+          }
+          else
+          {
+            PRINTF(1)("Class with ID %x is not a synchronizeable!\n", (int)leafClassId);
+            delete b;
+            offset += syncDataLength;
+            continue;
+          }
         }
 
-        reciever = 0;
-        dataLength = (*it)->readBytes(downBuffer, DATA_STREAM_BUFFER_SIZE, &reciever);
-
-        if ( dataLength<=0 ){
-          reciever = 0;
+        int n = sync->setStateDiff( peer->second.userId, buf+offset, syncDataLength, state, fromState ); 
+        offset += n;
+        //NETPRINTF(0)("SSSSSEEEEETTTTT: %s %d\n",sync->getClassName(), n);
+
+      }
+      
+      if ( offset != length )
+      {
+        PRINTF(0)("offset (%d) != length (%d)\n", offset, length);
+        peer->second.socket->disconnectServer();
+      }
+      
+      //TODO REMOVE THIS
+      int saveOffset = offset;
+      
+      for ( SynchronizeableList::iterator it = synchronizeables.begin(); it != synchronizeables.end(); it++ )
+      {
+        Synchronizeable & sync = **it;
+      
+        if ( !sync.beSynchronized() || sync.getUniqueID() < 0 )
           continue;
-        }
-
-        dataLength = networkProtocol->createHeader((byte*)downBuffer, dataLength, DATA_STREAM_BUFFER_SIZE, static_cast<const Synchronizeable&>(*(*it)));
-
-        Header* header = (Header*)downBuffer;
-        if ( header->synchronizeableID < this->maxConnections+2 )
-        {
-          //if ( !isServer() ) PRINTF(0)("RESET UNIQUEID FROM %d TO 0 maxCon=%d\n", header->synchronizeableID, this->maxConnections);
-          header->synchronizeableID = 0;
-        }
-        else
-        {
-          //if ( !isServer() ) PRINTF(0)("UNIQUEID=%d\n", header->synchronizeableID);
-        }
-
-        if ( dataLength<=0 )
-          continue;
-
-        if ( reciever!=0 )
-        {
-          if ( reciever < 0)
-          {
-            for ( int i = 0; i<networkSockets.size(); i++)
-            {
-              if ( i!=abs(reciever) && networkSockets[i] != NULL )
-              {
-                PRINTF(0)("write %d bytes to socket %d uniqueid %d reciever %d\n", dataLength, i, (*it)->getUniqueID(), reciever);
-                networkSockets[i]->writePacket(downBuffer, dataLength);
-              }
-            }
-          }
-          else
-          {
-            if ( networkSockets[reciever] != NULL )
-            {
-              PRINTF(5)("write %d bytes to socket %d\n", dataLength, reciever);
-              networkSockets[reciever]->writePacket(downBuffer, dataLength);
-            }
-            else
-            {
-              PRINTF(1)("networkSockets[reciever] == NULL\n");
-            }
-          }
-        }
-        else
-        {
-          for ( int i = 0; i<networkSockets.size(); i++)
-          {
-            if ( networkSockets[i] != NULL )
-            {
-              PRINTF(5)("write %d bytes to socket %d\n", dataLength, i);
-              networkSockets[i]->writePacket(downBuffer, dataLength);
-            }
-          }
-        }
-
-      } while( reciever!=0 );
-    }
-  }
-
-  /* UPSTREAM */
-
-  for ( int i = 0; i<networkSockets.size(); i++)
-  {
-    if ( networkSockets[i] )
-    {
-      do {
-        dataLength = networkSockets[i]->readPacket(upBuffer, DATA_STREAM_BUFFER_SIZE);
-
-        if ( dataLength<=0 )
-          continue;
-
-        header = networkProtocol->extractHeader(upBuffer, dataLength);
-        dataLength -= sizeof(header);
-
-        PRINTF(5)("read %d bytes from socket uniqueID = %d\n", dataLength, header.synchronizeableID);
-
-        if ( dataLength != header.length )
-        {
-          PRINTF(1)("packetsize in header and real packetsize do not match! %d:%d\n", dataLength, header.length);
-          continue;
-        }
-
-        if ( header.synchronizeableID == 0 )
-        {
-          header.synchronizeableID = i;
-        }
-
-        for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
-        {
-          if ( *it && (*it)->getUniqueID()==header.synchronizeableID )
-          {
-            if ( (*it)->writeBytes(upBuffer+sizeof(header), dataLength, i) != header.length )
-            {
-              PRINTF(1)("%s did not read all the data id = %d!\n", (*it)->getClassName(), (*it)->getUniqueID());
-              break;
-            }
-            continue;
-          }
-        }
-
-      } while ( dataLength>0 );
-    }
-  }
-}
-
-void NetworkStream::updateConnectionList( )
-{
-  //check for new connections
-
-  NetworkSocket* tempNetworkSocket = serverSocket->getNewSocket();
-
-  if ( tempNetworkSocket )
-  {
-    int clientId;
-    if ( freeSocketSlots.size() >0 )
-    {
-      clientId = freeSocketSlots.back();
-      freeSocketSlots.pop_back();
-      networkSockets[clientId] = tempNetworkSocket;
-      handshakes[clientId] = new Handshake(true, clientId, this->networkGameManager->getUniqueID());
-      handshakes[clientId]->setUniqueID(clientId);
-    } else
-    {
-      clientId = networkSockets.size();
-      networkSockets.push_back(tempNetworkSocket);
-      Handshake* tHs = new Handshake(true, clientId, this->networkGameManager->getUniqueID());
-      tHs->setUniqueID(clientId);
-      handshakes.push_back(tHs);
-    }
-
-    if ( clientId > this->maxConnections )
-    {
-      handshakes[clientId]->doReject();
-      PRINTF(0)("Will reject client %d because there are to many connections!\n", clientId);
-    }
-    else
-
-    PRINTF(0)("New Client: %d\n", clientId);
-
-    //this->connectSynchronizeable(*handshakes[clientId]);
-  }
-
-
-  //check if connections are ok else remove them
-  for ( int i = 1; i<networkSockets.size(); i++)
-  {
-    if ( networkSockets[i] && !networkSockets[i]->isOk() )
-    {
-      //TODO: tell EntityManager that this player left the game
-      PRINTF(0)("Client is gone: %d\n", i);
-
-      //delete networkSockets[i];
-      networkSockets[i]->disconnectServer();
-      networkSockets[i]->destroy();
-      networkSockets[i] = NULL;
-
-      if ( handshakes[i] )
-        delete handshakes[i];
-      handshakes[i] = NULL;
-
-
-      NetworkGameManager::getInstance()->signalLeftPlayer(i);
-
-      if ( i == networkSockets.size()-1 )
-      {
-        networkSockets.pop_back();
-        handshakes.pop_back();
+      
+        sync.handleRecvState( peer->second.userId, state, fromState );
       }
-      else
-      {
-        freeSocketSlots.push_back(i);
-      }
-    }
-  }
-
-
-}
-
-void NetworkStream::setMaxConnections( int n )
-{
-  if ( !this->isServer() )
-  {
-    PRINTF(1)("Cannot set maxConnections because I am no server.\n");
-  }
-  if ( this->networkSockets.size() > 1 )
-  {
-    PRINTF(1)("Cannot set maxConnections because there are already %d connections.\n", this->networkSockets.size());
+      
+      peer->second.connectionMonitor->processZippedIncomingPacket( compBuf, compLength, state, ackedState );
+      peer->second.connectionMonitor->processUnzippedIncomingPacket( buf, offset, state, ackedState );
+    
+      assert( peer->second.lastAckedState <= ackedState );
+      peer->second.lastAckedState = ackedState;
+      
+      assert( peer->second.lastRecvedState < state );
+      peer->second.lastRecvedState = state;
+      
+      assert( saveOffset == offset );
+      
+    }
+  
+  }
+  
+}
+
+/**
+ * is executed when a handshake has finished
+ * @todo create playable for new user
+ */
+void NetworkStream::handleNewClient( int userId )
+{
+  MessageManager::getInstance()->initUser( userId );
+  
+  networkGameManager->signalNewPlayer( userId );
+}
+
+/**
+ * removes old items from oldSynchronizeables
+ */
+void NetworkStream::cleanUpOldSyncList( )
+{
+  int now = SDL_GetTicks();
+  
+  for ( std::map<int,int>::iterator it = oldSynchronizeables.begin(); it != oldSynchronizeables.end();  )
+  {
+    if ( it->second < now - 10*1000 )
+    {
+      std::map<int,int>::iterator delIt = it;
+      it++;
+      oldSynchronizeables.erase( delIt );
+      continue;
+    }
+    it++;
+  }
+}
+
+/**
+ * writes data to DATA/dicts/newdict
+ * @param data pointer to data
+ * @param length length
+ */
+void NetworkStream::writeToNewDict( byte * data, int length )
+{
+  if ( remainingBytesToWriteToDict <= 0 )
     return;
-  }
-
-  if ( n > MAX_CONNECTIONS )
-  {
-    PRINTF(1)("Cannot set maxConnectiosn to %d because of hardcoded limit %d\n", n, MAX_CONNECTIONS);
+  
+  if ( length > remainingBytesToWriteToDict )
+    length = remainingBytesToWriteToDict;
+  
+  std::string fileName = ResourceManager::getInstance()->getDataDir();
+  fileName += "/dicts/newdict";
+  
+  FILE * f = fopen( fileName.c_str(), "a" );
+  
+  if ( !f )
+  {
+    PRINTF(2)("could not open %s\n", fileName.c_str());
+    remainingBytesToWriteToDict = 0;
     return;
   }
-
-  this->maxConnections = n;
-  this->networkGameManager->setUniqueID( n+2 );
-}
-
-
-
-void NetworkStream::debug()
-{
-  if( this->isServer())
-    PRINT(0)(" Host ist Server with ID: %i\n", this->myHostId);
-  else
-    PRINT(0)(" Host ist Client with ID: %i\n", this->myHostId);
-
-  PRINT(0)(" Got %i connected Synchronizeables, showing active Syncs:\n", this->synchronizeables.size());
-  for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
-  {
-    if( (*it)->beSynchronized() == true)
-      PRINT(0)("  Synchronizeable of class: %s::%s, with unique ID: %i, Synchronize: %i\n", (*it)->getClassName(), (*it)->getName(),
-               (*it)->getUniqueID(), (*it)->beSynchronized());
-  }
-  PRINT(0)(" Maximal Connections: %i\n", this->maxConnections);
-
-}
-
-
-int NetworkStream::getSyncCount()
-{
-  int n = 0;
-  for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
-    if( (*it)->beSynchronized() == true)
-      ++n;
-
-  //return synchronizeables.size();
-  return n;
-}
-
-
-
-
-
-
+  
+  if ( fwrite( data, 1, length, f ) != length )
+  {
+    PRINTF(2)("could not write to file\n");
+    fclose( f );
+    return;
+  }
+  
+  fclose( f );
+  
+  remainingBytesToWriteToDict -= length;  
+}
+
+
+
+
+
+
Index: /trunk/src/lib/network/network_stream.h
===================================================================
--- /trunk/src/lib/network/network_stream.h	(revision 7953)
+++ /trunk/src/lib/network/network_stream.h	(revision 7954)
@@ -9,20 +9,33 @@
 #include <vector>
 #include <list>
+#include <map>
 
 #include "data_stream.h"
-#include "network_protocol.h"
 #include "server_socket.h"
 #include "handshake.h"
+#include "connection_monitor.h"
+#include "udp_server_socket.h"
 
 class Synchronizeable;
 class NetworkSocket;
 class ServerSocket;
-class ConnectionMonitor;
-class NetworkProtocol;
 class NetworkGameManager;
 
+class PeerInfo
+{
+  public:
+    PeerInfo() { clear(); }
+    void clear() { userId = 0; isServer = false; socket = NULL; handshake = NULL; lastAckedState = 0; lastRecvedState = 0; connectionMonitor = NULL; }
+    int                 userId;
+    bool                isServer;
+    NetworkSocket *     socket;
+    Handshake *         handshake;
+    ConnectionMonitor * connectionMonitor;
+    int                 lastAckedState;
+    int                 lastRecvedState;
+};
+
 typedef std::list<Synchronizeable*>  SynchronizeableList;
-typedef std::vector<NetworkSocket*>  NetworkSocketVector;
-typedef std::vector<Handshake*>      HandshakeVector;
+typedef std::map<int,PeerInfo>       PeerList;
 
 
@@ -32,6 +45,6 @@
   public:
     NetworkStream();
-    NetworkStream(IPaddress& address);
-    NetworkStream(unsigned int port);
+    NetworkStream( std::string host, int port);
+    NetworkStream( int port );
 
     virtual ~NetworkStream();
@@ -47,6 +60,5 @@
     inline bool isActive() const { return this->bActive; }
 
-    inline int getMaxConnections(){ return maxConnections; }
-    void setMaxConnections( int n );
+    inline int getMaxConnections(){ return MAX_CONNECTIONS; }
 
     virtual void processData();
@@ -56,29 +68,43 @@
     int getSyncCount();
 
-    inline bool isUserIdActive( int userID ) { if (userID>=networkSockets.size()) return false; else return networkSockets[userID]!=NULL; }
+    inline bool isUserIdActive( int userID ) { return (peers.find(userID) != peers.end()); }
+    inline bool isUserServer( int userID ){ if ( !isUserIdActive(userID) ) return false; return peers[userID].isServer; }
 
     void debug();
+    
+    inline PeerInfo & getPeerInfo( int userId ) { return peers[userId]; }
 
 
   private:
     void updateConnectionList();
+    void handleHandshakes();
+    void handleUpstream();
+    void handleDownstream(); 
+    void handleNewClient( int userId );
+    void cleanUpOldSyncList();
+    
+    void writeToNewDict( byte * data, int length );
 
 
   private:
-    NetworkProtocol*           networkProtocol;
-    ConnectionMonitor*         connectionMonitor;
     SynchronizeableList        synchronizeables;
-    NetworkSocketVector        networkSockets;
-    HandshakeVector            handshakes;
+    PeerList                   peers;
     ServerSocket*              serverSocket;
     int                        type;
-    Header                     packetHeader;
     bool                       bActive;
     std::list<int>             freeSocketSlots;
 
     int                        myHostId;
-    int                        maxConnections;
+    
+    int                        currentState;                //!< current state id
 
     NetworkGameManager*        networkGameManager;
+
+    std::map<int,int>          oldSynchronizeables;         //!< used to save recently deleted sync ids to not recreate them
+    
+    byte                       buf[UDP_PACKET_SIZE];        //!< used by handleUp/Downstream
+    byte                       compBuf[UDP_PACKET_SIZE];    //!< used by handleUp/Downstream
+
+    int                        remainingBytesToWriteToDict; //!< if > 0 NetworkStream will write packets to DATA/dicts/newdict
 };
 #endif /* _NETWORK_STREAM */
Index: /trunk/src/lib/network/server_socket.cc
===================================================================
--- /trunk/src/lib/network/server_socket.cc	(revision 7953)
+++ /trunk/src/lib/network/server_socket.cc	(revision 7954)
@@ -26,118 +26,15 @@
 #include "debug.h"
 
-ServerSocket::ServerSocket(  )
+
+/**
+ * constructor
+ * @param port port to assign to socket
+ */
+ServerSocket::ServerSocket( int port )
 {
-  init();
+  bOk = true;
 }
 
-ServerSocket::ServerSocket( unsigned int port )
+ServerSocket::~ ServerSocket( )
 {
-  init();
-  listen(port);
 }
-
-/**
- * Default destructor
- */
-ServerSocket::~ServerSocket( )
-{
-  /* Quit SDL_net */
-  // NOTE: what if other instances of NetworkSocket running?
-  SDLNet_Quit();
-  PRINTF(5)("SDL_net shutdown\n");
-
-  _isListening = false;
-}
-
-void ServerSocket::init( )
-{
-  /* set the class id for the base object */
-  this->setClassID(CL_SERVER_SOCKET, "ServerSocket");
-
-  terminateThread = false;
-  listenSocket = NULL;
-  _isListening = false;
-
-  if(SDLNet_Init()==-1)
-  {
-    PRINTF(1)("SDLNet_Init: %s\n", SDLNet_GetError());
-    return;
-  }
-  else
-    PRINTF(5)("SDL_net initialized\n");
-
-  PRINTF(0)("ServerSocket created\n");
-}
-
-
-/**
- * Tells the NetworkSocket to listen on a specific port for incoming connections.
- * NetworkSocket::writeBytes(...) will have no effect until there is a valuable connection.
- * @param port
- */
-bool ServerSocket::listen(unsigned int port)
-{
-  PRINTF(0)("ServerSocket::listen()\n");
-  _isListening = true;
-  //check if not already connected or listening
-  if (listenSocket)
-  {
-    PRINTF(1)("ServerSocket::listen: tcpSocket!=NULL! maybe you already called listen or did not call close()!\n");
-    _isListening = false;
-    return false;
-  }
-
-  IPaddress ip;
-
-  if (SDLNet_ResolveHost(&ip, NULL, port)==-1)
-  {
-    PRINTF(1)("SDLNet_ResolveHost: %s\n", SDLNet_GetError());
-    _isListening = false;
-    return false;
-  }
-
-  listenSocket = SDLNet_TCP_Open(&ip);
-
-  if (!listenSocket)
-  {
-    PRINTF(1)("SDLNet_TCP_Open: %s\n", SDLNet_GetError());
-    _isListening = false;
-    return false;
-  }
-
-  return true;
-}
-
-
-NetworkSocket* ServerSocket::getNewSocket( )
-{
-  if ( !listenSocket )
-  {
-    PRINTF(1)("listenSocket == NULL! Maybe you forgot to call listen()\n");
-    close();
-    return NULL;
-  }
-
-  TCPsocket sock = SDLNet_TCP_Accept(listenSocket);
-
-  if ( !sock )
-  {
-    return NULL;
-  }
-  else
-  {
-    return new NetworkSocket(sock);
-  }
-}
-
-void ServerSocket::close( )
-{
-  if ( listenSocket )
-  {
-    SDLNet_TCP_Close( listenSocket );
-    listenSocket = NULL;
-  }
-
-  _isListening = false;
-}
-
Index: /trunk/src/lib/network/server_socket.h
===================================================================
--- /trunk/src/lib/network/server_socket.h	(revision 7953)
+++ /trunk/src/lib/network/server_socket.h	(revision 7954)
@@ -8,9 +8,4 @@
 #define _SERVER_SOCKET
 
-#ifdef HAVE_SDL_H
-#include <SDL_thread.h>
-#else
-#include <SDL/SDL_thread.h>
-#endif
 /* include this file, it contains some default definitions */
 #include "netdefs.h"
@@ -21,25 +16,21 @@
 #include "network_socket.h"
 
-//sleep when waiting for connections
-#define _MSECONDS_SLEEP_LISTEN 100
 
 class ServerSocket : public BaseObject
 {
-  private:
-    TCPsocket listenSocket;
-    bool terminateThread;
+  public:
+    ServerSocket( int port);
 
-    bool _isListening;
+    virtual ~ServerSocket();
 
-    void init();
+    virtual bool listen( unsigned int port ) = 0;
+    virtual NetworkSocket* getNewSocket( void ) = 0;
+    virtual void close() = 0;
+    virtual void update() = 0;
+    virtual bool isOk() { return this->bOk; };
 
-  public:
-    ServerSocket();
-    ServerSocket( unsigned int port );
-    virtual ~ServerSocket();
-    bool listen( unsigned int port );
-    NetworkSocket* getNewSocket( void );
-    void close();
-    inline bool isOk(){ return listenSocket!=NULL; }
+  protected:
+    bool bOk;
+
 };
 
Index: /trunk/src/lib/network/synchronizeable.cc
===================================================================
--- /trunk/src/lib/network/synchronizeable.cc	(revision 7953)
+++ /trunk/src/lib/network/synchronizeable.cc	(revision 7954)
@@ -20,4 +20,5 @@
 #include "network_stream.h"
 #include "netdefs.h"
+#include "network_log.h"
 
 #include "state.h"
@@ -36,13 +37,10 @@
   this->setClassID(CL_SYNCHRONIZEABLE, "Synchronizeable");
   this->owner = -1;
-  this->state = 0;
   this->hostID = SharedNetworkData::getInstance()->getHostID();
   this->setIsServer(this->hostID == 0);
   this->uniqueID = NET_UID_UNASSIGNED;
   this->networkStream = NULL;
-  this->setRequestedSync( false );
-  this->setIsOutOfSync( !(this->isServer()) );
   this->bSynchronize = false;
-
+  
   if( State::isOnline())
   {
@@ -52,4 +50,11 @@
     this->setUniqueID(SharedNetworkData::getInstance()->getNewUniqueID());
   }
+
+  /* make sure loadClassId is first synced var because this is read by networkStream */
+  assert( syncVarList.size() == 0 );
+  mLeafClassId = this->registerVarId( new SynchronizeableInt( (int*)&this->getLeafClassID(), (int*)&this->getLeafClassID(), "leafClassId" ) );
+    
+  this->registerVar( new SynchronizeableInt( &this->owner, &this->owner, "owner" ) );
+  this->registerVar( new SynchronizeableString( &this->objectName, &this->objectName, "objectName" ) );
 }
 
@@ -64,31 +69,4 @@
     this->networkStream->disconnectSynchronizeable(*this);
 }
-
-
-/**
- *  write data to NetworkStream
- */
-int Synchronizeable::writeBytes(const byte* data, int length, int sender)
-{
-  PRINTF(5)("Synchronizeable::writeBytes was called\n");
-}
-
-
-/**
- *  read data from NetworkStream
- */
-int Synchronizeable::readBytes(byte* data, int maxLength, int * reciever)
-{
-  PRINTF(5)("Synchronizeable::readBytes was called\n");
-}
-
-
-void Synchronizeable::writeDebug() const
-{}
-
-
-void Synchronizeable::readDebug() const
-{}
-
 
 /**
@@ -106,18 +84,4 @@
 
 /**
- * Sets the outofsync flag to a given value
- * @param outOfSync: the boolean value which the outofsync flag is to set to
- */
-void Synchronizeable::setIsOutOfSync(bool outOfSync)
-{
-  if( outOfSync )
-    this->state = this->state | STATE_OUTOFSYNC;
-  else
-    this->state = this->state & (~STATE_OUTOFSYNC);
-  //PRINTF(0)("isoutofsync %s %d\n", this->getClassName(), state);
-}
-
-
-/**
  * Determines if the server flag is set
  * @return true, if the server flag is true, false else
@@ -129,36 +93,453 @@
 
 
-/**
- * Determines if the outofsync flag is set
- * @return true, if the outofsync flag is true, false else
- */
-bool Synchronizeable::isOutOfSync()
-{
-  return (this->state & STATE_OUTOFSYNC) >0;
-}
-
-
-/**
- * Determines if the requestedSync flag is set
- * @return true, if the requestedSync flag is true, false else
- */
-bool Synchronizeable::requestedSync()
-{
-  return (this->state & STATE_REQUESTEDSYNC) >0;
-}
-
-
-/**
- * Sets the requestedsync flag to a given value
- * @param requestedSync: the boolean value which the requestedsync flag is to set to
- */
-void Synchronizeable::setRequestedSync( bool requestedSync )
-{
-  if( requestedSync )
-    this->state = this->state | STATE_REQUESTEDSYNC;
+
+int Synchronizeable::getStateDiff( int userId, byte* data, int maxLength, int stateId, int fromStateId, int priorityTH )
+{
+  //make sure this user has his history
+  if ( sentStates.size() <= userId )
+    sentStates.resize( userId+1 );
+
+  //calculate needed memory
+  int neededSize = 0;
+
+  for ( SyncVarList::iterator it = syncVarList.begin(); it != syncVarList.end(); it++ )
+    neededSize += (*it)->getSize();
+
+  if ( !( neededSize <= maxLength ) )
+  {
+    PRINTF(0)( "%d > %d\n", neededSize, maxLength );
+    assert(false);
+  }
+
+  //remove older states from history than fromStateId
+  StateHistory::iterator it = sentStates[userId].begin();
+
+  while ( it != sentStates[userId].end() && (*it)->stateId < fromStateId )
+    it++;
+
+  if ( it != sentStates[userId].begin() )
+  {
+    for ( StateHistory::iterator it2 = sentStates[userId].begin(); it2 != it; it2++ )
+    {
+      if ( (*it2)->data != NULL )
+      {
+        delete [] (*it2)->data;
+        (*it2)->data = NULL;
+      }
+    }
+    sentStates[userId].erase( sentStates[userId].begin(), it );
+  }
+
+  //find state to create diff from
+  StateHistoryEntry * stateFrom = NULL;
+
+  it = sentStates[userId].begin();
+  while ( it != sentStates[userId].end() && (*it)->stateId != fromStateId )
+    it++;
+  
+//  if ( getLeafClassID() == CL_SPACE_SHIP )
+//  {
+//    PRINTF(0)("getStateDiff:SpaceShip from: %d stateId: %d\n", (it == sentStates[userId].end())?-1:fromStateId, stateId);
+//  }
+
+  if ( it == sentStates[userId].end() )
+  {
+    StateHistoryEntry * initialEntry = new StateHistoryEntry();
+
+    initialEntry->stateId = fromStateId;
+    initialEntry->dataLength = 0;
+    initialEntry->data = NULL;
+
+    stateFrom = initialEntry;
+  }
   else
-    this->state = this->state & (~STATE_REQUESTEDSYNC);
-}
-
-
-
+    stateFrom = (*it);
+
+  StateHistoryEntry * stateTo = new StateHistoryEntry();
+
+  stateTo->stateId = stateId;
+  stateTo->dataLength = neededSize;
+  stateTo->data = new byte[ neededSize ];
+
+  std::list<int>::iterator sizeIter = stateFrom->sizeList.begin();
+
+  int i = 0;
+  int n;
+  
+  bool hasPermission;
+
+  // now do the actual synchronization: kick all variables to write into a common buffer
+  for ( SyncVarList::iterator it = syncVarList.begin(); it != syncVarList.end(); it++ )
+  {
+    hasPermission = (
+            this->isServer() && (*it)->checkPermission( PERMISSION_SERVER ) ||
+            this->owner == this->hostID && (*it)->checkPermission( PERMISSION_OWNER ) ||
+            (*it)->checkPermission( PERMISSION_ALL ) 
+                    );
+    
+    if ( ( hasPermission && (*it)->getPriority() >= priorityTH ) || sizeIter == stateFrom->sizeList.end() )
+    {
+      n = (*it)->writeToBuf( stateTo->data+i, stateTo->dataLength - i );
+      //NETPRINTF(0)("getvar %s %d\n", (*it)->getName().c_str(), n);
+      stateTo->sizeList.push_back( n );
+      //(*it)->debug();
+      i += n;
+    }
+    else
+    {
+      for ( int j = 0; j<(*sizeIter); j++ )
+      {
+        assert( i < stateFrom->dataLength );
+        stateTo->data[i] = stateFrom->data[i];
+        i++;
+      }
+      //NETPRINTF(0)("getvar %s %d\n", (*it)->getName().c_str(), *sizeIter);
+      stateTo->sizeList.push_back( (*sizeIter) );
+    }
+
+    if ( sizeIter != stateFrom->sizeList.end() )
+      sizeIter++;
+  }
+
+  sentStates[userId].push_back( stateTo );
+  
+  assert( i == neededSize );
+
+  //write diff to data
+  for ( i = 0; i<neededSize; i++ )
+  {
+    if ( i < stateFrom->dataLength )
+      data[i] = stateTo->data[i] - stateFrom->data[i];
+    else
+      data[i] = stateTo->data[i];
+  }
+
+  return neededSize;
+}
+
+/**
+ * sets a new state out of a diff created on another host
+ * @param userId hostId of user who send me that diff
+ * @param data pointer to diff
+ * @param length length of diff
+ * @param stateId id of current state
+ * @param fromStateId id of the base state id
+ * @return number bytes read
+ * @todo check for permissions
+ */
+int Synchronizeable::setStateDiff( int userId, byte* data, int length, int stateId, int fromStateId )
+{
+  //make sure this user has his history
+  if ( recvStates.size() <= userId )
+    recvStates.resize( userId+1 );
+
+  //create new state
+  StateHistoryEntry * stateTo = new StateHistoryEntry();
+  stateTo->stateId = stateId;
+  stateTo->dataLength = length;
+  stateTo->data = new byte[ length ];
+
+
+  //find state to apply diff to
+  StateHistoryEntry * stateFrom = NULL;
+
+  StateHistory::iterator it = recvStates[userId].begin();
+  while ( it != recvStates[userId].end() && (*it)->stateId != fromStateId )
+    it++;
+
+  
+//  if ( getLeafClassID() == CL_SPACE_SHIP )
+//  {
+//    PRINTF(0)("setStateDiff:SpaceShip from: %d stateId: %d\n", (it == recvStates[userId].end())?-1:fromStateId, stateId);
+//  }
+
+  if ( it == recvStates[userId].end() )
+  {
+    StateHistoryEntry * initialEntry = new StateHistoryEntry();
+
+    initialEntry->stateId = fromStateId;
+    initialEntry->dataLength = 0;
+    initialEntry->data = NULL;
+
+    stateFrom = initialEntry;
+  }
+  else
+    stateFrom = (*it);
+  
+  //apply diff
+  for ( int i = 0; i<length; i++ )
+  {
+    if ( i < stateFrom->dataLength )
+      stateTo->data[i] = stateFrom->data[i] + data[i];
+    else
+      stateTo->data[i] = data[i];
+    
+  }
+  
+  //add state to state history
+  recvStates[userId].push_back( stateTo );
+  
+  int i = 0;
+  int n = 0;
+  std::list<int> changes;
+  
+  for ( SyncVarList::iterator it = syncVarList.begin(); it != syncVarList.end(); it++ )
+  {
+    if (
+        (*it)->checkPermission( PERMISSION_SERVER ) && networkStream->isUserServer( userId ) ||
+        (*it)->checkPermission( PERMISSION_OWNER ) && this->owner == userId ||
+        (*it)->checkPermission( PERMISSION_ALL ) 
+       )
+    {
+      n = (*it)->readFromBuf( stateTo->data + i, stateTo->dataLength - i );
+      i += n;
+      //NETPRINTF(0)("%s::setvar %s %d\n", getClassName(), (*it)->getName().c_str(), n);
+      //(*it)->debug();
+      if ( (*it)->getHasChanged() )
+      {
+        changes.push_back( (*it)->getVarId() );
+      }
+    }
+    else
+    {
+//      PRINTF(0)("DONT SET VAR BECAUSE OF PERMISSION: %s %d %d %d %d %d %d\n", (*it)->getName().c_str(), (*it)->checkPermission( PERMISSION_SERVER ), (*it)->checkPermission( PERMISSION_OWNER ), (*it)->checkPermission( PERMISSION_ALL ), networkStream->isUserServer( userId ), this->owner, userId );
+      n = (*it)->getSizeFromBuf( stateTo->data + i, stateTo->dataLength - i );
+      //NETPRINTF(0)("%s::setvar %s %d\n", getClassName(), (*it)->getName().c_str(), n);
+      //(*it)->debug();
+      i += n;
+    }
+  }
+
+  this->varChangeHandler( changes );
+  
+  return i;
+}
+
+ /**
+ * override this function to be notified on change
+ * of your registred variables.
+ * @param id id's which have changed
+ */
+void Synchronizeable::varChangeHandler( std::list<int> & id )
+{
+}
+
+/**
+ * registers a varable to be synchronized over network
+ * @param var see src/lib/network/synchronizeable_var/ for available classes
+ */
+void Synchronizeable::registerVar( SynchronizeableVar * var )
+{
+  PRINTF(0)("ADDING VAR: %s\n", var->getName().c_str());
+  syncVarList.push_back( var );
+}
+
+/**
+ * registers a varable to be synchronized over network
+ * return value is passed to varChangeHandler on change
+ * @param var see src/lib/network/synchronizeable_var/ for available classes
+ * @return handle passed to varChangeHandler on changes
+ */
+int Synchronizeable::registerVarId( SynchronizeableVar * var )
+{
+  PRINTF(0)("ADDING VAR: %s\n", var->getName().c_str());
+  syncVarList.push_back( var );
+  var->setWatched( true );
+  var->setVarId( syncVarList.size()-1 );
+  return syncVarList.size()-1;
+}
+
+/**
+ * removed user's states from memory
+ * @param userId user to clean
+ */
+void Synchronizeable::cleanUpUser( int userId )
+{
+  for ( UserStateHistory::iterator it = sentStates.begin(); it != sentStates.end(); it++ )
+  {
+    for ( StateHistory::iterator it2 = it->begin(); it2 != it->end(); it2++ )
+    {
+      if ( (*it2)->data )
+        delete [] (*it2)->data;
+      (*it2)->data = NULL;
+      
+      delete *it2;
+    }
+  }
+  
+  sentStates.clear();
+  
+  for ( UserStateHistory::iterator it = recvStates.begin(); it != recvStates.end(); it++ )
+  {
+    for ( StateHistory::iterator it2 = it->begin(); it2 != it->end(); it2++ )
+    {
+      if ( (*it2)->data )
+        delete [] (*it2)->data;
+      (*it2)->data = NULL;
+      
+      delete *it2;
+    }
+  }
+  
+  recvStates.clear();
+}
+
+/**
+ * this function is called after recieving a state.
+ * @param userId 
+ * @param stateId 
+ * @param fromStateId 
+ */
+void Synchronizeable::handleRecvState( int userId, int stateId, int fromStateId )
+{
+   //make sure this user has his history
+  if ( recvStates.size() <= userId )
+    recvStates.resize( userId+1 );
+  
+  //remove old states
+  StateHistory::iterator it = recvStates[userId].begin();
+
+#if 0
+  while ( it != recvStates[userId].end() && (*it)->stateId < fromStateId )
+    it++;
+
+  if ( it != recvStates[userId].begin() )
+  {
+    for ( StateHistory::iterator it2 = recvStates[userId].begin(); it2 != it; it2++ )
+    {
+      if ( (*it2)->data != NULL )
+      {
+        delete [] (*it2)->data;
+        (*it2)->data = NULL;
+      }
+    }
+    recvStates[userId].erase( recvStates[userId].begin(), it );
+  }
+#endif
+
+  for ( it = recvStates[userId].begin(); it != recvStates[userId].end();  )
+  {
+    if ( (*it)->stateId < fromStateId )
+    {
+      StateHistory::iterator delIt = it;
+      it ++;
+      
+      if ( (*delIt)->data )
+        delete [] (*delIt)->data;
+      recvStates[userId].erase( delIt );
+      
+      continue;
+    }
+    it++;
+  }
+  
+  StateHistory::iterator fromState = recvStates[userId].end();
+  StateHistory::iterator toState = recvStates[userId].end();
+  
+  for ( it = recvStates[userId].begin(); it != recvStates[userId].end(); it++ )
+  {
+    if ( (*it)->stateId == stateId )
+      toState = it;
+    if ( (*it)->stateId == fromStateId )
+      fromState = it;
+    
+    if ( fromState != recvStates[userId].end() && toState != recvStates[userId].end() )
+      break;
+  }
+  
+  // setStateDiff was not called and i know fromStateId
+  if ( fromState != recvStates[userId].end() && toState == recvStates[userId].end() )
+  {
+    StateHistoryEntry * entry = new StateHistoryEntry;
+    
+    entry->dataLength = (*fromState)->dataLength;
+    if ( entry->dataLength > 0 )
+    {
+      entry->data = new byte[entry->dataLength];
+          
+      assert( (*fromState)->data );
+      memcpy( entry->data, (*fromState)->data, entry->dataLength );
+    }
+    else
+      entry->data = NULL;
+    
+    entry->sizeList = (*fromState)->sizeList;
+    entry->stateId = stateId;
+    
+    recvStates[userId].push_back(entry);
+  }
+}
+
+/**
+ * this function is called after sending a state
+ * @param userId 
+ * @param stateId 
+ * @param fromStateId 
+ */
+void Synchronizeable::handleSentState( int userId, int stateId, int fromStateId )
+{
+   //make sure this user has his history
+  if ( sentStates.size() <= userId )
+    sentStates.resize( userId+1 );
+
+   //remove old states
+  StateHistory::iterator it = sentStates[userId].begin();
+
+  for ( it = sentStates[userId].begin(); it != sentStates[userId].end();  )
+  {
+    if ( (*it)->stateId < fromStateId )
+    {
+      StateHistory::iterator delIt = it;
+      it ++;
+      
+      if ( (*delIt)->data )
+        delete [] (*delIt)->data;
+      sentStates[userId].erase( delIt );
+      
+      continue;
+    }
+    it++;
+  }
+
+  
+  StateHistory::iterator fromState = sentStates[userId].end();
+  StateHistory::iterator toState = sentStates[userId].end();
+  
+  for ( it = sentStates[userId].begin(); it != sentStates[userId].end(); it++ )
+  {
+    if ( (*it)->stateId == stateId )
+      toState = it;
+    if ( (*it)->stateId == fromStateId )
+      fromState = it;
+    
+    if ( fromState != sentStates[userId].end() && toState != sentStates[userId].end() )
+      break;
+  }
+
+  
+  // getStateDiff was not called and i know fromStateId
+  if ( fromState != sentStates[userId].end() && toState == sentStates[userId].end() )
+  {
+    StateHistoryEntry * entry = new StateHistoryEntry;
+    
+    entry->dataLength = (*fromState)->dataLength;
+    if ( entry->dataLength > 0 )
+    {
+      entry->data = new byte[entry->dataLength];
+      
+      assert( (*fromState)->data );
+      memcpy( entry->data, (*fromState)->data, entry->dataLength );
+    }
+    else
+      entry->data = NULL;
+    
+    entry->sizeList = (*fromState)->sizeList;
+    entry->stateId = stateId;
+    
+    sentStates[userId].push_back(entry);
+  }
+  
+}
+
+
+
Index: /trunk/src/lib/network/synchronizeable.h
===================================================================
--- /trunk/src/lib/network/synchronizeable.h	(revision 7953)
+++ /trunk/src/lib/network/synchronizeable.h	(revision 7954)
@@ -1,4 +1,4 @@
 /*!
- * @file connection_monitor.h
+ * @file synchronizeable.h
     \brief interface for all classes that have to be synchronized
  */
@@ -10,5 +10,14 @@
 #include "netdefs.h"
 #include "converter.h"
-
+#include "vector.h"
+#include "quaternion.h"
+#include "synchronizeable_var/synchronizeable_var.h"
+#include "synchronizeable_var/synchronizeable_vector.h"
+#include "synchronizeable_var/synchronizeable_quaternion.h"
+#include "synchronizeable_var/synchronizeable_string.h"
+#include "synchronizeable_var/synchronizeable_int.h"
+#include "synchronizeable_var/synchronizeable_float.h"
+#include "synchronizeable_var/synchronizeable_bool.h"
+#include "synchronizeable_var/synchronizeable_uint.h"
 
 
@@ -18,285 +27,20 @@
 //State constants: They have to be of the form 2^n
 #define STATE_SERVER 1
-#define STATE_OUTOFSYNC 2
-#define STATE_REQUESTEDSYNC 4
 
-enum {
-  NWT_SS_WE_STATE = 1000000,
-  NWT_SS_B,
-  NWT_SS_FLAGS,
-  NWT_SS_MOUSEDIRX,
-  NWT_SS_MOUSEDIRY,
-  NWT_SS_MOUSEDIRZ,
-  NWT_SS_MOUSEDIRW,
-  NWT_SS_PN_SYNC,
-  NWT_SS_VELX,
-  NWT_SS_VELY,
-  NWT_SS_VELZ,
-  NWT_SS_PL_SYNC,
-  NWT_SS_CO_N,
-  NWT_SS_CO_CLID,
-
-  NWT_HS_HOST_ID,
-  NWT_HS_NGM_ID,
-
-  NWT_PL_B,
-  NWT_PL_FLAGS,
-  NWT_PL_SCORE,
-
-  NWT_PN_BO_WRITESTATE,
-  NWT_PN_PARENTMODE,
-  NWT_PN_COORX,
-  NWT_PN_COORY,
-  NWT_PN_COORZ,
-  NWT_PN_ROTX,
-  NWT_PN_ROTY,
-  NWT_PN_ROTZ,
-  NWT_PN_ROTV,
-
-  NWT_PN_FLAGS,
-  NWT_PN_SCOORX,
-  NWT_PN_SCOORY,
-  NWT_PN_SCOORZ,
-  NWT_PN_SROTX,
-  NWT_PN_SROTY,
-  NWT_PN_SROTZ,
-  NWT_PN_SROTV,
-
-  NWT_BO_NAME,
-
-  NWT_WE_PN_WRITESTATE,
-  NWT_WE_PN_MODELFILENAME,
-  NWT_WE_PN_SCALING,
-
-  NWT_GT_WE_STATE,
-
-  NWT_SB_WE_STATE,
-  NWT_SB_SIZE,
-  NWT_SB_TEXTURENAME,
-
-  NWT_TER_WE_STATE,
-
-  NWT_PU_WE_STATE,
-
-  NWT_TPU_WE_STATE,
-
-  NWT_LPU_WE_STATE,
-
-  NWT_WPU_WE_STATE,
-
-  NWT_PPU_WE_STATE,
-  NWT_PPU_TYPE,
-  NWT_PPU_VALUE,
-  NWT_PPU_MINVALUE,
-  NWT_PPU_MAXVALUE,
-
-  NWT_WAT_STATE,
-  NWT_WAT_WE_STATE,
-  NWT_WAT_SIZEX,
-  NWT_WAT_SIZEY,
-  NWT_WAT_RESX,
-  NWT_WAT_RESY,
-  NWT_WAT_HEIGHT
+struct StateHistoryEntry
+{
+  int             stateId;
+  byte *          data;
+  int             dataLength;
+  std::list<int>  sizeList;
 };
 
+typedef std::list<StateHistoryEntry*> StateHistory;
 
-//macros to help writing data in byte buffer
-/*
- * Important: these macros must be used in
- *     SYNCHELP_READ_*:  virtual void      writeBytes(const byte* data, int length, int sender);
- *     SYNCHELP_WRITE_*: virtual int       readBytes(byte* data, int maxLength, int * reciever);
- * with the same argument names!
- *
- * id is one int out of that enum on top of this comment it is used to identify
- * read/write. when you read a value you have to use exactly the same as you used
- * to write or you will see an assertion failing.
- *
- * SYNCHELP_WRITE_BEGIN()
- * SYNCHELP_WRITE_INT(i,id)
- * SYNCHELP_WRITE_FLOAT(f,id)
- * SYNCHELP_WRITE_BYTE(b,id)
- * SYNCHELP_WRITE_STRING(s,id)
- * SYNCHELP_WRITE_N
- *
- * SYNCHELP_READ_BEGIN()
- * SYNCHELP_READ_INT(i,id)
- * SYNCHELP_READ_FLOAT(f,id)
- * SYNCHELP_READ_STRING(s,l,id) l = size of buffer s
- * SYNCHELP_READ_STRINGM(s,id)  allocates memory for string! you have to delete this later
- * SYNCHELP_READ_BYTE(b,id)
- * SYNCHELP_READ_REMAINING() returns the remaining buffer size
- * SYNCHELP_READ_NEXTBYTE()  reads the next byte but it is not removed from the buffer
- * SYNCHELP_READ_N
- *
- *
- *
- * Example 1:
- *  SYNCHELP_READ_BEGIN();
- *  SYNCHELP_READ_FLOAT(size);
- *  SYNCHELP_READ_STRING( textureName, 1024 ); //1024 is the length of textureName
- *  delete[] textureName;
- *  textureName = NULL;
- *  SYNCHELP_READ_STRINGM( texturename );      //this will call new char[strlen()+1]
- *
- * Example 2:
- *  SYNCHELP_WRITE_BEGIN();
- *  SYNCHELP_WRITE_FLOAT(this->size);
- *  SYNCHELP_WRITE_STRING(this->textureName);
- *  return SYNCHELP_WRITE_N;
- *
- */
+typedef std::vector<StateHistory> UserStateHistory;
 
-#define SYNCHELP_WRITE_DEBUG(n) {\
-  __synchelp_write_n = Converter::intToByteArray( n, data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
-  assert( __synchelp_write_n == INTSIZE ); \
-  __synchelp_write_i += __synchelp_write_n; \
-}
-
-#define SYNCHELP_READ_DEBUG(n) {  \
-  int nn; \
-  __synchelp_read_n = Converter::byteArrayToInt( data+__synchelp_read_i, &nn );  \
-  assert( __synchelp_read_n == INTSIZE ); \
-  if ( n != nn ) { \
-    PRINTF(1)("Check your code! read/writes not in right order! read %d instead of %d\n", nn, n); \
-    assert( false ); \
-  } \
-  __synchelp_read_i += __synchelp_read_n; \
-}
-
-#define SYNCHELP_WRITE_BEGIN()    int __synchelp_write_i = 0; \
-                                  int __synchelp_write_n
-#define SYNCHELP_WRITE_INT(i,n) { SYNCHELP_WRITE_DEBUG(n); \
-                                __synchelp_write_n = \
-                                Converter::intToByteArray( i, data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
-                                assert( __synchelp_write_n == INTSIZE ); \
-                                if ( __synchelp_write_n <= 0) \
-{ \
-                                  PRINTF(1)("Buffer is too small to store a int\n"); \
-                                  return 0; \
-} \
-                                __synchelp_write_i += __synchelp_write_n; \
-}
-#define SYNCHELP_WRITE_FLOAT(f,n) { SYNCHELP_WRITE_DEBUG(n); \
-                                __synchelp_write_n = \
-                                Converter::floatToByteArray( f, data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
-                                assert( __synchelp_write_n == FLOATSIZE ); \
-                                if ( __synchelp_write_n <= 0) \
-{ \
-                                  PRINTF(1)("Buffer is too small to store a float\n"); \
-                                  return 0; \
-} \
-                                __synchelp_write_i += __synchelp_write_n; \
-}
-#define SYNCHELP_WRITE_BYTE(b,n) { SYNCHELP_WRITE_DEBUG(n); \
-                                \
-                                if (maxLength - __synchelp_write_i < 1) \
-{ \
-                                  PRINTF(1)("Buffer is too small to store string\n"); \
-                                  return 0; \
-} \
-                                data[__synchelp_write_i] = b; \
-                                __synchelp_write_i++; \
-}
-#define SYNCHELP_WRITE_STRING(s,n) { SYNCHELP_WRITE_DEBUG(n); \
-                                __synchelp_write_n = \
-                                Converter::stringToByteArray( s, data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
-                                assert( __synchelp_write_n == ((std::string)s).length()+INTSIZE ); \
-                                if ( __synchelp_write_n <= 0) \
-{ \
-                                  PRINTF(1)("Buffer is too small to store string\n"); \
-                                  return 0; \
-} \
-                                __synchelp_write_i += __synchelp_write_n; \
-}
-#define SYNCHELP_WRITE_N        __synchelp_write_i
-#define SYNCHELP_WRITE_FKT(f,n)   { SYNCHELP_WRITE_DEBUG(n); \
-                                  PRINTF(0)("calling %s with %d left\n", #f, maxLength - __synchelp_write_i);  \
-                                  byte * spos = data+__synchelp_write_i;  \
-                                  if (maxLength - __synchelp_write_i < INTSIZE) \
-{ \
-                                    PRINTF(1)("Buffer is too small to store more data\n"); \
-                                    return 0; \
-} \
-                                  __synchelp_write_i += INTSIZE; \
-                                  __synchelp_write_n = \
-                                  f( data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
-                                  __synchelp_write_i += __synchelp_write_n;  \
-                                  Converter::intToByteArray( __synchelp_write_n, spos, INTSIZE ); \
-                                }
-
-
-#define SYNCHELP_READ_BEGIN()     int __synchelp_read_i = 0; \
-                                  int __synchelp_read_n
-
-#define SYNCHELP_READ_INT(i,n)       { SYNCHELP_READ_DEBUG(n); \
-                                    if ( length-__synchelp_read_i < INTSIZE ) \
-{ \
-                                      PRINTF(1)("There is not enough data to read an int\n");  \
-                                      return 0; \
-} \
-                                    __synchelp_read_n = Converter::byteArrayToInt( data+__synchelp_read_i, &i );  \
-                                    assert( __synchelp_read_n == INTSIZE ); \
-                                    __synchelp_read_i += __synchelp_read_n; \
-}
-#define SYNCHELP_READ_FLOAT(f,n)    { SYNCHELP_READ_DEBUG(n); \
-                                    if ( length-__synchelp_read_i < FLOATSIZE ) \
-{ \
-                                      PRINTF(1)("There is not enough data to read a flaot\n");  \
-                                      return 0; \
-} \
-                                    __synchelp_read_n = Converter::byteArrayToFloat( data+__synchelp_read_i, &f );  \
-                                    assert( __synchelp_read_n == FLOATSIZE ) ;\
-                                    __synchelp_read_i += __synchelp_read_n; \
-}
-#define SYNCHELP_READ_STRING(s,n)    {SYNCHELP_READ_DEBUG(n); \
-                                    __synchelp_read_n = Converter::byteArrayToString( data+__synchelp_read_i, s, length-__synchelp_read_i );  \
-                                    assert( __synchelp_read_n == s.length()+INTSIZE ) ;\
-                                    if ( __synchelp_read_n <0 )  \
-{ \
-                                      PRINTF(1)("There is not enough data to read string\n");  \
-                                      return 0; \
-} \
-                                    __synchelp_read_i += __synchelp_read_n; \
-}
-#if 0 //not needed any more
-#define SYNCHELP_READ_STRINGM(s,n)    { SYNCHELP_READ_DEBUG(n); \
-                                    __synchelp_read_n = Converter::byteArrayToStringM( data+__synchelp_read_i, s );  \
-                                    assert( __synchelp_read_n == strlen(s)+INTSIZE ) ;\
-                                    if ( __synchelp_read_n <0 )  \
-{ \
-                                      PRINTF(1)("There is not enough data to read string\n");  \
-                                      return 0; \
-} \
-                                    __synchelp_read_i += __synchelp_read_n; \
-}
-#endif
-#define SYNCHELP_READ_BYTE(b,n)      { SYNCHELP_READ_DEBUG(n); \
-                                    if ( length-__synchelp_read_i < 1 ) \
-{ \
-                                      PRINTF(1)("There is not enough data to read a byte\n");  \
-                                      return 0; \
-} \
-                                    b = data[__synchelp_read_i]; \
-                                    __synchelp_read_i ++;  \
-}
-#define SYNCHELP_READ_FKT(f,n)   { SYNCHELP_READ_DEBUG(n); \
-                                  int s; \
-                                  if ( length-__synchelp_read_i < INTSIZE ) \
-{ \
-                                      PRINTF(1)("There is not enough data to read an int\n");  \
-                                      return 0; \
-} \
-                                    __synchelp_read_n = Converter::byteArrayToInt( data+__synchelp_read_i, &s );  \
-                                    assert( __synchelp_read_n == INTSIZE ); \
-                                    __synchelp_read_i += __synchelp_read_n; \
-                                  __synchelp_read_i += \
-                                  f( data+__synchelp_read_i, s, sender); \
-                                  }
-#define SYNCHELP_READ_REMAINING() ( length-__synchelp_read_i )
-#define SYNCHELP_READ_NEXTBYTE() ( data[__synchelp_read_i] )
-#define SYNCHELP_READ_N           __synchelp_read_i
+typedef std::vector<SynchronizeableVar*> SyncVarList;
 
 class NetworkStream;
-
 
 class Synchronizeable : virtual public BaseObject
@@ -307,15 +51,17 @@
     virtual ~Synchronizeable();
 
-    virtual int       writeBytes(const byte* data, int length, int sender);
-    virtual int       readBytes(byte* data, int maxLength, int * reciever);
-    virtual void      writeDebug() const;
-    virtual void      readDebug() const;
+    void setIsServer( bool isServer );
+    bool isServer();
 
-    void setIsServer( bool isServer );
-    void setIsOutOfSync( bool outOfSync );
-    void setRequestedSync( bool requestedSync );
-    bool isServer();
-    bool isOutOfSync();
-    bool requestedSync();
+    virtual void varChangeHandler( std::list<int> & id );
+
+    virtual int getStateDiff( int userId, byte* data, int maxLength, int stateId, int fromStateId, int priorityTH );
+    virtual int setStateDiff( int userId, byte* data, int length, int stateId, int fromStateId );
+    virtual void cleanUpUser( int userId );
+    virtual void handleSentState( int userId, int stateId, int fromStateId );
+    virtual void handleRecvState( int userId, int stateId, int fromStateId );
+
+    void registerVar( SynchronizeableVar * var );
+    int registerVarId( SynchronizeableVar * var );
 
     inline void setUniqueID( int id ){ uniqueID = id; }
@@ -326,11 +72,8 @@
     inline void setOwner(int owner){ this->owner = owner; }
 
-    /** @returns true if this Synchronizeable has to be synchronized over network */
+    /** @returns true if this Synchronizeable wants to be synchronized over network */
     inline bool beSynchronized() { return this->bSynchronize; }
     /** @param bSynchronize sets the Synchronizeable to be sunchronized or not */
     inline void setSynchronized(bool bSynchronize) { this->bSynchronize = bSynchronize; }
-
-    inline void requestSync( int hostID ){ this->synchronizeRequests.push_back( hostID ); }
-    inline int getRequestSync( void ){ if ( this->synchronizeRequests.size()>0 ){ int n = *(synchronizeRequests.begin()); synchronizeRequests.pop_front(); return n; } else { return -1; } };
 
     inline void setNetworkStream(NetworkStream* stream) { this->networkStream = stream; }
@@ -339,15 +82,18 @@
 
   protected:
-    NetworkStream*    networkStream;
+    NetworkStream*    networkStream;  //!< reference network stream we are connected to
     int               state;
 
+  private:
+    int               uniqueID;       //!< unique id assigned to synchronizeable
+    int               mLeafClassId;   //!< store leafClassId to send via states
+    int               owner;          //!< hostId of owner ( 0 if none / server )
+    int               hostID;         //!< my own host id
+    bool              bSynchronize;   //!< do we need beeing synchronized?
 
-  private:
-    int               uniqueID;
-    int               owner;
-    int               hostID;
-    bool              bSynchronize;
+    SyncVarList       syncVarList;    //!< list containing variables to synchronize
 
-    std::list<int>    synchronizeRequests;
+    UserStateHistory  sentStates;     //!< store already sent states to create diffs from, offset corresponds to the user id
+    UserStateHistory  recvStates;     //!< store recieved states to apply diffs, offset corresponds to the user id
 
 };
Index: /trunk/src/lib/network/synchronizeable_var/synchronizeable_bool.cc
===================================================================
--- /trunk/src/lib/network/synchronizeable_var/synchronizeable_bool.cc	(revision 7954)
+++ /trunk/src/lib/network/synchronizeable_var/synchronizeable_bool.cc	(revision 7954)
@@ -0,0 +1,79 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+
+#include "synchronizeable_bool.h"
+
+
+/**
+ * standard constructor
+ */
+SynchronizeableBool::SynchronizeableBool( bool * ptrIn, bool * ptrOut, std::string name, int permission, int priority) : SynchronizeableVar( ptrIn, ptrOut, name, 1, permission, priority )
+{
+  this->vPtrIn = ptrIn;
+  this->vPtrOut = ptrOut;
+}
+
+
+/**
+ * standard deconstructor
+*/
+SynchronizeableBool::~SynchronizeableBool ()
+{
+}
+
+/**
+ * write var data to byte buffer
+ * @param buf pointer to write to
+ * @param maxLength writeToBuf will not write more than maxLength bytes
+ * @return number bytes written
+ */
+int SynchronizeableBool::writeToBuf( byte * buf, int maxLength )
+{
+  assert( maxLength >= 1 );
+  
+  buf[0] = ( *vPtrIn ) ? 1 : 0;
+  
+  return 1;
+}
+
+/**
+ * read var data from byte buffer
+ * @param buf pointer to read from
+ * @param maxLength readFromBuf will not read more than maxLength bytes
+ * @return number bytes read
+ */
+int SynchronizeableBool::readFromBuf( byte * buf, int maxLength )
+{
+  assert( maxLength >= 1 );
+  
+  bool oldVal = *vPtrOut;
+  
+  *vPtrOut = buf[0] != 0;
+  
+  setHasChanged( oldVal != *vPtrOut );
+  
+  return 1;
+}
+
+/**
+ * print out variable value
+ */
+void SynchronizeableBool::debug( )
+{
+  printf( "SYNCHRONIZEABLE_VAR: %s IN: %d OUT: %d\n", name.c_str(), (int)*vPtrIn, (int)*vPtrOut );
+}
+
+
Index: /trunk/src/lib/network/synchronizeable_var/synchronizeable_bool.h
===================================================================
--- /trunk/src/lib/network/synchronizeable_var/synchronizeable_bool.h	(revision 7954)
+++ /trunk/src/lib/network/synchronizeable_var/synchronizeable_bool.h	(revision 7954)
@@ -0,0 +1,34 @@
+/*!
+ * @file synchronizeable_int.h
+ * @brief Definition of SynchronizeableInt
+*/
+
+#include "synchronizeable_var/synchronizeable_var.h"
+
+#ifndef _SYNCHRONIZEABLE_BOOL_H
+#define _SYNCHRONIZEABLE_BOOL_H
+
+class SynchronizeableBool : public SynchronizeableVar {
+
+  public:
+    SynchronizeableBool( bool * ptrIn, bool * ptrOut, std::string name, int permission = PERMISSION_SERVER, int priority = 0 );
+    virtual ~SynchronizeableBool();
+    
+    virtual int writeToBuf( byte * buf, int maxLength );
+    virtual int readFromBuf( byte * buf, int maxLength );
+    
+    /**
+     * check if writeToBuf will return the same size every time
+     * @return true if same size every time
+     */
+    virtual bool hasStaticSize(){ return true; };
+    
+    virtual void debug();
+    
+  private:
+    bool * vPtrIn;       //!< pointer to data (read)
+    bool * vPtrOut;      //!< pointer to data (write)
+
+};
+
+#endif /* _PROTO_CLASS_H */
Index: /trunk/src/lib/network/synchronizeable_var/synchronizeable_float.cc
===================================================================
--- /trunk/src/lib/network/synchronizeable_var/synchronizeable_float.cc	(revision 7954)
+++ /trunk/src/lib/network/synchronizeable_var/synchronizeable_float.cc	(revision 7954)
@@ -0,0 +1,83 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+
+#include "synchronizeable_float.h"
+#include "converter.h"
+
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+SynchronizeableFloat::SynchronizeableFloat( float * ptrIn, float * ptrOut, std::string name, int permission, int priority) : SynchronizeableVar( ptrIn, ptrOut, name, FLOATSIZE, permission, priority )
+{
+  this->vPtrIn = ptrIn;
+  this->vPtrOut = ptrOut;
+}
+
+
+/**
+ * standard deconstructor
+*/
+SynchronizeableFloat::~SynchronizeableFloat ()
+{
+}
+
+/**
+ * write var data to byte buffer
+ * @param buf pointer to write to
+ * @param maxLength writeToBuf will not write more than maxLength bytes
+ * @return number bytes written
+ */
+int SynchronizeableFloat::writeToBuf( byte * buf, int maxLength )
+{
+  int res = Converter::floatToByteArray( *vPtrIn, buf, maxLength );
+  
+  assert( res == FLOATSIZE );
+  
+  return res;
+}
+
+/**
+ * read var data from byte buffer
+ * @param buf pointer to read from
+ * @param maxLength readFromBuf will not read more than maxLength bytes
+ * @return number bytes read
+ */
+int SynchronizeableFloat::readFromBuf( byte * buf, int maxLength )
+{
+  assert( maxLength >= FLOATSIZE );
+  
+  float oldVal = *vPtrOut;
+  
+  int res = Converter::byteArrayToFloat( buf, vPtrOut );
+  
+  setHasChanged( oldVal != *vPtrOut );
+  
+  assert( res == FLOATSIZE );
+  
+  return res;
+}
+
+
+/**
+ * print out variable value
+ */
+void SynchronizeableFloat::debug( )
+{
+  printf( "SYNCHRONIZEABLE_VAR: %s IN: %f OUT: %f\n", name.c_str(), *vPtrIn, *vPtrOut );
+}
+
Index: /trunk/src/lib/network/synchronizeable_var/synchronizeable_float.h
===================================================================
--- /trunk/src/lib/network/synchronizeable_var/synchronizeable_float.h	(revision 7954)
+++ /trunk/src/lib/network/synchronizeable_var/synchronizeable_float.h	(revision 7954)
@@ -0,0 +1,34 @@
+/*!
+ * @file synchronizeable_float.h
+ * @brief Definition of SynchronizeableFloat
+*/
+
+#include "synchronizeable_var/synchronizeable_var.h"
+
+#ifndef _SYNCHRONIZEABLE_FLOAT_H
+#define _SYNCHRONIZEABLE_FLOAT_H
+
+class SynchronizeableFloat : public SynchronizeableVar {
+
+  public:
+    SynchronizeableFloat( float * ptrIn, float * ptrOut, std::string name, int permission = PERMISSION_SERVER, int priority = 0 );
+    virtual ~SynchronizeableFloat();
+    
+    virtual int writeToBuf( byte * buf, int maxLength );
+    virtual int readFromBuf( byte * buf, int maxLength );
+        
+    /**
+     * check if writeToBuf will return the same size every time
+     * @return true if same size every time
+     */
+    virtual bool hasStaticSize(){ return true; };
+    
+    virtual void debug();
+    
+  private:
+    float * vPtrIn;       //!< pointer to data (read)
+    float * vPtrOut;      //!< pointer to data (write)
+
+};
+
+#endif /* _PROTO_CLASS_H */
Index: /trunk/src/lib/network/synchronizeable_var/synchronizeable_int.cc
===================================================================
--- /trunk/src/lib/network/synchronizeable_var/synchronizeable_int.cc	(revision 7954)
+++ /trunk/src/lib/network/synchronizeable_var/synchronizeable_int.cc	(revision 7954)
@@ -0,0 +1,83 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+
+#include "synchronizeable_int.h"
+#include "converter.h"
+
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+SynchronizeableInt::SynchronizeableInt( int * ptrIn, int * ptrOut, std::string name, int permission, int priority) : SynchronizeableVar( ptrIn, ptrOut, name, INTSIZE, permission, priority )
+{
+  this->vPtrIn = ptrIn;
+  this->vPtrOut = ptrOut;
+}
+
+
+/**
+ * standard deconstructor
+*/
+SynchronizeableInt::~SynchronizeableInt ()
+{
+}
+
+/**
+ * write var data to byte buffer
+ * @param buf pointer to write to
+ * @param maxLength writeToBuf will not write more than maxLength bytes
+ * @return number bytes written
+ */
+int SynchronizeableInt::writeToBuf( byte * buf, int maxLength )
+{
+  int res = Converter::intToByteArray( *vPtrIn, buf, maxLength );
+  
+  assert( res == INTSIZE );
+  
+  return res;
+}
+
+/**
+ * read var data from byte buffer
+ * @param buf pointer to read from
+ * @param maxLength readFromBuf will not read more than maxLength bytes
+ * @return number bytes read
+ */
+int SynchronizeableInt::readFromBuf( byte * buf, int maxLength )
+{
+  assert( maxLength >= INTSIZE );
+  
+  int oldVal = *vPtrOut;
+  
+  int res = Converter::byteArrayToInt( buf, vPtrOut );
+  
+  setHasChanged( oldVal != *vPtrOut );
+  
+  assert( res == INTSIZE );
+  
+  return res;
+}
+
+
+/**
+ * print out variable value
+ */
+void SynchronizeableInt::debug( )
+{
+  printf( "SYNCHRONIZEABLE_VAR: %s IN: %d OUT: %d\n", name.c_str(), *vPtrIn, *vPtrOut );
+}
+
Index: /trunk/src/lib/network/synchronizeable_var/synchronizeable_int.h
===================================================================
--- /trunk/src/lib/network/synchronizeable_var/synchronizeable_int.h	(revision 7954)
+++ /trunk/src/lib/network/synchronizeable_var/synchronizeable_int.h	(revision 7954)
@@ -0,0 +1,35 @@
+/*!
+ * @file synchronizeable_int.h
+ * @brief Definition of SynchronizeableInt
+*/
+
+#include "synchronizeable_var/synchronizeable_var.h"
+
+#ifndef _SYNCHRONIZEABLE_INT_H
+#define _SYNCHRONIZEABLE_INT_H
+
+class SynchronizeableInt : public SynchronizeableVar {
+
+  public:
+    SynchronizeableInt( int * ptrIn, int * ptrOut, std::string name, int permission = PERMISSION_SERVER, int priority = 0 );
+    virtual ~SynchronizeableInt();
+    
+    virtual int writeToBuf( byte * buf, int maxLength );
+    virtual int readFromBuf( byte * buf, int maxLength );
+    
+    /**
+     * check if writeToBuf will return the same size every time
+     * @return true if same size every time
+     */
+    virtual bool hasStaticSize(){ return true; };
+    
+    virtual void debug();
+    
+  protected:
+    int * vPtrIn;       //!< pointer to data (read)
+    int * vPtrOut;      //!< pointer to data (write)
+
+
+};
+
+#endif /* _PROTO_CLASS_H */
Index: /trunk/src/lib/network/synchronizeable_var/synchronizeable_quaternion.cc
===================================================================
--- /trunk/src/lib/network/synchronizeable_var/synchronizeable_quaternion.cc	(revision 7954)
+++ /trunk/src/lib/network/synchronizeable_var/synchronizeable_quaternion.cc	(revision 7954)
@@ -0,0 +1,119 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+
+#include "synchronizeable_quaternion.h"
+#include "converter.h"
+
+
+/**
+ * standard constructor
+ */
+SynchronizeableQuaternion::SynchronizeableQuaternion( Quaternion * ptrIn, Quaternion * ptrOut, std::string name, int permission, int priority) : SynchronizeableVar( ptrIn, ptrOut, name, 4*INTSIZE, permission, priority )
+{
+  this->vPtrIn = ptrIn;
+  this->vPtrOut = ptrOut;
+}
+
+
+/**
+ * standard deconstructor
+ */
+SynchronizeableQuaternion::~SynchronizeableQuaternion ()
+{
+}
+
+/**
+ * write var data to byte buffer
+ * @param buf pointer to write to
+ * @param maxLength writeToBuf will not write more than maxLength bytes
+ * @return number bytes written
+ */
+int SynchronizeableQuaternion::writeToBuf( byte * buf, int maxLength )
+{
+  int n = 0;
+  int res;
+
+  res = Converter::floatToByteArray( vPtrIn->v.x, buf + n, maxLength - n );
+  assert( res > 0 );
+  n += res;
+
+  res = Converter::floatToByteArray( vPtrIn->v.y, buf + n, maxLength - n );
+  assert( res > 0 );
+  n += res;
+
+  res = Converter::floatToByteArray( vPtrIn->v.z, buf + n, maxLength - n );
+  assert( res > 0 );
+  n += res;
+
+  res = Converter::floatToByteArray( vPtrIn->w, buf +  n, maxLength - n );
+  assert( res > 0 );
+  n += res;
+
+  assert( 4*FLOATSIZE == n );
+
+  return n;
+}
+
+/**
+ * read var data from byte buffer
+ * @param buf pointer to read from
+ * @param maxLength readFromBuf will not read more than maxLength bytes
+ * @return number bytes read
+ */
+int SynchronizeableQuaternion::readFromBuf( byte * buf, int maxLength )
+{
+  assert( maxLength >= 4*FLOATSIZE );
+
+  float x,y,z,w;
+
+  int res;
+  int n = 0;
+
+  res = Converter::byteArrayToFloat( buf + n, &x );
+  assert( res > 0 );
+  n += res;
+
+  res = Converter::byteArrayToFloat( buf + n, &y );
+  assert( res > 0 );
+  n += res;
+
+  res = Converter::byteArrayToFloat( buf + n, &z );
+  assert( res > 0 );
+  n += res;
+
+  res = Converter::byteArrayToFloat( buf + n, &w );
+  assert( res > 0 );
+  n += res;
+  
+  Quaternion oldVal = *vPtrOut;
+
+  *vPtrOut = Quaternion( Vector(x, y, z), w );
+  
+  setHasChanged( ! ( oldVal == *vPtrOut ) );
+
+  assert( n == 4*FLOATSIZE );
+  return n;
+}
+
+
+/**
+ * print out variable value
+ */
+void SynchronizeableQuaternion::debug( )
+{
+  printf( "SYNCHRONIZEABLE_VAR: %s IN: ((%f, %f, %f), %f) OUT: ((%f %f %f), %f)\n", name.c_str(), vPtrIn->v.x, vPtrIn->v.y, vPtrIn->v.z, vPtrIn->w, vPtrOut->v.x, vPtrOut->v.y, vPtrOut->v.z, vPtrOut->w );
+}
+
Index: /trunk/src/lib/network/synchronizeable_var/synchronizeable_quaternion.h
===================================================================
--- /trunk/src/lib/network/synchronizeable_var/synchronizeable_quaternion.h	(revision 7954)
+++ /trunk/src/lib/network/synchronizeable_var/synchronizeable_quaternion.h	(revision 7954)
@@ -0,0 +1,36 @@
+/*!
+ * @file synchronizeable_quaternion.h
+ * @brief Definition of SynchronizeableQuaternion
+*/
+
+#include "synchronizeable_var/synchronizeable_var.h"
+
+#ifndef _SYNCHRONIZEABLE_QUATERNION_H
+#define _SYNCHRONIZEABLE_QUATERNION_H
+
+#include "quaternion.h"
+
+class SynchronizeableQuaternion : public SynchronizeableVar {
+
+  public:
+    SynchronizeableQuaternion( Quaternion * ptrIn, Quaternion * ptrOut, std::string name, int permission = PERMISSION_SERVER, int priority = 0 );
+    virtual ~SynchronizeableQuaternion();
+    
+    virtual int writeToBuf( byte * buf, int maxLength );
+    virtual int readFromBuf( byte * buf, int maxLength );
+        
+    /**
+     * check if writeToBuf will return the same size every time
+     * @return true if same size every time
+     */
+    virtual bool hasStaticSize(){ return true; };
+    
+    virtual void debug();
+    
+  private:
+    Quaternion * vPtrIn;       //!< pointer to data (read)
+    Quaternion * vPtrOut;      //!< pointer to data (write)
+
+};
+
+#endif /* _PROTO_CLASS_H */
Index: /trunk/src/lib/network/synchronizeable_var/synchronizeable_string.cc
===================================================================
--- /trunk/src/lib/network/synchronizeable_var/synchronizeable_string.cc	(revision 7954)
+++ /trunk/src/lib/network/synchronizeable_var/synchronizeable_string.cc	(revision 7954)
@@ -0,0 +1,103 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+
+#include "synchronizeable_string.h"
+#include "converter.h"
+
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+SynchronizeableString::SynchronizeableString( std::string * ptrIn, std::string * ptrOut, std::string name, int permission, int priority) : SynchronizeableVar( ptrIn, ptrOut, name, 0, permission, priority )
+{
+  this->vPtrIn = ptrIn;
+  this->vPtrOut = ptrOut;
+}
+
+
+/**
+ * standard deconstructor
+*/
+SynchronizeableString::~SynchronizeableString ()
+{
+}
+
+/**
+ * write var data to byte buffer
+ * @param buf pointer to write to
+ * @param maxLength writeToBuf will not write more than maxLength bytes
+ * @return number bytes written
+ */
+int SynchronizeableString::writeToBuf( byte * buf, int maxLength )
+{
+  int res = Converter::stringToByteArray( *vPtrIn, buf, maxLength );
+  
+  assert( res > 0 );
+  
+  return res;
+}
+
+/**
+ * read var data from byte buffer
+ * @param buf pointer to read from
+ * @param maxLength readFromBuf will not read more than maxLength bytes
+ * @return number bytes read
+ */
+int SynchronizeableString::readFromBuf( byte * buf, int maxLength )
+{
+  std::string oldVal = *vPtrOut;
+      
+  int res = Converter::byteArrayToString( buf, *vPtrOut, maxLength );
+  
+  setHasChanged( oldVal != *vPtrOut );
+  
+  if ( res < 0 )
+  {
+    printf("%s | res (%d) < 0\n", this->getName().c_str(), res);
+  }
+  assert( res > 0 );
+  
+  return res;
+}
+
+/**
+ * print out variable value
+ */
+void SynchronizeableString::debug( )
+{
+  printf( "SYNCHRONIZEABLE_VAR: %s IN: '%s' OUT: '%s'\n", name.c_str(), vPtrIn->c_str(), vPtrOut->c_str() );
+}
+
+
+/**
+ * reads actual size from buffer. this is used when size is not constant
+ * @param buf pointer to data
+ * @param maxLength maximal size of data
+ * @return same as readFromBuf would return
+ */
+int SynchronizeableString::getSizeFromBuf( byte * buf, int maxLength )
+{
+  std::string t;
+  
+  int res = Converter::byteArrayToString( buf, t, maxLength );
+  
+  assert( res > 0 );
+  
+  return res;
+}
+
+
Index: /trunk/src/lib/network/synchronizeable_var/synchronizeable_string.h
===================================================================
--- /trunk/src/lib/network/synchronizeable_var/synchronizeable_string.h	(revision 7954)
+++ /trunk/src/lib/network/synchronizeable_var/synchronizeable_string.h	(revision 7954)
@@ -0,0 +1,42 @@
+/*!
+ * @file synchronizeable_string.h
+ * @brief Definition of SynchronizeableString
+*/
+
+#include "synchronizeable_var/synchronizeable_var.h"
+#include "converter.h"
+
+#ifndef _SYNCHRONIZEABLE_STRING_H
+#define _SYNCHRONIZEABLE_STRING_H
+
+#include <string>
+
+class SynchronizeableString : public SynchronizeableVar {
+
+  public:
+    SynchronizeableString( std::string * ptrIn, std::string * ptrOut, std::string name, int permission = PERMISSION_SERVER, int priority = 0 );
+    virtual ~SynchronizeableString();
+    
+    virtual int writeToBuf( byte * buf, int maxLength );
+    virtual int readFromBuf( byte * buf, int maxLength );
+    
+        
+    /**
+     * check if writeToBuf will return the same size every time
+     * @return true if same size every time
+     */
+    virtual bool hasStaticSize(){ return false; };
+    
+    virtual int getSize(){ return vPtrIn->length()+INTSIZE; }
+    
+    virtual int getSizeFromBuf( byte * buf, int maxLength );
+    
+    virtual void debug();
+    
+  private:
+    std::string * vPtrIn;       //!< pointer to data (read)
+    std::string * vPtrOut;      //!< pointer to data (write)
+
+};
+
+#endif /* _SYNCHRONIZEABLE_STRING_H */
Index: /trunk/src/lib/network/synchronizeable_var/synchronizeable_uint.cc
===================================================================
--- /trunk/src/lib/network/synchronizeable_var/synchronizeable_uint.cc	(revision 7954)
+++ /trunk/src/lib/network/synchronizeable_var/synchronizeable_uint.cc	(revision 7954)
@@ -0,0 +1,43 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+
+#include "synchronizeable_uint.h"
+
+
+/**
+ * standard constructor
+*/
+SynchronizeableUInt::SynchronizeableUInt( unsigned int * ptrIn, unsigned int * ptrOut, std::string name, int permission, int priority) : SynchronizeableInt( (int*)ptrIn, (int*)ptrOut, name, permission, priority )
+{
+}
+
+
+/**
+ * standard deconstructor
+*/
+SynchronizeableUInt::~SynchronizeableUInt ()
+{
+}
+
+
+/**
+ * print out variable value
+ */
+void SynchronizeableUInt::debug( )
+{
+  printf( "SYNCHRONIZEABLE_VAR: %s IN: %u OUT: %u\n", name.c_str(), *vPtrIn, *vPtrOut );
+}
+
Index: /trunk/src/lib/network/synchronizeable_var/synchronizeable_uint.h
===================================================================
--- /trunk/src/lib/network/synchronizeable_var/synchronizeable_uint.h	(revision 7954)
+++ /trunk/src/lib/network/synchronizeable_var/synchronizeable_uint.h	(revision 7954)
@@ -0,0 +1,21 @@
+/*!
+ * @file synchronizeable_uint.h
+ * @brief Definition of SynchronizeableInt
+*/
+
+#include "synchronizeable_var/synchronizeable_int.h"
+
+#ifndef _SYNCHRONIZEABLE_UINT_H
+#define _SYNCHRONIZEABLE_UINT_H
+
+class SynchronizeableUInt : public SynchronizeableInt {
+
+  public:
+    SynchronizeableUInt( unsigned int * ptrIn, unsigned int * ptrOut, std::string name, int permission = PERMISSION_SERVER, int priority = 0 );
+    virtual ~SynchronizeableUInt();
+    
+    virtual void debug();
+
+};
+
+#endif /* _PROTO_CLASS_H */
Index: /trunk/src/lib/network/synchronizeable_var/synchronizeable_var.cc
===================================================================
--- /trunk/src/lib/network/synchronizeable_var/synchronizeable_var.cc	(revision 7954)
+++ /trunk/src/lib/network/synchronizeable_var/synchronizeable_var.cc	(revision 7954)
@@ -0,0 +1,48 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+
+#include "synchronizeable_var.h"
+
+
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+SynchronizeableVar::SynchronizeableVar ( void * ptrIn, void * ptrOut, std::string name, int length, int permission, int priority)
+{
+  assert( ptrIn );
+  assert( ptrOut );
+
+  this->ptrIn = ptrIn;
+  this->ptrOut = ptrOut;
+  this->length = length;
+  this->permission = permission;
+  this->priority = priority;
+  this->realPriority = priority;
+  this->name = name;
+  this->bWatched = false;
+  this->changed = false;
+}
+
+
+/**
+ * standard deconstructor
+*/
+SynchronizeableVar::~SynchronizeableVar ()
+{
+}
+
Index: /trunk/src/lib/network/synchronizeable_var/synchronizeable_var.h
===================================================================
--- /trunk/src/lib/network/synchronizeable_var/synchronizeable_var.h	(revision 7954)
+++ /trunk/src/lib/network/synchronizeable_var/synchronizeable_var.h	(revision 7954)
@@ -0,0 +1,157 @@
+/*!
+ * @file synchronizeable_var.h
+ * @brief Definition of SynchronizeableVar
+*/
+
+#ifndef _SYNCHRONIZEABLE_VAR_H
+#define _SYNCHRONIZEABLE_VAR_H
+
+#include <string>
+#include "netdefs.h"
+#include <assert.h>
+
+enum {
+  PERMISSION_SERVER = 1,
+  PERMISSION_OWNER  = 2,
+  PERMISSION_ALL    = 4
+};
+
+class SynchronizeableVar {
+
+  public:
+    SynchronizeableVar( void * ptrIn, void * ptrOut, std::string name, int length, int permission = PERMISSION_SERVER, int priority = 0 );
+    virtual ~SynchronizeableVar();
+
+    /**
+     * check if synchronizeable wants to be informed on changes
+     * @return true if synchronizeable wants to be informed on changes
+     */
+    inline bool beWatched(){ return this->bWatched; }
+    
+    /** 
+     * set flag if synchronizeable wants to be informed on changes
+     */
+    inline void setWatched( bool watched ){ this->bWatched = watched; }
+
+    /**
+     * write var data to byte buffer
+     * @param buf pointer to write to
+     * @param maxLength writeToBuf will not write more than maxLength bytes
+     * @return number bytes written
+     */
+    virtual int writeToBuf( byte * buf, int maxLength ) = 0;
+
+    /**
+     * read var data from byte buffer
+     * @param buf pointer to read from
+     * @param maxLength readFromBuf will not read more than maxLength bytes
+     * @return number bytes read
+     */
+    virtual int readFromBuf( byte * buf, int maxLength ) = 0;
+
+    /**
+     * check if writeToBuf will return the same size every time
+     * @return true if same size every time
+     */
+    virtual bool hasStaticSize() = 0;
+
+    /**
+     * get size writeToBuf needs
+     * @return size in bytes
+     */
+    virtual int getSize(){ return length; }
+
+    /**
+     * check for permission to write
+     * @return true if you can write
+     */
+    inline bool checkPermission( int permission ){ return (permission & this->permission) != 0; }
+
+    /**
+     * get variable name
+     * @return name
+     */
+    inline std::string getName(){ return name; }
+
+    /**
+     * set variable name
+     * @param name new name
+     */
+    inline void setName( std::string name ) { this->name = name; }
+
+    /**
+     * get priority
+     * @return priority
+     */
+    inline int getPriority() { return this->priority; }
+
+    /**
+     * set priority
+     * @param p priority
+     */
+    inline void setPriority( int p ) { this->priority = p; }
+
+    /**
+     * reset priority to variable specific default value
+     */
+    inline void resetPriority() { this->priority = this->realPriority; }
+    
+    /**
+     * reads actual size from buffer. this is used when size is not constant
+     * @param buf pointer to data
+     * @param maxLength maximal size of data
+     * @return same as readFromBuf would return
+     */
+    virtual inline int getSizeFromBuf( byte * buf, int maxLength ){ return this->getSize(); }
+    
+    /**
+     * set variable id
+     * @param id
+     */
+    inline void setVarId( int id ){ this->varId = id; }
+    
+    /** 
+     * get variable id
+     * @return variable id
+     */
+    inline int getVarId(){ return varId; }
+    
+    /**
+     * set hasChanged
+     * @param changed
+     */
+    inline void setHasChanged( bool changed ){ this->changed = changed; }
+    
+    /** 
+     * get hasChanged
+     * @return variable id
+     */
+    inline bool getHasChanged(){ return changed; }
+    
+    /**
+     * print out variable value
+     */
+    virtual void debug() = 0;
+
+
+  private:
+    bool bWatched;      //!< true if synchronizeable wants to be informed on changes
+    
+    int permission;     //!< who is allowed to change this var
+    int priority;       //!< priority assigned to var
+    int realPriority;   //!< priority assigned to var, increased every time not sent
+    int varId;          //!< id to identify varables
+    
+    bool changed;       //!< true if last readFromBuf changed anything
+
+  protected:
+    void * ptrIn;       //!< pointer to data (read)
+    void * ptrOut;      //!< pointer to data (write)
+    int length;         //!< data length
+
+
+    std::string name;    //!< variable name (for debugging)
+
+};
+
+#endif /* _PROTO_CLASS_H */
Index: /trunk/src/lib/network/synchronizeable_var/synchronizeable_vector.cc
===================================================================
--- /trunk/src/lib/network/synchronizeable_var/synchronizeable_vector.cc	(revision 7954)
+++ /trunk/src/lib/network/synchronizeable_var/synchronizeable_vector.cc	(revision 7954)
@@ -0,0 +1,112 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+
+#include "synchronizeable_vector.h"
+#include "converter.h"
+
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+SynchronizeableVector::SynchronizeableVector( Vector * ptrIn, Vector * ptrOut, std::string name, int permission, int priority) : SynchronizeableVar( ptrIn, ptrOut, name, 3*FLOATSIZE, permission, priority )
+{
+  this->vPtrIn = ptrIn;
+  this->vPtrOut = ptrOut;
+}
+
+
+/**
+ * standard deconstructor
+*/
+SynchronizeableVector::~SynchronizeableVector ()
+{
+}
+
+/**
+ * write var data to byte buffer
+ * @param buf pointer to write to
+ * @param maxLength writeToBuf will not write more than maxLength bytes
+ * @return number bytes written
+ */
+int SynchronizeableVector::writeToBuf( byte * buf, int maxLength )
+{
+  int n = 0;
+  int res;
+
+  res = Converter::floatToByteArray( vPtrIn->x, buf + n, maxLength - n );
+  assert( res > 0 );
+  n += res;
+
+  res = Converter::floatToByteArray( vPtrIn->y, buf + n, maxLength - n );
+  assert( res > 0 );
+  n += res;
+
+  res = Converter::floatToByteArray( vPtrIn->z, buf + n, maxLength - n );
+  assert( res > 0 );
+  n += res;
+
+  assert( 3*FLOATSIZE == n );
+
+  return n;
+}
+
+/**
+ * read var data from byte buffer
+ * @param buf pointer to read from
+ * @param maxLength readFromBuf will not read more than maxLength bytes
+ * @return number bytes read
+ */
+int SynchronizeableVector::readFromBuf( byte * buf, int maxLength )
+{
+  assert( maxLength >= 3*FLOATSIZE );
+
+  float x,y,z;
+
+  int res;
+  int n = 0;
+  
+  Vector oldVec = *vPtrOut;
+
+  res = Converter::byteArrayToFloat( buf + n, &x );
+  assert( res > 0 );
+  n += res;
+
+  res = Converter::byteArrayToFloat( buf + n, &y );
+  assert( res > 0 );
+  n += res;
+
+  res = Converter::byteArrayToFloat( buf + n, &z );
+  assert( res > 0 );
+  n += res;
+
+  *vPtrOut = Vector( x, y, z );
+  
+  setHasChanged( !(*vPtrOut == oldVec) );
+
+  assert( n == 3*FLOATSIZE );
+  return n;
+}
+
+
+/**
+ * print out variable value
+ */
+void SynchronizeableVector::SynchronizeableVector::debug( )
+{
+  printf( "SYNCHRONIZEABLE_VAR: %s IN: (%f, %f, %f) OUT: (%f %f %f)\n", name.c_str(), vPtrIn->x, vPtrIn->y, vPtrIn->z, vPtrOut->x, vPtrOut->y, vPtrOut->z );
+}
+
Index: /trunk/src/lib/network/synchronizeable_var/synchronizeable_vector.h
===================================================================
--- /trunk/src/lib/network/synchronizeable_var/synchronizeable_vector.h	(revision 7954)
+++ /trunk/src/lib/network/synchronizeable_var/synchronizeable_vector.h	(revision 7954)
@@ -0,0 +1,36 @@
+/*!
+ * @file synchronizeable_vector.h
+ * @brief Definition of SynchronizeableVector
+*/
+
+#include "synchronizeable_var/synchronizeable_var.h"
+
+#ifndef _SYNCHRONIZEABLE_VECTOR_H
+#define _SYNCHRONIZEABLE_VECTOR_H
+
+#include "vector.h"
+
+class SynchronizeableVector : public SynchronizeableVar {
+
+  public:
+    SynchronizeableVector( Vector * ptrIn, Vector * ptrOut, std::string name, int permission = PERMISSION_SERVER, int priority = 0 );
+    virtual ~SynchronizeableVector();
+    
+    virtual int writeToBuf( byte * buf, int maxLength );
+    virtual int readFromBuf( byte * buf, int maxLength );
+    
+    /**
+     * check if writeToBuf will return the same size every time
+     * @return true if same size every time
+     */
+    virtual bool hasStaticSize(){ return true; }
+    
+    virtual void debug();
+    
+  private:
+    Vector * vPtrIn;       //!< pointer to data (read)
+    Vector * vPtrOut;      //!< pointer to data (write)
+
+};
+
+#endif /* _PROTO_CLASS_H */
Index: /trunk/src/lib/network/tcp_server_socket.cc
===================================================================
--- /trunk/src/lib/network/tcp_server_socket.cc	(revision 7954)
+++ /trunk/src/lib/network/tcp_server_socket.cc	(revision 7954)
@@ -0,0 +1,137 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer:
+*/
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+#include "tcp_server_socket.h"
+#include "tcp_socket.h"
+
+
+/* header for debug output */
+#include "debug.h"
+
+TcpServerSocket::TcpServerSocket( int port ) : ServerSocket( port )
+{
+  init();
+  listen(port);
+}
+
+/**
+ * Default destructor
+ */
+TcpServerSocket::~TcpServerSocket( )
+{
+  /* Quit SDL_net */
+  // NOTE: what if other instances of NetworkSocket running?
+  SDLNet_Quit();
+  PRINTF(5)("SDL_net shutdown\n");
+
+  _isListening = false;
+}
+
+void TcpServerSocket::init( )
+{
+  /* set the class id for the base object */
+  this->setClassID(CL_SERVER_SOCKET, "TcpServerSocket");
+
+  terminateThread = false;
+  listenSocket = NULL;
+  _isListening = false;
+
+  if(SDLNet_Init()==-1)
+  {
+    PRINTF(1)("SDLNet_Init: %s\n", SDLNet_GetError());
+    return;
+  }
+  else
+    PRINTF(5)("SDL_net initialized\n");
+
+  PRINTF(0)("TcpServerSocket created\n");
+}
+
+
+/**
+ * Tells the NetworkSocket to listen on a specific port for incoming connections.
+ * NetworkSocket::writeBytes(...) will have no effect until there is a valuable connection.
+ * @param port
+ */
+bool TcpServerSocket::listen(unsigned int port)
+{
+  PRINTF(0)("TcpServerSocket::listen()\n");
+  _isListening = true;
+  //check if not already connected or listening
+  if (listenSocket)
+  {
+    PRINTF(1)("TcpServerSocket::listen: tcpSocket!=NULL! maybe you already called listen or did not call close()!\n");
+    _isListening = false;
+    return false;
+  }
+
+  IPaddress ip;
+
+  if (SDLNet_ResolveHost(&ip, NULL, port)==-1)
+  {
+    PRINTF(1)("SDLNet_ResolveHost: %s\n", SDLNet_GetError());
+    _isListening = false;
+    return false;
+  }
+
+  listenSocket = SDLNet_TCP_Open(&ip);
+
+  if (!listenSocket)
+  {
+    PRINTF(1)("SDLNet_TCP_Open: %s\n", SDLNet_GetError());
+    _isListening = false;
+    return false;
+  }
+
+  return true;
+}
+
+
+NetworkSocket* TcpServerSocket::getNewSocket( )
+{
+  if ( !listenSocket )
+  {
+    PRINTF(1)("listenSocket == NULL! Maybe you forgot to call listen()\n");
+    close();
+    return NULL;
+  }
+
+  TCPsocket sock = SDLNet_TCP_Accept(listenSocket);
+
+  if ( !sock )
+  {
+    return NULL;
+  }
+  else
+  {
+    return new TcpSocket(sock);
+  }
+}
+
+void TcpServerSocket::close( )
+{
+  if ( listenSocket )
+  {
+    SDLNet_TCP_Close( listenSocket );
+    listenSocket = NULL;
+  }
+
+  _isListening = false;
+}
Index: /trunk/src/lib/network/tcp_server_socket.h
===================================================================
--- /trunk/src/lib/network/tcp_server_socket.h	(revision 7954)
+++ /trunk/src/lib/network/tcp_server_socket.h	(revision 7954)
@@ -0,0 +1,41 @@
+/*!
+ * @file server_socket.h
+ *  waits for incoming connections
+
+ */
+
+#ifndef _TCP_SERVER_SOCKET
+#define _TCP_SERVER_SOCKET
+
+/* include this file, it contains some default definitions */
+#include "netdefs.h"
+
+
+/* include base_object.h since all classes are derived from this one */
+#include "base_object.h"
+#include "server_socket.h"
+
+
+class TcpServerSocket : public ServerSocket
+{
+  public:
+    TcpServerSocket( int port );
+
+    virtual ~TcpServerSocket();
+
+    virtual bool listen( unsigned int port );
+    virtual NetworkSocket* getNewSocket( void );
+    virtual void close();
+    virtual void update() {};
+    
+  private:
+    TCPsocket listenSocket;
+    bool terminateThread;
+
+    bool _isListening;
+
+    void init();
+ 
+};
+
+#endif
Index: /trunk/src/lib/network/tcp_socket.cc
===================================================================
--- /trunk/src/lib/network/tcp_socket.cc	(revision 7954)
+++ /trunk/src/lib/network/tcp_socket.cc	(revision 7954)
@@ -0,0 +1,479 @@
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner, David Hasenfratz
+   co-programmer:
+*/
+
+
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+#include "converter.h"
+
+/* include your own header */
+#include "tcp_socket.h"
+
+/* header for debug output */
+#include "debug.h"
+
+/**
+ * Default constructor
+ */
+TcpSocket::TcpSocket()
+{
+  this->init();
+}
+
+/**
+ * Constructor to connect directly
+ */
+TcpSocket::TcpSocket( std::string host, int port )
+{
+  this->init();
+  connectToServer( host, port);
+}
+
+
+TcpSocket::TcpSocket( TCPsocket sock )
+{
+  this->init();
+  this->tcpSocket = sock;
+
+  readThread = SDL_CreateThread(thread_read, (void*)this);
+  writeThread = SDL_CreateThread(thread_write, (void*)this);
+}
+
+void TcpSocket::init()
+{
+  /* set the class id for the base object */
+  this->setClassID(CL_NETWORK_SOCKET, "TcpSocket");
+
+  tcpSocket = NULL;
+  incomingBufferLength = 0;
+  outgoingBufferLength = 0;
+
+  readThread = NULL;
+  writeThread = NULL;
+
+
+  thread_write_running = false;
+  thread_read_running = false;
+
+  incomingBufferMutex = SDL_CreateMutex();
+  outgoingBufferMutex = SDL_CreateMutex();
+
+
+  socketMutex = SDL_CreateMutex();
+  terminateThread = false;
+
+  /* Init SDL_net */
+  //NOTE: do we need to call SDLNet_Init for all instances?
+  if(SDLNet_Init()==-1)
+  {
+    PRINTF(1)("SDLNet_Init: %s\n", SDLNet_GetError());
+    return;
+  }
+  else
+    PRINTF(5)("SDL_net initialized\n");
+
+  PRINTF(0)("TcpSocket created\n");
+
+}
+
+
+
+/**
+ * Default destructor
+ * dont use this from outside: use destroy() instead!!
+ */
+TcpSocket::~TcpSocket( )
+{
+  this->terminateThread = true;
+  /* Quit SDL_net */
+  // NOTE: what if other instances of TcpSocket running?
+  SDLNet_Quit();
+  PRINTF(5)("SDL_net shutdown\n");
+
+  SDL_DestroyMutex(incomingBufferMutex);
+  SDL_DestroyMutex(outgoingBufferMutex);
+  SDL_DestroyMutex(socketMutex);
+  SDL_DestroyMutex(threadTerminationMutex);
+}
+
+/**
+ * This function establishes a TCP/UDP connection to a given server (function argument).
+ * It is called by the NetworkStream. It creates a TCP/UDP socket for the connection.
+ * @param ip
+ */
+void TcpSocket::connectToServer( std::string host, int port)
+{
+  IPaddress ip;
+  
+  bOk = true; 
+  
+  if ( SDLNet_ResolveHost( &ip, host.c_str(), port ) != 0 )
+  {
+    PRINTF(1)("could not resolve host %s\n", host.c_str() );
+    bOk = false;
+    return;
+  }
+  
+  //check if not already connected or listening
+  if (tcpSocket)
+  {
+    PRINTF(1)("TcpSocket::listen: tcpSocket!=NULL! maybe you already called listen or connectToServer or did not call disconnectServer()!");
+  }
+
+  /* Connect to the host and port contained in ip using a TCP connection. */
+  tcpSocket = SDLNet_TCP_Open(&ip);
+  if(!tcpSocket)
+  {
+    PRINTF(1)("SDLNet_TCP_Open: %s\n", SDLNet_GetError());
+    return;
+  }
+
+  readThread = SDL_CreateThread(thread_read, (void*)this);
+  writeThread = SDL_CreateThread(thread_write, (void*)this);
+}
+
+
+/**
+ * DTears down a TCP/UDP connection.
+ */
+void TcpSocket::disconnectServer( )
+{
+  terminateThread = true;
+  /* Close the connection */
+
+  SDL_mutexP(socketMutex);
+  SDLNet_TCP_Close(tcpSocket);
+  tcpSocket = NULL;
+  SDL_mutexV(socketMutex);
+}
+
+
+/**
+ * This function writes some bytes (data) to the network connection (if the connection is already
+ * estabilhed) otherwise it just does nothing (silently discarding the data). And writes some
+ * warnings
+ * @param data: pointer to the data to send
+ * @param length: n bytes to send
+ * @return the number successfully written bytes
+ */
+int TcpSocket::writeBytes(byte * data, int length)
+{
+  PRINTF(5)("TcpSocket::writeBytes()\n");
+#ifdef _USE_OUTGOING_BUFFER
+
+#define min(a,b) (a<b)?a:b
+  int nbytes = min(_OUTGOING_BUFFER_SIZE - outgoingBufferLength, length);
+#undef min
+
+  if (!tcpSocket || data==NULL || nbytes<=0)
+{
+  assert(_OUTGOING_BUFFER_SIZE - outgoingBufferLength > 0);
+  return 0;
+}
+
+  SDL_mutexP(outgoingBufferMutex);
+
+  memcpy(outgoingBuffer + outgoingBufferLength, data, nbytes);
+  outgoingBufferLength += nbytes;
+
+  SDL_mutexV(outgoingBufferMutex);
+
+
+  return nbytes;
+#else
+  SDL_mutexP(socketMutex);
+
+  if (!tcpSocket || data==NULL)
+    return 0;
+
+  int res = SDLNet_TCP_Send(tcpSocket, data, length);
+
+  SDL_mutexV(socketMutex);
+
+  if (res<length)
+    PRINTF(1)("SDLNet_TCP_Send: %s\n", SDLNet_GetError());
+
+  return res;
+#endif
+}
+
+/**
+ * Reads in the bytes from the network interface and passes it to the NetworkStream.
+ * This function must internaly be implemented/connected as a thread, since the read
+ * functions of many network libraries are blocking an would therefore block the whole
+ * program.
+ * From outside, the thread shouldn't be accessible at all.
+ * @param data: pointer to memory, big enough to store length bytes
+ * @param length: n bytes to read
+ * @return the number successfully read bytes. -1 on error. may be less than length!
+ */
+int TcpSocket::readBytes(byte * data, int length)
+{
+  PRINTF(5)("TcpSocket::readBytes()\n");
+  if (data==NULL)
+    return 0;
+
+  int nbytes = (length<incomingBufferLength) ? length : incomingBufferLength;
+
+
+  //printf("readBytes: nbytes = %d; length=%d; incomingBufferLength=%d\n", nbytes, length, incomingBufferLength);
+
+  // just in case ...
+  if (nbytes<0)
+    return -1;
+
+  if (nbytes==0)
+    return 0;
+
+  SDL_mutexP(incomingBufferMutex);
+
+  memcpy(data, incomingBuffer, nbytes);
+
+  //important: use memmove because the memory areas may overlap
+  memmove(incomingBuffer, incomingBuffer+nbytes, incomingBufferLength-nbytes);
+  incomingBufferLength -= nbytes;
+
+  SDL_mutexV(incomingBufferMutex);
+
+  return nbytes;
+}
+
+/**
+ * Reads in the bytes form the network interface and passes it to the NetworkStream.
+ * It only reads the bytes if there are enough bytes in our buffer.
+ * @param data: pointer to memory, big enough to store length bytes
+ * @param length: n bytes to read
+ * @return the number successfully read bytes. -1 on error. 0 if there are not enough bytes in our buffer.
+ */
+int TcpSocket::readBlock(byte * data, int length)
+{
+  printf("TcpSocket: got %i bytes, NetworkStream requested %i bytes\n", this->incomingBufferLength, length);
+  if (incomingBufferLength >= length)
+    return readBytes(data, length);
+  else return 0;
+}
+
+
+/**
+ * used to create a thread to read from socket
+ * @param data: pointer to TcpSocket
+ */
+int TcpSocket::thread_read( void * data )
+{
+  int nbytesread = 0;
+  int nbytestoread = 0;
+  char buffer[_LOCAL_BUFFER_SIZE];
+  TcpSocket * self = (TcpSocket*)data;
+
+  self->thread_read_running = true;
+
+  while (!self->terminateThread)
+  {
+#define min(a,b) (a<b)?a:b
+    nbytestoread = min(_INCOMING_BUFFER_SIZE - self->incomingBufferLength, _LOCAL_BUFFER_SIZE);
+#undef min
+
+    //if buffer is full
+    if (nbytestoread<=0 || !self->tcpSocket)
+{
+  SDL_Delay(_MSECONDS_SLEEP_FULL_BUFFER);
+  continue;
+}
+
+    nbytesread = SDLNet_TCP_Recv(self->tcpSocket, buffer, nbytestoread);
+
+    SDL_mutexP(self->incomingBufferMutex);
+
+    if (nbytesread<=0)
+{
+  if (nbytesread<0)
+    printf("SDLNet_TCP_Recv: %s\n", SDLNet_GetError());
+
+  SDL_mutexP(self->socketMutex);
+
+  SDLNet_TCP_Close(self->tcpSocket);
+  self->tcpSocket = NULL;
+
+  SDL_mutexV(self->socketMutex);
+  SDL_mutexV(self->incomingBufferMutex);
+  continue;
+}
+
+    //printf("thread_read: nbytesread=%d\n", nbytesread);
+
+    memcpy(self->incomingBuffer+self->incomingBufferLength, buffer, nbytesread);
+    self->incomingBufferLength += nbytesread;
+
+    SDL_mutexV(self->incomingBufferMutex);
+  }
+
+  SDL_mutexP(self->threadTerminationMutex);
+  self->thread_read_running = false;
+
+  if ( !self->thread_write_running )
+{
+    //delete self;
+  SDL_mutexV(self->threadTerminationMutex);
+}
+  else
+{
+  SDL_mutexV(self->threadTerminationMutex);
+}
+
+
+#ifdef DONTEXITTHREADS
+  while ( true )
+{
+  SDL_Delay(1000);
+}
+#endif
+  
+  PRINTF(0)("QUIT READ THREAD\n");
+  
+  return 0;
+}
+
+int TcpSocket::thread_write( void * data )
+{
+  int nbyteswrite = 0;
+  int nbytestowrite = 0;
+  char buffer[_LOCAL_BUFFER_SIZE];
+  TcpSocket * self = (TcpSocket*)data;
+
+  self->thread_write_running = true;
+
+  while (!self->terminateThread)
+  {
+#define min(a,b) (a<b)?a:b
+    nbytestowrite = min(self->outgoingBufferLength, _LOCAL_BUFFER_SIZE);
+#undef min
+
+//     printf("thread_write nbytes=%d listening=%d\n", nbytestowrite, (int)self->_isListening);
+
+    //if buffer is full
+    if (nbytestowrite<=0 || !self->tcpSocket)
+{
+  SDL_Delay(_MSECONDS_SLEEP_EMPTY_BUFFER);
+  continue;
+}
+
+    SDL_mutexP(self->outgoingBufferMutex);
+
+    //printf("a\n");
+
+    memcpy(buffer, self->outgoingBuffer, nbytestowrite);
+    self->outgoingBufferLength -= nbytestowrite;
+    memmove(self->outgoingBuffer, self->outgoingBuffer+nbytestowrite, self->outgoingBufferLength);
+
+    SDL_mutexV(self->outgoingBufferMutex);
+
+    nbyteswrite = SDLNet_TCP_Send(self->tcpSocket, buffer, nbytestowrite);
+
+    if (nbyteswrite<=0)
+{
+  printf("SDLNet_TCP_Recv: %s\n", SDLNet_GetError());
+
+  SDL_mutexP(self->socketMutex);
+
+  SDLNet_TCP_Close(self->tcpSocket);
+  self->tcpSocket = NULL;
+
+  SDL_mutexV(self->socketMutex);
+  continue;
+}
+
+  }
+
+  SDL_mutexP(self->threadTerminationMutex);
+  self->thread_write_running = false;
+
+  if ( !self->thread_read_running )
+{
+    //delete self;
+  SDL_mutexV(self->threadTerminationMutex);
+}
+  else
+{
+  SDL_mutexV(self->threadTerminationMutex);
+}
+
+#ifdef DONTEXITTHREADS
+  while ( true )
+{
+  SDL_Delay(1000);
+}
+#endif
+
+  PRINTF(0)("QUIT WRITE THREAD\n");
+
+  return 0;
+  
+}
+
+bool TcpSocket::writePacket( byte * data, int length )
+{
+  PRINTF(5)("TcpSocket::writePacket() size=%d\n", length);
+
+  if ( length > 1024 )
+    PRINTF(2)("WARNING SENDING BIG PACKET SIZE = %d\n", length);
+
+  byte blen[INTSIZE];
+
+  Converter::intToByteArray( length, blen, INTSIZE );
+
+  writeBytes(blen, INTSIZE);
+  writeBytes(data, length);
+}
+
+int TcpSocket::readPacket( byte * data, int maxLength )
+{
+  PRINTF(5)("TcpSocket::readPacket()\n");
+  if (incomingBufferLength<INTSIZE)
+  {
+    return 0;
+  }
+
+  int blen;
+  Converter::byteArrayToInt( incomingBuffer, &blen );
+
+  if (blen>maxLength)
+  {
+    PRINTF(1)("Buffersize is too small (%d) for packet (%d).\n", maxLength, blen);
+    assert(false);
+    return 0;
+  }
+
+  if (blen>incomingBufferLength)
+  {
+    return 0;
+  }
+
+  byte t[INTSIZE];
+  readBytes(t, INTSIZE);
+  int res = readBytes(data, blen);
+
+  if (res!=blen)
+    return -1;
+  else
+    return blen;
+
+}
+
+
Index: /trunk/src/lib/network/tcp_socket.h
===================================================================
--- /trunk/src/lib/network/tcp_socket.h	(revision 7954)
+++ /trunk/src/lib/network/tcp_socket.h	(revision 7954)
@@ -0,0 +1,97 @@
+/*!
+ * @file network_socket.h
+  *  Main interface for the network module. Manages all the modules
+
+*/
+
+#ifndef _TCP_SOCKET
+#define _TCP_SOCKET
+
+//TODO HACK else gdb will not work on server
+#define DONTEXITTHREADS
+
+//if you want to use outgoing buffer define _USE_OUTGOING_BUFFER
+#define _USE_OUTGOING_BUFFER
+
+#define _INCOMING_BUFFER_SIZE 2024000
+#define _OUTGOING_BUFFER_SIZE 2024000
+#define _LOCAL_BUFFER_SIZE 1024
+//sleep if incoming buffer is full
+#define _MSECONDS_SLEEP_FULL_BUFFER 10
+//sleep if outgoing buffer is empty
+#define _MSECONDS_SLEEP_EMPTY_BUFFER 10
+
+
+/* contains memmove and memcpy */
+#include <string.h>
+
+#ifdef HAVE_SDL_H
+#include <SDL_thread.h>
+#else
+#include <SDL/SDL_thread.h>
+#endif
+/* include this file, it contains some default definitions */
+#include "netdefs.h"
+
+
+/* include network_socket.h since all classes are derived from this one */
+#include "network_socket.h"
+
+class TcpSocket : public NetworkSocket
+{
+  public:
+    TcpSocket();
+    TcpSocket( std::string host, int port );
+    TcpSocket(TCPsocket sock);
+    virtual ~TcpSocket();
+
+    virtual void connectToServer( std::string host, int port );
+    
+    virtual void disconnectServer();
+
+    virtual bool writePacket(byte * data, int length);
+
+    virtual int readPacket(byte * data, int maxLength);
+
+  private:
+    TCPsocket tcpSocket;
+
+    byte incomingBuffer[_INCOMING_BUFFER_SIZE];
+#ifdef _USE_OUTGOING_BUFFER
+  byte outgoingBuffer[_OUTGOING_BUFFER_SIZE];
+#endif
+  int incomingBufferLength;
+#ifdef _USE_OUTGOING_BUFFER
+  int outgoingBufferLength;
+#endif
+
+  SDL_mutex * incomingBufferMutex;
+#ifdef _USE_OUTGOING_BUFFER
+  SDL_mutex * outgoingBufferMutex;
+#endif
+  SDL_mutex * socketMutex;
+  bool terminateThread;
+
+  SDL_mutex* threadTerminationMutex;
+  static int thread_read(void * data);
+  bool thread_read_running;
+  bool thread_write_running;
+
+  SDL_Thread*            readThread;
+  SDL_Thread*            writeThread;
+
+#ifdef _USE_OUTGOING_BUFFER
+  static int thread_write(void * data);
+#endif
+
+  int writeBytes(byte * data, int length);
+  int readBytes(byte * data, int length);
+  int readBlock(byte * data, int length);
+
+  void init();
+
+};
+
+
+
+#endif /* _NETWORK_SOCKET */
Index: /trunk/src/lib/network/udp_server_socket.cc
===================================================================
--- /trunk/src/lib/network/udp_server_socket.cc	(revision 7954)
+++ /trunk/src/lib/network/udp_server_socket.cc	(revision 7954)
@@ -0,0 +1,294 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer:
+*/
+
+#include "udp_server_socket.h"
+
+
+
+/**
+ * constructor
+ * @param port port to listen on 
+ */
+UdpServerSocket::UdpServerSocket( int port ) : ServerSocket( port )
+{
+  packet = SDLNet_AllocPacket( UDP_PACKET_SIZE );
+  
+  if ( !packet )
+  {
+    PRINTF(1)("SDLNet_AllocPacket: %s\n", SDLNet_GetError());
+    
+    assert( false );
+    bOk = false;
+  }
+  
+  memset( packet->data, 0, UDP_PACKET_SIZE );
+  
+  listen( port );
+}
+
+/**
+ * default destructor
+ */
+UdpServerSocket::~UdpServerSocket( )
+{
+  for ( int i = 0; i < packetBuffer.size(); i++ )
+    removeUserPackets( i );
+  
+  if ( packet )
+    SDLNet_FreePacket( packet );
+  
+  if ( socket )
+    SDLNet_UDP_Close( socket );
+}
+
+/**
+ * tell udpServerSocket to recieve packets on port
+ * @param port port
+ * @return true on success
+ */
+bool UdpServerSocket::listen( unsigned int port )
+{
+  socket = SDLNet_UDP_Open( port );
+  
+  PRINTF(0)("listening on port: %d\n", port);
+  
+  if ( !socket )
+  {
+    
+    bOk = false;
+    return false;
+  }
+  
+  return true;
+}
+
+/**
+ * get newly connected socket. note
+ * @return new socket or NULL if no new socket exists
+ */
+NetworkSocket * UdpServerSocket::getNewSocket( void )
+{
+  NetworkSocket * result = NULL;
+  
+  if ( newSocketList.size() > 0 )
+  {
+    result = newSocketList.front();
+  
+    newSocketList.pop_front();
+  }
+  
+  return result;
+}
+
+/**
+ * stop listening on server
+ */
+void UdpServerSocket::close( )
+{
+  
+  for ( int i = 0; i < packetBuffer.size(); i++ )
+    removeUserPackets( i );
+  
+  packetBuffer.clear();
+  userList.clear();
+  
+  SDLNet_UDP_Close( socket );
+  socket = NULL;
+}
+
+/**
+ * clean up users buffer
+ * @param userId users userid
+ */
+void UdpServerSocket::removeUserPackets( int userId )
+{
+  if ( userId >= packetBuffer.size() )
+    return;
+  
+  for ( NetworkPacketList::iterator it = packetBuffer[userId].begin(); it!=packetBuffer[userId].end(); it++ )
+  {
+    if ( it->data )
+    {
+      free( it->data );
+      it->data = NULL;
+    }
+  }
+  
+  packetBuffer[userId].clear();
+}
+
+/**
+ * get next packet for user
+ * @param userId user id
+ * @return recieved packet or packet with length 0 if no packet available
+ */
+NetworkPacket UdpServerSocket::getPacket( int userId )
+{
+  NetworkPacket res;
+  res.data = NULL;
+  res.length = 0;
+  
+  if ( packetBuffer.size() > userId && packetBuffer[userId].size() > 0 )
+  {
+    res.data = packetBuffer[userId].front().data;
+    res.length = packetBuffer[userId].front().length;
+    packetBuffer[userId].pop_front();
+  }
+  
+  return res;
+}
+
+/**
+ * get number of packets recieved for user
+ * @param userId user id
+ * @return number of packets in buffer
+ */
+int UdpServerSocket::getPacketCount( int userId )
+{
+  if ( userId >= packetBuffer.size() )
+    return -1;
+  
+  return packetBuffer[userId].size();
+}
+
+/**
+ * will set user state 
+ * @param userId users id
+ * @param ip users host / port
+ */
+void UdpServerSocket::initUser( int userId, IPaddress ip )
+{
+  int channel = SDLNet_UDP_Bind( socket, userId, &ip );
+  if( channel != userId ) 
+  {
+    PRINTF(1)("SDLNet_UDP_Bind: %s\n", SDLNet_GetError());
+    assert(false);
+    return;
+  }
+  
+  if ( userId < packetBuffer.size() )
+    removeUserPackets( userId );
+  
+  if ( packetBuffer.size() <= userId )
+    packetBuffer.resize( userId + 1 );
+  
+  if ( userList.size() <= userId )
+    userList.resize( userId + 1 );
+  
+  userList[ userId ] = ip;
+}
+
+/**
+ * remove user from list
+ * @param userId user id
+ */
+void UdpServerSocket::removeUser( int userId )
+{
+  removeUserPackets( userId );
+  
+  if ( userId >= userList.size() )
+    return;
+  
+  userList[userId].host = 0;
+  userList[userId].port = 0;
+  
+  SDLNet_UDP_Unbind( socket, userId );
+}
+
+/**
+ * send one packet to client associated to userId
+ * @param networkPacket packet to send
+ * @param userId users id
+ * @return true on success
+ */
+bool UdpServerSocket::sendPacket( NetworkPacket networkPacket , int userId )
+{
+  assert( networkPacket.length <= UDP_PACKET_SIZE );
+  
+  memcpy( packet->data, networkPacket.data, networkPacket.length );
+  packet->len = networkPacket.length;
+  packet->channel = -1;
+  
+  if ( SDLNet_UDP_Send( socket, userId, packet ) == 0 )
+  {
+    PRINTF(1)("SDLNet_UDP_Send: %s\n", SDLNet_GetError());
+    return false;
+  }
+  
+  return true;
+}
+
+/**
+ * do periodically things
+ */
+void UdpServerSocket::update( )
+{
+  int res;
+  int newConn = 0;
+  
+  for ( res = SDLNet_UDP_Recv( socket, packet ); res == 1; res = SDLNet_UDP_Recv( socket, packet ) )
+  {
+    int userId;
+    bool isNewConnection = false;
+    
+    for ( userId =0; userId < userList.size(); userId++ )
+      if ( userList[userId].host == packet->address.host && userList[userId].port == packet->address.port )
+        break;
+    
+    if ( userId >= userList.size() )
+    {
+      
+      newConn++;
+      isNewConnection = true;
+      
+      if ( newConn > MAX_NEW_CONNECTIONS )
+      {
+        PRINTF(2)("Too many new connections. Dropping packet\n");
+        continue;
+      }
+      
+      for ( userId =0; userId < userList.size(); userId++ )
+        if ( userList[userId].host == 0 && userList[userId].port == 0 )
+          break;
+      
+      initUser( userId, packet->address );
+      UdpSocket * sock = new UdpSocket( this, packet->address, userId );
+      newSocketList.push_back( sock );
+      PRINTF(0)("NEW CONNECTION %x\n", packet->address.host );
+    }
+    
+    //add new packet to packetbuffer
+
+    NetworkPacket networkPacket;
+    networkPacket.length = packet->len;
+    if ( packet->len != 0 )
+    {
+      networkPacket.data = (byte*)malloc( packet->len );
+      assert( networkPacket.data );
+    }
+    else
+    {
+      if ( isNewConnection )
+        continue;
+      
+      networkPacket.data = NULL;
+    }
+    memcpy( networkPacket.data, packet->data, packet->len );
+    packetBuffer[userId].push_back( networkPacket );
+
+  }
+  
+  assert( res == 0 );
+}
Index: /trunk/src/lib/network/udp_server_socket.h
===================================================================
--- /trunk/src/lib/network/udp_server_socket.h	(revision 7954)
+++ /trunk/src/lib/network/udp_server_socket.h	(revision 7954)
@@ -0,0 +1,70 @@
+/*!
+ * @file udp_server_socket.h
+ *  waits for incoming connections
+
+ */
+
+#ifndef _UDP_SERVER_SOCKET
+#define _UDP_SERVER_SOCKET
+
+/* include this file, it contains some default definitions */
+#include "netdefs.h"
+
+
+/* include base_object.h since all classes are derived from this one */
+#include "base_object.h"
+#include "server_socket.h"
+#include "udp_socket.h"
+
+#include <list>
+#include <vector>
+
+#define UDP_PACKET_SIZE 10240
+#define MAX_NEW_CONNECTIONS 8
+
+struct NetworkPacket
+{
+  int length;
+  byte * data;
+};
+
+typedef std::list<NetworkPacket> NetworkPacketList;
+
+typedef std::vector<NetworkPacketList> PacketBuffer;
+
+typedef std::vector<IPaddress> UserList;
+
+typedef std::list<UdpSocket*> UdpSocketList;
+
+class UdpServerSocket : public ServerSocket
+{
+  public:
+    UdpServerSocket( int port);
+
+    virtual ~UdpServerSocket();
+
+    virtual bool listen( unsigned int port );
+    
+    virtual NetworkSocket* getNewSocket( void );
+    
+    virtual void close();
+    
+    virtual void update();
+    
+    void removeUserPackets( int userId );
+    void removeUser( int userId );
+    NetworkPacket getPacket( int userId );
+    bool sendPacket( NetworkPacket networkPacket, int userId );
+    int getPacketCount( int childId );
+    void initUser( int childId, IPaddress ip );
+    
+  private:
+    UDPsocket     socket;           //!< will be uses to send/recieve data
+    UDPpacket *   packet;           //!< packet structure to recieve packet
+    PacketBuffer  packetBuffer;     //!< will store recieved packets for UdpSockets
+    UserList      userList;         //!< contains information about clients
+    UdpSocketList newSocketList;    //!< contains new socket
+
+};
+
+#endif
Index: /trunk/src/lib/network/udp_socket.cc
===================================================================
--- /trunk/src/lib/network/udp_socket.cc	(revision 7954)
+++ /trunk/src/lib/network/udp_socket.cc	(revision 7954)
@@ -0,0 +1,239 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer:
+*/
+
+#include "udp_socket.h"
+#include "udp_server_socket.h"
+
+
+void UdpSocket::init( )
+{
+  //TODO setClassId
+  this->serverSocket = NULL;
+  this->socket = NULL;
+  this->packet = NULL;
+}
+
+
+/**
+ * constructor - connects to give host
+ * @param host host
+ * @param port port
+ */
+UdpSocket::UdpSocket( std::string host, int port )
+{
+  init();
+  this->packet = SDLNet_AllocPacket( UDP_PACKET_SIZE );
+  
+  assert( this->packet );
+  
+  memset( packet->data, 0, UDP_PACKET_SIZE );
+  PRINTF(0)("PACKET DATA: %x\n", packet->data);
+  
+  this->connectToServer( host, port );
+}
+
+/**
+ * default constructor. use this one if you want to call connecttoServer
+ */
+UdpSocket::UdpSocket( )
+{
+  this->init();
+  this->packet = SDLNet_AllocPacket( UDP_PACKET_SIZE );
+  
+  if ( !packet )
+  {
+    PRINTF(1)("SDLNet_AllocPacket: %s\n", SDLNet_GetError());
+    
+    assert( false );
+    bOk = false;
+  }
+  
+}
+
+/**
+ * constructor. used by UdpServerSocket
+ * @param serverSocket pointer to serverSocket
+ * @param ip client's ip address
+ * @param userId userid used by serverSocket
+ */
+UdpSocket::UdpSocket( UdpServerSocket * serverSocket, IPaddress ip, int userId )
+{
+  this->init();
+  this->serverSocket = serverSocket;
+  this->userId = userId;
+}
+
+/**
+ * destructor
+ */
+UdpSocket::~UdpSocket( )
+{
+  if ( serverSocket )
+    serverSocket->removeUser( userId );
+  
+  disconnectServer();
+  
+  if ( this->packet )
+    SDLNet_FreePacket( this->packet );
+  
+  if ( socket )
+    SDLNet_UDP_Close( socket );
+}
+
+/**
+ * connect to server
+ * @param host host name
+ * @param port port number
+ */
+void UdpSocket::connectToServer( std::string host, int port )
+{
+  assert( serverSocket == NULL );
+  
+  IPaddress ip;
+  
+  PRINTF(0)("connect to server %s on port %d\n", host.c_str(), port);
+  
+  if ( SDLNet_ResolveHost( &ip, host.c_str(), port ) != 0 )
+  {
+    PRINTF(1)("SDLNet_ResolveHost: %s\n", SDLNet_GetError() );
+    bOk = false;
+    return;
+  }
+  
+  socket = SDLNet_UDP_Open(0);
+  if ( !socket )
+  {
+    PRINTF(1)("SDLNet_UDP_Open: %s\n", SDLNet_GetError() );
+    bOk = false;
+    return;
+  }
+  
+  int channel = SDLNet_UDP_Bind(socket, 1, &ip);
+  if ( channel == -1 ) 
+  {
+    PRINTF(1)("SDLNet_UDP_Bind: %s\n", SDLNet_GetError());
+    bOk = false;
+    return;
+  }
+  
+  writePacket( NULL, 0 );
+}
+
+/**
+ * disconnect from server
+ */
+void UdpSocket::disconnectServer( )
+{
+  SDLNet_UDP_Unbind( socket, -1 );
+  SDLNet_UDP_Close( socket );
+  bOk = false;
+  socket = NULL;
+}
+
+/**
+ * send one packet to other host
+ * @param data pointer to data which will be sent
+ * @param length length of data
+ * @return true on success
+ */
+bool UdpSocket::writePacket( byte * data, int length )
+{
+  if ( serverSocket )
+  {
+    NetworkPacket networkPacket;
+    networkPacket.length = length;
+    networkPacket.data = data;
+    if ( !serverSocket->sendPacket( networkPacket, this->userId ) )
+    {
+      bOk = false;
+      return false;
+    }
+    else
+      return true;
+  }
+  else
+  {
+    assert( length <= packet->maxlen );
+    
+    memcpy( packet->data, data, length );
+    packet->len = length;
+    
+    if ( SDLNet_UDP_Send( socket, 1, packet) == 0 )
+    {
+      PRINTF(1)("SDLNet_UDP_Send: %s\n", SDLNet_GetError());
+      bOk = false;
+      return false;
+    }
+    
+    return true;
+  }
+}
+
+/**
+ * recieve one packet from another host
+ * @param data pointer to buffer to copy data into
+ * @param maxLength maximal length of buffer
+ * @return less than 0 on error, number bytes read else
+ */
+int UdpSocket::readPacket( byte * data, int maxLength )
+{
+  assert( maxLength <= UDP_PACKET_SIZE );
+  
+  if ( serverSocket )
+  {
+    NetworkPacket networkPacket = serverSocket->getPacket( this->userId );
+    
+    if ( networkPacket.length > 0 )
+    {
+      assert( maxLength > networkPacket.length );
+      
+      memcpy( data, networkPacket.data, networkPacket.length );
+    }
+    
+    if ( networkPacket.data )
+    {
+      free( networkPacket.data );
+      networkPacket.data = NULL;
+    }
+    
+    return networkPacket.length;
+  }
+  else
+  {
+    int numrecv = SDLNet_UDP_Recv( socket, packet);
+    if ( numrecv > 0) 
+    {
+      assert( packet->len <= maxLength );
+      
+      memcpy( data, packet->data, packet->len );
+      return packet->len;
+    }
+    else if ( numrecv < 0 )
+    {
+      PRINTF(1)("SDLNet_UDP_Recv: %s\n", SDLNet_GetError());
+      bOk = false;
+      return -1;
+    }
+    else
+    {
+      return 0;
+    }
+  }
+  
+  return 0;
+}
+
+
+
Index: /trunk/src/lib/network/udp_socket.h
===================================================================
--- /trunk/src/lib/network/udp_socket.h	(revision 7954)
+++ /trunk/src/lib/network/udp_socket.h	(revision 7954)
@@ -0,0 +1,47 @@
+/*!
+ * @file upd_socket.h
+ *  class to connect to other clients via udp
+ */
+
+#ifndef _UDP_SOCKET
+#define _UDP_SOCKET
+
+/* include this file, it contains some default definitions */
+#include "netdefs.h"
+
+
+/* include base_object.h since all classes are derived from this one */
+#include "network_socket.h"
+
+class UdpServerSocket;
+
+class UdpSocket : public NetworkSocket
+{
+  public:
+    UdpSocket();
+    UdpSocket( UdpServerSocket * serverSocket, IPaddress ip, int userId );
+    UdpSocket( std::string host, int port );
+    virtual ~UdpSocket();
+
+    virtual void connectToServer( std::string host, int port );
+    
+    virtual void disconnectServer();
+
+    virtual bool writePacket(byte * data, int length);
+
+    virtual int readPacket(byte * data, int maxLength);
+    
+  private:
+    UdpServerSocket * serverSocket;   //!< will get packets here
+    int               userId;         //!< user id used by serverSocket
+    IPaddress         ip;             //!< host,port
+    UDPsocket         socket;         //!< socket used to send/recieve
+    UDPpacket *       packet;
+    
+    void init();
+
+};
+
+
+
+#endif /* _NETWORK_SOCKET */
Index: /trunk/src/lib/network/zip.cc
===================================================================
--- /trunk/src/lib/network/zip.cc	(revision 7954)
+++ /trunk/src/lib/network/zip.cc	(revision 7954)
@@ -0,0 +1,253 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+#include "zip.h"
+
+#include "src/lib/util/loading/resource_manager.h"
+
+/**
+ *  the singleton reference to this class
+ */
+Zip* Zip::singletonRef = NULL;
+
+
+/**
+ * standard constructor
+ */
+Zip::Zip()
+{
+
+}
+
+
+/**
+ * @brief standard deconstructor
+ */
+Zip::~Zip()
+{
+  Zip::singletonRef = NULL;
+}
+
+/**
+ * load a dictionary to unzip. you can load more than one dictionary
+ * if you call unzip with data from zip without loading the same dictionary
+ * used with zip unzip will fail
+ * @param name name of dictionary
+ * @return true on success
+ */
+bool Zip::loadDictionary( std::string name )
+{
+  std::string fileName = ResourceManager::getInstance()->getDataDir();
+  //PRINTF(0)("datadir: %s\n", fileName.c_str());
+  fileName = fileName + "/dicts/" + name;
+  //PRINTF(0)("filename: %s\n", fileName.c_str());
+  
+  FILE * f = fopen( fileName.c_str(), "r" );
+  
+  if ( !f )
+  {
+    PRINTF(1)("Could not open %d\n", fileName.c_str());
+    return false;
+  }
+  
+  byte buf[1024];
+  
+  int nBytesRead = 0;
+  
+  while ( !feof( f ) )
+  {
+    nBytesRead += fread( buf, 1, sizeof(buf), f );
+  }
+  
+  DictionaryEntry entry;
+  
+  entry.dictLen = nBytesRead;
+  entry.dict = new Byte[nBytesRead];
+  
+  fseek( f, 0, SEEK_SET );
+  
+  assert( fread( entry.dict, 1, nBytesRead, f ) == nBytesRead );
+  
+  entry.adler = adler32( adler32( 0L, Z_NULL, 0 ), entry.dict, nBytesRead );
+  
+  dicts.push_back( entry );
+  
+  PRINTF(3)("Loaded dictionary '%s' with adler = %d\n", name.c_str(), entry.adler );
+  
+  return true;
+}
+
+/**
+ * zip data. you must call loadDictionary before
+ * @param from data to compress
+ * @param fromLength length of data to compress
+ * @param to pointer to compressed data
+ * @param maxLength max bytes to compress
+ * @param dict dictionary to use. default is 0
+ * @return num bytes writen to to
+ */
+int Zip::zip( byte * from, int fromLength, byte * to, int maxLength, int dict )
+{
+  if ( dicts.size() < dict+1 )
+  {
+    PRINTF(1)("you cannot use dict nr %d. num dicts: %d\n", dict, dicts.size() );
+    return -1;
+  }
+  
+  int res;
+
+  z_stream strm;
+
+  strm.zalloc = Z_NULL;
+  strm.zfree = Z_NULL;
+  strm.opaque = Z_NULL;
+
+  res = deflateInit( &strm, 9 );
+
+  if ( res != Z_OK )
+  {
+    PRINTF(1)("deflateInit error: %s\n", strm.msg);
+    return -1;
+  }
+
+  res = deflateSetDictionary( &strm, (Bytef*)(dicts[dict].dict), dicts[dict].dictLen );
+	
+  if ( res != Z_OK )
+  {
+    PRINTF(1)("deflateSetDictionary error: %s\n", strm.msg);
+    return -1;
+  }
+
+  strm.next_out = (Bytef*)to;
+  strm.avail_out = maxLength;
+  assert( strm.total_out == 0 );
+  strm.next_in = (Bytef*)from;
+  strm.avail_in = fromLength;
+  assert( strm.total_in == 0 );
+
+  res = deflate( &strm, Z_FINISH );
+	
+  if ( res != Z_STREAM_END )
+  {
+    PRINTF(1)("buffer to small or deflate error: %s\n", strm.msg);
+    return -1;
+  }
+
+  assert( strm.avail_out != 0 );
+  assert( strm.avail_in == 0 );
+
+  int zippedlen = strm.total_out;
+
+  res = deflateEnd( &strm );
+	
+  if ( res != Z_OK )
+  {
+    if ( res == Z_STREAM_ERROR )
+      PRINTF(1)("deflateEnd error: Z_STREAM_ERROR\n");
+    else if ( res == Z_DATA_ERROR )
+      PRINTF(1)("deflateEnd error: Z_DATA_ERROR %s\n", strm.msg);
+    else
+      PRINTF(1)("deflateEnd error: dont know\n");
+    
+    return -1;
+  }
+  
+  return zippedlen;
+
+}
+
+/**
+ * uncompress data. same dict as used in zip must be loaded
+ * @param from compressed data
+ * @param fromLength length of compressed data
+ * @param to buffer to copy uncompressed data to
+ * @param maxLength max bytes to copy to to
+ * @return num bytes writen to to
+ */
+int Zip::unZip( byte * from, int fromLength, byte * to, int maxLength )
+{
+  z_stream strm;
+  int res = 0;
+  
+  strm.zalloc = Z_NULL;
+  strm.zfree = Z_NULL;
+  strm.opaque = Z_NULL;
+
+  res = inflateInit( &strm );
+
+  if ( res != Z_OK )
+  {
+    PRINTF(1)("inflateInit error: %s\n", strm.msg);
+    return -1;
+  }
+	
+  strm.next_out = (Bytef*)to;
+  strm.avail_out = maxLength;
+  assert( strm.total_out == 0 );
+  strm.next_in = (Bytef*)from;
+  strm.avail_in = fromLength;
+  assert( strm.total_in == 0 );
+
+  assert( inflate( &strm, Z_NO_FLUSH ) == Z_NEED_DICT );
+	
+  int dictId = -1;
+  
+  for ( int i = 0; i < dicts.size(); i++ )
+  {
+    if ( dicts[i].adler == strm.adler )
+    {
+      dictId = i;
+      break;
+    }
+  }
+  
+  if ( dictId == -1 )
+  {
+    PRINTF(1)("Could not find dict used to compress this packet! ( adler = %d )\n", strm.adler);
+    return -1;
+  }
+      
+  res = inflateSetDictionary( &strm, (Bytef*)dicts[dictId].dict, dicts[dictId].dictLen );
+	
+  if ( res != Z_OK )
+  {
+    PRINTF(1)("inflateSetDictionary error: %s\n", strm.msg);
+    return -1;
+  }
+
+
+  res = inflate( &strm, Z_FINISH );
+	
+  if ( res != Z_STREAM_END )
+  {
+    PRINTF(1)("inflate error: %s\n", strm.msg);
+    return -1;
+  }
+
+  assert( strm.avail_out != 0 );
+  assert( strm.avail_in == 0 );
+
+  int unzippedlen = strm.total_out;
+
+  res = inflateEnd( &strm );
+	
+  if ( res != Z_OK )
+  {
+    PRINTF(1)("inflateEnd error: %s\n", strm.msg);
+    return -1;
+  }
+  
+  return unzippedlen;
+}
Index: /trunk/src/lib/network/zip.h
===================================================================
--- /trunk/src/lib/network/zip.h	(revision 7954)
+++ /trunk/src/lib/network/zip.h	(revision 7954)
@@ -0,0 +1,43 @@
+/*!
+ * @file zip.h
+ * @brief Definition of the Zip singleton Class
+ */
+
+#ifndef _ZIP_H
+#define _ZIP_H
+
+#include <zlib.h>
+#include <string>
+#include <vector>
+
+#include "netdefs.h"
+
+struct DictionaryEntry
+{
+  byte * dict;
+  int    dictLen;
+  uLong  adler;
+};
+
+//! A class for compressing/uncompressing packes.
+class Zip 
+{
+  public:
+    virtual ~Zip(void);
+    /** @returns a Pointer to the only object of this Class */
+    inline static Zip* getInstance(void) { if (!singletonRef) singletonRef = new Zip();  return singletonRef; };
+    
+    bool loadDictionary( std::string name );
+    int zip( byte * from, int fromLength, byte * to, int maxLength, int dict = 0 );
+    int unZip( byte * from, int fromLength, byte * to, int maxLength );
+    
+    int getDictCount(){ return dicts.size(); }
+
+  private:
+    Zip();
+    static Zip* singletonRef;
+    
+    std::vector<DictionaryEntry> dicts;
+};
+
+#endif /* _PROTO_SINGLETON_H */
Index: /trunk/src/orxonox.cc
===================================================================
--- /trunk/src/orxonox.cc	(revision 7953)
+++ /trunk/src/orxonox.cc	(revision 7954)
@@ -91,4 +91,8 @@
 REGISTER_ARG_FLAG( _, write_bt_to_file, "misc", "bt-to-file", "Write backtrace to file", "1");
 #endif
+
+REGISTER_ARG_ARG(  t, telnetport,  "network","telnetport",        "Port to use for network debug output",               "port" );
+REGISTER_ARG_ARG(  _, write_dict,  "compression", "writedict",    "write packets to DATA/dicts/newdict",               "numBytes" );
+
 
 /**
Index: /trunk/src/story_entities/multi_player_world.cc
===================================================================
--- /trunk/src/story_entities/multi_player_world.cc	(revision 7953)
+++ /trunk/src/story_entities/multi_player_world.cc	(revision 7954)
@@ -81,5 +81,5 @@
 void MultiPlayerWorld::synchronize()
 {
-  NetworkManager::getInstance()->synchronize();
+  NetworkManager::getInstance()->synchronize(this->dtS);
 }
 
Index: /trunk/src/story_entities/multi_player_world_data.cc
===================================================================
--- /trunk/src/story_entities/multi_player_world_data.cc	(revision 7953)
+++ /trunk/src/story_entities/multi_player_world_data.cc	(revision 7954)
@@ -226,4 +226,21 @@
     PNode::getNullParent()->init();
   }
+    // Fill the EntityLists. Tick then Draw:
+  this->tickLists.push_back(OM_DEAD_TICK);
+  this->tickLists.push_back(OM_ENVIRON);
+  this->tickLists.push_back(OM_COMMON);
+  this->tickLists.push_back(OM_GROUP_00);
+  this->tickLists.push_back(OM_GROUP_00_PROJ);
+  this->tickLists.push_back(OM_GROUP_01);
+  this->tickLists.push_back(OM_GROUP_01_PROJ);
+
+  this->drawLists.push_back(OM_ENVIRON_NOTICK);
+  this->drawLists.push_back(OM_ENVIRON);
+  this->drawLists.push_back(OM_COMMON);
+  this->drawLists.push_back(OM_GROUP_00);
+  this->drawLists.push_back(OM_GROUP_00_PROJ);
+  this->drawLists.push_back(OM_GROUP_01);
+  this->drawLists.push_back(OM_GROUP_01_PROJ);
+  
   State::setPlayer(this->localPlayer);
 }
Index: /trunk/src/subprojects/network/Makefile.am
===================================================================
--- /trunk/src/subprojects/network/Makefile.am	(revision 7953)
+++ /trunk/src/subprojects/network/Makefile.am	(revision 7954)
@@ -1,16 +1,21 @@
 MAINSRCDIR=../..
 include $(MAINSRCDIR)/defs/include_paths.am
+
+LIB_PREFIX=$(MAINSRCDIR)/lib
+include $(MAINSRCDIR)/lib/BuildLibs.am
+
 
 bin_PROGRAMS = network
 
 
-network_CPPFLAGS = -DNO_SHELL -DNO_SHELL_COMMAND
+network_CPPFLAGS = 
+#-DNO_SHELL -DNO_SHELL_COMMAND
 
-DEPENDENCIES = \
+network_DEPENDENCIES = \
 		$(MAINSRCDIR)/world_entities/libORXwe.a \
 		$(libORXlibs_a_LIBRARIES_) \
 		$(MAINSRCDIR)/util/libORXutils.a
 
-LDADD = \
+network_LDADD = \
 		$(MAINSRCDIR)/util/libORXutils.a \
 		$(libORXlibs_a_LIBRARIES_) \
Index: /trunk/src/subprojects/network/network_unit_test.cc
===================================================================
--- /trunk/src/subprojects/network/network_unit_test.cc	(revision 7953)
+++ /trunk/src/subprojects/network/network_unit_test.cc	(revision 7954)
@@ -9,7 +9,13 @@
 #include "network_socket.h"
 #include "server_socket.h"
+#include "udp_server_socket.h"
+#include "udp_socket.h"
 #include "network_stream.h"
 #include "synchronizeable.h"
 #include "converter.h"
+#include "state.h"
+#include "shared_network_data.h"
+#include "message_manager.h"
+#include "network_log.h"
 
 #include "simple_sync.h"
@@ -36,16 +42,25 @@
 int testSocket(int argc, char** argv)
 {
-  IPaddress ip;
-  SDLNet_ResolveHost(&ip, "127.0.0.1", 9999);
-  ServerSocket server;
-  server.listen(9999);
-
-  NetworkSocket* client1 = new NetworkSocket(ip);
-
-  NetworkSocket* server1 = server.getNewSocket();
-
-  NetworkSocket* client2 = new NetworkSocket(ip);
-
-  NetworkSocket* server2 = server.getNewSocket();
+  UdpServerSocket server(9999);
+
+  NetworkSocket* client1 = new UdpSocket("localhost", 9999);
+
+  NetworkSocket* server1 = NULL;
+  while ( server1 == NULL )
+  {
+    server.update();
+    server1 = server.getNewSocket();
+  }
+  
+  assert( server1->isOk() );
+
+  NetworkSocket* client2 = new UdpSocket("localhost", 9999);
+
+  NetworkSocket* server2 = NULL;
+  while ( server2 == NULL )
+  {
+    server.update();
+    server2 = server.getNewSocket();
+  }
 
   char buf[1024];
@@ -70,5 +85,7 @@
   n = server2->writePacket((byte*)str4, strlen(str4)+1);
   printf("%d bytes send from server2\n", n);
-  SDL_Delay(1000);
+  SDL_Delay(10);
+  
+  server.update();
 
   printf("read from server1\n");
@@ -103,7 +120,53 @@
 
   printf("data: '%s'\n", buf);
+  
+  
+  //22222222222222222222222222222222222222222
+  n = client1->writePacket((byte*)str1, strlen(str1)+1);
+  printf("%d bytes send from client1\n", n);
+  n = server1->writePacket((byte*)str2, strlen(str2)+1);
+  printf("%d bytes send from server1\n", n);
+  n = client2->writePacket((byte*)str3, strlen(str3)+1);
+  printf("%d bytes send from client2\n", n);
+  n = server2->writePacket((byte*)str4, strlen(str4)+1);
+  printf("%d bytes send from server2\n", n);
+  SDL_Delay(10);
+  
+  server.update();
+
+  printf("read from server1\n");
+  n = server1->readPacket((byte*)buf, 1024);
+  printf("read %d bytes\n", n);
+  if (n<0)
+    return -1;
+
+  printf("data: '%s'\n", buf);
+
+  printf("read from server2\n");
+  n = server2->readPacket((byte*)buf, 1024);
+  printf("read %d bytes\n", n);
+  if (n<0)
+    return -1;
+
+  printf("data: '%s'\n", buf);
+
+  printf("read from client1\n");
+  n = client1->readPacket((byte*)buf, 1024);
+  printf("read %d bytes\n", n);
+  if (n<0)
+    return -1;
+
+  printf("data: '%s'\n", buf);
+
+  printf("read from client2\n");
+  n = client2->readPacket((byte*)buf, 1024);
+  printf("read %d bytes\n", n);
+  if (n<0)
+    return -1;
+
+  printf("data: '%s'\n", buf);
 
   //sending bigger packets than 255 is not supported
-
+#if 0
   printf("try to send more than 255 bytes\n");
   printf("result: %d\n", client1->writePacket((byte*)buf, 1000));
@@ -113,5 +176,11 @@
   printf("try to read with a too small buffer\n");
   printf("result: %d\n", client1->readPacket((byte*)buf, strlen(str1)));
-
+#endif
+
+  delete client1;
+  delete client2;
+  delete server1;
+  delete server2; 
+  
   return 0;
 }
@@ -124,6 +193,6 @@
   printf("=================\n");
 
-  Synchronizeable* clientSync = new SimpleSync("Client\0");
-  Synchronizeable* serverSync = new SimpleSync("Server\0");
+  Synchronizeable* clientSync = new SimpleSync( std::string("Client") );
+  Synchronizeable* serverSync = new SimpleSync( std::string("Server") );
 
   unsigned int port = 9999;
@@ -144,5 +213,6 @@
   if(error == -1)
     printf("\n\nerror on address resolution, program inconsistancy\n\n");
-  nm->establishConnection(ip, *clientSync);
+  nm->establishConnection("localhost", port);
+  nm->connectSynchronizeable( *clientSync );
   /* adding some break for connection setup */
   SDL_Delay(20);
@@ -151,5 +221,5 @@
   for( int i = 0; i < 3; i++)
   {
-    nm->synchronize();
+    nm->synchronize( 1000 );
     /* simulate the network delay */
     SDL_Delay(50);
@@ -168,5 +238,9 @@
 }
 
-
+bool testCB( MessageId messageId, byte * data, int dataLength, void * someData, int userId )
+{
+  printf("GOT MESSAGE: %s\n", data);
+  return true;
+}
 
 /**
@@ -178,24 +252,32 @@
 int startServer(int argc, char** argv)
 {
-  if( argc <= 2)
-  {
-    printf(" Wrong arguments try following notations:\n");
-    printf("   --server [port number]\n");
-    return 0;
-  }
-
-  int port = atoi(argv[2]);
-  printf("Starting Server on port %i\n", port);
+
+
+  State::setOnline(true);
+  SharedNetworkData::getInstance()->setGameServer( true );
+  printf("Starting Server on port %i\n", 9999);
 
   NetworkManager* netMan = NetworkManager::getInstance();
-  Synchronizeable* ss = new SimpleSync("Server\0");
-
-  netMan->createServer(/**ss, */port);
+  
+  netMan->initialize();
+  
+  netMan->createServer(/**ss, */ 9999);
+  
+  SimpleSync* ss = new SimpleSync("Server");
+  ss->setSynchronized( true );
+  
+  NetworkLog::getInstance()->listen( 8888 );
+
+  //MessageManager::getInstance()->initUser( 1 );
+  MessageManager::getInstance()->registerMessageHandler( TESTMESSAGEID, testCB, NULL );
+  
   SDL_Delay(20);
 
   for(;;)
   {
-    netMan->synchronize();
-    SDL_Delay(1000);
+    MessageManager::getInstance()->sendMessage( TESTMESSAGEID, (byte*)"server to client", 18, RT_ALL, 0, MP_HIGHBANDWIDTH );
+    netMan->synchronize( 100 );
+    SDL_Delay(100);
+    ss->debug();
   }
 
@@ -210,9 +292,58 @@
 int startClient(int argc, char** argv)
 {
+
+
+  State::setOnline(true);
+  NetworkManager* netMan = NetworkManager::getInstance();
+  
+
+  netMan->initialize();
+  
+  std::string host;
+  
+  if ( argc > 2 )
+    host = argv[2];
+  else
+    host = "localhost";
+  
+  netMan->establishConnection(host, 9999);
+  
+//  SimpleSync* ss = new SimpleSync("SimpleSync");
+//  ss->setSynchronized( true );
+//  netMan->connectSynchronizeable( *ss );
+  
+  NetworkLog::getInstance()->listen( 7777 );
+
+  SimpleSync * ss = NULL;
+  
+  //MessageManager::getInstance()->initUser( 0 );
+  MessageManager::getInstance()->registerMessageHandler( TESTMESSAGEID, testCB, NULL );
+  
+  for(;;)
+  {
+    netMan->synchronize( 100 );
+    MessageManager::getInstance()->sendMessage( TESTMESSAGEID, (byte*)"client to server", 18, RT_ALL, 0, MP_HIGHBANDWIDTH );
+    ss = dynamic_cast<SimpleSync*>(ClassList::getObject( "Server", CL_SIMPLE_SYNC ) );
+    SDL_Delay(100);
+    if (ss)
+      ss->debug();
+  }
+
+
+  delete netMan;
+  delete ss;
+
+  return 0;
+}
+
+
+
+int startListen(int argc, char** argv)
+{
   if( argc < 3)
   {
     printf(" Wrong arguments try following notations:\n");
-    printf("   --client [server ip] [port number]\n");
-    printf("   --client [server name] [port number]\n");
+    printf("   --listen [server ip] [port number]\n");
+    printf("   --listen [server name] [port number]\n");
     return 0;
   }
@@ -228,12 +359,13 @@
 
   NetworkManager* netMan = NetworkManager::getInstance();
-  Synchronizeable* ss = new SimpleSync("Client\0");
-
-  netMan->establishConnection((const char*)"localhost", port/*,ip, *ss*/);
+  Synchronizeable* ss = new SimpleSync("SimpleSync\0");
+
+  netMan->establishConnection( name, port );
+  netMan->connectSynchronizeable( *ss );
 
   for(;;)
   {
-    netMan->synchronize();
-    SDL_Delay(500);
+    netMan->synchronize( 1000 );
+    SDL_Delay(10);
   }
 
@@ -245,45 +377,7 @@
 }
 
-
-
-int startListen(int argc, char** argv)
-{
-  if( argc < 3)
-  {
-    printf(" Wrong arguments try following notations:\n");
-    printf("   --listen [server ip] [port number]\n");
-    printf("   --listen [server name] [port number]\n");
-    return 0;
-  }
-
-  char* name = argv[2];
-  int port = atoi(argv[3]);
-  printf("Connecting to %s, on port %i\n", name, port);
-
-  IPaddress ip;
-  int error = SDLNet_ResolveHost(&ip, name, port);
-  if(error == -1)
-    printf("\n\nerror on address resolution, program inconsistancy\n\n");
-
-  NetworkManager* netMan = NetworkManager::getInstance();
-  Synchronizeable* ss = new ReadSync("WriteSync\0");
-
-  netMan->establishConnection(ip, *ss);
-
-  for(;;)
-  {
-    netMan->synchronize();
-    SDL_Delay(10);
-  }
-
-
-  delete netMan;
-  delete ss;
-
-  return 0;
-}
-
 void testFloatConverter(float f)
 {
+#if 0
   char* s = Converter::floatToBinString(f);
   printf("%f = ", f);
@@ -293,13 +387,15 @@
   printf("Byte Array: ");
   for (int i = 0; i < 4; i++)
-    printf("%i  ", res[i]);
+//    printf("%i  ", res[i]);
   printf("\n");
 
   float b = Converter::byteArrayToFloat(res);
   printf("ReConvert: %f \n", b);
+#endif
 }
 
 void testFloatConverter2(float f)
 {
+#if 0
   char* s = Converter::floatToBinString(f);
   printf("### %f = ", f);
@@ -314,4 +410,5 @@
   float b = Converter::_byteArrayToFloat(res);
   printf("ReConvert: %f \n", b);
+#endif
 }
 int converter(int argc, char** argv)
@@ -435,8 +532,8 @@
 
 
-bool ShellBuffer::addBufferLineStatic(const char* line, ...)
-{
+//bool ShellBuffer::addBufferLineStatic(const char* line, ...)
+//{
   //va_list arguments;
   //vprintf(line, arguments);
-  printf("%s", line);
-}
+  //  printf("%s", line);
+//}
Index: /trunk/src/subprojects/network/simple_sync.cc
===================================================================
--- /trunk/src/subprojects/network/simple_sync.cc	(revision 7953)
+++ /trunk/src/subprojects/network/simple_sync.cc	(revision 7954)
@@ -22,5 +22,11 @@
 #include "simple_sync.h"
 
+#include "class_id.h"
+#include "fast_factory.h"
+#include "lib/util/loading/factory.h"
+
 #include "debug.h"
+
+CREATE_FACTORY(SimpleSync, CL_SIMPLE_SYNC);
 
 
@@ -28,24 +34,13 @@
  *  default constructor
  */
-SimpleSync::SimpleSync(const char* name)
-  : Synchronizeable()
+SimpleSync::SimpleSync( std::string name )
 {
-  /* define the local buffer size */
-  this->outLength = 10;
-  this->recLength = 0;
-  this->inLength = 40;
-  this->outData = new byte[this->outLength];
-  this->inData = new byte[this->inLength];
-
-  /* init the buffer data */
-  for( int i = 0; i < this->outLength; i++)
-  {
-    this->outData[i] = i;
-  }
-  for( int i = 0; i < this->inLength; i++)
-  {
-    this->inData[i] = 0;
-  }
-
+  setName( name );
+  this->setClassID( CL_SIMPLE_SYNC, "SimpleSync" );
+  in = 0;
+  out = 1;
+  syncStr = "hallo test test";
+  id = this->registerVarId( new SynchronizeableInt( &in, &out, "var", PERMISSION_ALL ) );
+  registerVar( new SynchronizeableString( &syncStr, &syncStr, "syncStr" ) );
 }
 
@@ -56,68 +51,24 @@
 SimpleSync::~SimpleSync()
 {
-  if( this->outData)
-    delete[] this->outData;
-  if( this->inData)
-    delete[] this->inData;
+}
+
+void SimpleSync::debug( )
+{
+  printf("IN: %d OUT: %d\n", in, out);
+  printf("str: %s\n", syncStr.c_str());
+}
+
+SimpleSync::SimpleSync( const TiXmlElement * root )
+{
+  setName( "" );
+  this->setClassID( CL_SIMPLE_SYNC, "SimpleSync" );
+  in = 0;
+  out = 1;
+  syncStr = "hallo test test";
+  id = this->registerVarId( new SynchronizeableInt( &in, &out, "var", PERMISSION_ALL ) );
+  registerVar( new SynchronizeableString( &syncStr, &syncStr, "syncStr" ) );
 }
 
 
-/**
- *  write data to Synchronizeable
- */
-int SimpleSync::writeBytes(const byte* data, int length, int sender)
-{
-  PRINTF(0)("SimpleSync: got %i bytes of data\n", length);
-  this->recLength = length;
-  if(this->inLength < length)
-    PRINTF(0)("ERROR: local buffer is smaller than the data to receive.\n");
-
-  /* copy the data localy */
-  for( int i = 0; i < length; i++)
-  {
-    this->inData[i] = data[i];
-  }
-  /* and debug output */
-  this->writeDebug();
-}
 
 
-/**
- *  read data from Synchronizeable
- */
-int SimpleSync::readBytes(byte* data, int maxLength, int * reciever)
-{
-  PRINTF(0)("SimpleSync: sent %i bytes of data\n", this->outLength);
-
-  /* debug msg */
-  this->readDebug();
-
-  /* write the test message */
-  for( int i = 0; i < this->outLength; i++)
-    data[i] = this->outData[i];
-
-  /* return the length of the test */
-  return this->outLength;
-}
-
-
-void SimpleSync::writeDebug() const
-{
-  PRINTF(0)("Write in bytes: \t(0 <-) |");
-  for(int i = 0; i < this->recLength; i++)
-  {
-    PRINT(0)(" [%u] ",this->inData[i]);
-  }
-  PRINT(0)("|\n");
-}
-
-
-void SimpleSync::readDebug() const
-{
-  PRINTF(0)("Read out bytes: \t(0 ->) |");
-  for(int i = 0; i < this->outLength; i++)
-  {
-    PRINT(0)(" [%u] ",this->outData[i]);
-  }
-  PRINT(0)("|\n");
-}
Index: /trunk/src/subprojects/network/simple_sync.h
===================================================================
--- /trunk/src/subprojects/network/simple_sync.h	(revision 7953)
+++ /trunk/src/subprojects/network/simple_sync.h	(revision 7954)
@@ -13,22 +13,16 @@
   {
   public:
-    SimpleSync(const char* name);
+    SimpleSync( std::string name);
+    SimpleSync(const TiXmlElement* root = NULL);
     virtual ~SimpleSync();
-
-    virtual int writeBytes(const byte* data, int length, int sender);
-    virtual int readBytes(byte* data, int maxLength, int * reciever);
+    
+    void debug();
 
 
   private:
-    virtual void writeDebug() const;
-    virtual void readDebug() const;
-
-
-  private:
-    byte* inData;
-    int   inLength;
-    int   recLength;
-    byte* outData;
-    int   outLength;
+    int in;
+    int out;
+    std::string syncStr;
+    int id;
   };
 
Index: /trunk/src/util/multiplayer_team_deathmatch.cc
===================================================================
--- /trunk/src/util/multiplayer_team_deathmatch.cc	(revision 7953)
+++ /trunk/src/util/multiplayer_team_deathmatch.cc	(revision 7954)
@@ -203,10 +203,7 @@
       if ( terrz < terrain->getHeight( terrx, terry ) && ss->getAbsCoor().x > -1000 )
       {
-        //PRINTF(0)("COLLLLLLIIIIIDDDDEEEE\n");
-        ss->networkCollisionList.push_back( 1234567890 );
-        ss->doCollideNetwork( 1234567890 );
+        //TODO handle this
       }
-      //PRINTF(0)("x = %f, y = %f, z = %f, height = %f\n", terrx, terry, terrz, terrain->getHeight( terrx, terry ));
-      //ss->setRelCoorSoft( ss->getAbsCoor().x, terrain->getHeight( terrx, terry )-offsety, ss->getAbsCoor().z );
+
 
       float dist = (dynamic_cast<Playable*>(*it)->getAbsCoor() - big_left).len();
@@ -222,6 +219,5 @@
         if((*it)->isA(CL_SPACE_SHIP))
         {
-          dynamic_cast<SpaceShip*>(*it)->networkCollisionList.push_back(1163692);
-          dynamic_cast<SpaceShip*>(*it)->doCollideNetwork(11636922);
+          //TODO handle this
         }
       }
Index: /trunk/src/world_entities/environments/water.cc
===================================================================
--- /trunk/src/world_entities/environments/water.cc	(revision 7953)
+++ /trunk/src/world_entities/environments/water.cc	(revision 7954)
@@ -59,4 +59,10 @@
   // To test the Wave equation
   //this->wave(5.0,4.0, 1, 10);
+  
+  height_handle = registerVarId( new SynchronizeableFloat( &height, &height, "height" ) );
+  resX_handle = registerVarId( new SynchronizeableUInt( &resX, &resX, "resX" ) );
+  resY_handle = registerVarId( new SynchronizeableUInt( &resY, &resY, "resY" ) );
+  sizeX_handle = registerVarId( new SynchronizeableFloat( &sizeX, &sizeX, "sizeX" ) );
+  sizeY_handle = registerVarId( new SynchronizeableFloat( &sizeY, &sizeY, "sizeY" ) );
 }
 
@@ -291,116 +297,21 @@
 
 
-/**
- * Writes data from network containing information about the state
- * @param data pointer to data
- * @param length length of data
- * @param sender hostID of sender
- */
-int Water::writeBytes( const byte * data, int length, int sender )
-{
-  setRequestedSync( false );
-  setIsOutOfSync( false );
-
-  SYNCHELP_READ_BEGIN();
-
-  SYNCHELP_READ_FKT( Water::writeState, NWT_WAT_STATE );
-
-  return SYNCHELP_READ_N;
-}
-
-
-/**
- * data copied in data will bee sent to another host
- * @param data pointer to data
- * @param maxLength max length of data
- * @return the number of bytes writen
- */
-int Water::readBytes( byte * data, int maxLength, int * reciever )
-{
-  SYNCHELP_WRITE_BEGIN();
-
-  if ( isOutOfSync() && !requestedSync() && this->getHostID()!=this->getOwner() )
-  {
-    (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
-    setRequestedSync( true );
-  }
-
-  int rec = this->getRequestSync();
-  if ( rec > 0 )
-  {
-    *reciever = rec;
-    SYNCHELP_WRITE_FKT( Water::readState, NWT_WAT_STATE );
-  }
-
-  *reciever = 0;
-  return SYNCHELP_WRITE_N;
-}
-
-
-
-/**
- * data copied in data will bee sent to another host
- * @param data pointer to data
- * @param maxLength max length of data
- * @return the number of bytes writen
- */
-int Water::readState( byte * data, int maxLength )
-{
-  SYNCHELP_WRITE_BEGIN();
-
-  SYNCHELP_WRITE_FKT( WorldEntity::readState, NWT_WAT_WE_STATE );
-
-  // sync the size
-  SYNCHELP_WRITE_FLOAT( this->sizeX, NWT_WAT_SIZEX );
-  SYNCHELP_WRITE_FLOAT( this->sizeY, NWT_WAT_SIZEY );
-
-  //sync resolution
-  SYNCHELP_WRITE_INT( this->resX, NWT_WAT_RESX );
-  SYNCHELP_WRITE_INT( this->resY, NWT_WAT_RESY );
-
-  //sync the height
-  SYNCHELP_WRITE_FLOAT( this->height, NWT_WAT_HEIGHT );
-
-  return SYNCHELP_WRITE_N;
-}
-
-
-/**
- * Writes data from network containing information about the state
- * @param data pointer to data
- * @param length length of data
- * @param sender hostID of sender
- */
-int Water::writeState( const byte * data, int length, int sender )
-{
-  SYNCHELP_READ_BEGIN();
-
-  SYNCHELP_READ_FKT( WorldEntity::writeState, NWT_WAT_WE_STATE );
-
-  float f1, f2;
-  int i1, i2;
-
-  //read the size
-  SYNCHELP_READ_FLOAT( f1, NWT_WAT_SIZEX );
-  SYNCHELP_READ_FLOAT( f2, NWT_WAT_SIZEY );
-  this->sizeX = f1;
-  this->sizeY = f2;
-  PRINTF(0)("Setting Water to size: %f x %f\n", f1, f2);
-
-  //read the resolution
-  SYNCHELP_READ_INT( i1, NWT_WAT_RESX );
-  SYNCHELP_READ_INT( i2, NWT_WAT_RESY );
-  this->resX = i1;
-  this->resY = i2;
-  PRINTF(0)("Setting Water to resolution: %i x %i\n", i1, i2);
-
-  //read the height
-  SYNCHELP_READ_FLOAT( f1, NWT_WAT_HEIGHT );
-  this->height = f1;
-
-  this->rebuildGrid();
-
-  return SYNCHELP_READ_N;
-}
-
-
+
+/**
+ * function to handle changes in synced vars
+ * @param id ids which have changed
+ */
+void Water::varChangeHandler( std::list< int > & id )
+{
+  if ( std::find( id.begin(), id.end(), height_handle ) != id.end() ||
+       std::find( id.begin(), id.end(), resX_handle ) != id.end() ||
+       std::find( id.begin(), id.end(), resY_handle ) != id.end() ||
+       std::find( id.begin(), id.end(), sizeX_handle ) != id.end() ||
+       std::find( id.begin(), id.end(), sizeY_handle ) != id.end()
+     )
+  {
+    this->rebuildGrid();
+  }
+  
+  WorldEntity::varChangeHandler( id );
+}
Index: /trunk/src/world_entities/environments/water.h
===================================================================
--- /trunk/src/world_entities/environments/water.h	(revision 7953)
+++ /trunk/src/world_entities/environments/water.h	(revision 7954)
@@ -38,10 +38,6 @@
    void draw() const;
    void tick(float dt);
-
-   virtual int writeBytes(const byte* data, int length, int sender);
-   virtual int readBytes(byte* data, int maxLength, int * reciever);
-
-   int writeState( const byte * data, int length, int sender );
-   int readState( byte * data, int maxLength );
+   
+   virtual void varChangeHandler( std::list<int> & id );
 
   private:
@@ -56,8 +52,14 @@
     Material        waterMaterial;
     Shader*         waterShader;
+    
     float           height;          //!< The hight of the Water
+    int             height_handle;   //!< Handle to notify about changes of height
 
-    unsigned int    resX, resY;
-    float           sizeX, sizeY;
+    unsigned int    resX, resY;      //!< Grid resolution
+    int             resX_handle;     //!< Handle to notify about changes of resX
+    int             resY_handle;     //!< Handle to notify about changes of resY
+    float           sizeX, sizeY;    //!< waters size
+    int             sizeX_handle;    //!< Handle to notify about changes of sizeX
+    int             sizeY_handle;    //!< Handle to notify about changes of sizeY
 
     float phase;
Index: /trunk/src/world_entities/npcs/ground_turret.cc
===================================================================
--- /trunk/src/world_entities/npcs/ground_turret.cc	(revision 7953)
+++ /trunk/src/world_entities/npcs/ground_turret.cc	(revision 7954)
@@ -180,49 +180,2 @@
   Explosion::explode(this, Vector(10,10,10));
 }
-
-/**
- * Writes data from network containing information about the state
- * @param data pointer to data
- * @param length length of data
- * @param sender hostID of sender
- */
-int GroundTurret::writeBytes( const byte * data, int length, int sender )
-{
-  setRequestedSync( false );
-  setIsOutOfSync( false );
-
-  SYNCHELP_READ_BEGIN();
-
-  SYNCHELP_READ_FKT( WorldEntity::writeState, NWT_GT_WE_STATE );
-
-  return SYNCHELP_READ_N;
-}
-
-/**
- * data copied in data will bee sent to another host
- * @param data pointer to data
- * @param maxLength max length of data
- * @return the number of bytes writen
- */
-int GroundTurret::readBytes( byte * data, int maxLength, int * reciever )
-{
-  SYNCHELP_WRITE_BEGIN();
-
-  if ( isOutOfSync() && !requestedSync() && this->getHostID()!=this->getOwner() )
-  {
-    (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
-    setRequestedSync( true );
-  }
-
-  int rec = this->getRequestSync();
-  if ( rec > 0 )
-  {
-    *reciever = rec;
-
-    SYNCHELP_WRITE_FKT( WorldEntity::readState, NWT_GT_WE_STATE );
-
-  }
-
-  *reciever = 0;
-  return SYNCHELP_WRITE_N;
-}
Index: /trunk/src/world_entities/npcs/ground_turret.h
===================================================================
--- /trunk/src/world_entities/npcs/ground_turret.h	(revision 7953)
+++ /trunk/src/world_entities/npcs/ground_turret.h	(revision 7954)
@@ -30,7 +30,4 @@
   virtual void tick(float time);
 
-  virtual int writeBytes(const byte* data, int length, int sender);
-  virtual int readBytes(byte* data, int maxLength, int * reciever);
-
  private:
    PNode  weaponHolder[2];
Index: /trunk/src/world_entities/playable.cc
===================================================================
--- /trunk/src/world_entities/playable.cc	(revision 7953)
+++ /trunk/src/world_entities/playable.cc	(revision 7954)
@@ -62,8 +62,10 @@
 
   this->score = 0;
-  this->oldScore = 0;
   this->collider = NULL;
 
   this->bDead = false;
+
+  registerVar( new SynchronizeableInt( &score, &score, "score" ) );
+  registerVar( new SynchronizeableBool( &bFire, &bFire, "bFire", PERMISSION_OWNER));
 }
 
@@ -484,79 +486,4 @@
 
 
-#define DATA_FLAGS    1
-#define DATA_SCORE    2
-
-#define FLAGS_bFire   1
-
-int Playable::writeSync( const byte * data, int length, int sender )
-{
-  SYNCHELP_READ_BEGIN();
-
-  byte b;
-  SYNCHELP_READ_BYTE( b, NWT_PL_B );
-
-  byte flags;
-
-  if ( b == DATA_FLAGS )
-  {
-    SYNCHELP_READ_BYTE( flags, NWT_PL_FLAGS );
-
-    bFire = (flags & FLAGS_bFire) != 0;
-
-    return SYNCHELP_READ_N;
-  }
-
-  if ( b == DATA_SCORE )
-  {
-    int newScore;
-    SYNCHELP_READ_BYTE( newScore, NWT_PL_SCORE );
-    setScore( newScore );
-
-    return SYNCHELP_READ_N;
-  }
-
-  return SYNCHELP_READ_N;
-}
-
-int Playable::readSync( byte * data, int maxLength )
-{
-  SYNCHELP_WRITE_BEGIN();
-
-  if ( score != oldScore && isServer() )
-  {
-    SYNCHELP_WRITE_BYTE( DATA_SCORE, NWT_PL_B);
-    SYNCHELP_WRITE_INT( score, NWT_PL_SCORE );
-    oldScore = score;
-
-    return SYNCHELP_WRITE_N;
-  }
-
-  byte flags = 0;
-
-  if ( bFire )
-    flags |= FLAGS_bFire;
-
-
-  SYNCHELP_WRITE_BYTE( DATA_FLAGS, NWT_PL_B);
-  SYNCHELP_WRITE_BYTE( flags, NWT_PL_FLAGS );
-  oldFlags = flags;
-
-
-  return SYNCHELP_WRITE_N;
-}
-
-bool Playable::needsReadSync( )
-{
-  if ( score != oldScore && isServer() )
-    return true;
-
-  byte flags = 0;
-
-  if ( bFire )
-    flags |= FLAGS_bFire;
-
-  return flags!=oldFlags;
-}
-
 
 /**
Index: /trunk/src/world_entities/playable.h
===================================================================
--- /trunk/src/world_entities/playable.h	(revision 7953)
+++ /trunk/src/world_entities/playable.h	(revision 7954)
@@ -81,10 +81,4 @@
   virtual void tick(float dt);
 
-  // NETWORK
-  int       writeSync(const byte* data, int length, int sender);
-  int       readSync(byte* data, int maxLength );
-  bool      needsReadSync();
-
-
   // Transformations:
   static Playable::Playmode stringToPlaymode(const std::string& playmode);
@@ -115,6 +109,5 @@
   int                   oldFlags;           //!< Used for synchronisation
 
-  int                   score;
-  int                   oldScore;
+  int                   score;              //!< players score
 
   bool                  bDead;
Index: /trunk/src/world_entities/power_ups/laser_power_up.cc
===================================================================
--- /trunk/src/world_entities/power_ups/laser_power_up.cc	(revision 7953)
+++ /trunk/src/world_entities/power_ups/laser_power_up.cc	(revision 7954)
@@ -120,40 +120,3 @@
 }
 
-int LaserPowerUp::writeBytes( const byte * data, int length, int sender )
-{
-  setRequestedSync( false );
-  setIsOutOfSync( false );
 
-  SYNCHELP_READ_BEGIN();
-
-  SYNCHELP_READ_FKT( PowerUp::writeState, NWT_LPU_WE_STATE );
-
-  return SYNCHELP_READ_N;
-}
-
-
-
-int LaserPowerUp::readBytes( byte * data, int maxLength, int * reciever )
-{
-  if ( isOutOfSync() && !requestedSync() && this->getHostID()!=this->getOwner() )
-  {
-    (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
-    setRequestedSync( true );
-  }
-
-  int rec = this->getRequestSync();
-  if ( rec > 0 )
-  {
-    *reciever = rec;
-
-    SYNCHELP_WRITE_BEGIN();
-
-    SYNCHELP_WRITE_FKT( PowerUp::readState, NWT_LPU_WE_STATE );
-
-    return SYNCHELP_WRITE_N;
-  }
-
-  *reciever = 0;
-  return 0;
-}
-
Index: /trunk/src/world_entities/power_ups/laser_power_up.h
===================================================================
--- /trunk/src/world_entities/power_ups/laser_power_up.h	(revision 7953)
+++ /trunk/src/world_entities/power_ups/laser_power_up.h	(revision 7954)
@@ -26,7 +26,4 @@
   virtual void draw() const;
 
-  virtual int writeBytes(const byte* data, int length, int sender);
-  virtual int readBytes(byte* data, int maxLength, int * reciever );
-
   private:
    void init();
Index: /trunk/src/world_entities/power_ups/param_power_up.cc
===================================================================
--- /trunk/src/world_entities/power_ups/param_power_up.cc	(revision 7953)
+++ /trunk/src/world_entities/power_ups/param_power_up.cc	(revision 7954)
@@ -43,4 +43,9 @@
   if( root != NULL)
     this->loadParams(root);
+  
+  registerVar( new SynchronizeableInt( (int*)&type, (int*)&type, "type" ) );
+  registerVar( new SynchronizeableFloat( &value, &value, "value" ) );
+  registerVar( new SynchronizeableFloat( &max_value, &max_value, "max_value" ) );
+  registerVar( new SynchronizeableFloat( &min_value, &min_value, "min_value" ) );
 }
 
@@ -119,62 +124,2 @@
 }
 
-int ParamPowerUp::writeBytes( const byte * data, int length, int sender )
-{
-  setRequestedSync( false );
-  setIsOutOfSync( false );
-
-  SYNCHELP_READ_BEGIN();
-
-  SYNCHELP_READ_FKT( PowerUp::writeState, NWT_PPU_WE_STATE );
-
-  int i;
-  SYNCHELP_READ_INT( i, NWT_PPU_TYPE );
-  this->type = (EnumParamPowerUpType)i;
-  SYNCHELP_READ_FLOAT( this->value, NWT_PPU_VALUE );
-
-  if ( this->value != 0 )
-  {
-    SYNCHELP_READ_FLOAT( this->min_value, NWT_PPU_MINVALUE );
-    SYNCHELP_READ_FLOAT( this->max_value, NWT_PPU_MAXVALUE );
-    respawn();
-  }
-
-  return SYNCHELP_READ_N;
-}
-
-
-
-int ParamPowerUp::readBytes( byte * data, int maxLength, int * reciever )
-{
-  if ( isOutOfSync() && !requestedSync() && this->getHostID()!=this->getOwner() )
-  {
-    (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
-    setRequestedSync( true );
-  }
-
-  int rec = this->getRequestSync();
-  if ( rec > 0 )
-  {
-    *reciever = rec;
-
-    SYNCHELP_WRITE_BEGIN();
-
-    SYNCHELP_WRITE_FKT( PowerUp::readState, NWT_PPU_WE_STATE );
-
-    int i = (int)this->type;
-    SYNCHELP_WRITE_INT( i, NWT_PPU_TYPE );
-    SYNCHELP_WRITE_FLOAT( this->value, NWT_PPU_VALUE );
-
-    if ( this->value != 0 )
-    {
-      SYNCHELP_WRITE_FLOAT( this->min_value, NWT_PPU_MINVALUE );
-      SYNCHELP_WRITE_FLOAT( this->max_value, NWT_PPU_MAXVALUE );
-    }
-
-    return SYNCHELP_WRITE_N;
-  }
-
-  *reciever = 0;
-  return 0;
-}
-
Index: /trunk/src/world_entities/power_ups/param_power_up.h
===================================================================
--- /trunk/src/world_entities/power_ups/param_power_up.h	(revision 7953)
+++ /trunk/src/world_entities/power_ups/param_power_up.h	(revision 7954)
@@ -32,7 +32,4 @@
   float getValue();
 
-  virtual int writeBytes(const byte* data, int length, int sender);
-  virtual int readBytes(byte* data, int maxLength, int * reciever );
-
 protected:
   virtual void respawn();
Index: /trunk/src/world_entities/power_ups/power_up.cc
===================================================================
--- /trunk/src/world_entities/power_ups/power_up.cc	(revision 7953)
+++ /trunk/src/world_entities/power_ups/power_up.cc	(revision 7954)
@@ -201,34 +201,2 @@
 
 
-/********************************************************************************************
- NETWORK STUFF
- ********************************************************************************************/
-
-
-/**
- * data copied in data will bee sent to another host
- * @param data pointer to data
- * @param maxLength max length of data
- * @return the number of bytes writen
- */
-int PowerUp::readState( byte * data, int maxLength )
-{
-  SYNCHELP_WRITE_BEGIN();
-  SYNCHELP_WRITE_FKT( WorldEntity::readState, NWT_PU_WE_STATE );
-  return SYNCHELP_WRITE_N;
-}
-
-
-/**
- * Writes data from network containing information about the state
- * @param data pointer to data
- * @param length length of data
- * @param sender hostID of sender
- */
-int PowerUp::writeState( const byte * data, int length, int sender )
-{
-  SYNCHELP_READ_BEGIN();
-  SYNCHELP_READ_FKT( WorldEntity::writeState, NWT_PU_WE_STATE );
-  return SYNCHELP_READ_N;
-}
-
Index: /trunk/src/world_entities/power_ups/power_up.h
===================================================================
--- /trunk/src/world_entities/power_ups/power_up.h	(revision 7953)
+++ /trunk/src/world_entities/power_ups/power_up.h	(revision 7954)
@@ -34,7 +34,4 @@
   void setRespawnTime(const float respawn);
 
-  int       writeState(const byte* data, int length, int sender);
-  int       readState(byte* data, int maxLength );
-
 protected:
   PowerUp(float r, float g, float b);
Index: /trunk/src/world_entities/power_ups/turret_power_up.cc
===================================================================
--- /trunk/src/world_entities/power_ups/turret_power_up.cc	(revision 7953)
+++ /trunk/src/world_entities/power_ups/turret_power_up.cc	(revision 7954)
@@ -115,47 +115,2 @@
   glPopMatrix();
 }
-
-
-
-
-/********************************************************************************************
- NETWORK STUFF
- ********************************************************************************************/
-
-
-int TurretPowerUp::writeBytes( const byte * data, int length, int sender )
-{
-  setRequestedSync( false );
-  setIsOutOfSync( false );
-
-  SYNCHELP_READ_BEGIN();
-
-  SYNCHELP_READ_FKT( PowerUp::writeState, NWT_TPU_WE_STATE );
-
-  return SYNCHELP_READ_N;
-}
-
-
-int TurretPowerUp::readBytes( byte * data, int maxLength, int * reciever )
-{
-  if ( isOutOfSync() && !requestedSync() && this->getHostID()!=this->getOwner() )
-  {
-    (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
-    setRequestedSync( true );
-  }
-
-  int rec = this->getRequestSync();
-  if ( rec > 0 )
-  {
-    *reciever = rec;
-
-    SYNCHELP_WRITE_BEGIN();
-
-    SYNCHELP_WRITE_FKT( PowerUp::readState, NWT_TPU_WE_STATE );
-
-    return SYNCHELP_WRITE_N;
-  }
-
-  *reciever = 0;
-  return 0;
-}
Index: /trunk/src/world_entities/power_ups/turret_power_up.h
===================================================================
--- /trunk/src/world_entities/power_ups/turret_power_up.h	(revision 7953)
+++ /trunk/src/world_entities/power_ups/turret_power_up.h	(revision 7954)
@@ -24,7 +24,4 @@
   virtual void draw() const;
 
-  virtual int writeBytes(const byte* data, int length, int sender);
-  virtual int readBytes(byte* data, int maxLength, int * reciever );
-
   private:
    void init();
Index: /trunk/src/world_entities/power_ups/weapon_power_up.cc
===================================================================
--- /trunk/src/world_entities/power_ups/weapon_power_up.cc	(revision 7953)
+++ /trunk/src/world_entities/power_ups/weapon_power_up.cc	(revision 7954)
@@ -103,43 +103,2 @@
 }
 
-int WeaponPowerUp::writeBytes( const byte * data, int length, int sender )
-{
-  setRequestedSync( false );
-  setIsOutOfSync( false );
-
-  SYNCHELP_READ_BEGIN();
-
-  SYNCHELP_READ_FKT( PowerUp::writeState, NWT_WPU_WE_STATE );
-
-  //TODO: sync weapon class ( see loadParams )
-
-  return SYNCHELP_READ_N;
-}
-
-
-
-int WeaponPowerUp::readBytes( byte * data, int maxLength, int * reciever )
-{
-  if ( isOutOfSync() && !requestedSync() && this->getHostID()!=this->getOwner() )
-  {
-    (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
-    setRequestedSync( true );
-  }
-
-  int rec = this->getRequestSync();
-  if ( rec > 0 )
-  {
-    *reciever = rec;
-
-    SYNCHELP_WRITE_BEGIN();
-
-    SYNCHELP_WRITE_FKT( PowerUp::readState, NWT_WPU_WE_STATE );
-
-    //TODO: sync weapon class ( see loadParams )
-
-    return SYNCHELP_WRITE_N;
-  }
-
-  *reciever = 0;
-  return 0;
-}
Index: /trunk/src/world_entities/power_ups/weapon_power_up.h
===================================================================
--- /trunk/src/world_entities/power_ups/weapon_power_up.h	(revision 7953)
+++ /trunk/src/world_entities/power_ups/weapon_power_up.h	(revision 7954)
@@ -24,7 +24,4 @@
   void setWeaponClass(const std::string& name);
 
-  virtual int writeBytes(const byte* data, int length, int sender);
-  virtual int readBytes(byte* data, int maxLength, int * reciever );
-
   bool process(WeaponManager* manager);
 
Index: /trunk/src/world_entities/skybox.cc
===================================================================
--- /trunk/src/world_entities/skybox.cc	(revision 7953)
+++ /trunk/src/world_entities/skybox.cc	(revision 7954)
@@ -95,4 +95,7 @@
 {
   this->rebuild();
+  
+  textureName_handle = registerVarId( new SynchronizeableString( &textureName, &textureName, "textureName") );
+  size_handle = registerVarId( new SynchronizeableFloat( &size, &size, "size" ) );
 }
 
@@ -290,62 +293,21 @@
 }
 
-int SkyBox::writeBytes( const byte * data, int length, int sender )
-{
-  setRequestedSync( false );
-  setIsOutOfSync( false );
-
-  SYNCHELP_READ_BEGIN();
-
-  SYNCHELP_READ_FKT( WorldEntity::writeState, NWT_SB_WE_STATE );
-
-  SYNCHELP_READ_FLOAT( size, NWT_SB_SIZE );
-  if ( !this->textureName.empty() )
+void SkyBox::varChangeHandler( std::list< int > & id )
+{
+  bool somethinChanged = false;
+  
+  if ( std::find( id.begin(), id.end(), textureName_handle ) != id.end() )
   {
-    textureName = "";
+    somethinChanged = true;
+    setTexture( textureName );
   }
-  std::string texName;
-  SYNCHELP_READ_STRING( texName, NWT_SB_TEXTURENAME );
-
-  this->setSize( size );
-  this->setTextureAndType( texName, "jpg" );
-  this->rebuild();
-
-  return SYNCHELP_READ_N;
-}
-
-
-
-int SkyBox::readBytes( byte * data, int maxLength, int * reciever )
-{
-  if ( isOutOfSync() && !requestedSync() && this->getHostID()!=this->getOwner() )
+  
+  if ( std::find( id.begin(), id.end(), size_handle ) != id.end() )
   {
-    (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
-    setRequestedSync( true );
+    somethinChanged = true;
   }
-
-  int rec = this->getRequestSync();
-  if ( rec > 0 )
-  {
-    *reciever = rec;
-
-    SYNCHELP_WRITE_BEGIN();
-
-    SYNCHELP_WRITE_FKT( WorldEntity::readState, NWT_SB_WE_STATE );
-
-    SYNCHELP_WRITE_FLOAT(this->size, NWT_SB_SIZE);
-    SYNCHELP_WRITE_STRING(this->textureName, NWT_SB_TEXTURENAME);
-
-    return SYNCHELP_WRITE_N;
-  }
-
-  *reciever = 0;
-  return 0;
-}
-
-void SkyBox::writeDebug( ) const
-{
-}
-
-void SkyBox::readDebug( ) const
-{
-}
+  
+  rebuild();
+  
+  WorldEntity::varChangeHandler( id );
+}
Index: /trunk/src/world_entities/skybox.h
===================================================================
--- /trunk/src/world_entities/skybox.h	(revision 7953)
+++ /trunk/src/world_entities/skybox.h	(revision 7954)
@@ -58,8 +58,5 @@
   static void disableCubeMap();
 
-  virtual int       writeBytes(const byte* data, int length, int sender);
-  virtual int       readBytes(byte* data, int maxLength, int * reciever);
-  virtual void      writeDebug() const;
-  virtual void      readDebug() const;
+  virtual void varChangeHandler( std::list<int> & id );
 
  private:
@@ -72,4 +69,7 @@
   float           textureSize;     //!< this is the length of a texture (assumes a square texture)
   std::string     textureName;     //!< Name of the Texture
+  
+  int textureName_handle;          //!< used to notify about changes of textureName
+  int size_handle;                 //!< used to notify about changes of size
 
 };
Index: /trunk/src/world_entities/space_ships/hover.cc
===================================================================
--- /trunk/src/world_entities/space_ships/hover.cc	(revision 7953)
+++ /trunk/src/world_entities/space_ships/hover.cc	(revision 7954)
@@ -175,4 +175,15 @@
   this->getWeaponManager().getFixedTarget()->setParent(&this->cameraNode);
   this->getWeaponManager().getFixedTarget()->setRelCoor(1000,0,0);
+  
+  // NETWORK THINGS
+  
+  registerVar( new SynchronizeableBool( &bForward, &bForward, "bForward", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bBackward, &bBackward, "bBackward", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bLeft, &bLeft, "bLeft", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bRight, &bRight, "bRight", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bAscend, &bAscend, "bAscend", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bDescend, &bDescend, "bDescend", PERMISSION_OWNER ) );
+  
+  registerVar( new SynchronizeableFloat( &rotation, &rotation, "rotation", PERMISSION_OWNER ) );
 }
 
Index: /trunk/src/world_entities/space_ships/space_ship.cc
===================================================================
--- /trunk/src/world_entities/space_ships/space_ship.cc	(revision 7953)
+++ /trunk/src/world_entities/space_ships/space_ship.cc	(revision 7954)
@@ -93,19 +93,4 @@
   if (root != NULL)
     this->loadParams(root);
-  else
-  {
-    //this->loadModel("models/ships/reap_#.obj");
-    //TODO HACK this is only for network multiplayer games.
-    if( this->getOwner()%2 == 0)
-    {
-      this->loadModel("models/ships/reap_#.obj");
-      this->toList(OM_GROUP_00);
-    }
-    else
-    {
-      this->loadModel( "models/ships/fighter.obj" );
-      this->toList(OM_GROUP_01);
-    }
-  }
 
 }
@@ -234,5 +219,16 @@
   this->burstSystem->setColor(0.5, .5,.5,.8,.8);
   this->burstSystem->setColor(1.0, .8,.8,.8,.0);
-
+  
+  registerVar( new SynchronizeableVector( &velocity, &velocity, "velocity" ) );
+  registerVar( new SynchronizeableQuaternion( &mouseDir, &mouseDir, "mousedir", PERMISSION_OWNER ) );
+
+  registerVar( new SynchronizeableBool( &bUp, &bUp, "bUp", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bDown, &bDown, "bDown", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bLeft, &bLeft, "bLeft", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bRight, &bRight, "bRight", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bAscend, &bAscend, "bAscend", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bDescend, &bDescend, "bDescend", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bRollL, &bRollL, "bRollL", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bRollR, &bRollR, "bRollR", PERMISSION_OWNER ) );
 }
 
@@ -306,6 +302,5 @@
     if ( isServer() )
     {
-      networkCollisionList.push_back( entity->getHealth() );
-      doCollideNetwork( entity->getHealth() );
+      //TODO handle this
     }
   }
@@ -349,5 +344,5 @@
 
   // spaceship controlled movement
-  if (this->getOwner() == this->getHostID())
+  //if (this->getOwner() == this->getHostID())
     this->calculateVelocity(time);
 
@@ -509,273 +504,4 @@
 
 
-#define MASK_bUp         1
-#define MASK_bDown       2
-#define MASK_bLeft       4
-#define MASK_bRight      8
-#define MASK_bAscend    16
-#define MASK_bDescend   32
-#define MASK_bRollL     64
-#define MASK_bRollR    128
-
-#define DATA_state       1
-#define DATA_flags       2
-#define DATA_mouse       3
-#define DATA_sync        4
-#define DATA_velocity    5
-#define DATA_playables   6
-#define DATA_collision   7
-
-int SpaceShip::writeBytes( const byte * data, int length, int sender )
-{
-  SYNCHELP_READ_BEGIN();
-
-  byte b;
-
-  while ( SYNCHELP_READ_REMAINING()>0 )
-  {
-    SYNCHELP_READ_BYTE( b, NWT_SS_B );
-
-    if ( b == DATA_state )
-    {
-      setRequestedSync( false );
-      setIsOutOfSync( false );
-      SYNCHELP_READ_FKT( WorldEntity::writeState, NWT_SS_WE_STATE );
-
-      continue;
-    }
-
-    if ( b == DATA_flags )
-    {
-      if ( this->getOwner() != this->getHostID() )
-      {
-        byte flags = 0;
-        SYNCHELP_READ_BYTE( flags, NWT_SS_FLAGS );
-
-        bUp = (flags & MASK_bUp) != 0;
-        bDown = (flags & MASK_bDown) != 0;
-        bLeft = (flags & MASK_bLeft) != 0;
-        bRight = (flags & MASK_bRight) != 0;
-        bAscend = (flags & MASK_bAscend) != 0;
-        bDescend = (flags & MASK_bDescend) != 0;
-        bRollL = (flags & MASK_bRollL) != 0;
-        bRollR = (flags & MASK_bRollR) != 0;
-
-      }
-      else
-        assert(false);
-
-      continue;
-    }
-
-    if ( b == DATA_mouse )
-    {
-      if ( this->getOwner() != this->getHostID() )
-      {
-        SYNCHELP_READ_FLOAT( mouseDir.w, NWT_SS_MOUSEDIRW );
-        SYNCHELP_READ_FLOAT( mouseDir.v.x, NWT_SS_MOUSEDIRX );
-        SYNCHELP_READ_FLOAT( mouseDir.v.y, NWT_SS_MOUSEDIRY );
-        SYNCHELP_READ_FLOAT( mouseDir.v.z, NWT_SS_MOUSEDIRZ );
-      }
-      else
-        assert(false);
-
-      continue;
-    }
-
-    if ( b == DATA_sync )
-    {
-      if ( this->getOwner() != this->getHostID() )
-      {
-        SYNCHELP_READ_FKT( PNode::writeSync, NWT_SS_PN_SYNC );
-      }
-      else
-        assert(false);
-
-      continue;
-    }
-
-    if ( b == DATA_velocity )
-    {
-      if ( this->getOwner() != this->getHostID() )
-      {
-        SYNCHELP_READ_FLOAT( velocity.x, NWT_SS_VELX );
-        SYNCHELP_READ_FLOAT( velocity.y, NWT_SS_VELY );
-        SYNCHELP_READ_FLOAT( velocity.z, NWT_SS_VELZ );
-      }
-      else
-        assert(false);
-
-      continue;
-    }
-
-    if ( b == DATA_playables )
-    {
-      if ( this->getOwner() != this->getHostID() )
-      {
-        SYNCHELP_READ_FKT( Playable::writeSync, NWT_SS_PL_SYNC );
-      }
-      else
-        assert(false);
-    }
-
-    if ( b == DATA_collision )
-    {
-      int n;
-      float energy;
-      SYNCHELP_READ_INT( n, NWT_SS_CO_N );
-
-      for ( int i = 0; i<n; i++ )
-      {
-        SYNCHELP_READ_FLOAT( energy, NWT_SS_CO_CLID );
-        doCollideNetwork( energy );
-      }
-    }
-  }
-
-  return SYNCHELP_READ_N;
-}
-
-
-
-int SpaceShip::readBytes( byte * data, int maxLength, int * reciever )
-{
-  SYNCHELP_WRITE_BEGIN();
-
-  if ( isOutOfSync() && !requestedSync() /*&& this->getHostID()!=this->getOwner()*/ )
-  {
-    (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
-    setRequestedSync( true );
-    PRINTF(0)("REQUESTED STATE %d\n", this->getUniqueID());
-  }
-
-  int rec = this->getRequestSync();
-  if ( rec > 0 )
-  {
-    *reciever = rec;
-
-    PRINTF(0)("SEND STATE %d %d\n", this->getUniqueID(), rec);
-
-    SYNCHELP_WRITE_BYTE( (byte)DATA_state, NWT_SS_B );
-
-    SYNCHELP_WRITE_FKT( WorldEntity::readState, NWT_SS_WE_STATE );
-
-    return SYNCHELP_WRITE_N;
-  }
-
-  *reciever = 0 - this->getOwner();
-  //TODO: implement with SYNCHELP_WRITE_SENT()
-  bool sentSomething = false;
-
-  if ( PNode::needsReadSync() && ( this->getHostID()==0 || this->getOwner() == this->getHostID() ) )
-  {
-    PRINTF(0)("sending PNode::readSync\n");
-    SYNCHELP_WRITE_BYTE( DATA_sync, NWT_SS_B );
-    SYNCHELP_WRITE_FKT( PNode::readSync, NWT_SS_PN_SYNC );
-    sentSomething = true;
-  }
-
-  if ( this->getHostID()==0 || this->getHostID()==this->getOwner() )
-  {
-    byte mask = 0;
-
-    if ( bUp )
-      mask |= MASK_bUp;
-    if ( bDown )
-      mask |= MASK_bDown;
-    if ( bLeft )
-      mask |= MASK_bLeft;
-    if ( bRight )
-      mask |= MASK_bRight;
-    if ( bAscend )
-      mask |= MASK_bAscend;
-    if ( bRollL )
-      mask |= MASK_bRollL;
-    if ( bRollR )
-      mask |= MASK_bRollR;
-
-
-    if ( mask != oldMask )
-    {
-      oldMask = mask;
-      PRINTF(0)("sending mask\n");
-      sentSomething = true;
-      SYNCHELP_WRITE_BYTE( DATA_flags, NWT_SS_B );
-      SYNCHELP_WRITE_BYTE( mask, NWT_SS_FLAGS );
-    }
-#define __OFFSET_MDIR_W 0.01
-#define __OFFSET_MDIR_V 0.01
-    if ( fabs( oldMouseDir.w - mouseDir.w ) > __OFFSET_MDIR_W ||
-         fabs( oldMouseDir.v.x - mouseDir.v.x ) > __OFFSET_MDIR_V ||
-         fabs( oldMouseDir.v.y - mouseDir.v.y ) > __OFFSET_MDIR_V ||
-         fabs( oldMouseDir.v.z - mouseDir.v.z ) > __OFFSET_MDIR_V )
-    {
-      oldMouseDir = mouseDir;
-
-      SYNCHELP_WRITE_BYTE( DATA_mouse, NWT_SS_B );
-      PRINTF(0)("SENDING mousedir\n");
-      sentSomething = true;
-      SYNCHELP_WRITE_FLOAT( mouseDir.w, NWT_SS_MOUSEDIRW );
-      SYNCHELP_WRITE_FLOAT( mouseDir.v.x, NWT_SS_MOUSEDIRX );
-      SYNCHELP_WRITE_FLOAT( mouseDir.v.y, NWT_SS_MOUSEDIRY );
-      SYNCHELP_WRITE_FLOAT( mouseDir.v.z, NWT_SS_MOUSEDIRZ );
-    }
-#define __OFFSET_VEL 0.05
-    if ( fabs( oldVelocity.x - velocity.x ) > __OFFSET_VEL*fabs(oldVelocity.x)+0.1 ||
-         fabs( oldVelocity.y - velocity.y ) > __OFFSET_VEL*fabs(oldVelocity.y)+0.1 ||
-         fabs( oldVelocity.z - velocity.z ) > __OFFSET_VEL*fabs(oldVelocity.z)+0.1 )
-    {
-      oldVelocity.x = velocity.x;
-      oldVelocity.y = velocity.y;
-      oldVelocity.z = velocity.z;
-      PRINTF(0)("SENDING velocity\n");
-      sentSomething = true;
-      SYNCHELP_WRITE_BYTE( DATA_velocity, NWT_SS_B );
-      SYNCHELP_WRITE_FLOAT( velocity.x, NWT_SS_VELX );
-      SYNCHELP_WRITE_FLOAT( velocity.y, NWT_SS_VELY );
-      SYNCHELP_WRITE_FLOAT( velocity.z, NWT_SS_VELZ );
-    }
-
-    while ( Playable::needsReadSync() )
-    {
-      sentSomething = true;
-      PRINTF(0)("SYNCHELP_WRITE_FKT( Playable::readSync, NWT_SS_PL_SYNC )\n");
-      SYNCHELP_WRITE_BYTE( DATA_playables, NWT_SS_B );
-      SYNCHELP_WRITE_FKT( Playable::readSync, NWT_SS_PL_SYNC );
-    }
-
-  }
-
-  if ( !sentSomething )
-  {
-    *reciever = 0;
-
-    if ( networkCollisionList.size()>0 )
-    {
-      SYNCHELP_WRITE_BYTE( DATA_collision, NWT_SS_B );
-
-      SYNCHELP_WRITE_INT( networkCollisionList.size(), NWT_SS_CO_N );
-
-      for ( std::list<float>::iterator it = networkCollisionList.begin(); it!=networkCollisionList.end(); it++ )
-      {
-        SYNCHELP_WRITE_FLOAT( *it, NWT_SS_CO_CLID );
-      }
-
-      networkCollisionList.clear();
-    }
-  }
-
-  return SYNCHELP_WRITE_N;
-}
-
-
-void SpaceShip::doCollideNetwork( float energy )
-{
-  this->decreaseHealth( energy );
-  if( this->getHealth() <= 0)
-  {
-    this->die();
-  }
-}
-
-
-
+
+
Index: /trunk/src/world_entities/space_ships/space_ship.h
===================================================================
--- /trunk/src/world_entities/space_ships/space_ship.h	(revision 7953)
+++ /trunk/src/world_entities/space_ships/space_ship.h	(revision 7954)
@@ -43,11 +43,4 @@
     virtual void process(const Event &event);
 
-    virtual int       writeBytes(const byte* data, int length, int sender);
-    virtual int       readBytes(byte* data, int maxLength, int * reciever);
-
-    //HACK HACK HACK HACK make this private or remove it
-    void doCollideNetwork( float energy );
-    std::list<float>        networkCollisionList;
-
   private:
     void init();
Index: /trunk/src/world_entities/terrain.cc
===================================================================
--- /trunk/src/world_entities/terrain.cc	(revision 7953)
+++ /trunk/src/world_entities/terrain.cc	(revision 7954)
@@ -423,44 +423,4 @@
 }
 
-int Terrain::writeBytes( const byte * data, int length, int sender )
-{
-  setRequestedSync( false );
-  setIsOutOfSync( false );
-
-  SYNCHELP_READ_BEGIN();
-  SYNCHELP_READ_FKT( WorldEntity::writeState, NWT_TER_WE_STATE );
-
-  return SYNCHELP_READ_N;
-}
-
-int Terrain::readBytes( byte * data, int maxLength, int * reciever )
-{
-  if ( isOutOfSync() && !requestedSync() && this->getHostID()!=this->getOwner() )
-  {
-    (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
-    setRequestedSync( true );
-  }
-
-  int rec = this->getRequestSync();
-  if ( rec > 0 )
-  {
-    *reciever = rec;
-
-    SYNCHELP_WRITE_BEGIN();
-    SYNCHELP_WRITE_FKT( WorldEntity::readState, NWT_TER_WE_STATE );
-    return SYNCHELP_WRITE_N;
-
-  }
-
-  *reciever = 0;
-  return 0;
-}
-
-void Terrain::writeDebug( ) const
-  {}
-
-void Terrain::readDebug( ) const
-  {}
-
 float Terrain::getHeight(float x, float y)
 {
Index: /trunk/src/world_entities/terrain.h
===================================================================
--- /trunk/src/world_entities/terrain.h	(revision 7953)
+++ /trunk/src/world_entities/terrain.h	(revision 7954)
@@ -33,9 +33,4 @@
   virtual ~Terrain();
 
-  virtual int       writeBytes(const byte* data, int length, int sender);
-  virtual int       readBytes(byte* data, int maxLength, int * reciever);
-  virtual void      writeDebug() const;
-  virtual void      readDebug() const;
-
   void init();
   virtual void loadParams(const TiXmlElement* root);
Index: /trunk/src/world_entities/world_entity.cc
===================================================================
--- /trunk/src/world_entities/world_entity.cc	(revision 7953)
+++ /trunk/src/world_entities/world_entity.cc	(revision 7954)
@@ -70,5 +70,6 @@
   this->toList(OM_NULL);
 
-  //this->collisionHandles = new *CollisionHandle[CREngine::CR_NUMBER]();
+  modelFileName_handle = registerVarId( new SynchronizeableString( &modelFileName, &modelFileName, "modelFileName" ) );
+  scaling_handle = registerVarId( new SynchronizeableFloat( &scaling, &scaling, "scaling" ) );
 }
 
@@ -132,4 +133,14 @@
   this->modelLODName = fileName;
   this->scaling = scaling;
+
+  std::string name = fileName;
+
+  if (  name.find( ResourceManager::getInstance()->getDataDir() ) == 0 )
+  {
+    name.erase(ResourceManager::getInstance()->getDataDir().size());
+  }
+
+  this->modelFileName = name;
+
   if (!fileName.empty())
   {
@@ -524,93 +535,18 @@
 
 
-
-
-/********************************************************************************************
- NETWORK STUFF
- ********************************************************************************************/
-
-
-/**
- * Writes data from network containing information about the state
- * @param data pointer to data
- * @param length length of data
- * @param sender hostID of sender
- */
-int WorldEntity::writeState( const byte * data, int length, int sender )
-{
-  std::string modelFileName;
-  SYNCHELP_READ_BEGIN();
-
-  SYNCHELP_READ_FKT( PNode::writeState, NWT_WE_PN_WRITESTATE );
-
-  SYNCHELP_READ_STRING( modelFileName, NWT_WE_PN_MODELFILENAME );
-  SYNCHELP_READ_FLOAT( scaling, NWT_WE_PN_SCALING );
-  //check if modelFileName is relative to datadir or absolute
-
-
-  PRINTF(0)("================ LOADING MODEL %s, %f\n", modelFileName.c_str(), scaling);
-
-  if ( modelFileName != "" )
-  {
-    loadModel( modelFileName, scaling);
-    PRINTF(0)("modelfilename: %s\n", getModel( 0 )->getName());
-  }
-
-  /*SYNCHELP_READ_STRINGM( modelFileName );
-
-  if ( strcmp(modelFileName, "") )
-    if ( strstr(modelFileName, ResourceManager::getInstance()->getDataDir()) )
-    {
-      this->md2TextureFileName = new char[strlen(modelFileName)-strlen(ResourceManager::getInstance()->getDataDir())+1];
-      strcpy((char*)this->md2TextureFileName, modelFileName+strlen(ResourceManager::getInstance()->getDataDir()));
-    }
-    else
-    {
-      this->md2TextureFileName = modelFileName;
-    }
-  */
-
-  return SYNCHELP_READ_N;
-}
-
-
-/**
- * data copied in data will bee sent to another host
- * @param data pointer to data
- * @param maxLength max length of data
- * @return the number of bytes writen
- */
-int WorldEntity::readState( byte * data, int maxLength )
-{
-  SYNCHELP_WRITE_BEGIN();
-
-  SYNCHELP_WRITE_FKT( PNode::readState, NWT_WE_PN_WRITESTATE );
-
-  if ( getModel(0) && getModel(0)->getName() != "" )
-  {
-    std::string name = getModel( 0 )->getName();
-
-    if (  name.find( ResourceManager::getInstance()->getDataDir() ) == 0 )
-    {
-      name.erase(ResourceManager::getInstance()->getDataDir().size());
-    }
-
-    SYNCHELP_WRITE_STRING( name, NWT_WE_PN_MODELFILENAME );
-  }
-  else
-  {
-    SYNCHELP_WRITE_STRING("", NWT_WE_PN_MODELFILENAME);
-  }
-
-  SYNCHELP_WRITE_FLOAT( scaling, NWT_WE_PN_SCALING );
-  /*if ( this->md2TextureFileName!=NULL && strcmp(this->md2TextureFileName, "") )
-  {
-    SYNCHELP_WRITE_STRING(this->md2TextureFileName);
-  }
-  else
-  {
-    SYNCHELP_WRITE_STRING("");
-  }*/
-
-  return SYNCHELP_WRITE_N;
-}
+/**
+ * handler for changes on registred vars
+ * @param id id's which changed
+ */
+void WorldEntity::varChangeHandler( std::list< int > & id )
+{
+  if ( std::find( id.begin(), id.end(), modelFileName_handle ) != id.end() ||
+       std::find( id.begin(), id.end(), scaling_handle ) != id.end()
+     )
+  {
+    loadModel( modelFileName, scaling );
+  }
+
+  PNode::varChangeHandler( id );
+}
+
Index: /trunk/src/world_entities/world_entity.h
===================================================================
--- /trunk/src/world_entities/world_entity.h	(revision 7953)
+++ /trunk/src/world_entities/world_entity.h	(revision 7954)
@@ -99,4 +99,6 @@
   OrxGui::GLGuiWidget* getHealthWidget();
   bool hasHealthWidget() const { return this->healthWidget; };
+  
+  virtual void varChangeHandler( std::list<int> & id );
 
   /* --- Misc Stuff Block --- */
@@ -133,5 +135,12 @@
   ObjectManager::EntityList::iterator objectListIterator; //!< The iterator position of this Entity in the given list of the ObjectManager.
 
-  float                   scaling;
+  
+  //network stuff
+  
+  float       scaling;                         //!< model's scaling factor
+  int         scaling_handle;                  //!< handle for syncing var
+  
+  std::string modelFileName;                  //!< model's file name
+  int         modelFileName_handle;           //!< handle for syncing var
   CollisionHandle**       collisionHandles;
 
