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 */
