Index: /trunk/src/lib/event/event_handler.cc
===================================================================
--- /trunk/src/lib/event/event_handler.cc	(revision 8622)
+++ /trunk/src/lib/event/event_handler.cc	(revision 8623)
@@ -503,4 +503,12 @@
 
 
+int EventHandler::releaseMouse(void* p)
+{
+  SDL_WM_GrabInput(SDL_GRAB_OFF);
+  SDL_ShowCursor(SDL_DISABLE);
+  return 0;
+}
+
+
 /**
  * @param state The State to get the Name of.
Index: /trunk/src/lib/event/event_handler.h
===================================================================
--- /trunk/src/lib/event/event_handler.h	(revision 8622)
+++ /trunk/src/lib/event/event_handler.h	(revision 8623)
@@ -56,4 +56,6 @@
   static elState StringToELState(const std::string& stateName);
 
+  static int releaseMouse(void* p);
+
 private:
   EventHandler();
Index: /trunk/src/lib/network/Makefile.am
===================================================================
--- /trunk/src/lib/network/Makefile.am	(revision 8622)
+++ /trunk/src/lib/network/Makefile.am	(revision 8623)
@@ -24,4 +24,5 @@
 		      zip.cc \
 		      player_stats.cc \
+		      udp_broadcast.cc \
 		      \
 		      synchronizeable_var/synchronizeable_var.cc \
@@ -58,4 +59,5 @@
 		 zip.h \
 		 player_stats.h \
+		 udp_broadcast.h \
 		 \
 		 synchronizeable_var/synchronizeable_var.h \
Index: /trunk/src/lib/network/connection_monitor.cc
===================================================================
--- /trunk/src/lib/network/connection_monitor.cc	(revision 8622)
+++ /trunk/src/lib/network/connection_monitor.cc	(revision 8623)
@@ -130,4 +130,15 @@
 
 /**
+ * remove old packets
+ * @param packetHistory 
+ * @param tick 
+ */
+void ConnectionMonitor::removeOldPackets( std::map< int, int > & packetHistory, int tick )
+{
+  while ( packetHistory.begin()->first < tick - MSECS_TO_CALC_BWIDTH )
+    packetHistory.erase( packetHistory.begin() );
+}
+
+/**
  * calculate bandwidth out of packethistory
  * @param packetHistory packet history
@@ -135,12 +146,10 @@
  * @return bandwidth in bytes/sec
  */
-float ConnectionMonitor::calculateBandWidth( std::map< int, int > packetHistory, int tick )
-{
-  // delete old packets
-  while ( packetHistory.begin()->first < tick - MSECS_TO_CALC_BWIDTH )
-    packetHistory.erase( packetHistory.begin() );
+float ConnectionMonitor::calculateBandWidth( std::map< int, int > & packetHistory, int tick )
+{
+  removeOldPackets( packetHistory, tick );
   
   float res = 0.0f;
-  
+#if 0
   for ( std::map<int,int>::iterator it = packetHistory.begin(); it != packetHistory.end(); it++ )
   {
@@ -155,5 +164,18 @@
   
   res *= 1000.0f;
-  
+#endif
+
+  for ( std::map<int,int>::iterator it = packetHistory.begin(); it != packetHistory.end(); it++ )
+  {
+    res += it->second;
+  }
+  
+  if ( packetHistory.size() <= 1 )
+    res = 0.0f;
+  else
+    res /= (float)(tick - packetHistory.begin()->first);
+  
+  res *= 1000.0f;
+
   return res;
 }
Index: /trunk/src/lib/network/connection_monitor.h
===================================================================
--- /trunk/src/lib/network/connection_monitor.h	(revision 8622)
+++ /trunk/src/lib/network/connection_monitor.h	(revision 8623)
@@ -15,5 +15,5 @@
 #define N_PACKETS_FOR_PING 20
 #define MSECS_TO_CALC_BWIDTH 1000
-#define SECS_TO_TIMEOUT 10
+#define SECS_TO_TIMEOUT 30
 
 class ConnectionMonitor : virtual public BaseObject
@@ -36,5 +36,6 @@
 
   private:
-    float calculateBandWidth( std::map<int,int> packetHistory, int tick );
+    float calculateBandWidth( std::map<int,int> & packetHistory, int tick );
+    void removeOldPackets( std::map<int,int> & packetHistory, int tick );
 
     int userId;       //!< user's id
Index: /trunk/src/lib/network/data_stream.cc
===================================================================
--- /trunk/src/lib/network/data_stream.cc	(revision 8622)
+++ /trunk/src/lib/network/data_stream.cc	(revision 8623)
@@ -53,5 +53,8 @@
 DataStream::~DataStream()
 {
-
+  delete [] this->upBuffer;
+  this->upBuffer = NULL;
+  delete [] this->downBuffer;
+  this->downBuffer = NULL;
 }
 
@@ -120,4 +123,4 @@
 int passUp(byte* data)
 {
-
+  return 0;
 }
Index: /trunk/src/lib/network/message_manager.cc
===================================================================
--- /trunk/src/lib/network/message_manager.cc	(revision 8622)
+++ /trunk/src/lib/network/message_manager.cc	(revision 8623)
@@ -47,5 +47,5 @@
       if ( it2->data )
       {
-        delete it2->data;
+        delete [] it2->data;
         it2->data = NULL;
       }
@@ -319,5 +319,5 @@
     {
       NetworkMessage msg;
-      
+
       msg.data = new byte[dataLength];
       memcpy( msg.data, data, dataLength );
@@ -326,12 +326,25 @@
       msg.number = newNumber++;
       msg.priority = messagePriority;
-      
+
       it->second.messages.push_back( msg );
       
-      if ( recieverType == RT_ALL_ME )
-        incomingMessabeBuffer.push_back( msg );
-    }
-  }
-}
-
-
+     
+    }
+  }
+  
+  if ( recieverType == RT_ALL_ME )
+  {
+    NetworkMessage msg;
+
+    msg.data = new byte[dataLength];
+    memcpy( msg.data, data, dataLength );
+    msg.length = dataLength;
+    msg.messageId = messageId;
+    msg.number = newNumber++;
+    msg.priority = messagePriority;
+
+    incomingMessabeBuffer.push_back( msg );
+  }
+}
+
+
Index: /trunk/src/lib/network/message_manager.h
===================================================================
--- /trunk/src/lib/network/message_manager.h	(revision 8622)
+++ /trunk/src/lib/network/message_manager.h	(revision 8623)
@@ -31,5 +31,6 @@
   MSGID_DELETESYNCHRONIZEABLE,
   MSGID_PREFEREDTEAM,
-  MSGID_CHANGEPLAYERNAME
+  MSGID_CHANGENICKNAME,
+  MSGID_CHATMESSAGE
 };
 
Index: /trunk/src/lib/network/network_game_manager.cc
===================================================================
--- /trunk/src/lib/network/network_game_manager.cc	(revision 8622)
+++ /trunk/src/lib/network/network_game_manager.cc	(revision 8623)
@@ -23,4 +23,5 @@
 #include "state.h"
 #include "class_list.h"
+#include "debug.h"
 
 #include "network_stream.h"
@@ -39,6 +40,4 @@
 #include "network_game_manager.h"
 
-#include "debug.h"
-
 
 /* using namespace std is default, this needs to be here */
@@ -59,8 +58,9 @@
 
   this->setSynchronized(true);
-
+  
   MessageManager::getInstance()->registerMessageHandler( MSGID_DELETESYNCHRONIZEABLE, delSynchronizeableHandler, NULL );
   MessageManager::getInstance()->registerMessageHandler( MSGID_PREFEREDTEAM, preferedTeamHandler, NULL );
-
+  MessageManager::getInstance()->registerMessageHandler( MSGID_CHATMESSAGE, chatMessageHandler, NULL );
+  
   this->gameState = 0;
   registerVar( new SynchronizeableInt( &gameState, &gameState, "gameState" ) );
@@ -72,4 +72,7 @@
 NetworkGameManager::~NetworkGameManager()
 {
+  delete MessageManager::getInstance();
+  
+  PlayerStats::deleteAllPlayerStats();
 }
 
@@ -77,6 +80,6 @@
 /**
  * insert new player into game
- * @param userId
- * @return
+ * @param userId 
+ * @return 
  */
 bool NetworkGameManager::signalNewPlayer( int userId )
@@ -85,34 +88,35 @@
   assert( State::getGameRules() );
   assert( State::getGameRules()->isA( CL_NETWORK_GAME_RULES ) );
-
+  
   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 );
-
+  
   BaseObject * bo = Factory::fabricate( playableClassId );
-
+  
   assert( bo != NULL );
   assert( bo->isA( CL_PLAYABLE ) );
-
+  
   Playable & playable = *(dynamic_cast<Playable*>(bo));
-
-  playable.loadModel( playableModel );
+  
+  if (  playableModel != "" )
+    playable.loadModel( playableModel );
   playable.setOwner( userId );
   playable.setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
   playable.setSynchronized( true );
-
+  
   PlayerStats * stats = rules.getNewPlayerStats( userId );
-
+  
   stats->setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
   stats->setSynchronized( true );
   stats->setOwner( getHostID() );
-
+  
   stats->setTeamId( team );
   stats->setPlayableClassId( playableClassId );
   stats->setPlayableUniqueId( playable.getUniqueID() );
   stats->setModelFileName( playableModel );
-
+  
   return true;
 }
@@ -121,6 +125,6 @@
 /**
  * remove player from game
- * @param userID
- * @return
+ * @param userID 
+ * @return 
  */
 bool NetworkGameManager::signalLeftPlayer(int userID)
@@ -132,5 +136,5 @@
     delete PlayerStats::getStats( userID );
   }
-
+  
   return true;
 }
@@ -140,9 +144,9 @@
 /**
  * handler for remove synchronizeable messages
- * @param messageId
- * @param data
- * @param dataLength
- * @param someData
- * @param userId
+ * @param messageId 
+ * @param data 
+ * @param dataLength 
+ * @param someData 
+ * @param userId 
  * @return true on successfull handling else handler will be called again
  */
@@ -154,8 +158,8 @@
     return true;
   }
-
+  
   int uniqueId = 0;
   int len = Converter::byteArrayToInt( data, &uniqueId );
-
+  
   if ( len != dataLength )
   {
@@ -163,7 +167,7 @@
     return true;
   }
-
+  
   const std::list<BaseObject*> * list = ClassList::getList( CL_SYNCHRONIZEABLE );
-
+  
   for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
   {
@@ -175,10 +179,10 @@
         return true;
       }
-
+      
       delete dynamic_cast<Synchronizeable*>(*it);
       return true;
     }
   }
-
+  
   return true;
 }
@@ -191,5 +195,5 @@
 {
   byte buf[INTSIZE];
-
+  
   assert( Converter::intToByteArray( uniqueId, buf, INTSIZE ) == INTSIZE );
 
@@ -201,18 +205,18 @@
 /**
  * handler for MSGID_PREFEREDTEAM message
- * @param messageId
- * @param data
- * @param dataLength
- * @param someData
- * @param userId
- * @return
+ * @param messageId 
+ * @param data 
+ * @param dataLength 
+ * @param someData 
+ * @param userId 
+ * @return 
  */
 bool NetworkGameManager::preferedTeamHandler( MessageId messageId, byte * data, int dataLength, void * someData, int userId )
 {
   assert( NetworkGameManager::getInstance()->isServer() );
-
+  
   int teamId = 0;
   int len = Converter::byteArrayToInt( data, &teamId );
-
+  
   if ( len != dataLength )
   {
@@ -220,7 +224,7 @@
     return true;
   }
-
+  
   NetworkGameManager::getInstance()->setPreferedTeam( userId, teamId );
-
+  
   return true;
 }
@@ -230,7 +234,7 @@
   if ( !PlayerStats::getStats( userId ) )
     return;
-
+  
   PlayerStats & stats = *(PlayerStats::getStats( userId ));
-
+  
   stats.setPreferedTeamId( teamId );
 }
@@ -238,5 +242,5 @@
 /**
  * set prefered team for this host
- * @param teamId
+ * @param teamId 
  */
 void NetworkGameManager::prefereTeam( int teamId )
@@ -247,7 +251,7 @@
   {
     byte buf[INTSIZE];
-
+    
     assert( Converter::intToByteArray( teamId, buf, INTSIZE) == INTSIZE );
-
+    
     MessageManager::getInstance()->sendMessage( MSGID_PREFEREDTEAM, buf, INTSIZE, RT_USER, 0, MP_HIGHBANDWIDTH );
   }
@@ -278,3 +282,49 @@
 
 
-
+bool NetworkGameManager::chatMessageHandler( MessageId messageId, byte * data, int dataLength, void * someData, int userId )
+{
+  assert( State::getGameRules() );
+  assert( State::getGameRules()->isA( CL_NETWORK_GAME_RULES ) );
+  
+  NetworkGameRules & rules = *(dynamic_cast<NetworkGameRules*>(State::getGameRules()));
+  
+  if ( dataLength < 2*INTSIZE )
+  {
+    PRINTF(2)("got too small chatmessage from client %d\n", userId);
+    
+    return true;
+  }
+  
+  int messageType = 0;
+  Converter::byteArrayToInt( data, &messageType );
+  std::string message;
+  Converter::byteArrayToString( data+INTSIZE, message, dataLength-INTSIZE );
+  
+  rules.handleChatMessage( userId, message, messageType );
+
+  return true;
+}
+
+/**
+ * send chat message
+ * @param message message text
+ * @param messageType some int
+ * @param userId user to send message to -1 = ALL
+ */
+void NetworkGameManager::sendChatMessage( const std::string & message, int messageType, int userId )
+{
+  byte * buf = new byte[message.length()+2*INTSIZE];
+
+  assert( Converter::intToByteArray( messageType, buf, INTSIZE ) == INTSIZE );
+  assert( Converter::stringToByteArray(message, buf+INTSIZE, message.length()+INTSIZE) == message.length()+INTSIZE );
+  
+  if ( userId == -1 )
+    MessageManager::getInstance()->sendMessage( MSGID_CHATMESSAGE, buf, message.length()+2*INTSIZE, RT_ALL_ME, 0, MP_HIGHBANDWIDTH );
+  else
+    MessageManager::getInstance()->sendMessage( MSGID_CHATMESSAGE, buf, message.length()+2*INTSIZE, RT_USER, userId, MP_HIGHBANDWIDTH );
+  
+  delete [] buf;
+}
+
+
+
Index: /trunk/src/lib/network/network_game_manager.h
===================================================================
--- /trunk/src/lib/network/network_game_manager.h	(revision 8622)
+++ /trunk/src/lib/network/network_game_manager.h	(revision 8623)
@@ -64,4 +64,6 @@
     
     void tick( float ds );
+    
+    void sendChatMessage( const std::string & message, int messageType, int userId = -1 );
 
   private:
@@ -70,4 +72,5 @@
     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 );
     
     void setPreferedTeam( int userId, int teamId );
Index: /trunk/src/lib/network/network_stream.cc
===================================================================
--- /trunk/src/lib/network/network_stream.cc	(revision 8622)
+++ /trunk/src/lib/network/network_stream.cc	(revision 8623)
@@ -95,5 +95,9 @@
   remainingBytesToWriteToDict = Preferences::getInstance()->getInt( "compression", "writedict", 0 );
   
-  assert( Zip::getInstance()->loadDictionary( "testdict" ) );
+  assert( Zip::getInstance()->loadDictionary( "testdict" ) >= 0 );
+  this->dictClient = Zip::getInstance()->loadDictionary( "dict2pl_client" );
+  assert( this->dictClient >= 0 );
+  this->dictServer = Zip::getInstance()->loadDictionary( "dict2p_server" );
+  assert( this->dictServer >= 0 );
 }
 
@@ -121,4 +125,10 @@
       delete i->second.handshake;
       i->second.handshake = NULL;
+    }
+    
+    if ( i->second.connectionMonitor )
+    {
+      delete i->second.connectionMonitor;
+      i->second.connectionMonitor = NULL;
     }
   }
@@ -198,4 +208,8 @@
         delete peers[0].handshake;
       peers[0].handshake = NULL;
+      
+      if ( peers[0].connectionMonitor )
+        delete peers[0].connectionMonitor;
+      peers[0].connectionMonitor = NULL;
     }
   }
@@ -282,4 +296,8 @@
       it->second.socket = NULL;
 
+      if ( it->second.connectionMonitor )
+        delete it->second.connectionMonitor;
+      it->second.connectionMonitor = NULL;
+      
       if ( it->second.handshake )
         delete it->second.handshake;
@@ -490,7 +508,11 @@
     assert( Converter::intToByteArray( offset, buf, INTSIZE ) == INTSIZE );
     
-    int compLength = Zip::getInstance()->zip( buf, offset, compBuf, UDP_PACKET_SIZE );
-    
-    if ( compLength < 0 )
+    int compLength = 0;
+    if ( this->isServer() )
+      compLength = Zip::getInstance()->zip( buf, offset, compBuf, UDP_PACKET_SIZE, dictServer );
+    else
+      compLength = Zip::getInstance()->zip( buf, offset, compBuf, UDP_PACKET_SIZE, dictClient );
+    
+    if ( compLength <= 0 )
     {
       PRINTF(1)("compression failed!\n");
@@ -501,5 +523,5 @@
     
     if ( this->remainingBytesToWriteToDict > 0 )
-      writeToNewDict( buf, offset );
+      writeToNewDict( buf, offset, true );
     
     peer->second.connectionMonitor->processUnzippedOutgoingPacket( tick, buf, offset, currentState );
@@ -538,5 +560,5 @@
       //PRINTF(0)("GGGGGOOOOOOOOOOTTTTTTTT: %d\n", compLength);
       packetLength = Zip::getInstance()->unZip( compBuf, compLength, buf, UDP_PACKET_SIZE );
-      
+
       if ( packetLength < 4*INTSIZE )
       {
@@ -547,5 +569,5 @@
       
       if ( this->remainingBytesToWriteToDict > 0 )
-        writeToNewDict( buf, packetLength );
+        writeToNewDict( buf, packetLength, false );
     
       assert( Converter::byteArrayToInt( buf, &length ) == INTSIZE );
@@ -556,5 +578,5 @@
       offset = 4*INTSIZE;
       
-      peer->second.connectionMonitor->processUnzippedIncomingPacket( tick, buf, offset, state, ackedState );
+      peer->second.connectionMonitor->processUnzippedIncomingPacket( tick, buf, packetLength, state, ackedState );
 
       //NETPRINTF(n)("got packet: %d, %d\n", length, packetLength);
@@ -729,5 +751,5 @@
  * @param length length
  */
-void NetworkStream::writeToNewDict( byte * data, int length )
+void NetworkStream::writeToNewDict( byte * data, int length, bool upstream )
 {
   if ( remainingBytesToWriteToDict <= 0 )
@@ -739,4 +761,9 @@
   std::string fileName = ResourceManager::getInstance()->getDataDir();
   fileName += "/dicts/newdict";
+  
+  if ( upstream )
+    fileName += "_upstream";
+  else
+    fileName += "_downstream";
   
   FILE * f = fopen( fileName.c_str(), "a" );
Index: /trunk/src/lib/network/network_stream.h
===================================================================
--- /trunk/src/lib/network/network_stream.h	(revision 8622)
+++ /trunk/src/lib/network/network_stream.h	(revision 8623)
@@ -84,5 +84,5 @@
     void cleanUpOldSyncList();
     
-    void writeToNewDict( byte * data, int length );
+    void writeToNewDict( byte * data, int length, bool upstream );
 
 
@@ -107,4 +107,7 @@
 
     int                        remainingBytesToWriteToDict; //!< if > 0 NetworkStream will write packets to DATA/dicts/newdict
+
+    int dictServer;
+    int dictClient;
 };
 #endif /* _NETWORK_STREAM */
Index: /trunk/src/lib/network/player_stats.cc
===================================================================
--- /trunk/src/lib/network/player_stats.cc	(revision 8622)
+++ /trunk/src/lib/network/player_stats.cc	(revision 8623)
@@ -24,8 +24,10 @@
 
 #include "debug.h"
+#include "shell_command.h"
 
 
 CREATE_FACTORY(PlayerStats, CL_PLAYER_STATS);
 
+
 /**
  * constructor
@@ -34,5 +36,5 @@
 {
   init();
-
+  
   this->userId = userId;
 }
@@ -56,5 +58,7 @@
   this->playableClassId = 0;
   this->modelFileName = "";
-
+  this->nickName = "Player";
+  this->oldNickName = "Player";
+  
   userId_handle = registerVarId( new SynchronizeableInt( &userId, &userId, "userId" ) );
   teamId_handle = registerVarId( new SynchronizeableInt( &teamId, &teamId, "teamId" ) );
@@ -64,5 +68,8 @@
   playableUniqueId_handle = registerVarId( new SynchronizeableInt( &playableUniqueId, &playableUniqueId, "playableUniqueId" ) );
   modelFileName_handle = registerVarId( new SynchronizeableString( &modelFileName, &modelFileName, "modelFileName" ) );
-
+  nickName_handler = registerVarId( new SynchronizeableString( &nickName, &nickName, "nickName" ) );
+  
+  MessageManager::getInstance()->registerMessageHandler( MSGID_CHANGENICKNAME, changeNickHandler, NULL );
+  
   PRINTF(0)("PlayerStats created\n");
 }
@@ -87,6 +94,12 @@
   {
     this->setPlayableUniqueId( this->playableUniqueId );
-
+    
     PRINTF(0)("uniqueID changed %d %d %d\n", userId, getHostID(), getUniqueID());
+  }
+  
+  if ( std::find( id.begin(), id.end(), nickName_handler ) != id.end() )
+  {
+    PRINTF(0)("user %s is now known as %s\n", oldNickName.c_str(), nickName.c_str());
+    oldNickName = nickName;
   }
 }
@@ -100,10 +113,10 @@
 {
   const std::list<BaseObject*> * list = ClassList::getList( CL_PLAYER_STATS );
-
+  
   if ( !list )
   {
     return NULL;
   }
-
+  
   for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
   {
@@ -113,5 +126,5 @@
     }
   }
-
+  
   return NULL;
 }
@@ -123,5 +136,5 @@
 {
   const std::list<BaseObject*> * list = ClassList::getList( CL_PLAYABLE );
-
+  
   if ( !list )
   {
@@ -129,5 +142,5 @@
     return;
   }
-
+  
   this->playable = NULL;
   for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
@@ -141,10 +154,10 @@
     }
   }
-
+  
   if ( this->playable && userId == getHostID() )
   {
     State::getPlayer()->setPlayable( this->playable );
   }
-
+  
   this->playableUniqueId = uniqueId;
 }
@@ -158,13 +171,69 @@
   if ( playable )
     return playable;
-
+  
   assert( playableUniqueId > 0 );
-
+  
   setPlayableUniqueId( playableUniqueId );
-
+  
   assert( playable );
-
+  
   return playable;
 }
 
-
+/**
+ * client sends server a message to change nick and server changes nick directly
+ * @param nick new nickname
+ */
+void PlayerStats::setNickName( std::string nick )
+{
+  if ( isServer() )
+  {
+    this->nickName = nick;
+    PRINTF(0)("user %s is now known as %s\n", oldNickName.c_str(), nickName.c_str());
+    oldNickName = nickName;
+    return;
+  }
+  else
+  {
+    byte * data = new byte[nick.length()+INTSIZE];
+    
+    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 );
+    return;
+  }
+}
+
+bool PlayerStats::changeNickHandler( MessageId messageId, byte * data, int dataLength, void * someData, int userId )
+{
+  std::string newNick;
+  int res = Converter::byteArrayToString( data, newNick, dataLength );
+  
+  if ( res != dataLength )
+  {
+    PRINTF(2)("invalid message size from user %d\n", userId);
+    newNick = "invalid";
+  }
+  
+  if ( PlayerStats::getStats( userId ) )
+    PlayerStats::getStats( userId )->setNickName( newNick );
+  
+  return true;
+}
+
+void PlayerStats::shellNick( const std::string& newNick )
+{
+  if ( getStats( SharedNetworkData::getInstance()->getHostID() ) )
+    getStats( SharedNetworkData::getInstance()->getHostID() )->setNickName( newNick );
+}
+
+
+
+void PlayerStats::deleteAllPlayerStats( )
+{
+  const std::list<BaseObject*> * list;
+  
+  while ( (list  = ClassList::getList( CL_PLAYER_STATS )) != NULL && list->begin() != list->end() )
+    delete *list->begin();
+}
+
Index: /trunk/src/lib/network/player_stats.h
===================================================================
--- /trunk/src/lib/network/player_stats.h	(revision 8622)
+++ /trunk/src/lib/network/player_stats.h	(revision 8623)
@@ -9,4 +9,5 @@
 #include "synchronizeable.h"
 #include "playable.h"
+#include "message_manager.h"
 
 #include <string>
@@ -54,4 +55,11 @@
     
     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 );
+    void shellNick( const std::string&  newNick );
+    
+    static void deleteAllPlayerStats();
 
   private:
@@ -59,4 +67,7 @@
     int teamId;                //!< teamId
     int preferedTeamId;        //!< preferedTeamId
+
+    std::string nickName;      //!< players nickname
+    std::string oldNickName;   //!< nickname player had before
 
     int score;                 //!< users score points
@@ -75,4 +86,5 @@
     int playableUniqueId_handle;
     int modelFileName_handle;
+    int nickName_handler;
     
     void init();
Index: /trunk/src/lib/network/synchronizeable.cc
===================================================================
--- /trunk/src/lib/network/synchronizeable.cc	(revision 8622)
+++ /trunk/src/lib/network/synchronizeable.cc	(revision 8623)
@@ -70,6 +70,40 @@
     this->networkStream->disconnectSynchronizeable(*this);
   
-  if ( this->isServer() && this->beSynchronized() && this->getUniqueID() > 0 )
+  if ( this->isServer() && this->beSynchronized() && this->getUniqueID() > 0 && !this->isA( CL_MESSAGE_MANAGER ) )
     NetworkGameManager::getInstance()->removeSynchronizeable( this->getUniqueID() );
+    
+  for ( SyncVarList::iterator it = syncVarList.begin(); it != syncVarList.end(); it++ )
+  {
+    delete *it;
+  }
+  syncVarList.clear();
+  
+  for ( UserStateHistory::iterator it = recvStates.begin(); it != recvStates.end(); it++ )
+  {
+    for ( StateHistory::iterator it2 = it->begin(); it2 != it->end(); it2++ )
+    {
+      if ( (*it2)->data )
+      {
+        delete [] (*it2)->data;
+        (*it2)->data = NULL;
+      }
+      delete *it2;
+    }
+
+  }
+  
+  for ( UserStateHistory::iterator it = sentStates.begin(); it != sentStates.end(); it++ )
+  {
+    for ( StateHistory::iterator it2 = it->begin(); it2 != it->end(); it2++ )
+    {
+      if ( (*it2)->data )
+      {
+        delete [] (*it2)->data;
+        (*it2)->data = NULL;
+      }
+      delete *it2;
+    }
+
+  }
 }
 
@@ -134,4 +168,6 @@
         (*it2)->data = NULL;
       }
+      
+      delete *it2;
     }
     sentStates[userId].erase( sentStates[userId].begin(), it );
@@ -159,10 +195,14 @@
 
     stateFrom = initialEntry;
+    
+    sentStates[userId].push_back( stateFrom );
   }
   else
     stateFrom = (*it);
 
-  StateHistoryEntry * stateTo = new StateHistoryEntry();
-
+  StateHistoryEntry * stateTo = new StateHistoryEntry;
+
+  sentStates[userId].push_back( stateTo );
+  
   stateTo->stateId = stateId;
   stateTo->dataLength = neededSize;
@@ -175,4 +215,5 @@
   
   bool hasPermission;
+  bool sizeChanged = false;
 
   // now do the actual synchronization: kick all variables to write into a common buffer
@@ -186,5 +227,8 @@
                     );
     
-    if ( ( sizeIter != stateFrom->sizeList.end() && *sizeIter != (*it)->getSize() ) || ( hasPermission && (*it)->getPriority() >= priorityTH ) || sizeIter == stateFrom->sizeList.end() )
+    if ( sizeIter == stateFrom->sizeList.end() || *sizeIter != (*it)->getSize() ) 
+      sizeChanged = true;
+    
+    if ( ( hasPermission && (*it)->getPriority() >= priorityTH ) || sizeChanged )
     {
       n = (*it)->writeToBuf( stateTo->data+i, stateTo->dataLength - i );
@@ -210,6 +254,4 @@
   }
 
-  sentStates[userId].push_back( stateTo );
-  
   if ( i != neededSize )
   {
@@ -275,4 +317,6 @@
 
     stateFrom = initialEntry;
+    
+    recvStates[userId].push_back( stateFrom );
   }
   else
@@ -374,6 +418,8 @@
     {
       if ( (*it)->data )
+      {
         delete [] (*it)->data;
-      (*it)->data = NULL;
+        (*it)->data = NULL;
+      }
     
       delete *it;
@@ -388,6 +434,8 @@
     {
       if ( (*it)->data )
+      {
         delete [] (*it)->data;
-      (*it)->data = NULL;
+        (*it)->data = NULL;
+      }
     
       delete *it;
@@ -438,5 +486,9 @@
       
       if ( (*delIt)->data )
+      {
         delete [] (*delIt)->data;
+        (*delIt)->data = NULL;
+      }
+      delete *delIt;
       recvStates[userId].erase( delIt );
       
@@ -506,5 +558,9 @@
       
       if ( (*delIt)->data )
+      {
         delete [] (*delIt)->data;
+        (*delIt)->data = NULL;
+      }
+      delete *delIt;
       sentStates[userId].erase( delIt );
       
Index: /trunk/src/lib/network/udp_broadcast.cc
===================================================================
--- /trunk/src/lib/network/udp_broadcast.cc	(revision 8623)
+++ /trunk/src/lib/network/udp_broadcast.cc	(revision 8623)
@@ -0,0 +1,104 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "udp_broadcast.h"
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+ */
+UdpBroadcast::UdpBroadcast ()
+{
+  this->port = 0;
+  packet = SDLNet_AllocPacket( BROADCAST_PACKET_SIZE );
+  
+  if ( !packet ) 
+  {
+    printf( "SDLNet_AllocPacket: %s\n", SDLNet_GetError() );
+    assert( packet );
+  }
+  
+  this->socket = NULL;
+}
+
+
+/**
+ * standard deconstructor
+ */
+UdpBroadcast::~UdpBroadcast ()
+{
+  if ( this->packet )
+  {
+    SDLNet_FreePacket( this->packet );
+    this->packet = NULL;
+  }
+  
+  if ( this->socket )
+  {
+    SDLNet_UDP_Close( this->socket );
+    this->socket = NULL;
+  }
+  
+}
+
+/**
+ * listen for incoming broadcast packets
+ * @param port port to listen on 
+ * @return true on success
+ */
+bool UdpBroadcast::listen( int port )
+{
+  return true;
+}
+
+/**
+ * prepare for sending broadcast packets to port
+ * @param port port to send to
+ * @return true on success
+ */
+bool UdpBroadcast::open( int port )
+{
+  this->port = port;
+  
+  return true;
+}
+
+/**
+ * send packet
+ * @param data data to send 
+ * @param length length of data
+ * @param ip if ip == NULL broadcast is used
+ * @return number of bytes sent
+ */
+int UdpBroadcast::send( byte * data, int length, IPaddress * ip )
+{
+  return 0;
+}
+
+/**
+ * recieve packets
+ * @param data pointer to buffer to copy data to
+ * @param maxLength maxmal number of bytes to copy to data
+ * @param ip if != 0 ip contains data about sender
+ * @return number of bytes recieved
+ */
+int UdpBroadcast::recv( byte * data, int maxLength, IPaddress * ip )
+{
+  return 0;
+}
+
+
Index: /trunk/src/lib/network/udp_broadcast.h
===================================================================
--- /trunk/src/lib/network/udp_broadcast.h	(revision 8623)
+++ /trunk/src/lib/network/udp_broadcast.h	(revision 8623)
@@ -0,0 +1,34 @@
+/*!
+ * @file proto_class.h
+ * @brief Definition of ...
+ */
+
+#ifndef _UDP_BROADCAST_H
+#define _UDP_BROADCAST_H
+
+#include "netdefs.h"
+#include <cassert>
+
+#define BROADCAST_PACKET_SIZE 1024
+
+//! A class for sending/recieving brotcast packets for lan
+class UdpBroadcast
+{
+
+  public:
+    UdpBroadcast();
+    virtual ~UdpBroadcast();
+    
+    bool listen( int port );
+    bool open( int port );
+    int send( byte * data, int length, IPaddress * ip = NULL );
+    int recv( byte * data, int maxLength, IPaddress * ip = NULL );
+
+  private:
+    int port;
+    UDPpacket * packet;
+    UDPsocket socket;
+
+};
+
+#endif /* _UDP_BROADCAST_H */
Index: /trunk/src/lib/network/udp_server_socket.cc
===================================================================
--- /trunk/src/lib/network/udp_server_socket.cc	(revision 8622)
+++ /trunk/src/lib/network/udp_server_socket.cc	(revision 8623)
@@ -220,4 +220,7 @@
 bool UdpServerSocket::sendPacket( NetworkPacket networkPacket , int userId )
 {
+  if ( !socket )
+    return false;
+  
   assert( networkPacket.length <= UDP_PACKET_SIZE );
 
Index: /trunk/src/lib/network/zip.cc
===================================================================
--- /trunk/src/lib/network/zip.cc	(revision 8622)
+++ /trunk/src/lib/network/zip.cc	(revision 8623)
@@ -49,5 +49,5 @@
  * @return true on success
  */
-bool Zip::loadDictionary( std::string name )
+int Zip::loadDictionary( std::string name )
 {
   std::string fileName = ResourceManager::getInstance()->getDataDir();
@@ -61,5 +61,5 @@
   {
     PRINTF(1)("Could not open %d\n", fileName.c_str());
-    return false;
+    return -1;
   }
 
@@ -88,5 +88,5 @@
   PRINTF(3)("Loaded dictionary '%s' with adler = %d\n", name.c_str(), entry.adler );
 
-  return true;
+  return dicts.size()-1;
 }
 
Index: /trunk/src/lib/network/zip.h
===================================================================
--- /trunk/src/lib/network/zip.h	(revision 8622)
+++ /trunk/src/lib/network/zip.h	(revision 8623)
@@ -28,5 +28,5 @@
     inline static Zip* getInstance(void) { if (!singletonRef) singletonRef = new Zip();  return singletonRef; };
     
-    bool loadDictionary( std::string name );
+    int loadDictionary( std::string name );
     int zip( byte * from, int fromLength, byte * to, int maxLength, int dict = 0 );
     int unZip( byte * from, int fromLength, byte * to, int maxLength );
Index: /trunk/src/lib/shell/some_shell_commands.cc
===================================================================
--- /trunk/src/lib/shell/some_shell_commands.cc	(revision 8622)
+++ /trunk/src/lib/shell/some_shell_commands.cc	(revision 8623)
@@ -28,5 +28,9 @@
 using namespace OrxShell;
 
+#include "network_game_rules.h"
+  SHELL_COMMAND(say, NetworkGameRules, shellSay)->setAlias("say");
 
+#include "player_stats.h"
+  SHELL_COMMAND(nick, PlayerStats, shellNick)->setAlias("nick");
 
 #include "class_list.h"
Index: /trunk/src/orxonox.cc
===================================================================
--- /trunk/src/orxonox.cc	(revision 8622)
+++ /trunk/src/orxonox.cc	(revision 8623)
@@ -445,4 +445,5 @@
   {
     SignalHandler::getInstance()->doCatch( argv[0], GDB_RUN_IN_FOREGROUND );
+    SignalHandler::getInstance()->registerCallback(EventHandler::releaseMouse, NULL);
   }
   else if ( Preferences::getInstance()->getString("misc", "bt-to-file", "1") == "1" )
Index: /trunk/src/subprojects/network/network_unit_test.cc
===================================================================
--- /trunk/src/subprojects/network/network_unit_test.cc	(revision 8622)
+++ /trunk/src/subprojects/network/network_unit_test.cc	(revision 8623)
@@ -276,5 +276,5 @@
   for(;;)
   {
-    MessageManager::getInstance()->sendMessage( TESTMESSAGEID, (byte*)"server to client", 18, RT_ALL, 0, MP_HIGHBANDWIDTH );
+    MessageManager::getInstance()->sendMessage( TESTMESSAGEID, (byte*)"server to client", 18, RT_ALL_NOT_ME, 0, MP_HIGHBANDWIDTH );
     netMan->synchronize( 100 );
     SDL_Delay(100);
@@ -323,5 +323,5 @@
   {
     netMan->synchronize( 100 );
-    MessageManager::getInstance()->sendMessage( TESTMESSAGEID, (byte*)"client to server", 18, RT_ALL, 0, MP_HIGHBANDWIDTH );
+    MessageManager::getInstance()->sendMessage( TESTMESSAGEID, (byte*)"client to server", 18, RT_ALL_NOT_ME, 0, MP_HIGHBANDWIDTH );
     ss = dynamic_cast<SimpleSync*>(ClassList::getObject( "Server", CL_SIMPLE_SYNC ) );
     SDL_Delay(100);
Index: /trunk/src/util/game_rules.h
===================================================================
--- /trunk/src/util/game_rules.h	(revision 8622)
+++ /trunk/src/util/game_rules.h	(revision 8623)
@@ -20,5 +20,5 @@
 
 
-class GameRules : public BaseObject
+class GameRules : virtual public BaseObject
 {
 
Index: /trunk/src/util/multiplayer_team_deathmatch.cc
===================================================================
--- /trunk/src/util/multiplayer_team_deathmatch.cc	(revision 8622)
+++ /trunk/src/util/multiplayer_team_deathmatch.cc	(revision 8623)
@@ -65,4 +65,5 @@
   this->currentGameState = GAMESTATE_PRE_GAME;
   this->gameStateTimer = 10.0f;
+  this->bShowTeamChange = false;
   
   this->box = NULL;
@@ -77,4 +78,6 @@
   if( root != NULL)
     this->loadParams(root);
+  
+  subscribeEvent( ES_GAME, SDLK_o );
 }
 
@@ -86,4 +89,6 @@
   if( this->deathScreen)
     delete this->deathScreen;
+  
+  unsubscribeEvent( ES_GAME, SDLK_o );
 }
 
@@ -150,9 +155,11 @@
     return;
   
-  if ( currentGameState == GAMESTATE_PRE_GAME )
+  if ( currentGameState == GAMESTATE_PRE_GAME || currentGameState == GAMESTATE_GAME )
   {
     if ( PlayerStats::getStats( SharedNetworkData::getInstance()->getHostID() )
-         && PlayerStats::getStats( SharedNetworkData::getInstance()->getHostID() )->getPreferedTeamId() == TEAM_NOTEAM 
          && box == NULL
+         &&  (PlayerStats::getStats( SharedNetworkData::getInstance()->getHostID() )->getPreferedTeamId() == TEAM_NOTEAM 
+         || bShowTeamChange )
+         
        )
     {
@@ -180,4 +187,11 @@
       buttonTeam1->connect(SIGNAL(buttonTeam1, released), this, SLOT(MultiplayerTeamDeathmatch, onButtonTeam1));
       
+      if ( bShowTeamChange )
+      {
+        OrxGui::GLGuiPushButton * buttonCancel = new OrxGui::GLGuiPushButton("Cancel");
+        box->pack( buttonCancel );
+        buttonCancel->connect(SIGNAL(buttonCancel, released), this, SLOT(MultiplayerTeamDeathmatch, onButtonCancel));
+      }
+      
       OrxGui::GLGuiPushButton * buttonExit = new OrxGui::GLGuiPushButton("Exit");
       box->pack( buttonExit );
@@ -191,4 +205,5 @@
        && PlayerStats::getStats( SharedNetworkData::getInstance()->getHostID() )
        && PlayerStats::getStats( SharedNetworkData::getInstance()->getHostID() )->getPreferedTeamId() != TEAM_NOTEAM 
+       && !bShowTeamChange
      )
   {
@@ -479,4 +494,5 @@
 {
   State::getCurrentStoryEntity()->stop();
+  this->bShowTeamChange = false;
 }
 
@@ -484,4 +500,5 @@
 {
   NetworkGameManager::getInstance()->prefereTeam( TEAM_RANDOM );
+  this->bShowTeamChange = false;
 }
 
@@ -489,4 +506,5 @@
 {
   NetworkGameManager::getInstance()->prefereTeam( 0 );
+  this->bShowTeamChange = false;
 }
 
@@ -494,4 +512,5 @@
 {
   NetworkGameManager::getInstance()->prefereTeam( 1 );
+  this->bShowTeamChange = false;
 }
 
@@ -499,4 +518,5 @@
 {
   NetworkGameManager::getInstance()->prefereTeam( TEAM_SPECTATOR );
+  this->bShowTeamChange = false;
 }
 
@@ -507,7 +527,44 @@
 }
 
-
-
-
-
-
+  /**
+   * function that processes events from the handler
+   * @param event: the event
+   * @todo replace SDLK_o with something from KeyMapper
+   */
+void MultiplayerTeamDeathmatch::process( const Event & event )
+{
+  if ( event.type == SDLK_o )
+  {
+    if ( event.bPressed )
+      this->bShowTeamChange = true;
+  }
+}
+
+void MultiplayerTeamDeathmatch::onButtonCancel( )
+{
+  this->bShowTeamChange = false;
+}
+
+
+
+/**
+ * this method is called by NetworkGameManger when he recieved a chat message
+ * @param userId senders user id
+ * @param message message string
+ * @param messageType some int
+ */
+void MultiplayerTeamDeathmatch::handleChatMessage( int userId, const std::string & message, int messageType )
+{
+  std::string name = "unknown";
+  
+  if ( PlayerStats::getStats( userId ) )
+  {
+    name = PlayerStats::getStats( userId )->getNickName();
+  }
+  
+  PRINTF(0)("CHATMESSAGE %s: %s\n", name.c_str(), message.c_str() );
+}
+
+
+
+
Index: /trunk/src/util/multiplayer_team_deathmatch.h
===================================================================
--- /trunk/src/util/multiplayer_team_deathmatch.h	(revision 8622)
+++ /trunk/src/util/multiplayer_team_deathmatch.h	(revision 8623)
@@ -12,5 +12,5 @@
 #include "network_game_rules.h"
 
-#include "glgui_box.h"
+#include "glgui.h"
 
 class TiXmlElement;
@@ -27,5 +27,5 @@
 
 
-class MultiplayerTeamDeathmatch : public NetworkGameRules
+class MultiplayerTeamDeathmatch : public NetworkGameRules, public EventListener
 {
 
@@ -55,4 +55,8 @@
     
     int getRandomTeam();
+    
+    virtual void process(const Event &event);
+    
+    virtual void handleChatMessage( int userId, const std::string & message, int messageType );
 
   protected:
@@ -74,7 +78,8 @@
     float              gameStateTimer;             //!< if less than 0 -> change game state
 
+    bool               bShowTeamChange;            //!< if true -> show team change dialog
+
     OrxGui::GLGuiBox* box;
-
-
+    
     void calculateTeamScore();
     void nextGameState();
@@ -87,4 +92,5 @@
     void onButtonTeam0();
     void onButtonTeam1();
+    void onButtonCancel();
     void onButtonExit();
 };
Index: /trunk/src/util/network_game_rules.cc
===================================================================
--- /trunk/src/util/network_game_rules.cc	(revision 8622)
+++ /trunk/src/util/network_game_rules.cc	(revision 8623)
@@ -17,4 +17,6 @@
 
 #include "network_game_rules.h"
+
+#include "network_game_manager.h"
 
 using namespace std;
@@ -53,2 +55,9 @@
 }
 
+
+void NetworkGameRules::shellSay( const std::string & message )
+{
+  NetworkGameManager::getInstance()->sendChatMessage( message, 0 );
+}
+
+
Index: /trunk/src/util/network_game_rules.h
===================================================================
--- /trunk/src/util/network_game_rules.h	(revision 8622)
+++ /trunk/src/util/network_game_rules.h	(revision 8623)
@@ -25,4 +25,8 @@
     
     virtual PlayerStats * getNewPlayerStats( int userId ){ return new PlayerStats( userId ); }
+    
+    virtual void handleChatMessage( int userId, const std::string & message, int messageType ) = 0;
+    
+    void shellSay( const std::string & message );
 
 
Index: /trunk/src/util/signal_handler.h
===================================================================
--- /trunk/src/util/signal_handler.h	(revision 8622)
+++ /trunk/src/util/signal_handler.h	(revision 8623)
@@ -17,5 +17,5 @@
 };
 
-typedef bool (*SignalCallback)( void * someData );
+typedef int (*SignalCallback)( void * someData );
 
 #ifndef __WIN32__
@@ -44,5 +44,5 @@
   public:
     inline static SignalHandler* getInstance() { if (!SignalHandler::singletonRef) SignalHandler::singletonRef = new SignalHandler(); return SignalHandler::singletonRef; }
-      
+
     void registerCallback( SignalCallback cb, void * someData );
 
@@ -55,5 +55,5 @@
     void catchSignal( int sig );
     SignalRecList sigRecList;
-    
+
     SignalCallbackList callbackList;
 
Index: /trunk/src/world_entities/space_ships/turbine_hover.cc
===================================================================
--- /trunk/src/world_entities/space_ships/turbine_hover.cc	(revision 8622)
+++ /trunk/src/world_entities/space_ships/turbine_hover.cc	(revision 8623)
@@ -211,4 +211,14 @@
   this->getWeaponManager().getFixedTarget()->setParent(&this->cameraNode);
   this->getWeaponManager().getFixedTarget()->setRelCoor(1000,0,0);
+  
+  registerVar( new SynchronizeableBool( &bForward, &bForward, "bForward", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bBackward, &bBackward, "bBackward", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bLeft, &bLeft, "bLeft", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bRight, &bRight, "bRight", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bAscend, &bAscend, "bAscend", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bDescend, &bDescend, "bDescend", PERMISSION_OWNER ) );
+  //registerVar( new SynchronizeableQuaternion( &direction, &direction, "direction", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableFloat( &cameraLook, &cameraLook, "cameraLook", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableFloat( &rotation, &rotation, "rotation", PERMISSION_OWNER ) );
 }
 
