Index: trunk/src/lib/network/Makefile.am
===================================================================
--- trunk/src/lib/network/Makefile.am	(revision 9494)
+++ trunk/src/lib/network/Makefile.am	(revision 9656)
@@ -27,4 +27,5 @@
 		      \
 		      proxy/network_settings.cc \
+		      proxy/proxy_control.cc \
 		      \
 		      monitor/connection_monitor.cc \
@@ -76,5 +77,6 @@
 		udp_broadcast.h \
 		\
-		proxy/network_settings.cc \
+		proxy/network_settings.h \
+		proxy/proxy_control.h \
 		\
 		monitor/connection_monitor.h \
Index: trunk/src/lib/network/README.NETWORK
===================================================================
--- trunk/src/lib/network/README.NETWORK	(revision 9494)
+++ trunk/src/lib/network/README.NETWORK	(revision 9656)
@@ -1,16 +1,24 @@
 
+
+
+
+WORD OF WARNING:
+================
+ - Allways keep the network_settings.conf file from the data repos up-to-date!! Its very important, that the user numbers are synchronized!
 
 
 WORKING_STACK:
 ==============
- - it works to connecto to a master server which is connected to a proxy itself
-
+ - removed compiler warnings in some modules
+ - totaly rework of the permission system
+ - introduced a new PERMISSION layer: PERMISSION_SERVER which gives the nearest server the authority to handle
 
 
 UNSOLVED:
 =========
- - what if the proxy server gets a new client and wants to add it to the game? There are some problems waiting in the network game manager
- - actualy the whole message sending system won't work in this network topic. proxys have to relay messages to clients
- - the clients cant get its ip in the handleHandshakes without throuwing sigseg
+ - the clients cant get its ip in the handleHandshakes without throwing sigseg
+ - MessageManager: proxy/server forward the messages always. Perhaps there is a case, where messages get forwarded forever if there is a loop in the network. think about it again.
+ - Permissions: Proxy Servers shouldn't be able to create new eneitites on the server
+ - the nick name must be handled new
 
 
@@ -48,8 +56,14 @@
 
 
+The ids are created by the master/proxy servers. Each server receives an address space of 1000 nodes where it is able to assign nodes to. This address space could be extended quite easely, since we got plenty of numbers in 4bytes (integer)
+
+The handshake sync has always the uniqueId == userId. This is why there are some reserved uniqueIds
+
 
 uniqueId:
 =========
 uniqueId is an id (unique :D) for each synchronizeable to be identified in a network. the number space for uniqueIds goes from 0 to maxplayers - 1
+
+The handshake sync has always the uniqueId == userId. This is why there are some reserved uniqueIds
 
 
@@ -62,4 +76,5 @@
 PERMISSION_ALL                 : all clients can write this variable
 
+Only the master server should have the permission to create new WorldEntities and to add them to the game
 
 
@@ -72,2 +87,10 @@
 
 
+MessageManager:
+===============
+The message manager has special handling if its a master/proxy: the messages will simply be forwarded to the other server
+
+
+Proxy Control:
+==============
+The ProxyControl class manages the state of the network by exchanging state messages.
Index: trunk/src/lib/network/handshake.cc
===================================================================
--- trunk/src/lib/network/handshake.cc	(revision 9494)
+++ trunk/src/lib/network/handshake.cc	(revision 9656)
@@ -71,5 +71,5 @@
   remoteState.error = 0;
   remoteState.errorString = "";
-  remoteState.hostId = -1;
+  remoteState.hostId = NET_ID_UNASSIGNED;
   remoteState.networkManagerId = -1;
   remoteState.messageManagerId = -1;
Index: trunk/src/lib/network/message_manager.cc
===================================================================
--- trunk/src/lib/network/message_manager.cc	(revision 9494)
+++ trunk/src/lib/network/message_manager.cc	(revision 9656)
@@ -11,5 +11,9 @@
    ### File Specific:
    main-programmer: Christoph Renner
-   co-programmer: ...
+   co-programmer: Patrick Boenzli (patrick@orxonox.ethz.ch)
+
+     June 2006: finishing work on the network stream for pps presentation (rennerc@ee.ethz.ch)
+     July 2006: some code rearangement and integration of the proxy server mechanism (boenzlip@ee.ethz.ch)
+     July 2006: message forwarding algorithms
 */
 
@@ -44,5 +48,5 @@
 MessageManager::~MessageManager ()
 {
-  for ( MessageQueue::iterator it = messageQueue.begin(); it != messageQueue.end(); it++ )
+  for ( MessageQueue::iterator it = outgoingMessageQueue.begin(); it != outgoingMessageQueue.end(); it++ )
   {
     for ( std::list<NetworkMessage>::iterator it2 = it->second.messages.begin(); it2 != it->second.messages.end(); it2++ )
@@ -59,5 +63,5 @@
   }
 
-  messageQueue.clear();
+  outgoingMessageQueue.clear();
 
   this->messageHandlerMap.clear();
@@ -85,9 +89,9 @@
   int n;
 
-  n = Converter::intToByteArray( messageQueue[userId].toAck.size(), data + i, maxLength );
+  n = Converter::intToByteArray( outgoingMessageQueue[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++)
+  for ( std::list<int>::iterator it = outgoingMessageQueue[userId].toAck.begin(); it != outgoingMessageQueue[userId].toAck.end(); it++)
   {
     n = Converter::intToByteArray( *it, data + i, maxLength );
@@ -96,24 +100,46 @@
   }
 
-  messageQueue[userId].toAck.clear();
-
-  n = Converter::intToByteArray( messageQueue[userId].messages.size(), data + i, maxLength );
+  outgoingMessageQueue[userId].toAck.clear();
+
+  n = Converter::intToByteArray( outgoingMessageQueue[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++ )
-  {
+  // write the message down, a message has this structure:
+  //   | data_length | serial_number | message_type | source_id | dest_id | ...data... |
+  //      4byte        4byte            4byte         4byte      4byte     data_length
+  for ( std::list<NetworkMessage>::iterator it = outgoingMessageQueue[userId].messages.begin(); it != outgoingMessageQueue[userId].messages.end(); it++ )
+  {
+    // send data length
     n = Converter::intToByteArray( it->length, data + i, maxLength );
     i += n;
     assert( n == INTSIZE );
 
+    // send serial number
     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 );
-
+    // send message type
+    n = Converter::intToByteArray( it->messageType, data + i, maxLength );
+    i += n;
+    assert( n == INTSIZE );
+
+    // send sender id
+    n = Converter::intToByteArray( it->senderId, data + i, maxLength );
+    i += n;
+    assert( n == INTSIZE );
+
+    // send destination id
+    n = Converter::intToByteArray( it->destinationId, data + i, maxLength );
+    i += n;
+    assert( n == INTSIZE );
+
+    // send receiver type
+    n = Converter::intToByteArray( it->recieverType, data + i, maxLength );
+    i += n;
+    assert( n == INTSIZE );
+
+    // and copy the data
     assert( i + it->length <= maxLength );
     memcpy( data + i, it->data, it->length );
@@ -141,4 +167,5 @@
   int nAcks;
 
+
   assert( i + INTSIZE <= length );
   n = Converter::byteArrayToInt( data + i, &nAcks );
@@ -167,8 +194,11 @@
   i += n;
 
-  int messageLength, messageId;
-
+  int messageLength, messageType;
+  int senderId, destinationId, recieverType;
+
+  // now go through all newly received messages and assemble them
   for ( int j = 0; j < nMessages; j++ )
   {
+    // read the length
     assert( i + INTSIZE <= length );
     n = Converter::byteArrayToInt( data + i, &messageLength );
@@ -176,4 +206,5 @@
     i += n;
 
+    // read the serial number
     assert( i + INTSIZE <= length );
     n = Converter::byteArrayToInt( data + i, &number );
@@ -181,38 +212,144 @@
     i += n;
 
-    assert( i + INTSIZE <= length );
-    n = Converter::byteArrayToInt( data + i, &messageId );
+    // read the message type
+    assert( i + INTSIZE <= length );
+    n = Converter::byteArrayToInt( data + i, &messageType );
+    assert( n == INTSIZE );
+    i += n;
+
+    // read the sender id
+    assert( i + INTSIZE <= length );
+    n = Converter::byteArrayToInt( data + i, &senderId );
+    assert( n == INTSIZE );
+    i += n;
+
+    //read the destination id
+    assert( i + INTSIZE <= length );
+    n = Converter::byteArrayToInt( data + i, &destinationId);
+    assert( n == INTSIZE );
+    i += n;
+
+    // read the receiver type
+    assert( i + INTSIZE <= length );
+    n = Converter::byteArrayToInt( data + i, &recieverType);
     assert( n == INTSIZE );
     i += n;
 
     if ( number > 0 )
-      messageQueue[userId].toAck.push_back( number );
-
+      outgoingMessageQueue[userId].toAck.push_back( number );
+
+//     PRINTF(0)("got message with type: %i\n", messageType);
     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() )
+    // make sure there is a message handler for this message type
+    assert( messageHandlerMap.find( (MessageType)messageType ) != messageHandlerMap.end());
+
+
+    if ( std::find( outgoingMessageQueue[userId].recievedMessages.begin(), outgoingMessageQueue[userId].recievedMessages.end(), number ) ==
+         outgoingMessageQueue[userId].recievedMessages.end() )
     {
-      if ( !(*(messageHandlerMap[(MessageId)messageId].cb))( (MessageId)messageId, data + i, messageLength, messageHandlerMap[(MessageId)messageId].someData, userId ) )
+
+      // find out if this message is addressed for this client too
+      if( recieverType == RT_ALL_BUT_ME  && SharedNetworkData::getInstance()->getHostID() != senderId ||
+          recieverType == RT_ALL_ME ||
+          recieverType == RT_NOT_USER && SharedNetworkData::getInstance()->getHostID() != destinationId ||
+          recieverType == RT_USER  && SharedNetworkData::getInstance()->getHostID() == destinationId ||
+          recieverType == RT_SERVER && SharedNetworkData::getInstance()->isMasterServer() ||
+          recieverType == RT_SERVER && SharedNetworkData::getInstance()->isProxyServerActive())
       {
-        NetworkMessage msg;
-
-        msg.data = new byte[messageLength];
-        memcpy( msg.data, data + i, messageLength );
-        msg.length = messageLength;
-        msg.messageId = (MessageId)messageId;
-        msg.number = userId;
-
-        incomingMessageBuffer.push_back( msg );
+
+        PRINTF(0)("<<< MessageManager: got msg with type: %i, from sender %i, to rec: %i\n", messageType, senderId, destinationId);
+      // call the handler function and handle errors
+        if ( !(*(messageHandlerMap[(MessageType)messageType].cb))( (MessageType)messageType, data + i, messageLength,
+                 messageHandlerMap[(MessageType)messageType].someData, senderId, destinationId ) )
+        {
+        // if the message is not handled correctly, bush it back to the incoming packets therefore trying it later
+          NetworkMessage msg;
+
+          msg.data = new byte[messageLength];
+          memcpy( msg.data, data + i, messageLength );
+          msg.length = messageLength;
+          msg.messageType = (MessageType)messageType;
+          msg.number = userId;
+          msg.senderId = senderId;
+          msg.recieverType = (RecieverType)recieverType;
+          msg.destinationId = destinationId;
+
+          incomingMessageQueue.push_back( msg );
+        }
       }
-      messageQueue[userId].recievedMessages.push_back( number );
+
+
+      // check if the message needs to be forwarded
+      if( recieverType == RT_ALL_BUT_ME ||
+          recieverType == RT_ALL_ME ||
+          recieverType == RT_NOT_USER ||
+          recieverType == RT_USER  && SharedNetworkData::getInstance()->getHostID() != destinationId ||
+          recieverType == RT_SERVER && SharedNetworkData::getInstance()->isProxyServerActive() )
+      {
+        // forwarding the messages but only if its a proxy
+        if( SharedNetworkData::getInstance()->isProxyServerActive())
+        {
+          PRINTF(0)("===========>> Forwarding Message msg with type: %i, from sender %i, to rec: %i\n", messageType, senderId, destinationId);
+          NetworkMessage msg;
+
+          msg.data = new byte[messageLength];
+          memcpy( msg.data, data + i, messageLength );
+          msg.length = messageLength;
+          msg.messageType = (MessageType)messageType;
+          msg.number = userId;
+          msg.senderId = senderId;
+          msg.destinationId = destinationId;
+          msg.recieverType = (RecieverType)recieverType;
+
+          this->sendMessage(msg.messageType, msg.data, msg.length, msg.recieverType, msg.senderId = senderId, msg.destinationId, MP_HIGHBANDWIDTH);
+        }
+      }
+
+      // save the serial number for ack signaling
+      outgoingMessageQueue[userId].recievedMessages.push_back( number );
     }
+
     i += messageLength;
   }
 
 
-  //TODO maybe handle incomingMessage in tick function. else local messages will not be handled if no clients are connected
-  for ( std::list<NetworkMessage>::iterator it = incomingMessageBuffer.begin(); it != incomingMessageBuffer.end();  )
-  {
-    if ( (*(messageHandlerMap[it->messageId].cb))( it->messageId, it->data, it->length, messageHandlerMap[it->messageId].someData, it->number ) )
+  //walk throu message queue and remove acked messages
+  for ( std::list<NetworkMessage>::iterator it = outgoingMessageQueue[userId].messages.begin(); it != outgoingMessageQueue[userId].messages.end();  )
+  {
+    if ( std::find( acks.begin(), acks.end(), it->number) != acks.end() )
+    {
+      std::list<NetworkMessage>::iterator delIt = it;
+      it++;
+      outgoingMessageQueue[userId].messages.erase( delIt );
+      continue;
+    }
+    it++;
+  }
+
+  //TODO find bether way. maybe with timestamp
+  if ( outgoingMessageQueue[userId].recievedMessages.size() > 1000 )
+  {
+    for ( int j = 0; j < (int)outgoingMessageQueue[userId].recievedMessages.size() - 1000; j++ )
+      outgoingMessageQueue[userId].recievedMessages.erase( outgoingMessageQueue[userId].recievedMessages.begin() );
+  }
+
+  return i;
+}
+
+
+
+
+/**
+ * processes the message manager data, specialy check for localy generated messages
+ */
+void MessageManager::processData()
+{
+  // now call the message handlers with the new message
+  for ( std::list<NetworkMessage>::iterator it = incomingMessageQueue.begin(); it != incomingMessageQueue.end();  )
+  {
+    PRINTF(0)("<<< MessageManager: got local msg with type: %i, from sender %i, to rec: %i\n", (*it).messageType, (*it).senderId, (*it).destinationId);
+
+    if ( (*(messageHandlerMap[it->messageType].cb))( it->messageType, it->data, it->length, messageHandlerMap[it->messageType].someData,
+                                                     /*it->number, */it->senderId, it->destinationId ) )
     {
       std::list<NetworkMessage>::iterator delIt = it;
@@ -220,5 +357,5 @@
         delete it->data;
       it++;
-      incomingMessageBuffer.erase( delIt );
+      incomingMessageQueue.erase( delIt );
       continue;
     }
@@ -226,26 +363,8 @@
   }
 
-  //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;
-}
+}
+
+
+
 
 /**
@@ -255,8 +374,8 @@
 void MessageManager::cleanUpUser( int userId )
 {
-  if ( messageQueue.find( userId ) == messageQueue.end() )
+  if ( outgoingMessageQueue.find( userId ) == outgoingMessageQueue.end() )
     return;
 
-  for ( std::list<NetworkMessage>::iterator it = messageQueue[userId].messages.begin(); it != messageQueue[userId].messages.end(); it++ )
+  for ( std::list<NetworkMessage>::iterator it = outgoingMessageQueue[userId].messages.begin(); it != outgoingMessageQueue[userId].messages.end(); it++ )
   {
     if ( it->data )
@@ -265,25 +384,25 @@
   }
 
-  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
+  outgoingMessageQueue[userId].toAck.clear();
+
+  outgoingMessageQueue.erase( userId );
+}
+
+/**
+ * registers function to handle messages with id messageType. someData is passed to callbackfuntion
+ * @param messageType 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 )
+bool MessageManager::registerMessageHandler( MessageType messageType, MessageCallback cb, void * someData )
 {
   MessageHandler messageHandler;
 
   messageHandler.cb = cb;
-  messageHandler.messageId = messageId;
+  messageHandler.messageType = messageType;
   messageHandler.someData = someData;
 
-  messageHandlerMap[messageId] = messageHandler;
+  messageHandlerMap[messageType] = messageHandler;
 
   return true;
@@ -297,7 +416,9 @@
 {
   // just do something so map creates a new entry
-  messageQueue[userId].toAck.clear();
-  //assert( messageQueue[userId].messages.size() == 0 );
-}
+  outgoingMessageQueue[userId].toAck.clear();
+  //assert( outgoingMessageQueue[userId].messages.size() == 0 );
+}
+
+
 
 /**
@@ -308,22 +429,47 @@
  *               RT_NOT_USER send to all but reciever
  *
- * @param messageId message id
+ * @param messageType 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++ )
-  {
+ * @param recieverType type of the receiver
+ * @param reciever the userId of the receiver if needed (depends on the ReceiverType)
+ */
+void MessageManager::sendMessage( MessageType messageType, byte * data, int dataLength, RecieverType recieverType, int reciever, MessagePriority messagePriority )
+{
+  this->sendMessage(messageType, data, dataLength, recieverType, SharedNetworkData::getInstance()->getHostID(), reciever, messagePriority);
+}
+
+
+/**
+ * send a message to one or more clients as a special client
+ * 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 messageType message id
+ * @param data pointer to data
+ * @param dataLength length of data
+ * @param recieverType type of the receiver
+ * @param sender the userId of the sender if there is need for shadowing it (eg. for msg forwarding)
+ * @param reciever the userId of the receiver if needed (depends on the ReceiverType)
+ */
+    void MessageManager::sendMessage( MessageType messageType, byte * data, int dataLength, RecieverType recieverType, int sender, int reciever, MessagePriority messagePriority )
+{
+  PRINTF(0)(" >>> MessageManager: sending msg with type: %i, recieverType: %i, reciever %i\n", messageType, recieverType, reciever);
+
+  // go through all outgoing message queues and add the message if its appropriate
+  for ( MessageQueue::iterator it = this->outgoingMessageQueue.begin(); it != this->outgoingMessageQueue.end(); it++ )
+  {
+
     if (
-         recieverType == RT_ALL_ME ||
-         recieverType == RT_ALL_BUT_ME ||
-         recieverType == RT_USER && it->first == reciever ||
-         recieverType == RT_NOT_USER && it->first != reciever ||
-         recieverType == RT_SERVER && getNetworkStream()->isUserMasterServer( it->first ) ||
-         recieverType == RT_SERVER && getNetworkStream()->isUserProxyServerActive( it->first )
-       )
+         recieverType == RT_ALL_ME      ||
+         recieverType == RT_ALL_BUT_ME  ||
+         recieverType == RT_USER        && it->first == reciever ||
+         recieverType == RT_USER        && reciever == NET_ID_MASTER_SERVER && !getNetworkStream()->isUserMasterServer( it->first ) ||  //(*)
+         recieverType == RT_NOT_USER    && it->first != reciever ||
+         recieverType == RT_SERVER      && getNetworkStream()->isUserMasterServer( it->first ) ||
+         recieverType == RT_SERVER      && getNetworkStream()->isUserProxyServerActive( it->first )
+       )// (*) special case: forward
     {
       NetworkMessage msg;
@@ -332,13 +478,22 @@
       memcpy( msg.data, data, dataLength );
       msg.length = dataLength;
-      msg.messageId = messageId;
-      msg.number = newNumber++;
+      msg.messageType = messageType;
+      msg.number = this->newNumber++;
+      msg.senderId = sender;
+      msg.destinationId = reciever;
+      msg.recieverType = recieverType;
       msg.priority = messagePriority;
 
       it->second.messages.push_back( msg );
     }
-  }
-
-  if ( recieverType == RT_ALL_ME )
+
+
+  }
+
+
+  // if the message is also for myself, handle it here
+  if ( recieverType == RT_ALL_ME ||
+       recieverType == RT_USER   && reciever == SharedNetworkData::getInstance()->getHostID()
+     )
   {
     NetworkMessage msg;
@@ -347,11 +502,14 @@
     memcpy( msg.data, data, dataLength );
     msg.length = dataLength;
-    msg.messageId = messageId;
+    msg.messageType = messageType;
     msg.number = SharedNetworkData::getInstance()->getHostID();
+    msg.senderId = sender;
+    msg.destinationId = reciever;
+    msg.recieverType = recieverType;
     msg.priority = messagePriority;
 
-    incomingMessageBuffer.push_back( msg );
-  }
-}
-
-
+    this->incomingMessageQueue.push_back( msg );
+  }
+}
+
+
Index: trunk/src/lib/network/message_manager.h
===================================================================
--- trunk/src/lib/network/message_manager.h	(revision 9494)
+++ trunk/src/lib/network/message_manager.h	(revision 9656)
@@ -20,5 +20,5 @@
       int length
       int number
-      int MessageId
+      int MessageType
       byte * data
     )[1..nmsg]
@@ -26,17 +26,23 @@
 
 
-enum MessageId
+//!< different message ids
+enum MessageType
 {
-  TESTMESSAGEID = 1,
-  MSGID_DELETESYNCHRONIZEABLE,
-  MSGID_PREFEREDTEAM,
-  MSGID_CHANGENICKNAME,
-  MSGID_CHATMESSAGE,
-  MSGID_RESPAWN
+  TESTMESSAGEID                  = 1,         //!< for testing purposes
+  MSGID_DELETESYNCHRONIZEABLE,                //!< message for sync deletion
+  MSGID_PREFEREDTEAM,                         //!< change prefered team
+  MSGID_CHANGENICKNAME,                       //!< change nicknames
+  MSGID_CHATMESSAGE,                          //!< chat message
+  MSGID_RESPAWN,                              //!< respawn message
+
+  MSGID_PROXY_NEWCLIENT,                       //!< informs the master server about a new client
+  MSGID_PROXY_LEAVECLIENT,                     //!< informs the master and other proxy servers about a leaving client
+  MSGID_PROXY_COMMAND,                         //!< command handler: delivers commands from and to proxies/clients
 };
 
-typedef bool (*MessageCallback)( MessageId messageId, byte * data, int dataLength, void * someData, int userId );
 
-enum RecieverType
+typedef bool (*MessageCallback)( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId );
+
+typedef enum RecieverType
 {
   RT_ALL_BUT_ME = 1,   //!< message is sent to all users but myself
@@ -57,9 +63,12 @@
 struct NetworkMessage
 {
-  MessageId        messageId;
-  byte *           data;
-  int              length;
-  int              number;
-  MessagePriority  priority;
+  MessageType      messageType;                         //!< type of the message
+  byte *           data;                                //!< data
+  int              length;                              //!< length of the data
+  int              number;                              //!< serial number
+  int              senderId;                            //!< userId of the sender
+  int              destinationId;                       //!< userId of the destination
+  RecieverType     recieverType;                        //!< type of the receiver
+  MessagePriority  priority;                            //!< priority of the messages
 };
 
@@ -73,17 +82,19 @@
 typedef std::map<int,MessageUserQueue> MessageQueue;
 
+
+
 struct MessageHandler
 {
-  MessageCallback cb;
-  MessageId       messageId;
-  void *          someData;
+  MessageCallback   cb;
+  MessageType       messageType;
+  void *            someData;
 };
 
-typedef std::map<MessageId,MessageHandler> MessageHandlerMap;
+typedef std::map<MessageType,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; }
@@ -91,8 +102,19 @@
    virtual ~MessageManager();
 
-   bool registerMessageHandler( MessageId messageId, MessageCallback cb, void * someData );
+   bool registerMessageHandler( MessageType messageType, MessageCallback cb, void * someData );
 
-   void sendMessage( MessageId messageId, byte * data, int dataLength, RecieverType recieverType, int reciever, MessagePriority messagePriority );
+   void sendMessage( MessageType messageType, byte * data, int dataLength, RecieverType recieverType, int reciever, MessagePriority messagePriority );
+   void sendMessage( MessageType messageType, byte * data, int dataLength, RecieverType recieverType, int sender, int reciever, MessagePriority messagePriority );
 
+   void initUser( int userId );
+
+   void processData();
+
+
+  protected:
+    MessageManager();
+
+
+  private:
    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 );
@@ -101,16 +123,16 @@
    virtual void handleRecvState( int userId, int stateId, int fromStateId ){}
 
-   void initUser( int userId );
-
 
  private:
-   static MessageManager *   singletonRef;
-   MessageQueue              messageQueue;           //!< stores messages to send
+   static MessageManager *   singletonRef;           //!< the singleton reference
+
+   std::list<NetworkMessage> incomingMessageQueue;   //!< the incoming message buffer
+   MessageQueue              outgoingMessageQueue;   //!< stores messages to send
    MessageHandlerMap         messageHandlerMap;      //!< contains handlers for messages
 
    int                       newNumber;              //!< used to create unique message numbers
-   std::list<NetworkMessage> incomingMessageBuffer;
+
 
 };
 
-#endif /* _PROTO_CLASS_H */
+#endif /* _MESSAGE_MANAGER_H */
Index: trunk/src/lib/network/monitor/network_monitor.cc
===================================================================
--- trunk/src/lib/network/monitor/network_monitor.cc	(revision 9494)
+++ trunk/src/lib/network/monitor/network_monitor.cc	(revision 9656)
@@ -10,5 +10,5 @@
 
 ### File Specific:
-   main-programmer: Patrick Boenzli
+   main-programmer: Patrick Boenzli (patrick@orxonox.ethz.ch)
 */
 
@@ -49,4 +49,5 @@
   this->networkStream = networkStream;
   this->playerNumber = 0;
+  this->connectionNumber = 0;
   // create the localnode, init it and add it to the nodes list
   this->localNode = new NetworkNode( this->networkStream->getPeerInfo());
@@ -66,9 +67,7 @@
       PeerInfo* peer = new PeerInfo();
       peer->ip = (*it);
-      peer->nodeType = NET_PROXY_SERVER_ACTIVE;
+      peer->nodeType = NET_PROXY_SERVER_PASSIVE;
       peer->userId = -1;
 
-      NetworkNode* node = new NetworkNode(peer);
-      this->addNode( node);
       this->addActiveProxyServer( this->localNode, peer);
     }
@@ -141,17 +140,24 @@
     return;
 
+  PRINTF(0)("^^^^^^^^^^^^^^^^^^^^^^^^^^ adding node: %i with type: %s\n\n", pInfo->userId, pInfo->getNodeTypeString().c_str());
+
   if( pInfo->isClient())
-    this->localNode->addClient(pInfo);
+  {
+    this->localNode->addClient(new NetworkNode(pInfo));
+  }
   else if( pInfo->isProxyServerActive())
   {
-    this->localNode->addActiveProxyServer(pInfo);
-    // create a new node, since a proxy can connect clients again
-    NetworkNode* node = new NetworkNode(pInfo);
-    this->nodeList.push_back(node);
+    this->localNode->addActiveProxyServer(new NetworkNode(pInfo));
+  }
+  else if( pInfo->isProxyServerActivePassive())
+  {
+    this->localNode->addPassiveProxyServer(new NetworkNode(pInfo));
   }
   else if( pInfo->isMasterServer())
   {
-    this->localNode->addMasterServer(pInfo);
-  }
+    this->localNode->addMasterServer(new NetworkNode(pInfo));
+  }
+  else
+    assert(false);
 }
 
@@ -168,9 +174,39 @@
 
   if( pInfo->isClient())
-    node->addClient(pInfo);
+    node->addClient(new NetworkNode(pInfo));
   else if( pInfo->isProxyServerActive())
-    node->addActiveProxyServer(pInfo);
+    node->addActiveProxyServer(new NetworkNode(pInfo));
   else if( pInfo->isMasterServer())
-    node->addMasterServer(pInfo);
+    node->addMasterServer(new NetworkNode(pInfo));
+}
+
+
+
+/**
+ * removes a node from the network monitor
+ * @param pInfo the node to remove
+ */
+void NetworkMonitor::removeNode(PeerInfo* pInfo)
+{
+  this->removeNode(this->localNode, pInfo);
+}
+
+
+/**
+ * removes the network node
+ * @param node the network node where the PeerInfo node is connected to
+ * @param pInfo the PeerInfo to remove
+ */
+void NetworkMonitor::removeNode(NetworkNode* node, PeerInfo* pInfo)
+{
+  if( node == NULL || pInfo == NULL)
+    return;
+
+  if( pInfo->isClient())
+    node->removeClient(pInfo->userId);
+  else if( pInfo->isProxyServerActive())
+    node->removeActiveProxyServer(pInfo->userId);
+  else if( pInfo->isMasterServer())
+    node->removeMasterServer(pInfo->userId);
 }
 
@@ -197,4 +233,37 @@
 
 /**
+ * @param userId of the searched node
+ * @returns the PeerInfo of the userId peer
+ */
+PeerInfo* NetworkMonitor::getPeerByUserId( int userId)
+{
+  NetworkNode* node = this->getNodeByUserId(userId);
+  if( node != NULL)
+    return node->getPeerInfo();
+
+  return NULL;
+}
+
+/**
+ * searches for a given NetworkNode
+ * @param userId of the searched node
+ * @returns the PeerInfo of the userId peer
+ */
+NetworkNode* NetworkMonitor::getNodeByUserId( int userId)
+{
+  std::list<NetworkNode*>::iterator it = this->nodeList.begin();
+  NetworkNode* node = NULL;
+  for(; it != this->nodeList.end(); it++)
+  {
+    node = (*it)->getNodeByUserId(userId);
+    if( node != NULL)
+      return node;
+  }
+
+  return NULL;
+}
+
+
+/**
  * this displays the network monitor gui
  */
@@ -203,13 +272,6 @@
   if (this->box == NULL)
   {
-    this->box = new OrxGui::GLGuiBox(OrxGui::Vertical);
-    {
-      NetworkStatsWidget* netStats = new NetworkStatsWidget(this);
-      this->box->pack(netStats);
-
-    }
-
+    this->box = new NetworkStatsWidget(this);
     this->box->showAll();
-    this->box->setAbsCoor2D(300, 40);
   }
   else
@@ -251,5 +313,5 @@
   for(; it != this->nodeList.end(); it++)
   {
-    (*it)->debug(0);
+    (*it)->debug(1);
   }
 
Index: trunk/src/lib/network/monitor/network_monitor.h
===================================================================
--- trunk/src/lib/network/monitor/network_monitor.h	(revision 9494)
+++ trunk/src/lib/network/monitor/network_monitor.h	(revision 9656)
@@ -42,16 +42,19 @@
 
     /** adds to @param node a network node @param pInfo a new client */
-    inline void addClient(NetworkNode* node, PeerInfo* pInfo) { node->addClient(pInfo); }
+    inline void addClient(NetworkNode* node, PeerInfo* pInfo) { node->addClient(new NetworkNode(pInfo)); }
     /** adds to @param node a network node @param pInfo a new proxy server */
-    inline void addActiveProxyServer(NetworkNode* node, PeerInfo* pInfo) { node->addActiveProxyServer(pInfo); }
+    inline void addActiveProxyServer(NetworkNode* node, PeerInfo* pInfo) { node->addActiveProxyServer(new NetworkNode(pInfo)); }
     /** adds to @param node a network node @param pInfo a new proxy server */
-    inline void addPassiveProxyServer(NetworkNode* node, PeerInfo* pInfo) { node->addPassiveProxyServer(pInfo); }
+    inline void addPassiveProxyServer(NetworkNode* node, PeerInfo* pInfo) { node->addPassiveProxyServer(new NetworkNode(pInfo)); }
     /** adds to @param node a network node @param pInfo a new master server*/
-    inline void addMasterServer(NetworkNode* node, PeerInfo* pInfo) { node->addMasterServer(pInfo); }
+    inline void addMasterServer(NetworkNode* node, PeerInfo* pInfo) { node->addMasterServer(new NetworkNode(pInfo)); }
 
-    inline void removeClient(NetworkNode* node, PeerInfo* pInfo) { node->removeClient(pInfo); }
-    inline void removeActiveProxyServer(NetworkNode* node, PeerInfo* pInfo) { node->removeActiveProxyServer(pInfo); }
-    inline void removePassiveProxyServer(NetworkNode* node, PeerInfo* pInfo) { node->removePassiveProxyServer(pInfo); }
-    inline void removeMasterServer(NetworkNode* node, PeerInfo* pInfo) { node->removeMasterServer(pInfo); }
+    void removeNode(PeerInfo* pInfo);
+    void removeNode(NetworkNode* node, PeerInfo* pInfo);
+
+    inline void removeClient(NetworkNode* node, int userId) { node->removeClient(userId); }
+    inline void removeActiveProxyServer(NetworkNode* node, int userId) { node->removeActiveProxyServer(userId); }
+    inline void removePassiveProxyServer(NetworkNode* node, int userId) { node->removePassiveProxyServer(userId); }
+    inline void removeMasterServer(NetworkNode* node, int userId) { node->removeMasterServer(userId); }
 
     PeerInfo* getFirstChoiceProxy() const;
@@ -61,5 +64,5 @@
 
     /** @returns the active proxy server list of the localnode */
-    inline std::list<PeerInfo*> getActiveProxyServer() const { return this->localNode->getActiveProxyServer(); }
+    inline std::list<NetworkNode*> getActiveProxyServers() const { return this->localNode->getActiveProxyServers(); }
 
     /* slots admin and info interface */
@@ -76,4 +79,12 @@
 
     inline const std::list<NetworkNode*>& getNodeList() const { return this->nodeList; };
+    PeerInfo* getPeerByUserId( int userId);
+    NetworkNode* getNodeByUserId( int userId);
+
+    /* forced reconnection interface */
+    inline void setForcedReconnection(IP address) { this->bForcedRecon = true; this->forcedReconnection = address;}
+    inline bool isForcedReconnection() const { return this->bForcedRecon; }
+    inline IP getForcedReconnectionIP() { this->bForcedRecon = false; return this->forcedReconnection; }
+
 
     void toggleGUI();
@@ -92,4 +103,7 @@
     int                          playerNumber;                 //!< total number of players in the game
     int                          connectionNumber;             //!< total number of connections at this localhost
+
+    IP                           forcedReconnection;           //!< ip of a forced reconnection
+    bool                         bForcedRecon;                 //!< true if there is a forced recon
 };
 
Index: trunk/src/lib/network/monitor/network_node.cc
===================================================================
--- trunk/src/lib/network/monitor/network_node.cc	(revision 9494)
+++ trunk/src/lib/network/monitor/network_node.cc	(revision 9656)
@@ -18,5 +18,4 @@
 #include "debug.h"
 
-
 /**
  * constructor
@@ -39,5 +38,5 @@
  * adds a client
  */
-void NetworkNode::addClient(PeerInfo* node)
+void NetworkNode::addClient(NetworkNode* node)
 {
   this->clientList.push_back(node);
@@ -49,5 +48,5 @@
  * adds a proxy server
  */
-void NetworkNode::addActiveProxyServer(PeerInfo* node)
+void NetworkNode::addActiveProxyServer(NetworkNode* node)
 {
   this->activeProxyServerList.push_back(node);
@@ -58,5 +57,5 @@
  * adds a proxy server
  */
-void NetworkNode::addPassiveProxyServer(PeerInfo* node)
+void NetworkNode::addPassiveProxyServer(NetworkNode* node)
 {
   this->passiveProxyServerList.push_back(node);
@@ -66,5 +65,5 @@
  * adds a master server
  */
-void NetworkNode::addMasterServer(PeerInfo* node)
+void NetworkNode::addMasterServer(NetworkNode* node)
 {
   this->masterServerList.push_back(node);
@@ -75,7 +74,7 @@
  * removes a client
  */
-void NetworkNode::removeClient(PeerInfo* node)
-{
-  std::list<PeerInfo*>::iterator it = this->clientList.begin();
+void NetworkNode::removeClient(NetworkNode* node)
+{
+  std::list<NetworkNode*>::iterator it = this->clientList.begin();
   for(; it != this->clientList.end(); it++)
   {
@@ -94,7 +93,7 @@
  * removes a proxy server
  */
-void NetworkNode::removeActiveProxyServer(PeerInfo* node)
-{
-  std::list<PeerInfo*>::iterator it = this->activeProxyServerList.begin();
+void NetworkNode::removeActiveProxyServer(NetworkNode* node)
+{
+  std::list<NetworkNode*>::iterator it = this->activeProxyServerList.begin();
   for(; it != this->activeProxyServerList.end(); it++)
   {
@@ -113,7 +112,7 @@
  * removes a proxy server
  */
-void NetworkNode::removePassiveProxyServer(PeerInfo* node)
-{
-  std::list<PeerInfo*>::iterator it = this->passiveProxyServerList.begin();
+void NetworkNode::removePassiveProxyServer(NetworkNode* node)
+{
+  std::list<NetworkNode*>::iterator it = this->passiveProxyServerList.begin();
   for(; it != this->passiveProxyServerList.end(); it++)
   {
@@ -131,7 +130,7 @@
  * removes a master server
  */
-void NetworkNode::removeMasterServer(PeerInfo* node)
-{
-  std::list<PeerInfo*>::iterator it = this->masterServerList.begin();
+void NetworkNode::removeMasterServer(NetworkNode* node)
+{
+  std::list<NetworkNode*>::iterator it = this->masterServerList.begin();
   for(; it != this->masterServerList.end(); it++)
   {
@@ -145,4 +144,128 @@
 
   PRINTF(2)("Could not remove client from the list, very strange...");
+}
+
+
+
+
+/**
+ * removes a client
+ */
+void NetworkNode::removeClient(int userId)
+{
+  std::list<NetworkNode*>::iterator it = this->clientList.begin();
+  for(; it != this->clientList.end(); it++)
+  {
+    if( (*it)->getPeerInfo()->userId == userId)
+    {
+      this->clientList.erase(it);
+      this->playerNumber--;
+      return;
+    }
+  }
+
+  PRINTF(2)("Could not remove client from the list, very strange...");
+}
+
+/**
+ * removes a proxy server
+ */
+void NetworkNode::removeActiveProxyServer(int userId)
+{
+  std::list<NetworkNode*>::iterator it = this->activeProxyServerList.begin();
+  for(; it != this->activeProxyServerList.end(); it++)
+  {
+    if( (*it)->getPeerInfo()->userId == userId)
+    {
+      this->activeProxyServerList.erase(it);
+      this->playerNumber--;
+      return;
+    }
+  }
+
+  PRINTF(2)("Could not remove proxy server from the list, very strange...");
+}
+
+/**
+ * removes a proxy server
+ */
+void NetworkNode::removePassiveProxyServer(int userId)
+{
+  std::list<NetworkNode*>::iterator it = this->passiveProxyServerList.begin();
+  for(; it != this->passiveProxyServerList.end(); it++)
+  {
+    if( (*it)->getPeerInfo()->userId == userId)
+    {
+      this->passiveProxyServerList.erase(it);
+      return;
+    }
+  }
+
+  PRINTF(2)("Could not remove proxy server from the list, very strange...");
+}
+
+/**
+ * removes a master server
+ */
+void NetworkNode::removeMasterServer(int userId)
+{
+  std::list<NetworkNode*>::iterator it = this->masterServerList.begin();
+  for(; it != this->masterServerList.end(); it++)
+  {
+    if( (*it)->getPeerInfo()->userId == userId)
+    {
+      this->masterServerList.erase(it);
+      this->playerNumber--;
+      return;
+    }
+  }
+
+  PRINTF(2)("Could not remove client from the list, very strange...");
+}
+
+
+
+
+
+/**
+ *  gets the peer info by user id
+ * @param userId  the user id of the node to look up
+ * @return the peer info of this node NULL if nothing found
+ */
+PeerInfo* NetworkNode::getPeerByUserId( int userId)
+{
+  // look through the master server lists
+  std::list<NetworkNode*>::const_iterator it = this->masterServerList.begin();
+  for( ;it != this->masterServerList.end(); it++)
+  {
+    if( (*it)->getPeerInfo()->userId == userId)
+      return (*it)->getPeerInfo();
+  }
+
+  // look through the active proxy server list
+  it = this->activeProxyServerList.begin();
+  for( ; it != this->activeProxyServerList.end(); it++)
+  {
+    if( (*it)->getPeerInfo()->userId == userId)
+      return (*it)->getPeerInfo();
+  }
+
+  // look through the passive server list
+  it = this->passiveProxyServerList.begin();
+  for( ; it != this->passiveProxyServerList.end(); it++)
+  {
+    if( (*it)->getPeerInfo()->userId == userId)
+      return (*it)->getPeerInfo();
+  }
+
+  // look through the client list
+  it = this->clientList.begin();
+  for( ; it != this->clientList.end(); it++)
+  {
+    if( (*it)->getPeerInfo()->userId == userId)
+      return (*it)->getPeerInfo();
+  }
+
+  return NULL;
 }
 
@@ -154,12 +277,12 @@
 PeerInfo* NetworkNode::getClient(int index) const
 {
-  if( this->clientList.size() < index)
+  if( (int)this->clientList.size() < index)
     return NULL;
 
-  std::list<PeerInfo*>::const_iterator it = this->clientList.begin();
+  std::list<NetworkNode*>::const_iterator it = this->clientList.begin();
   for(int i = 0; it != this->clientList.end(); it++, i++)
   {
   if( i == index)
-    return (*it);
+    return (*it)->getPeerInfo();
   }
 
@@ -174,12 +297,12 @@
 PeerInfo* NetworkNode::getActiveProxyServer(int index) const
 {
-  if( this->activeProxyServerList.size() < index)
+  if( (int)this->activeProxyServerList.size() < index)
     return NULL;
 
-  std::list<PeerInfo*>::const_iterator it = this->activeProxyServerList.begin();
+  std::list<NetworkNode*>::const_iterator it = this->activeProxyServerList.begin();
   for(int i = 0; it != this->activeProxyServerList.end(); it++, i++)
   {
     if( i == index)
-      return (*it);
+      return (*it)->getPeerInfo();
   }
 
@@ -194,12 +317,12 @@
 PeerInfo* NetworkNode::getPassiveProxyServer(int index) const
 {
-  if( this->passiveProxyServerList.size() < index)
+  if( (int)this->passiveProxyServerList.size() < index)
     return NULL;
 
-  std::list<PeerInfo*>::const_iterator it = this->passiveProxyServerList.begin();
+  std::list<NetworkNode*>::const_iterator it = this->passiveProxyServerList.begin();
   for(int i = 0; it != this->passiveProxyServerList.end(); it++, i++)
   {
     if( i == index)
-      return (*it);
+      return (*it)->getPeerInfo();
   }
 
@@ -214,12 +337,62 @@
 PeerInfo* NetworkNode::getMasterServer(int index) const
 {
-  if( this->masterServerList.size() < index)
+  if( (int)this->masterServerList.size() < index)
     return NULL;
 
-  std::list<PeerInfo*>::const_iterator it = this->masterServerList.begin();
+  std::list<NetworkNode*>::const_iterator it = this->masterServerList.begin();
   for(int i = 0; it != this->masterServerList.end(); it++, i++)
   {
     if( i == index)
-      return (*it);
+      return (*it)->getPeerInfo();
+  }
+
+  return NULL;
+}
+
+
+
+/**
+ * searches for a given NetworkNode
+ * @param userId of the searched node
+ * @returns the PeerInfo of the userId peer
+ */
+NetworkNode* NetworkNode::getNodeByUserId( int userId)
+{
+  if( this->peerInfo->userId == userId)
+    return this;
+
+
+  NetworkNode* node = NULL;
+  std::list<NetworkNode*>::const_iterator it = this->masterServerList.begin();
+
+  for(; it != this->masterServerList.end(); it++)
+  {
+    node = (*it)->getNodeByUserId(userId);
+    if( node != NULL)
+      return node;
+  }
+
+  it = this->activeProxyServerList.begin();
+  for(; it != this->activeProxyServerList.end(); it++)
+  {
+    node = (*it)->getNodeByUserId(userId);
+    if( node != NULL)
+      return node;
+  }
+
+  it = this->passiveProxyServerList.begin();
+  for(; it != this->passiveProxyServerList.end(); it++)
+  {
+    node = (*it)->getNodeByUserId(userId);
+    if( node != NULL)
+      return node;
+  }
+
+  it = this->clientList.begin();
+  for(; it != this->clientList.end(); it++)
+  {
+    node = (*it)->getNodeByUserId(userId);
+    if( node != NULL)
+      return node;
   }
 
@@ -234,37 +407,53 @@
 void NetworkNode::debug(int depth) const
 {
-  PRINT(0)(" = %s\n", this->peerInfo->getNodeTypeString().c_str());
-
-  PRINT(0)("    master servers: %i\n", this->masterServerList.size());
-  std::list<PeerInfo*>::const_iterator it = this->masterServerList.begin();
-  for(; it != this->masterServerList.end(); it++)
-  {
-    IP* ip = &(*it)->ip;
-    PRINT(0)("     - ms, id: %i (%s)\n", (*it)->userId, ip->ipString().c_str());
-  }
-
-  PRINT(0)("    proxy servers active: %i\n", this->activeProxyServerList.size());
-  it = this->activeProxyServerList.begin();
-  for(; it != this->activeProxyServerList.end(); it++)
-  {
-    IP* ip = &(*it)->ip;
-    PRINT(0)("     - ps-a, id: %i (%s)\n", (*it)->userId, ip->ipString().c_str());
-  }
-
-  PRINT(0)("    proxy servers passive: %i\n", this->passiveProxyServerList.size());
-  it = this->passiveProxyServerList.begin();
-  for(; it != this->passiveProxyServerList.end(); it++)
-  {
-    IP* ip = &(*it)->ip;
-    PRINT(0)("     - ps-p, id: %i (%s)\n", (*it)->userId, ip->ipString().c_str());
-  }
-
-  PRINT(0)("    clients: %i\n", this->clientList.size());
-  it = this->clientList.begin();
-  for(; it != this->clientList.end(); it++)
-  {
-    IP* ip = &(*it)->ip;
-    PRINT(0)("     - client, id: %i (%s)\n", (*it)->userId, ip->ipString().c_str());
-  }
-}
-
+  char indent[depth +1];
+  for( int i = 0; i < depth; i++) {     indent[i] = ' ';  }
+  indent[depth] = '\0';
+
+  PRINT(0)("%s + %s, with id %i and ip: %s\n", indent, this->peerInfo->getNodeTypeString().c_str(), this->peerInfo->userId, this->peerInfo->ip.ipString().c_str());
+
+
+
+  std::list<NetworkNode*>::const_iterator it;
+  if( !this->masterServerList.empty())
+  {
+    it = this->masterServerList.begin();
+
+    for(; it != this->masterServerList.end(); it++)
+    {
+      (*it)->debug(depth+1);
+    }
+  }
+
+  if( !this->activeProxyServerList.empty())
+  {
+    it = this->activeProxyServerList.begin();
+
+    for(; it != this->activeProxyServerList.end(); it++)
+    {
+      (*it)->debug(depth+1);
+    }
+  }
+
+
+  if( !this->passiveProxyServerList.empty())
+  {
+    it = this->passiveProxyServerList.begin();
+
+    for(; it != this->passiveProxyServerList.end(); it++)
+    {
+      (*it)->debug(depth+1);
+    }
+  }
+
+  if( !this->clientList.empty())
+  {
+    it = this->clientList.begin();
+
+    for(; it != this->clientList.end(); it++)
+    {
+      (*it)->debug(depth+1);
+    }
+  }
+}
+
Index: trunk/src/lib/network/monitor/network_node.h
===================================================================
--- trunk/src/lib/network/monitor/network_node.h	(revision 9494)
+++ trunk/src/lib/network/monitor/network_node.h	(revision 9656)
@@ -13,5 +13,4 @@
 #include <list>
 
-
 //!< a class representing a node in the network (this can be a MASTER_SERVER, PROXY_SERVER or a CLIENT
 class NetworkNode
@@ -22,13 +21,19 @@
 
 
-    void addClient(PeerInfo* node);
-    void addActiveProxyServer(PeerInfo* node);
-    void addPassiveProxyServer(PeerInfo* node);
-    void addMasterServer(PeerInfo* node);
+    void addClient(NetworkNode* node);
+    void addActiveProxyServer(NetworkNode* node);
+    void addPassiveProxyServer(NetworkNode* node);
+    void addMasterServer(NetworkNode* node);
 
-    void removeClient(PeerInfo* node);
-    void removeActiveProxyServer(PeerInfo* node);
-    void removePassiveProxyServer(PeerInfo* node);
-    void removeMasterServer(PeerInfo* node);
+    void removeClient(NetworkNode* node);
+    void removeActiveProxyServer(NetworkNode* node);
+    void removePassiveProxyServer(NetworkNode* node);
+    void removeMasterServer(NetworkNode* node);
+
+    void removeClient(int userId);
+    void removeActiveProxyServer(int userId);
+    void removePassiveProxyServer(int userId);
+    void removeMasterServer(int userId);
+
 
     PeerInfo* getClient(int index) const;
@@ -38,12 +43,13 @@
 
     /** @returns the master server list */
-    inline std::list<PeerInfo*> getMasterServer() const { return this->masterServerList; }
+    inline std::list<NetworkNode*> getMasterServers() const { return this->masterServerList; }
     /** @returns the active proxy server list */
-    inline std::list<PeerInfo*> getActiveProxyServer() const { return this->activeProxyServerList; }
+    inline std::list<NetworkNode*> getActiveProxyServers() const { return this->activeProxyServerList; }
     /** @returns the passive proxy server list */
-    inline std::list<PeerInfo*> getPassiveProxyServer() const { return this->passiveProxyServerList; }
+    inline std::list<NetworkNode*> getPassiveProxyServers() const { return this->passiveProxyServerList; }
     /** @returns the client list */
-    inline std::list<PeerInfo*> getClient() const { return this->clientList; }
+    inline std::list<NetworkNode*> getClients() const { return this->clientList; }
 
+    PeerInfo* getPeerByUserId( int userId);
 
     /** @returns the number of players */
@@ -53,4 +59,6 @@
     /** @returns the peer info of this node */
     inline PeerInfo* getPeerInfo() const { return this->peerInfo; }
+
+    NetworkNode* getNodeByUserId( int userId);
 
     void debug(int depth) const;
@@ -63,8 +71,8 @@
 
     /* network nodes directly connected to this node */
-    std::list<PeerInfo*>         clientList;                   //!< list of all clients in the network
-    std::list<PeerInfo*>         activeProxyServerList;        //!< list of all proxy servers in the network
-    std::list<PeerInfo*>         passiveProxyServerList;       //!< list of all proxy servers in the network
-    std::list<PeerInfo*>         masterServerList;             //!< list of all master servers in the network (should be 1!! :D)
+    std::list<NetworkNode*>         clientList;                   //!< list of all clients in the network
+    std::list<NetworkNode*>         activeProxyServerList;        //!< list of all proxy servers in the network
+    std::list<NetworkNode*>         passiveProxyServerList;       //!< list of all proxy servers in the network
+    std::list<NetworkNode*>         masterServerList;             //!< list of all master servers in the network (should be 1!! :D)
 
 };
Index: trunk/src/lib/network/monitor/network_stats_widget.cc
===================================================================
--- trunk/src/lib/network/monitor/network_stats_widget.cc	(revision 9494)
+++ trunk/src/lib/network/monitor/network_stats_widget.cc	(revision 9656)
@@ -18,4 +18,5 @@
 #include "network_stats_widget.h"
 #include "network_monitor.h"
+#include "peer_info.h"
 
 #include "multi_type.h"
@@ -23,6 +24,9 @@
 #include "shell_command.h"
 
-// SHELL_COMMAND(gui, NetworkMonitor, toggleGUI)
-//  ->setAlias("ProxyGui");
+#include "loading/resource_manager.h"
+
+// this fcuk does not work!
+// SHELL_COMMAND(gui, NetworkStatsWidget, toggleGUI)
+// ->setAlias("ProxyGui");
 
 
@@ -30,7 +34,34 @@
     : GLGuiBox(OrxGui::Horizontal)
 {
+  this->init();
+
   this->setName(name);
   this->setIP(ip);
 
+}
+
+HostWidget::HostWidget(const PeerInfo* peerInfo)
+    : GLGuiBox(OrxGui::Horizontal)
+{
+  this->init();
+  if (peerInfo == NULL)
+  {
+    this->setName("INVALID");
+    return;
+  }
+  this->setName(peerInfo->getNodeTypeString() + "ID: " + MultiType(peerInfo->userId).getString());
+  this->setIP(peerInfo->ip);
+}
+
+void HostWidget::init()
+{
+  if(_font == NULL)
+    _font = new Font(ResourceManager::getInstance()->getDataDir() + "/fonts/arial.ttf", 20);
+
+  //this->_name.setFont(*_font);
+  this->_name.setTextSize(15);
+  //this->_ip.setFont(*_font);
+  this->_ip.setTextSize(15);
+
   this->pack(&this->_name);
   this->pack(&this->_ip);
@@ -49,4 +80,7 @@
 }
 
+Font* HostWidget::_font = NULL;
+
+
 
 
@@ -54,15 +88,49 @@
 
 
-ProxyWidget::ProxyWidget(const std::string& proxyName, const IP& ip)
+NodeWidget::NodeWidget(const std::string& proxyName, const IP& ip)
     : _proxyWidget(proxyName, ip)
 {
-  this->_clientNameWidth = 100.0f;
+  this->_nodeNameWidth = 100.0f;
   this->pack(&_proxyWidget);
 }
 
-void ProxyWidget::addClient(const std::string& name, const IP& ip)
+NodeWidget::NodeWidget(const NetworkNode* node)
+    : _proxyWidget(node->getPeerInfo())// "node", node->getPeerInfo()->ip)
+{
+  this->_nodeNameWidth = 100.0f;
+  this->pack(&_proxyWidget);
+
+  std::list<NetworkNode*> list = node->getMasterServers();
+  std::list<NetworkNode*>::const_iterator it;
+
+  for(it = list.begin(); it != list.end(); it++)
+    this->addNode(*it);
+
+  list = node->getActiveProxyServers();
+  for(it = list.begin(); it != list.end(); it++)
+    this->addNode(*it);
+
+  list = node->getPassiveProxyServers();
+  for(it = list.begin(); it != list.end(); it++)
+    this->addNode(*it);
+
+  list = node->getClients();
+  for(it = list.begin(); it != list.end(); it++)
+    this->addNode(*it);
+}
+
+
+void NodeWidget::addNode(const NetworkNode* node)
+{
+  this->_nodes.push_back(new NodeWidget(node));
+  this->pack(this->_nodes.back());
+  this->_nodes.back()->show();
+}
+
+
+void NodeWidget::addNode(const std::string& name, const IP& ip)
 {
   HostWidget* newClient = new HostWidget(name, ip);
-  newClient->setNameWidth(this->_clientNameWidth);
+  newClient->setNameWidth(this->_nodeNameWidth);
 
   this->pack(newClient);
@@ -72,70 +140,70 @@
 }
 
-bool ProxyWidget::removeClient(const IP& ip)
-{
-  std::vector<HostWidget*>::iterator rmIt;
-  for(rmIt = this->_clients.begin(); rmIt != this->_clients.end(); ++rmIt)
-  {
-    if (*(*rmIt) == ip)
-    {
-      delete (*rmIt);
-      this->_clients.erase(rmIt);
-      return true;
-    }
-  }
-  return false;
-}
-
-bool ProxyWidget::removeClient(const std::string& name)
-{
-  std::vector<HostWidget*>::iterator rmIt;
-  for(rmIt = this->_clients.begin(); rmIt != this->_clients.end(); ++rmIt)
-  {
-    if (*(*rmIt) == name)
-    {
-      delete (*rmIt);
-      this->_clients.erase(rmIt);
-      return true;
-    }
-  }
-  return false;
-
-}
-
-bool ProxyWidget::removeClient(const std::string& name, const IP& ip)
-{
-  std::vector<HostWidget*>::iterator rmIt;
-  for(rmIt = this->_clients.begin(); rmIt != this->_clients.end(); ++rmIt)
-  {
-    if (*(*rmIt) == ip && *(*rmIt) == name)
-    {
-      delete (*rmIt);
-      this->_clients.erase(rmIt);
-      return true;
-    }
-  }
-  return false;
-}
-
-
-void ProxyWidget::setClientNameWidths(float width)
-{
-  this->_clientNameWidth = width;
-  for (unsigned int i = 0; i < this->_clients.size(); ++i)
-    this->_clients[i]->setNameWidth(width);
-}
-
-void ProxyWidget::hiding()
+bool NodeWidget::removeNode(const IP& ip)
+{
+//   std::vector<HostWidget*>::iterator rmIt;
+//   for(rmIt = this->_nodes.begin(); rmIt != this->_nodes.end(); ++rmIt)
+//   {
+//     if (*(*rmIt) == ip)
+//     {
+//       delete (*rmIt);
+//       this->_nodes.erase(rmIt);
+//       return true;
+//     }
+//   }
+//   return false;
+}
+
+bool NodeWidget::removeNode(const std::string& name)
+{
+//   std::vector<HostWidget*>::iterator rmIt;
+//   for(rmIt = this->_nodes.begin(); rmIt != this->_nodes.end(); ++rmIt)
+//   {
+//     if (*(*rmIt) == name)
+//     {
+//       delete (*rmIt);
+//       this->_nodes.erase(rmIt);
+//       return true;
+//     }
+//   }
+//   return false;
+
+}
+
+bool NodeWidget::removeNode(const std::string& name, const IP& ip)
+{
+//   std::vector<HostWidget*>::iterator rmIt;
+//   for(rmIt = this->_nodes.begin(); rmIt != this->_nodes.end(); ++rmIt)
+//   {
+//     if (*(*rmIt) == ip && *(*rmIt) == name)
+//     {
+//       delete (*rmIt);
+//       this->_nodes.erase(rmIt);
+//       return true;
+//     }
+//   }
+//   return false;
+}
+
+
+void NodeWidget::setNodeNameWidths(float width)
+{
+/*  this->_nodeNameWidth = width;
+  for (unsigned int i = 0; i < this->_nodes.size(); ++i)
+    this->_nodes[i]->setNameWidth(width);*/
+}
+
+void NodeWidget::hiding()
 {
   this->_proxyWidget.hide();
-  for (unsigned int i = 0; i < this->_clients.size(); ++i)
-    this->_clients[i]->hide();
-}
-
-void ProxyWidget::showing()
+  for (unsigned int i = 0; i < this->_nodes.size(); ++i)
+    this->_nodes[i]->hide();
+}
+
+void NodeWidget::showing()
 {
   this->_proxyWidget.show();
-  for (unsigned int i = 0; i < this->_clients.size(); ++i)
-    this->_clients[i]->show();
+  for (unsigned int i = 0; i < this->_nodes.size(); ++i)
+    this->_nodes[i]->show();
 }
 
@@ -147,7 +215,8 @@
  */
 NetworkStatsWidget::NetworkStatsWidget(const NetworkMonitor* monitor)
-    : GLGuiBox(OrxGui::Vertical), _thisHost("myName", IP(127, 0, 0 , 1))
+    : OrxGui::GLGuiFixedpositionBox(OrxGui::Center, OrxGui::Vertical), _thisHost("myName", IP(127, 0, 0 , 1))
 {
   this->_monitor = monitor;
+  this->_passedTime = 0.0f;
 
   /*
@@ -169,10 +238,17 @@
   this->_bar.setChangedValueColor(Color::black);
   */
+  this->_thisHostIs.setText(std::string("I am ") + _monitor->getLocalNode()->getPeerInfo()->getNodeTypeString());
+
+  this->pack(&this->_thisHostIs);
+
   this->pack(&this->_thisHost);
+
+  this->pack(&this->_serverBox);
 
   this->pack(&this->_upstreamText);
   this->pack(&this->_downstreamText);
 
-  this->pack(&this->_serverIP);
+
+  this->rebuild();
 }
 
@@ -183,4 +259,38 @@
 NetworkStatsWidget::~NetworkStatsWidget ()
 {}
+
+
+void NetworkStatsWidget::addNode(const NetworkNode* node)
+{
+  this->_proxies.push_back(new NodeWidget(node));
+  this->_serverBox.pack(this->_proxies.back());
+  this->_proxies.back()->show();
+}
+
+
+
+
+NetworkStatsWidget* NetworkStatsWidget::_statsWidget = NULL;
+
+#include "class_list.h"
+
+void NetworkStatsWidget::toggleGUI()
+{
+  BaseObject* bo = NULL;
+  const std::list<BaseObject*>* ls = ClassList::getList(CL_NETWORK_MONITOR);
+  if (ls != NULL && !ls->empty())
+    bo = ls->front();
+
+  if (bo != NULL && NetworkStatsWidget::_statsWidget == NULL)
+  {
+    NetworkStatsWidget::_statsWidget = new NetworkStatsWidget(dynamic_cast<NetworkMonitor*> (bo));
+    NetworkStatsWidget::_statsWidget->showAll();
+  }
+  else
+  {
+    delete NetworkStatsWidget::_statsWidget;
+    NetworkStatsWidget::_statsWidget = NULL;
+  }
+}
 
 
@@ -204,6 +314,40 @@
 
 
+void NetworkStatsWidget::addProxy(const std::string& name, const IP& proxy)
+{}
+
+void NetworkStatsWidget::clearProxies()
+{}
+
+
+void NetworkStatsWidget::rebuild()
+{
+  while (!this->_proxies.empty())
+  {
+    delete this->_proxies.back();
+    this->_proxies.pop_back();
+  }
+
+  const NetworkNode* node = this->_monitor->getLocalNode();
+  if (node == NULL)
+  {
+    printf("NO NODE\n");
+    return;
+  }
+
+  this->addNode(node);
+}
+
+
+
 void NetworkStatsWidget::tick(float dt)
 {
+
+  if ((_passedTime+= dt) > 1.0f)
+  {
+    this->_passedTime = 0.0f;
+    this->rebuild();
+  }
+
   assert (this->_monitor->getLocalNode() != NULL);
   assert(this->_monitor->getLocalNode()->getPeerInfo() != NULL);
@@ -220,5 +364,5 @@
 void NetworkStatsWidget::resize()
 {
-  GLGuiBox::resize();
+  GLGuiFixedpositionBox::resize();
 }
 
Index: trunk/src/lib/network/monitor/network_stats_widget.h
===================================================================
--- trunk/src/lib/network/monitor/network_stats_widget.h	(revision 9494)
+++ trunk/src/lib/network/monitor/network_stats_widget.h	(revision 9656)
@@ -2,17 +2,19 @@
  * @file network_stats_widget.h
  * @brief Definition of an EnergyWidget, that displays a bar and a Text
-*/
+ */
 
 #ifndef _NETWORK_STATS_WIDGET_H
 #define _NETWORK_STATS_WIDGET_H
 
-#include "glgui_box.h"
+#include "glgui_fixedposition_box.h"
 #include "glgui_bar.h"
 #include "glgui_text.h"
+#include "glgui_pushbutton.h"
 
 #include "network/ip.h"
 
 class NetworkMonitor;
-
+class NetworkNode;
+class PeerInfo;
 
 class HostWidget : public OrxGui::GLGuiBox
@@ -20,8 +22,8 @@
   public:
     HostWidget(const std::string& name, const IP& ip);
-    ~HostWidget() {};
+    HostWidget(const PeerInfo* peerInfo);
 
     void setName(const std::string& name) { this->_name.setText(name); };
-    void setIP(const IP& ip) { this->_ip.setText(ip.ipString()); this->_storedIP = ip; };
+    void setIP(const IP& ip) { this->_ip.setText(std::string("at ") + ip.ipString()); this->_storedIP = ip; };
 
     void setNameWidth(float width) { this->_name.setLineWidth(width); };
@@ -35,22 +37,28 @@
 
   private:
+    void init();
+  private:
     OrxGui::GLGuiText _name;           //!< The Name of the Proxy server to be displayed.
     OrxGui::GLGuiText _ip;             //!< The IP of the proxy server.
     IP                _storedIP;       //!< The ip to compare.
+
+    static Font*      _font;
 };
 
 
-class ProxyWidget : public OrxGui::GLGuiBox
+class NodeWidget : public OrxGui::GLGuiBox
 {
   public:
-    ProxyWidget(const std::string& proxyName, const IP& ip);
+    NodeWidget(const std::string& proxyName, const IP& ip);
+    NodeWidget(const NetworkNode* node);
 
-    void addClient(const std::string& name, const IP& ip);
+    void addNode(const NetworkNode* node);
+    void addNode(const std::string& name, const IP& ip);
 
-    bool removeClient(const IP& ip);
-    bool removeClient(const std::string& name);
-    bool removeClient(const std::string& name, const IP& ip);
+    bool removeNode(const IP& ip);
+    bool removeNode(const std::string& name);
+    bool removeNode(const std::string& name, const IP& ip);
 
-    void setClientNameWidths(float width);
+    void setNodeNameWidths(float width);
 
 
@@ -63,6 +71,6 @@
     HostWidget                _proxyWidget;
 
-    std::vector<HostWidget*>  _clients;
-    float                     _clientNameWidth;
+    std::vector<NodeWidget*>  _nodes;
+    float                     _nodeNameWidth;
 };
 
@@ -71,7 +79,9 @@
 
 //! A class to display network Statistics.
-class NetworkStatsWidget : public OrxGui::GLGuiBox
+class NetworkStatsWidget : public OrxGui::GLGuiFixedpositionBox
 {
   public:
+    static void toggleGUI();
+
     NetworkStatsWidget(const NetworkMonitor* monitor);
     virtual ~NetworkStatsWidget();
@@ -84,5 +94,9 @@
 
     void addProxy(const std::string& name, const IP& proxy);
+    void addNode(const NetworkNode* node);
 
+    void clearProxies();
+
+    void rebuild();
 
     //void rebuildConnectedHosts(std::vector<hosts> hosts);
@@ -101,4 +115,5 @@
     const NetworkMonitor*  _monitor;
 
+    OrxGui::GLGuiText      _thisHostIs;
     HostWidget             _thisHost;
 
@@ -106,9 +121,13 @@
     OrxGui::GLGuiText      _downstreamText;
 
-    std::vector<HostWidget*>_connectedProxies;
+    OrxGui::GLGuiBox       _serverBox;
 
-    OrxGui::GLGuiText       _serverIP;
+    std::vector<NodeWidget*> _proxies;
 
 
+    static NetworkStatsWidget*    _statsWidget;
+
+
+    float                   _passedTime;
     //OrxGui::GLGuiText       _valueText;
     //OrxGui::GLGuiBar        _bar;
Index: trunk/src/lib/network/nettypes.h
===================================================================
--- trunk/src/lib/network/nettypes.h	(revision 9494)
+++ trunk/src/lib/network/nettypes.h	(revision 9656)
@@ -10,6 +10,7 @@
   PERMISSION_MASTER_SERVER = 1,
   PERMISSION_PROXY_SERVER  = 2,
-  PERMISSION_OWNER         = 4,
-  PERMISSION_ALL           = 8
+  PERMISSION_SERVER        = 4,
+  PERMISSION_OWNER         = 8,
+  PERMISSION_ALL           = 16
 };
 
Index: trunk/src/lib/network/network_game_manager.cc
===================================================================
--- trunk/src/lib/network/network_game_manager.cc	(revision 9494)
+++ trunk/src/lib/network/network_game_manager.cc	(revision 9656)
@@ -68,5 +68,5 @@
 
   this->gameState = 0;
-  registerVar( new SynchronizeableInt( &gameState, &gameState, "gameState" ) );
+  registerVar( new SynchronizeableInt( &gameState, &gameState, "gameState", PERMISSION_MASTER_SERVER ) );
 }
 
@@ -91,5 +91,5 @@
 bool NetworkGameManager::signalNewPlayer( int userId )
 {
-  assert( SharedNetworkData::getInstance()->isMasterServer() ||  SharedNetworkData::getInstance()->isProxyServerActive());
+  assert( SharedNetworkData::getInstance()->isMasterServer());
   assert( State::getGameRules() );
   assert( State::getGameRules()->isA( CL_NETWORK_GAME_RULES ) );
@@ -97,9 +97,9 @@
   NetworkGameRules & rules = *(dynamic_cast<NetworkGameRules*>(State::getGameRules()));
 
-  int team = rules.getTeamForNewUser();
-  ClassID playableClassId = rules.getPlayableClassId( userId, team );
-  std::string playableModel = rules.getPlayableModelFileName( userId, team, playableClassId );
-  std::string playableTexture = rules.getPlayableModelFileName( userId, team, playableClassId );
-  float       playableScale = rules.getPlayableScale( userId, team, playableClassId );
+  int          team = rules.getTeamForNewUser();
+  ClassID      playableClassId = rules.getPlayableClassId( userId, team );
+  std::string  playableModel = rules.getPlayableModelFileName( userId, team, playableClassId );
+  std::string  playableTexture = rules.getPlayableModelFileName( userId, team, playableClassId );
+  float        playableScale = rules.getPlayableScale( userId, team, playableClassId );
 
   BaseObject * bo = Factory::fabricate( playableClassId );
@@ -111,5 +111,5 @@
 
   playable.loadMD2Texture( playableTexture );
-
+  playable.setTeam(team);
   playable.loadModel( playableModel, 100.0f );
   playable.setOwner( userId );
@@ -159,5 +159,5 @@
 /**
  * handler for remove synchronizeable messages
- * @param messageId
+ * @param messageType
  * @param data
  * @param dataLength
@@ -166,5 +166,5 @@
  * @return true on successfull handling else handler will be called again
  */
-bool NetworkGameManager::delSynchronizeableHandler( MessageId messageId, byte * data, int dataLength, void * someData, int userId )
+bool NetworkGameManager::delSynchronizeableHandler( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
 {
 
@@ -172,7 +172,7 @@
 
   if ( SharedNetworkData::getInstance()->isMasterServer() ||
-       SharedNetworkData::getInstance()->isProxyServerActive() && SharedNetworkData::getInstance()->isUserClient(userId))
-  {
-    PRINTF(0)("Recieved DeleteSynchronizeable message from client %d!\n", userId);
+       SharedNetworkData::getInstance()->isProxyServerActive() && SharedNetworkData::getInstance()->isUserClient(senderId))
+  {
+    PRINTF(0)("Recieved DeleteSynchronizeable message from client %d!\n", senderId);
     return true;
   }
@@ -183,5 +183,5 @@
   if ( len != dataLength )
   {
-    PRINTF(2)("Recieved DeleteSynchronizeable message with incorrect size (%d) from client %d!\n", dataLength, userId);
+    PRINTF(2)("Recieved DeleteSynchronizeable message with incorrect size (%d) from client %d!\n", dataLength, senderId);
     return true;
   }
@@ -217,5 +217,5 @@
   assert( Converter::intToByteArray( uniqueId, buf, INTSIZE ) == INTSIZE );
 
-  MessageManager::getInstance()->sendMessage( MSGID_DELETESYNCHRONIZEABLE, buf, INTSIZE, RT_ALL_BUT_ME, 0, MP_HIGHBANDWIDTH );
+  MessageManager::getInstance()->sendMessage( MSGID_DELETESYNCHRONIZEABLE, buf, INTSIZE, RT_ALL_BUT_ME, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
 }
 
@@ -224,5 +224,5 @@
 /**
  * handler for MSGID_PREFEREDTEAM message
- * @param messageId
+ * @param messageType
  * @param data
  * @param dataLength
@@ -231,7 +231,7 @@
  * @return
  */
-bool NetworkGameManager::preferedTeamHandler( MessageId messageId, byte * data, int dataLength, void * someData, int userId )
-{
-  assert( SharedNetworkData::getInstance()->isMasterServer() ||  SharedNetworkData::getInstance()->isProxyServerActive());
+bool NetworkGameManager::preferedTeamHandler( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
+{
+  assert( SharedNetworkData::getInstance()->isMasterServer() );
 
   int teamId = 0;
@@ -240,13 +240,20 @@
   if ( len != dataLength )
   {
-    PRINTF(2)("Recieved DeleteSynchronizeable message with incorrect size (%d) from client %d!\n", dataLength, userId);
+    PRINTF(2)("Recieved DeleteSynchronizeable message with incorrect size (%d) from client %d!\n", dataLength, senderId);
     return true;
   }
 
-  NetworkGameManager::getInstance()->setPreferedTeam( userId, teamId );
-
-  return true;
-}
-
+  PRINTF(0)("Client %i wishes to play in team %i\n", senderId, teamId);
+  NetworkGameManager::getInstance()->setPreferedTeam( senderId, teamId );
+
+  return true;
+}
+
+
+/**
+ * this actualy sets the new prefered team id
+ * @param userId: the user that changes team
+ * @param teamId: the new team id for the user
+ */
 void NetworkGameManager::setPreferedTeam( int userId, int teamId )
 {
@@ -259,4 +266,5 @@
 }
 
+
 /**
  * set prefered team for this host
@@ -265,6 +273,6 @@
 void NetworkGameManager::prefereTeam( int teamId )
 {
-  if ( SharedNetworkData::getInstance()->isMasterServer() /*|| SharedNetworkData::getInstance()->isProxyServerActive()*/)
-    setPreferedTeam( SharedNetworkData::getInstance()->getHostID(), teamId );
+  if ( SharedNetworkData::getInstance()->isMasterServer() )
+    this->setPreferedTeam( SharedNetworkData::getInstance()->getHostID(), teamId );
   else
   {
@@ -273,5 +281,6 @@
     assert( Converter::intToByteArray( teamId, buf, INTSIZE) == INTSIZE );
 
-    MessageManager::getInstance()->sendMessage( MSGID_PREFEREDTEAM, buf, INTSIZE, RT_USER, 0, MP_HIGHBANDWIDTH );
+    // send this message to the master server
+    MessageManager::getInstance()->sendMessage( MSGID_PREFEREDTEAM, buf, INTSIZE, RT_USER, NET_ID_MASTER_SERVER, MP_HIGHBANDWIDTH );
   }
 }
@@ -306,10 +315,10 @@
 
 
-bool NetworkGameManager::chatMessageHandler( MessageId messageId, byte * data, int dataLength, void * someData, int userId )
-{
-  PRINTF(0)("NetworkGameManager::chatMessageHandler %d %d\n", userId, SharedNetworkData::getInstance()->getHostID() );
-  if ( (SharedNetworkData::getInstance()->isMasterServer() /*|| SharedNetworkData::getInstance()->isProxyServerActive()*/) && userId !=  SharedNetworkData::getInstance()->getHostID() )
-  {
-    MessageManager::getInstance()->sendMessage( messageId, data, dataLength, RT_ALL_BUT_ME, 0, MP_HIGHBANDWIDTH );
+bool NetworkGameManager::chatMessageHandler( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
+{
+  PRINTF(0)("NetworkGameManager::chatMessageHandler %d %d\n", senderId, SharedNetworkData::getInstance()->getHostID() );
+  if ( (SharedNetworkData::getInstance()->isMasterServer() /*|| SharedNetworkData::getInstance()->isProxyServerActive()*/) && senderId !=  SharedNetworkData::getInstance()->getHostID() )
+  {
+    MessageManager::getInstance()->sendMessage( messageType, data, dataLength, RT_ALL_BUT_ME, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
   }
 
@@ -321,11 +330,11 @@
   if ( dataLength < 3*INTSIZE )
   {
-    PRINTF(2)("got too small chatmessage from client %d\n", userId);
+    PRINTF(2)("got too small chatmessage from client %d\n", senderId);
 
     return true;
   }
 
-  int messageType = 0;
-  Converter::byteArrayToInt( data, &messageType );
+  int chatType = 0;
+  Converter::byteArrayToInt( data, &chatType);
   int senderUserId = 0;
   Converter::byteArrayToInt( data+INTSIZE, &senderUserId );
@@ -333,5 +342,5 @@
   Converter::byteArrayToString( data+2*INTSIZE, message, dataLength-2*INTSIZE );
 
-  rules.handleChatMessage( senderUserId, message, messageType );
+  rules.handleChatMessage( senderUserId, message, chatType);
 
   return true;
@@ -352,7 +361,7 @@
 
   if ( SharedNetworkData::getInstance()->isMasterServer() /*|| SharedNetworkData::getInstance()->isProxyServerActive()*/)
-    MessageManager::getInstance()->sendMessage( MSGID_CHATMESSAGE, buf, message.length()+3*INTSIZE, RT_ALL_ME, 0, MP_HIGHBANDWIDTH );
+    MessageManager::getInstance()->sendMessage( MSGID_CHATMESSAGE, buf, message.length()+3*INTSIZE, RT_ALL_ME, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
   else
-    MessageManager::getInstance()->sendMessage( MSGID_CHATMESSAGE, buf, message.length()+3*INTSIZE, RT_ALL_BUT_ME, 0, MP_HIGHBANDWIDTH );
+    MessageManager::getInstance()->sendMessage( MSGID_CHATMESSAGE, buf, message.length()+3*INTSIZE, RT_ALL_BUT_ME, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
 
 
Index: trunk/src/lib/network/network_game_manager.h
===================================================================
--- trunk/src/lib/network/network_game_manager.h	(revision 9494)
+++ trunk/src/lib/network/network_game_manager.h	(revision 9656)
@@ -19,16 +19,5 @@
 class PNode;
 
-typedef enum NetworkGameManagerProtocol {
-  NET_CREATE_ENTITY = 0,
-  NET_REMOVE_ENTITY,
-  NET_CREATE_ENTITY_LIST,
-  NET_REMOVE_ENTITY_LIST,
-  NET_REQUEST_CREATE,
-  NET_REQUEST_REMOVE,
-  NET_YOU_ARE_ENTITY,
-  NET_REQUEST_ENTITY_LIST,
 
-  NET_NUMBER
-};
 
 struct clientBuffer
@@ -70,7 +59,7 @@
     NetworkGameManager();
 
-    static bool delSynchronizeableHandler( MessageId messageId, byte * data, int dataLength, void * someData, int userId );
-    static bool preferedTeamHandler( MessageId messageId, byte * data, int dataLength, void * someData, int userId );
-    static bool chatMessageHandler( MessageId messageId, byte * data, int dataLength, void * someData, int userId );
+    static bool delSynchronizeableHandler( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  );
+    static bool preferedTeamHandler( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  );
+    static bool chatMessageHandler( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  );
 
     void setPreferedTeam( int userId, int teamId );
Index: trunk/src/lib/network/network_manager.cc
===================================================================
--- trunk/src/lib/network/network_manager.cc	(revision 9494)
+++ trunk/src/lib/network/network_manager.cc	(revision 9656)
@@ -31,4 +31,5 @@
 #include "network_log.h"
 #include "network_game_manager.h"
+#include "proxy/proxy_control.h"
 
 
@@ -37,4 +38,6 @@
 
 SHELL_COMMAND(debug, NetworkManager, debug);
+SHELL_COMMAND(redirTest, NetworkManager, setRedirectionTest);
+
 
 
@@ -111,8 +114,11 @@
   // create the network stream
   this->networkStream = new NetworkStream(NET_MASTER_SERVER);
-  this->networkStream->createServer( port, port + 1);
+  this->networkStream->createServer( port, port + 1, port + 2);
 
   // start the network game manager
   this->networkStream->createNetworkGameManager();
+
+  // init the proxy control center
+  ProxyControl::getInstance();
 
   PRINTF(0)("Created Network Master Server\n");
@@ -138,13 +144,11 @@
 
   // then start the server
-  this->networkStream->createServer( port, port +1);
-
+  this->networkStream->createServer( port, port + 1, port + 2);
 
   // and to the other proxy servers also, this would be very nice if its works
-
-
-  // start the network game manager
-  //this->networkStream->createNetworkGameManager();
-
+  /* put it here....*/
+
+  // init the proxy control center
+  ProxyControl::getInstance();
 
   PRINTF(0)("Created Network Proxy Server\n");
@@ -168,9 +172,23 @@
   this->networkStream->connectToMasterServer( name, port);
 
+
   // and start the handshake
   this->networkStream->startHandshake();
+  // create the proxy control
+  ProxyControl::getInstance();
 
   PRINTF(0)("Created Network Client\n");
   return 1;
+}
+
+
+/**
+ * reconnects this client to another server
+ * @param address new server address
+ */
+void NetworkManager::reconnectToServer(IP address)
+{
+  PRINTF(0)("Rec. reconnection command\n");
+  this->networkStream->reconnectToServer(address);
 }
 
@@ -216,2 +234,9 @@
   PRINT(0)("===========================================\n");
 }
+
+
+void NetworkManager::setRedirectionTest()
+{
+  this->networkStream->setRedirectionTest();
+}
+
Index: trunk/src/lib/network/network_manager.h
===================================================================
--- trunk/src/lib/network/network_manager.h	(revision 9494)
+++ trunk/src/lib/network/network_manager.h	(revision 9656)
@@ -39,8 +39,13 @@
     int createProxyServer( unsigned int port);
 
+    void reconnectToServer(IP address);
+
     void connectSynchronizeable(Synchronizeable& sync);
     void synchronize(float dtS);
 
     void debug();
+
+    void setRedirectionTest();
+
 
 
Index: trunk/src/lib/network/network_stream.cc
===================================================================
--- trunk/src/lib/network/network_stream.cc	(revision 9494)
+++ trunk/src/lib/network/network_stream.cc	(revision 9656)
@@ -11,8 +11,8 @@
 ### File Specific:
    main-programmer: Christoph Renner rennerc@ee.ethz.ch
-   co-programmer:   Patrick Boenzli  boenzlip@orxonox.ethz.ch
+   co-programmer:   Patrick Boenzli  patrick@orxonox.ethz.ch
 
      June 2006: finishing work on the network stream for pps presentation (rennerc@ee.ethz.ch)
-     July 2006: some code rearangement and integration of the proxy server mechanism (boenzlip@ee.ethz.ch)
+     July 2006: some code rearangement and integration of the proxy server mechanism (patrick@orxonox.ethz.ch)
 */
 
@@ -20,4 +20,5 @@
 #define DEBUG_MODULE_NETWORK
 
+#include "proxy/proxy_control.h"
 
 #include "base_object.h"
@@ -80,15 +81,23 @@
       // init the shared network data
       SharedNetworkData::getInstance()->setHostID(NET_ID_MASTER_SERVER);
+      this->pInfo->userId = NET_ID_MASTER_SERVER;
+      this->pInfo->nodeType = NET_MASTER_SERVER;
+
       break;
     case NET_PROXY_SERVER_ACTIVE:
       // init the shared network data
       SharedNetworkData::getInstance()->setHostID(NET_ID_PROXY_SERVER_01);
+      this->pInfo->nodeType = NET_PROXY_SERVER_ACTIVE;
+
       break;
     case NET_PROXY_SERVER_PASSIVE:
       // init the shared network data
       SharedNetworkData::getInstance()->setHostID(NET_ID_PROXY_SERVER_01);
+      this->pInfo->nodeType = NET_PROXY_SERVER_PASSIVE;
+
       break;
     case NET_CLIENT:
       SharedNetworkData::getInstance()->setHostID(NET_ID_UNASSIGNED);
+      this->pInfo->nodeType = NET_CLIENT;
       break;
   }
@@ -97,6 +106,5 @@
 
   // get the local ip address
-  IPaddress ip;
-  SDLNet_ResolveHost( &ip, NULL, 0);
+  IP ip("localhost", 0);
   this->pInfo->ip = ip;
 }
@@ -112,4 +120,5 @@
   this->setClassID(CL_NETWORK_STREAM, "NetworkStream");
   this->clientSocket = NULL;
+  this->clientSoftSocket = NULL;
   this->proxySocket = NULL;
   this->networkGameManager = NULL;
@@ -117,11 +126,13 @@
 
   this->pInfo = new PeerInfo();
-  this->pInfo->userId = 0;
+  this->pInfo->userId = NET_UID_UNASSIGNED;
   this->pInfo->lastAckedState = 0;
   this->pInfo->lastRecvedState = 0;
+  this->pInfo->bLocal = true;
 
   this->bRedirect = false;
 
   this->currentState = 0;
+  this->redirectionUID = NET_ID_MASTER_SERVER;
 
   remainingBytesToWriteToDict = Preferences::getInstance()->getInt( "compression", "writedict", 0 );
@@ -142,7 +153,13 @@
   if ( this->clientSocket )
   {
-    clientSocket->close();
-    delete clientSocket;
-    clientSocket = NULL;
+    this->clientSocket->close();
+    delete this->clientSocket;
+    this->clientSocket = NULL;
+  }
+  if ( this->clientSoftSocket )
+  {
+    this->clientSoftSocket->close();
+    delete this->clientSoftSocket;
+    this->clientSoftSocket = NULL;
   }
   if ( this->proxySocket)
@@ -199,4 +216,5 @@
   this->peers[node].connectionMonitor = new ConnectionMonitor( NET_ID_MASTER_SERVER );
   this->peers[node].ip = this->peers[node].socket->getRemoteAddress();
+  this->peers[node].bLocal = true;
 }
 
@@ -218,4 +236,5 @@
   this->peers[proxyId].connectionMonitor = new ConnectionMonitor( proxyId );
   this->peers[proxyId].ip = this->peers[proxyId].socket->getRemoteAddress();
+  this->peers[proxyId].bLocal = true;
 }
 
@@ -225,8 +244,9 @@
  * @param port: interface port for all clients
  */
-void NetworkStream::createServer(int clientPort, int proxyPort)
+void NetworkStream::createServer(int clientPort, int proxyPort, int clientSoftPort)
 {
   PRINTF(0)(" Creating new Server: listening for clients on port %i and for proxies on port %i", clientPort, proxyPort);
   this->clientSocket= new UdpServerSocket(clientPort);
+  this->clientSoftSocket= new UdpServerSocket(clientSoftPort);
   this->proxySocket = new UdpServerSocket(proxyPort);
 }
@@ -255,7 +275,8 @@
   Handshake* hs = new Handshake(this->pInfo->nodeType);
   // fake the unique id
-  hs->setUniqueID( NET_UID_HANDSHAKE );
-  assert( peers[userId].handshake == NULL );
-  peers[userId].handshake = hs;
+  hs->setUniqueID( userId);
+  assert( this->peers[userId].handshake == NULL );
+  this->peers[userId].handshake = hs;
+  this->peers[userId].bLocal = true;
 
   // set the preferred nick name
@@ -301,5 +322,8 @@
   // create the network monitor after all the init work and before there is any connection handlings
   if( this->networkMonitor == NULL)
+  {
     this->networkMonitor = new NetworkMonitor(this);
+    SharedNetworkData::getInstance()->setNetworkMonitor( this->networkMonitor);
+  }
 
 
@@ -318,4 +342,6 @@
     if ( this->clientSocket )
       this->clientSocket->update();
+    if ( this->clientSoftSocket)
+      this->clientSoftSocket->update();
     if( this->proxySocket)
       this->proxySocket->update();
@@ -328,4 +354,6 @@
     if ( this->clientSocket )
       this->clientSocket->update();
+    if ( this->clientSoftSocket)
+      this->clientSoftSocket->update();
     if( this->proxySocket)
       this->proxySocket->update();
@@ -348,5 +376,5 @@
     if( this->bRedirect)
     {
-      this->handleReconnect( NET_ID_MASTER_SERVER);
+      this->handleReconnect( this->redirectionUID);
     }
   }
@@ -362,4 +390,10 @@
   this->handleDownstream( tick );
   this->handleUpstream( tick );
+
+  // process the local data of the message manager
+  MessageManager::getInstance()->processData();
+
+  if( this->bSoftRedirect)
+    this->softReconnectToServer(0, IP("localhost", 10001));
 }
 
@@ -385,17 +419,23 @@
     if ( tempNetworkSocket )
     {
-      // determine the network node id
-      if ( freeSocketSlots.size() > 0 )
+      // get a userId
+//       if ( freeSocketSlots.size() > 0 )
+//       {
+//         // this should never be called
+//         userId = freeSocketSlots.back();
+//         freeSocketSlots.pop_back();
+//       }
+//       else
       {
-        userId = freeSocketSlots.back();
-        freeSocketSlots.pop_back();
-      }
-      else
-      {
-        userId = 1;
+        // each server (proxy and master) have an address space for new network nodes of 1000 nodes
+        // the first NET_ID_PROXY_MAX are always reserved for proxy servers
+        userId = SharedNetworkData::getInstance()->getHostID() * 1000 + NET_ID_PROXY_MAX + 1;
 
         for ( PeerList::iterator it = peers.begin(); it != peers.end(); it++ )
           if ( it->first >= userId )
             userId = it->first + 1;
+
+        // make sure that this server only uses an address space of 1000
+        assert( userId < (SharedNetworkData::getInstance()->getHostID() + 1) * 1000);
       }
       // this creates a new entry in the peers list
@@ -410,4 +450,23 @@
   }
 
+  if( this->clientSoftSocket != NULL)
+  {
+    tempNetworkSocket = this->clientSoftSocket->getNewSocket();
+
+    // we got new NET_CLIENT connecting
+    if ( tempNetworkSocket )
+    {
+
+      // this creates a new entry in the peers list
+      peers[userId].socket = tempNetworkSocket;
+      peers[userId].nodeType = NET_CLIENT;
+
+      // handle the newly connected client
+      this->handleSoftConnect(userId);
+
+      PRINTF(0)("New Client softly connected: %d :D\n", userId);
+    }
+  }
+
 
   if( this->proxySocket != NULL)
@@ -419,16 +478,26 @@
     {
       // determine the network node id
-      if ( freeSocketSlots.size() > 0 )
-      {
-        userId = freeSocketSlots.back();
-        freeSocketSlots.pop_back();
-      }
-      else
+//       if ( freeSocketSlots.size() > 0 )
+//       {
+//         userId = freeSocketSlots.back();
+//         freeSocketSlots.pop_back();
+//       }
+//       else
       {
         userId = 1;
 
-        for ( PeerList::iterator it = peers.begin(); it != peers.end(); it++ )
-          if ( it->first >= userId )
-            userId = it->first + 1;
+        // find an empty slot within the range
+        for( int i = 0; i < NET_ID_PROXY_MAX; i++)
+        {
+          if( this->peers.find( i) == this->peers.end())
+          {
+            userId = i;
+            break;
+          }
+        }
+
+//         for ( PeerList::iterator it = peers.begin(); it != peers.end(); it++ )
+//           if ( it->first >= userId )
+//             userId = it->first + 1;
       }
 
@@ -443,4 +512,5 @@
     }
   }
+
 
 
@@ -461,5 +531,9 @@
       PRINTF(0)("Client is gone: %d (%s)\n", it->second.userId, reason.c_str());
 
+
       this->handleDisconnect( it->second.userId);
+
+      if( SharedNetworkData::getInstance()->isProxyServerActive())
+        ProxyControl::getInstance()->signalLeaveClient(it->second.userId);
 
       it++;
@@ -469,6 +543,4 @@
     it++;
   }
-
-
 }
 
@@ -481,9 +553,10 @@
 {
   // create new handshake and init its variables
-  peers[userId].handshake = new Handshake(this->pInfo->nodeType, userId, this->networkGameManager->getUniqueID(), MessageManager::getInstance()->getUniqueID());
-  peers[userId].handshake->setUniqueID(userId);
-
-  peers[userId].connectionMonitor = new ConnectionMonitor( userId );
-  peers[userId].userId = userId;
+  this->peers[userId].handshake = new Handshake(this->pInfo->nodeType, userId, this->networkGameManager->getUniqueID(), MessageManager::getInstance()->getUniqueID());
+  this->peers[userId].handshake->setUniqueID(userId);
+
+  this->peers[userId].connectionMonitor = new ConnectionMonitor( userId );
+  this->peers[userId].userId = userId;
+  this->peers[userId].bLocal = true;
 
   PRINTF(0)("num sync: %d\n", synchronizeables.size());
@@ -494,17 +567,49 @@
   if( pi != NULL)
   {
-    peers[userId].handshake->setProxy1Address( pi->ip);
+    this->peers[userId].handshake->setProxy1Address( pi->ip);
   }
   pi = this->networkMonitor->getSecondChoiceProxy();
   if( pi != NULL)
-    peers[userId].handshake->setProxy2Address( pi->ip);
+    this->peers[userId].handshake->setProxy2Address( pi->ip);
 
   // check if the connecting client should reconnect to a proxy server
   if( SharedNetworkData::getInstance()->isMasterServer())
-    peers[userId].handshake->setRedirect(/*this->networkMonitor->isReconnectNextClient()*/false);
+  {
+    if( this->networkMonitor->isReconnectNextClient())
+    {
+      this->peers[userId].handshake->setRedirect(true);
+      PRINTF(0)("forwarding client to proxy server because this server is saturated\n");
+    }
+  }
 
   // the connecting node of course is a client
-  peers[userId].ip = peers[userId].socket->getRemoteAddress();
-}
+  this->peers[userId].ip = this->peers[userId].socket->getRemoteAddress();
+}
+
+
+/**
+ * this handles new soft connections
+ * @param userId: the id of the new user node
+ *
+ * soft connections are connections from clients that are already in the network and don't need a new handshake etc.
+ * the state of all entitites owned by userId are not deleted and stay
+ * soft connections can not be redirected therefore they are negotiated between the to parties
+ */
+void NetworkStream::handleSoftConnect( int userId)
+{
+  // create new handshake and init its variables
+  this->peers[userId].handshake = NULL;
+  this->peers[userId].handshake->setUniqueID(userId);
+
+  this->peers[userId].connectionMonitor = new ConnectionMonitor( userId );
+  this->peers[userId].userId = userId;
+  this->peers[userId].bLocal = true;
+
+  PRINTF(0)("num sync: %d\n", synchronizeables.size());
+
+  // the connecting node of course is a client
+  this->peers[userId].ip = this->peers[userId].socket->getRemoteAddress();
+}
+
 
 
@@ -524,4 +629,12 @@
     PRINT(0)(" Host ist Client with ID: %i\n", this->pInfo->userId);
   }
+
+  PRINT(0)(" Current number of connections is: %i\n", this->peers.size());
+  for ( PeerList::iterator it = peers.begin(); it != peers.end(); it++ )
+  {
+    PRINT(0)("  peers[%i] with uniqueId %i and address: %s\n", it->first, it->second.userId, it->second.ip.ipString().c_str());
+  }
+  PRINT(0)("\n\n");
+
 
   PRINT(0)(" Got %i connected Synchronizeables, showing active Syncs:\n", this->synchronizeables.size());
@@ -576,15 +689,16 @@
             // - client       <==> master server
             // - proxy server <==> master server
-            if(  SharedNetworkData::getInstance()->isClient() || SharedNetworkData::getInstance()->isProxyServerActive() && it->second.isMasterServer())
+            if(  SharedNetworkData::getInstance()->isClient() ||
+                 SharedNetworkData::getInstance()->isProxyServerActive() &&
+                 SharedNetworkData::getInstance()->isUserMasterServer(it->second.userId))
             {
-              PRINTF(0)("Handshake: i am in client role\n");
+              PRINTF(4)("Handshake: i am in client role\n");
 
               SharedNetworkData::getInstance()->setHostID( it->second.handshake->getHostId() );
               this->pInfo->userId = SharedNetworkData::getInstance()->getHostID();
 
-#warning the ip address is not set here because it results in a segfault when connecting to a proxy server => trace this later
 //               it->second.ip = it->second.socket->getRemoteAddress();
 
-              // it->second.nodeType = it->second.handshake->getRemoteNodeType();
+              it->second.nodeType = it->second.handshake->getRemoteNodeType();
               // it->second.ip = it->second.socket->getRemoteAddress();
               // add the new server to the nodes list (it can be a NET_MASTER_SERVER or NET_PROXY_SERVER)
@@ -633,5 +747,5 @@
               else if ( SharedNetworkData::getInstance()->isProxyServerActive() && it->second.isClient() )
               {
-                PRINTF(0)("Handshake: i am in server role\n");
+                PRINTF(4)("Handshake: Proxy in server role: connecting %i\n", it->second.userId);
 
                 it->second.ip = it->second.socket->getRemoteAddress();
@@ -639,5 +753,6 @@
                 this->networkMonitor->addNode(&it->second);
 
-                this->handleNewClient( it->second.userId );
+                // work with the ProxyControl to init the new client
+                ProxyControl::getInstance()->signalNewClient( it->second.userId);
 
                 if ( PlayerStats::getStats( it->second.userId ) && it->second.handshake->getPreferedNickName() != "" )
@@ -667,14 +782,22 @@
 /**
  * this functions handles a reconnect event received from the a NET_MASTER_SERVER or NET_PROXY_SERVER
+ * @param userId
  */
 void NetworkStream::handleReconnect(int userId)
 {
   this->bRedirect = false;
+#warning this peer will be created if it does not yet exist: dangerous
   PeerInfo* pInfo = &this->peers[userId];
+
+  IP proxyIP;
+  if( this->networkMonitor->isForcedReconnection())
+    proxyIP = this->networkMonitor->getForcedReconnectionIP();
+  else
+    proxyIP = pInfo->handshake->getProxy1Address();
 
   PRINTF(0)("===============================================\n");
   PRINTF(0)("Client is redirected to the other proxy servers\n");
   PRINTF(0)("  user id: %i\n", userId);
-  PRINTF(0)("  connecting to: %s\n", this->networkMonitor->getFirstChoiceProxy()->ip.ipString().c_str());
+  PRINTF(0)("  connecting to: %s\n", proxyIP.ipString().c_str());
   PRINTF(0)("===============================================\n");
 
@@ -683,10 +806,8 @@
   pInfo->lastRecvedState = 0;
 
-  // temp save the ip address here
-  IP proxyIP = pInfo->handshake->getProxy1Address();
-
   // disconnect from the current server and reconnect to proxy server
   this->handleDisconnect( userId);
   this->connectToProxyServer(NET_ID_PROXY_SERVER_01, proxyIP.ipString(), 9999);
+//   this->connectToMasterServer(proxyIP.ipString(), 9999);
   #warning the ports are not yet integrated correctly in the ip class
 
@@ -696,4 +817,79 @@
 
 
+
+/**
+ * reconnects to another server, with full handshake
+ * @param address of the new server
+ */
+void NetworkStream::reconnectToServer(IP address)
+{
+  ///TODO make a redirection struct and push it to the network monitor
+  this->networkMonitor->setForcedReconnection(address);
+
+  // reconnect (depending on how we are connected at the moment)
+  if ( peers.find( NET_ID_MASTER_SERVER) != peers.end() )
+    this->redirectionUID = NET_ID_MASTER_SERVER;
+  else if( peers.find( NET_ID_PROXY_SERVER_01) != peers.end() )
+    this->redirectionUID = NET_ID_PROXY_SERVER_01;
+
+  this->bRedirect = true;
+}
+
+
+
+/**
+ * softly reconnecting to another server
+ * @param serverUserId the id of the client
+ * @param address  of the new server
+ */
+void NetworkStream::softReconnectToServer(int serverUserId, IP address)
+{
+//   this->networkMonitor->setForcedReconnection(address);
+//   this->handleReconnect( NET_ID_MASTER_SERVER);
+
+  // create the new udp socket and open the connection to the soft connection port
+  NetworkSocket* newSocket = new UdpSocket(address.ipString(), 10001);
+
+  // delete the synchronization state of this client for all syncs
+  for ( SynchronizeableList::iterator it2 = synchronizeables.begin(); it2 != synchronizeables.end(); it2++ )  {
+    (*it2)->cleanUpUser( serverUserId );
+  }
+
+  // temp save the old socket
+  NetworkSocket* oldSocket = this->peers[serverUserId].socket;
+
+  // now integrate the new socket
+  this->peers[serverUserId].socket = newSocket;
+
+  this->bSoftRedirect = false;
+  return;
+
+  // now remove the old socket
+  oldSocket->disconnectServer();
+  delete oldSocket;
+
+  // replace the old connection monitor
+  if ( this->peers[serverUserId].connectionMonitor )
+    delete this->peers[serverUserId].connectionMonitor;
+  this->peers[serverUserId].connectionMonitor = new ConnectionMonitor(serverUserId);
+
+  // remove old node from the network monitor
+  this->networkMonitor->removeNode(&this->peers[serverUserId]);
+
+}
+
+
+
+/**
+ * prepares a soft connection for a client to connect to
+ * @param userId that will connect to this server
+ */
+void NetworkStream::prepareSoftConnection(int userId)
+{
+  PRINTF(0)("prepare soft connection for userId %i\n");
+}
+
+
+
 /**
  * handles the disconnect event
@@ -702,17 +898,17 @@
 void NetworkStream::handleDisconnect( int userId )
 {
-  peers[userId].socket->disconnectServer();
-  delete peers[userId].socket;
-  peers[userId].socket = NULL;
-
-  if ( peers[userId].handshake )
-    delete peers[userId].handshake;
-  peers[userId].handshake = NULL;
-
-  if ( peers[userId].connectionMonitor )
-    delete peers[userId].connectionMonitor;
-  peers[userId].connectionMonitor = NULL;
-
-
+  this->peers[userId].socket->disconnectServer();
+  delete this->peers[userId].socket;
+  this->peers[userId].socket = NULL;
+
+  if ( this->peers[userId].handshake )
+    delete this->peers[userId].handshake;
+  this->peers[userId].handshake = NULL;
+
+  if ( this->peers[userId].connectionMonitor )
+    delete this->peers[userId].connectionMonitor;
+  this->peers[userId].connectionMonitor = NULL;
+
+  // delete the synchronization state of this client for all syncs
   for ( SynchronizeableList::iterator it2 = synchronizeables.begin(); it2 != synchronizeables.end(); it2++ )  {
     (*it2)->cleanUpUser( userId );
@@ -724,7 +920,7 @@
   this->freeSocketSlots.push_back( userId );
 
-  peers.erase( userId);
-}
-
+  this->networkMonitor->removeNode(&this->peers[userId]);
+  this->peers.erase( userId);
+}
 
 
@@ -793,8 +989,8 @@
       assert( offset + INTSIZE <= UDP_PACKET_SIZE );
 
-      // server fakes uniqueid == 0 for handshake
+      // server fakes uniqueid == 0 for handshake synchronizeable
       if ( ( SharedNetworkData::getInstance()->isMasterServer() ||
              SharedNetworkData::getInstance()->isProxyServerActive() &&  peer->second.isClient() ) &&
-             sync.getUniqueID() <= SharedNetworkData::getInstance()->getMaxPlayer() + 1) // plus one to handle one client more than the max to redirect it
+             ( sync.getUniqueID() >= 1000 || sync.getUniqueID() <= SharedNetworkData::getInstance()->getMaxPlayer() + 1 + NET_ID_PROXY_MAX))
         n = Converter::intToByteArray( 0, buf + offset, UDP_PACKET_SIZE - offset );
       else
@@ -930,8 +1126,10 @@
       while ( offset + 2 * INTSIZE < length )
       {
+        // read the unique id of the sync
         assert( offset > 0 );
         assert( Converter::byteArrayToInt( buf + offset, &uniqueId ) == INTSIZE );
         offset += INTSIZE;
 
+        // read the data length
         assert( Converter::byteArrayToInt( buf + offset, &syncDataLength ) == INTSIZE );
         offset += INTSIZE;
@@ -945,6 +1143,7 @@
         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 ) )
+          // client thinks his handshake has a special id: hostId * 1000 (host id of this server)
+          if ( (*it)->getUniqueID() == uniqueId ||                                          // so this client exists already go to sync work
+                 ( uniqueId == 0  && (*it)->getUniqueID() == peer->second.userId ) )        // so this is a Handshake!
           {
             sync = *it;
Index: trunk/src/lib/network/network_stream.h
===================================================================
--- trunk/src/lib/network/network_stream.h	(revision 9494)
+++ trunk/src/lib/network/network_stream.h	(revision 9656)
@@ -41,10 +41,16 @@
     void init();
 
+    /* network interface controls */
     void connectToMasterServer(std::string host, int port);
     void connectToProxyServer(int proxyId, std::string host, int port);
-    void createServer(int clientPort, int proxyPort);
+    void createServer(int clientPort, int proxyPort, int clientSoftPort);
 
     void createNetworkGameManager();
     void startHandshake(int userId = NET_ID_MASTER_SERVER);
+
+    void reconnectToServer(IP address);
+    void softReconnectToServer(int serverUserId, IP address);
+    void prepareSoftConnection(int userId);
+
 
     /* synchronizeable interface */
@@ -70,4 +76,6 @@
     inline PeerInfo* getPeerInfo() { return this->pInfo; }
     inline PeerList getPeerInfoList() { return this->peers; }
+
+    inline void setRedirectionTest() { this->bSoftRedirect = true; }
 
     /* data processing*/
@@ -96,6 +104,8 @@
 
     void handleConnect( int userId);
+    void handleSoftConnect( int userId);
     void handleReconnect( int userId );
     void handleDisconnect( int userId );
+    void handleSoftDisconnect( int userId);
 
     void writeToNewDict( byte * data, int length, bool upstream );
@@ -112,5 +122,6 @@
     NetworkMonitor*            networkMonitor;              //!< the network monitor
     NetworkGameManager*        networkGameManager;          //!< reference to the network game manager
-    ServerSocket*              clientSocket;                //!< the listening socket of the server
+    ServerSocket*              clientSocket;                //!< the listening socket for clients of the server
+    ServerSocket*              clientSoftSocket;            //!< the listening socket for soft connections to the server
     ServerSocket*              proxySocket;                 //!< socket for proxy connections
 
@@ -126,4 +137,6 @@
 
     bool                       bRedirect;                   //!< true if the master server sent a redirect command
+    int                        redirectionUID;              //!< uid of the redir host
+    bool                       bSoftRedirect;               //!< tsting
 };
 #endif /* _NETWORK_STREAM */
Index: trunk/src/lib/network/peer_info.cc
===================================================================
--- trunk/src/lib/network/peer_info.cc	(revision 9494)
+++ trunk/src/lib/network/peer_info.cc	(revision 9656)
@@ -42,6 +42,6 @@
 void PeerInfo::clear()
 {
-  this->userId = 0;
-  this->nodeType = NET_CLIENT;
+  this->userId = NET_ID_UNASSIGNED;
+  this->nodeType = NET_UNASSIGNED;
   this->socket = NULL;
   this->handshake = NULL;
@@ -49,4 +49,5 @@
   this->lastRecvedState = 0;
   this->connectionMonitor = NULL;
+  this->bLocal = false;
 
   this->ip = IP(0,0);
@@ -68,6 +69,5 @@
 const std::string PeerInfo::nodeNames[] =
 {
-
-  "maser server",
+  "master server",
   "proxy server active",
   "proxy server passive",
Index: trunk/src/lib/network/peer_info.h
===================================================================
--- trunk/src/lib/network/peer_info.h	(revision 9494)
+++ trunk/src/lib/network/peer_info.h	(revision 9656)
@@ -30,4 +30,5 @@
     static const std::string& nodeTypeToString(unsigned int type);
 
+    inline bool isLocal() { return this->bLocal; }
 
 
@@ -44,4 +45,6 @@
     int                 lastRecvedState;         //!< last received state
 
+    bool                bLocal;                  //!< true if this node is localy connected to this node
+
     static const std::string nodeNames[];
 
Index: trunk/src/lib/network/player_stats.cc
===================================================================
--- trunk/src/lib/network/player_stats.cc	(revision 9494)
+++ trunk/src/lib/network/player_stats.cc	(revision 9656)
@@ -41,5 +41,5 @@
   init();
 
-  this->userId = userId;
+  this->assignedUserId = userId;
 }
 
@@ -56,5 +56,5 @@
   this->setClassID( CL_PLAYER_STATS, "PlayerStats" );
 
-  this->userId = 0;
+  this->assignedUserId = 0;
   this->teamId = TEAM_NOTEAM;
   this->preferedTeamId = TEAM_NOTEAM;
@@ -65,16 +65,16 @@
   this->oldNickName = "Player";
 
-  userId_handle = registerVarId( new SynchronizeableInt( &userId, &userId, "userId" ) );
-  teamId_handle = registerVarId( new SynchronizeableInt( &teamId, &teamId, "teamId" ) );
-  preferedTeamId_handle = registerVarId( new SynchronizeableInt( &preferedTeamId, &preferedTeamId, "preferedUserId" ) );
-  score_handle = registerVarId( new SynchronizeableInt( &score, &score, "score" ) );
-  playableClassId_handle = registerVarId( new SynchronizeableInt( &playableClassId, &playableClassId, "playableClassId") );
-  playableUniqueId_handle = registerVarId( new SynchronizeableInt( &playableUniqueId, &playableUniqueId, "playableUniqueId" ) );
-  modelFileName_handle = registerVarId( new SynchronizeableString( &modelFileName, &modelFileName, "modelFileName" ) );
-  nickName_handler = registerVarId( new SynchronizeableString( &nickName, &nickName, "nickName" ) );
+  userId_handle = registerVarId( new SynchronizeableInt( &assignedUserId, &assignedUserId, "userId", PERMISSION_MASTER_SERVER ) );
+  teamId_handle = registerVarId( new SynchronizeableInt( &teamId, &teamId, "teamId", PERMISSION_MASTER_SERVER ) );
+  preferedTeamId_handle = registerVarId( new SynchronizeableInt( &preferedTeamId, &preferedTeamId, "preferedUserId", PERMISSION_MASTER_SERVER ) );
+  score_handle = registerVarId( new SynchronizeableInt( &score, &score, "score", PERMISSION_MASTER_SERVER ) );
+  playableClassId_handle = registerVarId( new SynchronizeableInt( &playableClassId, &playableClassId, "playableClassId", PERMISSION_MASTER_SERVER) );
+  playableUniqueId_handle = registerVarId( new SynchronizeableInt( &playableUniqueId, &playableUniqueId, "playableUniqueId", PERMISSION_MASTER_SERVER ) );
+  modelFileName_handle = registerVarId( new SynchronizeableString( &modelFileName, &modelFileName, "modelFileName", PERMISSION_MASTER_SERVER ) );
+  nickName_handler = registerVarId( new SynchronizeableString( &nickName, &nickName, "nickName", PERMISSION_MASTER_SERVER ) );
 
   MessageManager::getInstance()->registerMessageHandler( MSGID_CHANGENICKNAME, changeNickHandler, NULL );
 
-  PRINTF(0)("PlayerStats created\n");
+  PRINTF(5)("PlayerStats created\n");
 }
 
@@ -84,13 +84,12 @@
  */
 PlayerStats::~PlayerStats()
-{
-}
-
-
- /**
- * override this function to be notified on change
- * of your registred variables.
- * @param id id's which have changed
-  */
+{}
+
+
+/**
+* override this function to be notified on change
+* of your registred variables.
+* @param id id's which have changed
+ */
 void PlayerStats::varChangeHandler( std::list< int > & id )
 {
@@ -99,5 +98,5 @@
     this->setPlayableUniqueId( this->playableUniqueId );
 
-    PRINTF(0)("uniqueID changed %d %d %d\n", userId, SharedNetworkData::getInstance()->getHostID(), getUniqueID());
+    PRINTF(4)("uniqueID changed %d %d %d\n", assignedUserId, SharedNetworkData::getInstance()->getHostID(), getUniqueID());
   }
 
@@ -105,7 +104,14 @@
   {
     PRINTF(0)("user %s is now known as %s\n", oldNickName.c_str(), nickName.c_str());
-    oldNickName = nickName;
-  }
-}
+    this->oldNickName = nickName;
+  }
+
+  if ( std::find( id.begin(), id.end(), preferedTeamId_handle) != id.end() )
+  {
+    PRINTF(0)("user %s has changed team to %i\n", nickName.c_str(), this->teamId);
+  }
+}
+
+
 
 /**
@@ -123,7 +129,12 @@
   }
 
-  for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
-  {
-    if ( dynamic_cast<PlayerStats*>(*it)->getUserId() == userId )
+  for ( std::list<BaseObject*>::const_iterator it = list->
+        begin();
+        it != list->end();
+        it++ )
+  {
+
+
+    if ( dynamic_cast<PlayerStats*>(*it)->getAssignedUserId() == userId )
     {
       return dynamic_cast<PlayerStats*>(*it);
@@ -148,7 +159,11 @@
 
   this->playable = NULL;
-  for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
-  {
-    if ( dynamic_cast<Playable*>(*it)->getUniqueID() == uniqueId )
+  for ( std::list<BaseObject*>::const_iterator it = list->
+        begin();
+        it != list->end();
+        it++ )
+  {
+    if ( dynamic_cast<Playable*>(*it)->
+         getUniqueID() == uniqueId )
     {
       this->playable = dynamic_cast<Playable*>(*it);
@@ -159,7 +174,9 @@
   }
 
-  if ( this->playable && userId == SharedNetworkData::getInstance()->getHostID() )
+  if ( this->playable && this->assignedUserId == SharedNetworkData::getInstance()
+       ->getHostID() )
   {
     State::getPlayer()->setPlayable( this->playable );
+    // also set the team id
   }
 
@@ -204,10 +221,20 @@
     assert( Converter::stringToByteArray( nick, data, nick.length()+INTSIZE) == nick.length()+INTSIZE );
 
-    MessageManager::getInstance()->sendMessage( MSGID_CHANGENICKNAME, data, nick.length()+INTSIZE, RT_SERVER, 0, MP_HIGHBANDWIDTH );
+    MessageManager::getInstance()->sendMessage( MSGID_CHANGENICKNAME, data, nick.length()+INTSIZE, RT_SERVER, NET_MASTER_SERVER, MP_HIGHBANDWIDTH );
     return;
   }
 }
 
-bool PlayerStats::changeNickHandler( MessageId messageId, byte * data, int dataLength, void * someData, int userId )
+/**
+ * handler for the nick name
+ * @param messageType type of the message
+ * @param data  data of the message
+ * @param dataLength length of the data
+ * @param someData some additional data
+ * @param senderId userId of the sender
+ * @param destinationId userId of the rec
+ * @return true if handled correctly
+ */
+bool PlayerStats::changeNickHandler( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
 {
   std::string newNick;
@@ -216,14 +243,18 @@
   if ( res != dataLength )
   {
-    PRINTF(2)("invalid message size from user %d\n", userId);
+    PRINTF(2)("invalid message size from user %d\n", senderId);
     newNick = "invalid";
   }
 
-  if ( PlayerStats::getStats( userId ) )
-    PlayerStats::getStats( userId )->setNickName( newNick );
+  if ( PlayerStats::getStats( senderId) )
+    PlayerStats::getStats( senderId )->setNickName( newNick );
 
   return true;
 }
 
+/**
+ * sets the nick name from the shell
+ * @param newNick new prefered nick name
+ */
 void PlayerStats::shellNick( const std::string& newNick )
 {
@@ -236,4 +267,7 @@
 
 
+/**
+ * removes and delets all player stats
+ */
 void PlayerStats::deleteAllPlayerStats( )
 {
@@ -246,4 +280,7 @@
 
 
+/**
+ * @return the score list of this player stat
+ */
 ScoreList PlayerStats::getScoreList( )
 {
@@ -257,5 +294,8 @@
   }
 
-  for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
+  for ( std::list<BaseObject*>::const_iterator it = list->
+        begin();
+        it != list->end();
+        it++ )
   {
     PlayerStats & stats = *dynamic_cast<PlayerStats*>(*it);
Index: trunk/src/lib/network/player_stats.h
===================================================================
--- trunk/src/lib/network/player_stats.h	(revision 9494)
+++ trunk/src/lib/network/player_stats.h	(revision 9656)
@@ -16,8 +16,9 @@
 enum
 {
-  TEAM_NOTEAM = -3,
-  TEAM_RANDOM = -2,
-  TEAM_SPECTATOR = -1
+  TEAM_NOTEAM       = -3,
+  TEAM_RANDOM       = -2,
+  TEAM_SPECTATOR    = -1
 };
+
 
 struct PlayerScore
@@ -26,9 +27,12 @@
   int score;
 };
+
+
 typedef std::list<PlayerScore> TeamScoreList;
 typedef std::map<int,TeamScoreList> ScoreList;
 
+
 //! A class for storing player information
-class PlayerStats : public Synchronizeable 
+class PlayerStats : public Synchronizeable
 {
 
@@ -37,66 +41,69 @@
     PlayerStats( int userId );
     virtual ~PlayerStats();
-    
+
     virtual void varChangeHandler( std::list<int> & id );
-    
+
     static PlayerStats * getStats( int userId );
-    
-    inline int getUserId(){ return userId; }
-    
+    inline int getAssignedUserId(){ return this->assignedUserId; }
+
+
     inline int getTeamId(){ return teamId; }
     inline void setTeamId( int teamId ){ this->teamId = teamId; }
-    
+
     inline int getPreferedTeamId(){ return preferedTeamId; }
-    inline void setPreferedTeamId( int preferedTeamId ){ this->preferedTeamId = preferedTeamId; }
-    
+    inline void setPreferedTeamId( int preferedTeamId ) { this->preferedTeamId = preferedTeamId; }
+
     inline int getScore(){ return score; }
     inline void setScore( int score ){ this->score = score; }
-    
+
     inline int getPlayableClassId(){ return playableClassId; }
     void setPlayableClassId( int classId ){ this->playableClassId = classId; };
-    
+
     inline int getPlayableUniqueId(){ return playableUniqueId; }
     void setPlayableUniqueId( int uniqueId );
-    
+
     inline std::string getModelFileName(){ return modelFileName; }
     inline void setModelFileName( std::string filename ){ modelFileName = filename; }
-    
+
     Playable * getPlayable();
-    
+
     inline std::string getNickName(){ return this->nickName; }
     void setNickName( std::string nick );
-    static bool changeNickHandler( MessageId messageId, byte * data, int dataLength, void * someData, int userId );
+    static bool changeNickHandler( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  );
     void shellNick( const std::string&  newNick );
-    
+
     static void deleteAllPlayerStats();
-    
+
     static ScoreList getScoreList();
 
+
   private:
-    int userId;                //!< userId
-    int teamId;                //!< teamId
-    int preferedTeamId;        //!< preferedTeamId
+    void init();
 
-    std::string nickName;      //!< players nickname
-    std::string oldNickName;   //!< nickname player had before
 
-    int score;                 //!< users score points
-    int playableClassId;       //!< players playable class id
-    int playableUniqueId;      //!< playable's uniqueId
-    std::string modelFileName; //!< model filename
+  private:
+    // handles for SynchronizeableVars
+    int              userId_handle;
+    int              teamId_handle;
+    int              preferedTeamId_handle;
+    int              score_handle;
+    int              playableClassId_handle;
+    int              playableUniqueId_handle;
+    int              modelFileName_handle;
+    int              nickName_handler;
 
-    Playable * playable;       //!< pointer to players playable
+    int              assignedUserId;            //!< userId
+    int              teamId;                    //!< teamId
+    int              preferedTeamId;            //!< preferedTeamId
 
-    // handles for SynchronizeableVars
-    int userId_handle;
-    int teamId_handle;
-    int preferedTeamId_handle;
-    int score_handle;
-    int playableClassId_handle;
-    int playableUniqueId_handle;
-    int modelFileName_handle;
-    int nickName_handler;
-    
-    void init();
+    std::string      nickName;                  //!< players nickname
+    std::string      oldNickName;               //!< nickname player had before
+
+    int              score;                     //!< users score points
+    int              playableClassId;           //!< players playable class id
+    int              playableUniqueId;          //!< playable's uniqueId
+    std::string      modelFileName;             //!< model filename
+
+    Playable *       playable;                  //!< pointer to players playable
 };
 
Index: trunk/src/lib/network/proxy/network_settings.cc
===================================================================
--- trunk/src/lib/network/proxy/network_settings.cc	(revision 9494)
+++ trunk/src/lib/network/proxy/network_settings.cc	(revision 9656)
@@ -87,5 +87,6 @@
   // setUniqueID( maxCon+2 ) because we need one id for every handshake
   // and one for handshake to reject client maxCon+1
-  SharedNetworkData::getInstance()->setNewUniqueID( this->maxPlayer + 2);
+  // NEW: at most there will be
+  SharedNetworkData::getInstance()->setNewUniqueID( this->maxPlayer + NET_ID_PROXY_MAX + 2);
 }
 
Index: trunk/src/lib/network/proxy/proxy_control.cc
===================================================================
--- trunk/src/lib/network/proxy/proxy_control.cc	(revision 9656)
+++ trunk/src/lib/network/proxy/proxy_control.cc	(revision 9656)
@@ -0,0 +1,387 @@
+/*
+   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: Patrick Boenzli (patrick@orxonox.ethz.ch)
+*/
+
+#include "proxy_control.h"
+
+#include "class_list.h"
+#include "shell_command.h"
+
+#include "state.h"
+#include "shared_network_data.h"
+#include "network_manager.h"
+#include "network_game_manager.h"
+#include "ip.h"
+#include "peer_info.h"
+#include "network_stream.h"
+
+#include "converter.h"
+
+#include "preferences.h"
+
+#include "debug.h"
+
+#include "monitor/network_monitor.h"
+
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_NETWORK
+
+ProxyControl* ProxyControl::singletonRef = NULL;
+
+
+SHELL_COMMAND(forceReconnect, ProxyControl, forceReconnectionShell);
+
+/**
+ * constructor
+ */
+ProxyControl::ProxyControl()
+{
+  this->setClassID( CL_PROXY_CONTROL, "ProxyControl" );
+
+  this->setSynchronized(false);
+
+  MessageManager::getInstance()->registerMessageHandler( MSGID_PROXY_NEWCLIENT, messageHandlerNewClient, NULL );
+  MessageManager::getInstance()->registerMessageHandler( MSGID_PROXY_LEAVECLIENT, messageHandlerLeaveClient, NULL );
+  MessageManager::getInstance()->registerMessageHandler( MSGID_PROXY_COMMAND, messageHandlerCommand, NULL );
+
+
+  PRINTF(0)("ProxyControl created\n");
+}
+
+
+/**
+ * standard deconstructor
+ */
+ProxyControl::~ProxyControl()
+{
+  ProxyControl::singletonRef = NULL;
+}
+
+
+ /**
+ * override this function to be notified on change
+ * of your registred variables.
+ * @param id id's which have changed
+  */
+void ProxyControl::varChangeHandler( std::list< int > & id )
+{
+//   if ( std::find( id.begin(), id.end(), playableUniqueId_handle ) != id.end() )
+//   {
+//     this->setPlayableUniqueId( this->playableUniqueId );
+//
+//     PRINTF(0)("uniqueID changed %d %d %d\n", userId, SharedNetworkData::getInstance()->getHostID(), getUniqueID());
+//   }
+}
+
+
+/**
+ *  signals new client connected to this local proxy
+ *
+ *  byte 0 - 3     :      userId
+ *  byte 4 - 7     :      ip address (IPaddress.host)
+ *
+ * @param userId userId of the new client
+ */
+void ProxyControl::signalNewClient(int userId)
+{
+  PRINTF(0)("Signaling new Client: %i\n", userId);
+  // make sure we are a proxy server
+  assert(SharedNetworkData::getInstance()->isProxyServerActive());
+
+  byte data[2 * INTSIZE];
+  // write the userId in the message
+  assert( Converter::intToByteArray( userId, data, INTSIZE ) == INTSIZE );
+  // and the ip as an int
+  PeerInfo* pInfo = SharedNetworkData::getInstance()->getNetworkMonitor()->getPeerByUserId(userId);
+  assert(pInfo != NULL);
+  assert( Converter::intToByteArray( pInfo->ip.host(), data + INTSIZE, INTSIZE ) == INTSIZE );
+
+  MessageManager::getInstance()->sendMessage( MSGID_PROXY_NEWCLIENT, data, 2*INTSIZE, RT_SERVER, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
+}
+
+
+/**
+ * this is the handler for proxy signals: new clients
+ *
+ * @param messageType the type of the message
+ * @param data message data
+ * @param dataLength length of the message data
+ * @param someData some other atteched data
+ * @param senderId id of the sender client
+ * @param destinationId id of the destination client
+ * @return true if succeeded
+ */
+bool ProxyControl::messageHandlerNewClient( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
+{
+  // body data length correct?
+  if ( dataLength != 2 * INTSIZE )
+  {
+    PRINTF(2)("new client message has wrong size: %d\n", dataLength );
+    return true;
+  }
+  // read the userId fromt he message body
+  int newClientId = 0;
+  assert( Converter::byteArrayToInt( data, &newClientId) == INTSIZE );
+  // now read the ip address
+  int ipHost = 0;
+  assert( Converter::byteArrayToInt( data + INTSIZE, &ipHost) == INTSIZE );
+
+  // register the new node at the network monitor
+  NetworkMonitor* netMon = SharedNetworkData::getInstance()->getNetworkMonitor();
+  NetworkNode* nNode = netMon->getNodeByUserId(senderId); // this gets the proxy server who sent the msg
+  if( nNode == NULL)
+    PRINTF(0)("Couldn't find node %i! Error\n", senderId);
+  PeerInfo* pInfo = new PeerInfo();
+  pInfo->bLocal = false;
+  pInfo->ip = IP(ipHost, 9999);
+  pInfo->nodeType = NET_CLIENT;
+  pInfo->userId = newClientId;
+  netMon->addNode(nNode, pInfo);
+
+  PRINTF(0)("Got Signal: from %i new player arrived with userId: %i and ip: %s on %i\n", senderId, newClientId, pInfo->ip.ipString().c_str(), senderId);
+  // part for the master server
+  if( SharedNetworkData::getInstance()->isMasterServer())
+  {
+    // we now create the new player ship and stuff...
+    NetworkGameManager::getInstance()->signalNewPlayer(newClientId);
+  }
+
+  return true;
+}
+
+
+
+/**
+ *  signals client disconnect
+ * @param userId userId of the old client
+ */
+void ProxyControl::signalLeaveClient(int userId)
+{
+  PRINTF(0)("Signaling new Client: %i\n", userId);
+  // make sure we are a proxy server
+  assert(SharedNetworkData::getInstance()->isProxyServerActive());
+
+  byte data[INTSIZE];
+
+  assert( Converter::intToByteArray( userId, data, INTSIZE ) == INTSIZE );
+
+  MessageManager::getInstance()->sendMessage( MSGID_PROXY_LEAVECLIENT, data, INTSIZE, RT_SERVER, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
+}
+
+
+/**
+ * this is the handler for proxy signals: removing clients
+ *
+ * @param messageType the type of the message
+ * @param data message data
+ * @param dataLength length of the message data
+ * @param someData some other atteched data
+ * @param senderId id of the sender client
+ * @param destinationId id of the destination client
+ * @return true if succeeded
+ */
+bool ProxyControl::messageHandlerLeaveClient( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
+{
+  // body data length correct?
+  if ( dataLength != INTSIZE )
+  {
+    PRINTF(2)("leave client message has wrong size: %d\n", dataLength );
+    return true;
+  }
+  // read the userId fromt he message body
+  int leaveClientId = 0;
+  assert( Converter::byteArrayToInt( data, &leaveClientId) == INTSIZE );
+
+  // remove the node from the network monitor
+  NetworkMonitor* netMon = SharedNetworkData::getInstance()->getNetworkMonitor();
+  NetworkNode* nNode = netMon->getNodeByUserId(senderId); // this gets the proxy server who sent the msg
+  netMon->removeNode(nNode, netMon->getPeerByUserId(leaveClientId));
+
+  PRINTF(0)("Got Signal: from %i player left with userId: %i\n", senderId, leaveClientId);
+  // part for the master server
+  if( SharedNetworkData::getInstance()->isMasterServer())
+  {
+    // we now create the new player ship and stuff...
+    NetworkGameManager::getInstance()->signalLeftPlayer(leaveClientId);
+  }
+  else if(SharedNetworkData::getInstance()->isProxyServerActive())
+  {
+
+  }
+
+  return true;
+}
+
+
+
+/**
+ * forces a client to reconnect to another server
+ * @param userId the userId of the client/user :D
+ * @param newAddress the addresss the client should connect to (fully quali dns)
+ */
+void ProxyControl::forceReconnection(int userId, const std::string& newAddress)
+{
+  IP ipAddr = IP(newAddress, 9999);
+  this->forceReconnection(userId, newAddress);
+}
+
+
+
+/**
+ * thumb command: staticly reconnect node 10 to node 0
+ */
+void ProxyControl::forceReconnectionShellThumb()
+{
+  this->forceReconnectionShell(10, 0);
+}
+
+/**
+ * a shell command wrapper
+ * @param userId the userId of the client/user :D
+ * @param serverId the userId of the server to connect to
+ */
+void ProxyControl::forceReconnectionShell(int userId, int serverId)
+{
+  PRINTF(0)("shell reconnectoin command: %i to %i\n", userId, serverId);
+
+  this->forceReconnection(userId, serverId);
+}
+
+
+/**
+ * forces a client to reconnect to another server
+ * @param userId the userId of the client/user :D
+ * @param serverId the userId of the server to connect to
+ */
+void ProxyControl::forceReconnection(int userId, int serverId)
+{
+  PeerInfo* serverInfo = SharedNetworkData::getInstance()->getNetworkMonitor()->getPeerByUserId(serverId);
+  if( serverInfo == NULL)
+  {
+    PRINTF(0)("There is no server with userId %i registered in this network. Check the uid again\n", serverId);
+    return;
+  }
+  else if( serverInfo->isClient())
+  {
+    PRINTF(0)("You can't connec to to a client (userId %i)\n", serverId);
+    return;
+  }
+
+
+  this->forceReconnection(userId, serverId, serverInfo->ip);
+}
+
+
+/**
+ * forces a client to reconnect to another server
+ * @param userId the userId of the client/user :D
+ * @param newAddress the addresss the client should connect to
+ */
+void ProxyControl::forceReconnection(int userId, int serverId, IP newAddress)
+{
+  PRINTF(0)("forcing reconnection: userId %i to %s\n", userId, newAddress.ipString().c_str());
+  // make sure we are a proxy server
+
+  if( SharedNetworkData::getInstance()->isClient())
+  {
+    PRINTF(0)("I am client, got no right to force reconnection\n");
+    return;
+  }
+
+
+  byte data[3 * INTSIZE];
+
+  // write type of message
+  int type = PXY_RECONNECT;
+  assert( Converter::intToByteArray( type, data, INTSIZE ) == INTSIZE );
+  // write the userId in the message
+  assert( Converter::intToByteArray( userId, data + INTSIZE, INTSIZE ) == INTSIZE );
+  // and the ip as an int
+  PeerInfo* pInfo = SharedNetworkData::getInstance()->getNetworkMonitor()->getPeerByUserId(userId);
+  if( pInfo == NULL)
+  {
+    PRINTF(0)("There is no client with userId %i registered in this network. Check the uid again\n", userId);
+    return;
+  }
+  else if( pInfo->isMasterServer() || pInfo->isProxyServerActive())
+  {
+    PRINTF(0)("You cannont reconnect a %s, abording\n", pInfo->getNodeTypeString().c_str());
+    return;
+  }
+  assert( Converter::intToByteArray( newAddress.host(), data + 2 * INTSIZE, INTSIZE ) == INTSIZE );
+
+  PRINTF(0)("Sending reconnection command to: %i\n", userId);
+  // send the reconnection signal to the client who must reconnect
+  MessageManager::getInstance()->sendMessage( MSGID_PROXY_COMMAND, data, 3*INTSIZE, RT_USER, userId, MP_HIGHBANDWIDTH );
+  // and to the server who needs to accept the new client
+  MessageManager::getInstance()->sendMessage( MSGID_PROXY_COMMAND, data, 3*INTSIZE, RT_USER, serverId, MP_HIGHBANDWIDTH );
+}
+
+
+/**
+ * this is the handler for proxy commands
+ *
+ * @param messageType the type of the message
+ * @param data message data
+ * @param dataLength length of the message data
+ * @param someData some other atteched data
+ * @param senderId id of the sender client
+ * @param destinationId id of the destination client
+ * @return true if succeeded
+ */
+bool ProxyControl::messageHandlerCommand( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
+{
+  // body data length correct?
+  if ( dataLength != 3 * INTSIZE )
+  {
+    PRINTF(1)("leave client message has wrong size: %d\n", dataLength );
+    return true;
+  }
+
+  // read the command type
+  int type = 0;
+  assert( Converter::byteArrayToInt( data, &type) == INTSIZE );
+  PRINTF(0)("got command from %i with code %i\n", senderId, type);
+
+  // now distingush all different sorts of commands
+  switch( type)
+  {
+    case PXY_RECONNECT:
+    {
+      // now read the user id
+      int userId;
+      assert( Converter::byteArrayToInt( data + INTSIZE, &userId) == INTSIZE );
+      // and read the dest address
+      int ipHost = 0;
+      assert( Converter::byteArrayToInt( data + INTSIZE, &ipHost) == INTSIZE );
+
+      PRINTF(0)("Got reconnection command from %i: reconnect!\n", senderId);
+      // handle it
+      if( SharedNetworkData::getInstance()->getHostID() == userId)
+      {
+        if( SharedNetworkData::getInstance()->isClient())
+          SharedNetworkData::getInstance()->getDefaultSyncStream()->softReconnectToServer(userId, IP(ipHost, 9999));
+        else
+          SharedNetworkData::getInstance()->getDefaultSyncStream()->prepareSoftConnection(userId);
+      }
+      break;
+    }
+    default:
+      PRINTF(0)("Command not known with id %i\n", type);
+  }
+
+
+
+  return true;
+}
+
Index: trunk/src/lib/network/proxy/proxy_control.h
===================================================================
--- trunk/src/lib/network/proxy/proxy_control.h	(revision 9656)
+++ trunk/src/lib/network/proxy/proxy_control.h	(revision 9656)
@@ -0,0 +1,65 @@
+/*!
+ * @file player_stats.h
+ * @brief Definition of ProxyControl
+ *
+ * manages the clients on the proxies (connect/disconnect)
+ */
+
+#ifndef _PROXY_SETTINGS_H
+#define _PROXY_SETTINGS_H
+
+#include "synchronizeable.h"
+#include "message_manager.h"
+
+#include <string>
+#include <list>
+
+
+typedef enum proxyCommand {
+  PXY_RECONNECT              = 0,              //!< forces a reconnection of the node
+
+  PXY_WEAKUP,                                  //!< signal to weakup a sleeping proxy server (not impl. yet)
+  PXY_SLEEP,                                   //!< signal to sleep and disconnect clients
+
+  PXY_NUMBER
+};
+
+
+
+//! A class for storing player information
+class ProxyControl : public Synchronizeable
+{
+
+  public:
+    inline static ProxyControl* getInstance() { if (!ProxyControl::singletonRef) ProxyControl::singletonRef = new ProxyControl();
+      return ProxyControl::singletonRef; }
+    virtual ~ProxyControl();
+
+    virtual void varChangeHandler( std::list<int> & id );
+
+    /* connection signal handling */
+    void signalNewClient(int userId);
+    static bool messageHandlerNewClient( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  );
+
+    void signalLeaveClient(int userId);
+    static bool messageHandlerLeaveClient( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  );
+
+    /* proxy server network control */
+    void forceReconnectionShellThumb();
+    void forceReconnectionShell(int userId, int serverId);
+    void forceReconnection(int userId, int serverId);
+    void forceReconnection(int userId, int serverId, IP newAddress);
+    void forceReconnection(int userId, const std::string& newAddress);
+    static bool messageHandlerCommand( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  );
+
+  private:
+    ProxyControl();
+
+
+  private:
+    static ProxyControl*      singletonRef;            //!< Pointer to the only instance of this Class
+
+
+};
+
+#endif /* _PROXY_SETTINGS_H */
Index: trunk/src/lib/network/server_socket.h
===================================================================
--- trunk/src/lib/network/server_socket.h	(revision 9494)
+++ trunk/src/lib/network/server_socket.h	(revision 9656)
@@ -1,6 +1,6 @@
 /*!
  * @file server_socket.h
- *  waits for incoming connections
-
+ * waits for incoming connections and handles them.
+ *
  */
 
Index: trunk/src/lib/network/shared_network_data.h
===================================================================
--- trunk/src/lib/network/shared_network_data.h	(revision 9494)
+++ trunk/src/lib/network/shared_network_data.h	(revision 9656)
@@ -16,4 +16,5 @@
 
 class Synchronizeable;
+class NetworkMonitor;
 
 
@@ -64,4 +65,9 @@
     inline void setDefaultSyncStream(NetworkStream* defaultSyncStream) { this->defaultSyncStream = defaultSyncStream; }
 
+    /** @returns the network monitor reference */
+    inline NetworkMonitor* getNetworkMonitor() { return this->networkMonitor; }
+    /** @param networkMonitor sets the NetworkMonitor reference */
+    inline void setNetworkMonitor( NetworkMonitor* networkMonitor) { this->networkMonitor = networkMonitor; }
+
 
   private:
@@ -75,4 +81,5 @@
     int                             hostID;                  //!< The Host-ID of the Manager
     NetworkStream*                  defaultSyncStream;       //!< default synchronize NetworkStream
+    NetworkMonitor*                 networkMonitor;          //!< reference to the NetworkMonitor
 
     static SharedNetworkData*       singletonRef;            //!< Pointer to the only instance of this Class
Index: trunk/src/lib/network/synchronizeable.cc
===================================================================
--- trunk/src/lib/network/synchronizeable.cc	(revision 9494)
+++ trunk/src/lib/network/synchronizeable.cc	(revision 9656)
@@ -55,8 +55,8 @@
   /* 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" ) );
+  mLeafClassId = this->registerVarId( new SynchronizeableInt( (int*)&this->getLeafClassID(), (int*)&this->getLeafClassID(), "leafClassId", PERMISSION_MASTER_SERVER) );
+
+  this->registerVar( new SynchronizeableInt( &this->owner, &this->owner, "owner", PERMISSION_MASTER_SERVER ) );
+  this->registerVar( new SynchronizeableString( &this->objectName, &this->objectName, "objectName", PERMISSION_MASTER_SERVER ) );
 }
 
@@ -126,6 +126,6 @@
 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 )
+  // make sure this user has his history or resize for new clients
+  if ( (int)sentStates.size() <= userId )
     sentStates.resize( userId+1 );
 
@@ -133,4 +133,5 @@
   int neededSize = 0;
 
+  // calculate the needed space for network packet by summing up
   for ( SyncVarList::iterator it = syncVarList.begin(); it != syncVarList.end(); it++ )
   {
@@ -201,5 +202,4 @@
   int n;
 
-  bool hasPermission = false;
   bool sizeChanged = false;
 
@@ -207,31 +207,54 @@
   for ( SyncVarList::iterator it = syncVarList.begin(); it != syncVarList.end(); it++ )
   {
-    // DATA PERMISSIONS
-    // check if this synchronizeable has the permissions to write the data
-
-    // first check MASTER_SERVER permissions
-    if( SharedNetworkData::getInstance()->isMasterServer() && (*it)->checkPermission( PERMISSION_MASTER_SERVER ))
-      hasPermission = true;
-    // now check PROXY_SERVER permissions
-    else if( SharedNetworkData::getInstance()->isProxyServerActive() && (*it)->checkPermission( PERMISSION_PROXY_SERVER ))
-      hasPermission = true;
-    // now check OWNER permissions
-    else if( this->owner == SharedNetworkData::getInstance()->getHostID() && (*it)->checkPermission( PERMISSION_OWNER ))
-      hasPermission = true;
-    // now check ALL permissions
-    else if( (*it)->checkPermission( PERMISSION_ALL ))
-      hasPermission = true;
-    // SPECIAL: get write permissions if i am master server and i am able to overwrite the client stuff
-#warning this could probably override also clients that are connected to another proxy: the master server overwrites it
-    else if( SharedNetworkData::getInstance()->isMasterServer() && this->owner != userId && (*it)->checkPermission( PERMISSION_OWNER ))
-      hasPermission = true;
-    // SPECIAL: get write permissions if i am proxy server and i am able to overwrite the client stuff
-    else if( SharedNetworkData::getInstance()->isProxyServerActive() && this->networkStream->isUserClient(userId)
-             && this->owner != userId && (*it)->checkPermission( PERMISSION_OWNER ) )
-      hasPermission = true;
+
+    ////////////////////////////////
+    // Data SENDING Permissions
+    ////////////////////////////////
+    bool hasPermission = false;
+    bool b1, b2, b3, b4, b5, b6, b7, b8, b9;
+    b1 = b2 = b3 = b4 = b5 = b6 = b7 = b8 = b9 = false;
+
+
+    // Permission   OWNER accept if:
+    // I am the owner
+    if(       (*it)->checkPermission( PERMISSION_OWNER ) && this->owner == SharedNetworkData::getInstance()->getHostID()) {
+      hasPermission = true; b1 = true; }
+    // reciever != owner && owner is local
+    else if(  (*it)->checkPermission( PERMISSION_OWNER ) && userId != this->owner &&
+                (SharedNetworkData::getInstance()->isUserLocal(this->owner) || this->owner == SharedNetworkData::getInstance()->getHostID())) {
+      hasPermission = true; b2 = true; }
+
+
+    // Permission   MASTER_SERVER accept if:
+    // im MASTER_SERVER
+    else if( (*it)->checkPermission( PERMISSION_MASTER_SERVER ) && SharedNetworkData::getInstance()->isMasterServer()) {
+      hasPermission = true; b3 = true; }
+    // im PROXY_SERVER && reciever == CLIENT
+    else if( (*it)->checkPermission( PERMISSION_MASTER_SERVER ) && SharedNetworkData::getInstance()->isProxyServerActive() &&
+               SharedNetworkData::getInstance()->isUserClient( userId)) {
+      hasPermission = true;  b4 = true; }
+
+
+    // Pemission    SERVER accept if:
+    // i am server && reciever == CLIENT
+    else if( (*it)->checkPermission( PERMISSION_SERVER ) && !SharedNetworkData::getInstance()->isClient() &&
+               SharedNetworkData::getInstance()->isUserClient( userId)) {
+      hasPermission = true; b5 = true; }
+    // i am SERVER && reciever == SERVER && reciever != owner && ( owner is local || i am owner)
+    else if( (*it)->checkPermission( PERMISSION_SERVER ) && !SharedNetworkData::getInstance()->isClient() &&
+               userId != this->owner &&
+               ( SharedNetworkData::getInstance()->isUserLocal( this->owner) || this->owner ==  SharedNetworkData::getInstance()->getHostID())) {
+      hasPermission = true; b6 = true; }
+
+
+    // Permission   ALL accept if:
+    else if( (*it)->checkPermission( PERMISSION_ALL )) {
+      hasPermission = true; b7 = true; }
+    // or else refuse sending data
     else
       hasPermission = false;
 
 
+
     if ( sizeIter == stateFrom->sizeList.end() || *sizeIter != (*it)->getSize() )
       sizeChanged = true;
@@ -241,5 +264,18 @@
       n = (*it)->writeToBuf( stateTo->data+i, stateTo->dataLength - i );
       //NETPRINTF(0)("getvar %s %d\n", (*it)->getName().c_str(), n);
-      //PRINTF(0)("getvar %s %d\n", (*it)->getName().c_str(), n);
+//       PRINTF(0)("sending %s %d\n", (*it)->getName().c_str(), n);
+
+//       if( this->isA(CL_PLAYABLE))
+//       {
+//         PRINTF(0)("ms: %i, ps: %i, c: %i, sender: %i, reciever: %i, owner: %i, perm: (ow %i, ms %i, s %i, a %i)\n",
+//         SharedNetworkData::getInstance()->isMasterServer(), SharedNetworkData::getInstance()->isProxyServerActive(), SharedNetworkData::getInstance()->isClient(),
+//         SharedNetworkData::getInstance()->getHostID(), userId, this->owner,
+//         (*it)->checkPermission( PERMISSION_OWNER ), (*it)->checkPermission( PERMISSION_MASTER_SERVER ),
+//         (*it)->checkPermission( PERMISSION_SERVER ), (*it)->checkPermission( PERMISSION_ALL ));
+//         PRINTF(0)("hasPermission: %i, sizeChanged: %i, eval: %i, %i, %i, %i, %i, %i, %i\n", hasPermission, sizeChanged, b1, b2, b3, b4, b5, b6, b7);
+//         PRINTF(0)("sending %s %s %d\n", this->getClassCName(), (*it)->getName().c_str(), n);
+//       }
+
+
       stateTo->sizeList.push_back( n );
       // this is only for very hardcore debug sessions
@@ -282,5 +318,5 @@
 
 /**
- * sets a new state out of a diff created on another host
+ * sets a new state out of a diff created on another host (recieving data)
  * @param userId hostId of user who send me that diff
  * @param data pointer to diff
@@ -295,5 +331,5 @@
 {
   //make sure this user has his history
-  if ( recvStates.size() <= userId )
+  if ( (int)recvStates.size() <= userId )
     recvStates.resize( userId+1 );
 
@@ -345,5 +381,4 @@
   int n = 0;
   std::list<int> changes;
-  bool hasPermission = false;
 
   // extract the new state for every client
@@ -353,24 +388,54 @@
     // check if this synchronizeable has the permissions to write the data
 
-    // first check MASTER_SERVER permissions
-    if(  this->networkStream->isUserMasterServer( userId ) && (*it)->checkPermission( PERMISSION_MASTER_SERVER ))
-      hasPermission = true;
-    // now check PROXY_SERVER permissions
-    else if( this->networkStream->isUserProxyServerActive( userId )  && (*it)->checkPermission( PERMISSION_MASTER_SERVER )
-             && SharedNetworkData::getInstance()->isClient())
-      hasPermission = true;
-    // now check OWNER permissions
-    else if( this->owner == userId && (*it)->checkPermission( PERMISSION_OWNER ))
-      hasPermission = true;
-    // now check ALL permissions
-    else if( (*it)->checkPermission( PERMISSION_ALL ))
-      hasPermission = true;
-    // SPECIAL: get write permissions if im sending to a master server that does not own this sync
-    else if( this->networkStream->isUserMasterServer( userId ) && this->owner != SharedNetworkData::getInstance()->getHostID() && (*it)->checkPermission( PERMISSION_OWNER ))
-      hasPermission = true;
-    // SPECIAL: get write permissions if im sending to a proxy server that does not own this sync
-    else if( this->networkStream->isUserProxyServerActive( userId ) && SharedNetworkData::getInstance()->isClient()
-              && this->owner != SharedNetworkData::getInstance()->getHostID() && (*it)->checkPermission( PERMISSION_OWNER ))
-      hasPermission = true;
+    bool hasPermission = false;
+    bool b1, b2, b3, b4, b5, b6, b7, b8, b9;
+    b1 = b2 = b3 = b4 = b5 = b6 = b7 = b8 = b9 = false;
+
+    ////////////////////////////////
+    // Data RECIEVING Permissions
+    ////////////////////////////////
+
+    // i should never ever receive a state update from a synchronizeable, that belongs to me! If it does somethings wrong with the send rules
+//     assert(   !((*it)->checkPermission( PERMISSION_OWNER ) && this->owner == SharedNetworkData::getInstance()->getHostID()));
+
+
+    // Permission   OWNER accept if:
+    // sender == owner
+    if(      (*it)->checkPermission( PERMISSION_OWNER ) && this->owner == userId) {
+      hasPermission = true; b1 = true; }
+    // sender == MASTER_SERVER
+    else if( (*it)->checkPermission( PERMISSION_OWNER ) && SharedNetworkData::getInstance()->isUserMasterServer( userId)
+               && this->owner != SharedNetworkData::getInstance()->getHostID()) {
+      hasPermission = true; b2 = true; }
+    // sender == PROXY_SERVER
+      else if( (*it)->checkPermission( PERMISSION_OWNER ) && SharedNetworkData::getInstance()->isUserProxyServerActive( userId) &&
+                 this->owner != SharedNetworkData::getInstance()->getHostID()) {
+        hasPermission = true; b3 = true; }
+
+
+
+    // Permission   MASTER_SERVER accept if:
+    // sender == MASTER_SERVER
+    else if( (*it)->checkPermission( PERMISSION_MASTER_SERVER) && SharedNetworkData::getInstance()->isUserMasterServer( userId)) {
+      hasPermission = true; b4 = true; }
+    // sender == PROXY_SERVER && im not MASTER_SERVER && im not PROXY_SERVER
+    else if( (*it)->checkPermission( PERMISSION_MASTER_SERVER) && SharedNetworkData::getInstance()->isClient() &&
+               SharedNetworkData::getInstance()->isUserProxyServerActive( userId)) {
+      hasPermission = true; b5 = true; }
+
+    // Permission   SERVER accept if:
+    // sender == SERVER
+    else if( (*it)->checkPermission( PERMISSION_SERVER ) && !SharedNetworkData::getInstance()->isUserClient( userId) /*&&
+               SharedNetworkData::getInstance()->isClient()*/) {
+      hasPermission = true; b6 = true; }
+
+
+
+    // Pemission    ALL accept if:
+    else if(  (*it)->checkPermission( PERMISSION_ALL )) {
+      hasPermission = true; b8 = true; }
+
+
+   // no rights to over-write local data
     else
       hasPermission = false;
@@ -384,6 +449,19 @@
       i += n;
       //NETPRINTF(0)("%s::setvar %s %d\n", getClassCName(), (*it)->getName().c_str(), n);
-      //PRINTF(0)("%s::setvar %s %d\n", getClassCName(), (*it)->getName().c_str(), n);
+//       PRINTF(0)("recieving: %s %d\n",  (*it)->getName().c_str(), n);
       //(*it)->debug();
+
+//       if( this->isA(CL_PLAYABLE))
+//       {
+//         PRINTF(0)("ms: %i, ps: %i, c: %i, sender: %i, reciever: %i, owner: %i, perm: (ow %i, ms %i, s %i, a %i)\n",
+//         SharedNetworkData::getInstance()->isMasterServer(), SharedNetworkData::getInstance()->isProxyServerActive(), SharedNetworkData::getInstance()->isClient(),
+//         userId, SharedNetworkData::getInstance()->getHostID(), this->owner,
+//         (*it)->checkPermission( PERMISSION_OWNER ), (*it)->checkPermission( PERMISSION_MASTER_SERVER ),
+//         (*it)->checkPermission( PERMISSION_SERVER ), (*it)->checkPermission( PERMISSION_ALL ));
+//         PRINTF(0)("hasPermission: %i, eval: %i, %i, %i, %i, %i, %i, %i, %i\n", hasPermission, b1, b2, b3, b4, b5, b6, b7, b8);
+//         PRINTF(0)("rec %s %s %d\n", this->getClassCName(), (*it)->getName().c_str(), n);
+//       }
+
+
       if ( (*it)->getHasChanged() )
       {
@@ -444,5 +522,5 @@
 void Synchronizeable::cleanUpUser( int userId )
 {
-  if ( recvStates.size() > userId )
+  if ( (int)recvStates.size() > userId )
   {
     for ( std::list<StateHistoryEntry*>::iterator it = recvStates[userId].begin(); it != recvStates[userId].end(); it++ )
@@ -459,5 +537,5 @@
   }
 
-  if ( sentStates.size() > userId )
+  if ( (int)sentStates.size() > userId )
   {
 
@@ -485,5 +563,5 @@
 {
    //make sure this user has his history
-  if ( recvStates.size() <= userId )
+  if ( (int)recvStates.size() <= userId )
     recvStates.resize( userId+1 );
 
@@ -575,5 +653,5 @@
 {
    //make sure this user has his history
-  if ( sentStates.size() <= userId )
+  if ( (int)sentStates.size() <= userId )
     sentStates.resize( userId+1 );
 
Index: trunk/src/lib/network/synchronizeable_var/synchronizeable_bool.h
===================================================================
--- trunk/src/lib/network/synchronizeable_var/synchronizeable_bool.h	(revision 9494)
+++ trunk/src/lib/network/synchronizeable_var/synchronizeable_bool.h	(revision 9656)
@@ -12,5 +12,5 @@
 
   public:
-    SynchronizeableBool( bool * ptrIn, bool * ptrOut, std::string name, int permission = PERMISSION_MASTER_SERVER, int priority = 0 );
+    SynchronizeableBool( bool * ptrIn, bool * ptrOut, std::string name, int permission, int priority = 0 );
     virtual ~SynchronizeableBool();
 
Index: trunk/src/lib/network/synchronizeable_var/synchronizeable_float.h
===================================================================
--- trunk/src/lib/network/synchronizeable_var/synchronizeable_float.h	(revision 9494)
+++ trunk/src/lib/network/synchronizeable_var/synchronizeable_float.h	(revision 9656)
@@ -13,5 +13,5 @@
 
   public:
-    SynchronizeableFloat( float * ptrIn, float * ptrOut, std::string name, int permission = PERMISSION_MASTER_SERVER, int priority = 0 );
+    SynchronizeableFloat( float * ptrIn, float * ptrOut, std::string name, int permission, int priority = 0 );
     virtual ~SynchronizeableFloat();
 
Index: trunk/src/lib/network/synchronizeable_var/synchronizeable_int.h
===================================================================
--- trunk/src/lib/network/synchronizeable_var/synchronizeable_int.h	(revision 9494)
+++ trunk/src/lib/network/synchronizeable_var/synchronizeable_int.h	(revision 9656)
@@ -13,5 +13,5 @@
 
   public:
-    SynchronizeableInt( int * ptrIn, int * ptrOut, std::string name, int permission = PERMISSION_MASTER_SERVER, int priority = 0 );
+    SynchronizeableInt( int * ptrIn, int * ptrOut, std::string name, int permission, int priority = 0 );
     virtual ~SynchronizeableInt();
 
Index: trunk/src/lib/network/synchronizeable_var/synchronizeable_ip.h
===================================================================
--- trunk/src/lib/network/synchronizeable_var/synchronizeable_ip.h	(revision 9494)
+++ trunk/src/lib/network/synchronizeable_var/synchronizeable_ip.h	(revision 9656)
@@ -15,5 +15,5 @@
 
   public:
-    SynchronizeableIP( IP *ptrIn, IP * ptrOut, std::string name, int permission = PERMISSION_MASTER_SERVER, int priority = 0 );
+    SynchronizeableIP( IP *ptrIn, IP * ptrOut, std::string name, int permission, int priority = 0 );
     virtual ~SynchronizeableIP();
 
Index: trunk/src/lib/network/synchronizeable_var/synchronizeable_quaternion.h
===================================================================
--- trunk/src/lib/network/synchronizeable_var/synchronizeable_quaternion.h	(revision 9494)
+++ trunk/src/lib/network/synchronizeable_var/synchronizeable_quaternion.h	(revision 9656)
@@ -14,5 +14,5 @@
 
   public:
-    SynchronizeableQuaternion( Quaternion * ptrIn, Quaternion * ptrOut, std::string name, int permission = PERMISSION_MASTER_SERVER, int priority = 0 );
+    SynchronizeableQuaternion( Quaternion * ptrIn, Quaternion * ptrOut, std::string name, int permission, int priority = 0 );
     virtual ~SynchronizeableQuaternion();
 
Index: trunk/src/lib/network/synchronizeable_var/synchronizeable_string.h
===================================================================
--- trunk/src/lib/network/synchronizeable_var/synchronizeable_string.h	(revision 9494)
+++ trunk/src/lib/network/synchronizeable_var/synchronizeable_string.h	(revision 9656)
@@ -14,5 +14,5 @@
 
   public:
-    SynchronizeableString( std::string * ptrIn, std::string * ptrOut, std::string name, int permission = PERMISSION_MASTER_SERVER, int priority = 0 );
+    SynchronizeableString( std::string * ptrIn, std::string * ptrOut, std::string name, int permission, int priority = 0 );
     virtual ~SynchronizeableString();
 
Index: trunk/src/lib/network/synchronizeable_var/synchronizeable_uint.h
===================================================================
--- trunk/src/lib/network/synchronizeable_var/synchronizeable_uint.h	(revision 9494)
+++ trunk/src/lib/network/synchronizeable_var/synchronizeable_uint.h	(revision 9656)
@@ -13,5 +13,5 @@
 
   public:
-    SynchronizeableUInt( unsigned int * ptrIn, unsigned int * ptrOut, std::string name, int permission = PERMISSION_MASTER_SERVER, int priority = 0 );
+    SynchronizeableUInt( unsigned int * ptrIn, unsigned int * ptrOut, std::string name, int permission, int priority = 0 );
     virtual ~SynchronizeableUInt();
 
Index: trunk/src/lib/network/synchronizeable_var/synchronizeable_var.h
===================================================================
--- trunk/src/lib/network/synchronizeable_var/synchronizeable_var.h	(revision 9494)
+++ trunk/src/lib/network/synchronizeable_var/synchronizeable_var.h	(revision 9656)
@@ -15,5 +15,5 @@
 
   public:
-    SynchronizeableVar( void * ptrIn, void * ptrOut, std::string name, int length, int permission = PERMISSION_MASTER_SERVER, int priority = 0 );
+    SynchronizeableVar( void * ptrIn, void * ptrOut, std::string name, int length, int permission, int priority = 0 );
     virtual ~SynchronizeableVar();
 
Index: trunk/src/lib/network/synchronizeable_var/synchronizeable_vector.h
===================================================================
--- trunk/src/lib/network/synchronizeable_var/synchronizeable_vector.h	(revision 9494)
+++ trunk/src/lib/network/synchronizeable_var/synchronizeable_vector.h	(revision 9656)
@@ -14,5 +14,5 @@
 
   public:
-    SynchronizeableVector( Vector * ptrIn, Vector * ptrOut, std::string name, int permission = PERMISSION_MASTER_SERVER, int priority = 0 );
+    SynchronizeableVector( Vector * ptrIn, Vector * ptrOut, std::string name, int permission, int priority = 0 );
     virtual ~SynchronizeableVector();
 
Index: trunk/src/lib/network/udp_socket.h
===================================================================
--- trunk/src/lib/network/udp_socket.h	(revision 9494)
+++ trunk/src/lib/network/udp_socket.h	(revision 9656)
@@ -41,4 +41,13 @@
 
   private:
+    void init();
+
+    bool writeRawPacket( byte * data, int length );
+    bool checkUdpCmd( byte udpCmd );
+    bool checkRandomByte( byte rndByte );
+    byte generateNewRandomByte();
+
+
+  private:
     UdpServerSocket * serverSocket;   //!< will get packets here
     int               userId;         //!< user id used by serverSocket
@@ -47,12 +56,4 @@
 
     byte              randomByte;     //!< contains random bytes & 0xFC
-
-    bool writeRawPacket( byte * data, int length );
-    bool checkUdpCmd( byte udpCmd );
-    bool checkRandomByte( byte rndByte );
-    byte generateNewRandomByte();
-
-    void init();
-
 };
 
