Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 7954 in orxonox.OLD for trunk/src/lib/network


Ignore:
Timestamp:
May 29, 2006, 3:28:41 PM (19 years ago)
Author:
patrick
Message:

trunk: merged the network branche back to trunk.

Location:
trunk/src/lib/network
Files:
20 edited
31 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/lib/network/Makefile.am

    r7026 r7954  
    1313                      network_protocol.cc \
    1414                      server_socket.cc \
     15                      tcp_server_socket.cc \
     16                      tcp_socket.cc \
     17                      udp_server_socket.cc \
     18                      udp_socket.cc \
    1519                      handshake.cc \
    1620                      network_game_manager.cc \
    17                       converter.cc
     21                      converter.cc \
     22                      message_manager.cc \
     23                      network_log.cc \
     24                      zip.cc \
     25                      \
     26                      synchronizeable_var/synchronizeable_var.cc \
     27                      synchronizeable_var/synchronizeable_vector.cc \
     28                      synchronizeable_var/synchronizeable_int.cc \
     29                      synchronizeable_var/synchronizeable_quaternion.cc \
     30                      synchronizeable_var/synchronizeable_string.cc \
     31                      synchronizeable_var/synchronizeable_float.cc \
     32                      synchronizeable_var/synchronizeable_bool.cc \
     33                      synchronizeable_var/synchronizeable_uint.cc
    1834
    1935
     
    2945                 network_protocol.h \
    3046                 server_socket.h \
     47                 tcp_server_socket.h \
     48                 tcp_socket.h \
     49                 udp_server_socket.h \
     50                 udp_socket.h \
    3151                 handshake.h \
    3252                 network_game_manager.h \
    3353                 converter.h \
    34                  netdefs.h
     54                 netdefs.h \
     55                 message_manager.h \
     56                 network_log.h \
     57                 zip.h \
     58                 \
     59                 synchronizeable_var/synchronizeable_var.h \
     60                 synchronizeable_var/synchronizeable_vector.h \
     61                 synchronizeable_var/synchronizeable_int.h \
     62                 synchronizeable_var/synchronizeable_quaternion.h \
     63                 synchronizeable_var/synchronizeable_string.h \
     64                 synchronizeable_var/synchronizeable_float.h \
     65                 synchronizeable_var/synchronizeable_bool.h \
     66                 synchronizeable_var/synchronizeable_uint.h
    3567
    3668
  • trunk/src/lib/network/connection_monitor.cc

    r5822 r7954  
    1010
    1111### File Specific:
    12    main-programmer: Silvan Nellen
     12   main-programmer: Christoph Renner
    1313   co-programmer: ...
    1414*/
    1515
    1616#include "connection_monitor.h"
     17#include "network_log.h"
     18
    1719#include <debug.h>
    1820#include <SDL/SDL.h>
     
    2224using namespace std;
    2325
    24 ConnectionMonitor::ConnectionMonitor()
    25 {
    26 
     26/**
     27 * constructor
     28 * @param userId user's id
     29 */
     30ConnectionMonitor::ConnectionMonitor( int userId )
     31{
    2732  /* set the class id for the base object and add ist to class list*/
    2833  this->setClassID(CL_CONNECTION_MONITOR, "ConnectionMonitor");
    29 
    30   /*initialize variables*/
    31 
    32   /*Data of the lifetime of the ConnectionMonitor Object*/
    33   packetToAverage = 100;
    34   protocollType = "default(TCP)";
    35 
    36   startTime= SDL_GetTicks();
    37   totalReceivedPackets=0;
    38   averageDatarate=0;
    39   totalLostPackets=0;
    40   totalPacketloss=0;
    41 
    42   /*Data of the current packet*/
    43   currentPacketID=0;
    44   currentPacketTick=0;
    45   lastPacketID=0;
    46   lastPacketTick=0;
    47   currentDelay=0;
    48 
    49   /*Data of the last n packets (n is specified by paxketsToAverage)*/
    50   sizeOfLastFewPackets=0;
    51   currentDatarate=0;
    52   lastFewDelays = new unsigned int [packetToAverage];
    53   lastFewPackets = new byte* [packetToAverage];
    54   packetCounter=0;
    55 
    56 
    57 }
    58 
    59 
    60 ConnectionMonitor::~ConnectionMonitor()
    61 {
    62 
    63 
    64 }
    65 
    66 
    67 
    68 void ConnectionMonitor::processPacket(byte* currentPacket, unsigned int packetLength)
    69 {
    70   /*Process the current Packet*/
    71   currentPacketTick = SDL_GetTicks();
    72   currentDelay = currentPacketTick - lastPacketTick;
    73 
    74   /*Do whats needed for Averaging*/
    75 
    76   if(packetCounter == packetToAverage)
    77     {
    78       computeCurrentDatarate();
    79       displayStatistic();
    80       packetCounter = 0;
    81       sizeOfLastFewPackets = 0;
    82     }
    83 
    84   lastFewDelays[packetCounter] = currentDelay;
    85   lastFewPackets[packetCounter] = currentPacket;
    86   sizeOfLastFewPackets += packetLength;
    87 
    88   /*Update the lifetime Variables*/
    89   totalReceivedPackets ++;
    90   float timeDiff = this->currentPacketTick - this->startTime;
    91   if( timeDiff != 0.0f )
    92     averageDatarate = totalReceivedPackets/timeDiff;
    93 
    94   /*Preparefor the next Packet*/
    95   lastPacketTick = currentPacketTick;
    96   packetCounter++;
    97 }
    98 
    99 
    100 /* Compute the value of current Datarate*/
    101 void ConnectionMonitor::computeCurrentDatarate()
    102 {
    103   int timeForLastFewPackets=0;
    104   for(int i=0;i < packetToAverage;i++)
    105     timeForLastFewPackets += lastFewDelays[i];
    106 
    107   if( timeForLastFewPackets != 0)
    108     currentDatarate = sizeOfLastFewPackets/timeForLastFewPackets;
    109 }
    110 
    111 void doUDPRelatedStuff()
    112 {
    113   /*  Do protocol related stuff
    114 
    115   Only for Udp:
    116   "currentPacketID = getID from package";
    117 
    118   if(currentPacketID - lastPacketID > 1)
     34 
     35  this->userId = userId;
     36  this->ping = 0;
     37  this->incomingUnzippedBandWidth = 0;
     38  this->outgoingUnzippedBandWidth = 0;
     39  this->incomingZippedBandWidth = 0;
     40  this->outgoingZippedBandWidth = 0;
     41  this->nIncomingPackets = 0;
     42  this->nOutgoingPackets = 0;
     43  this->nZIncomingPackets = 0;
     44  this->nZOutgoingPackets = 0;
     45 
     46  this->lastPacketTick = 0;
     47  this->lastPrintTick = 0;
     48}
     49
     50/**
     51 * deconstructor
     52 */
     53ConnectionMonitor::~ConnectionMonitor( )
     54{
     55}
     56
     57/**
     58 * process unzipped outgoing packet
     59 * @param data pointer to packet data
     60 * @param length length of packet
     61 * @param stateId packet's state id
     62 */
     63void ConnectionMonitor::processUnzippedOutgoingPacket( byte * data, int length, int stateId )
     64{
     65  int tick = SDL_GetTicks();
     66 
     67  nOutgoingPackets++;
     68 
     69  // for ping calculation
     70  sentStateTicks[stateId] = tick;
     71 
     72  // calculate bandwidth
     73  outgoingUnzippedPacketHistory[tick] = length;
     74  outgoingUnzippedBandWidth = calculateBandWidth( outgoingUnzippedPacketHistory, tick );
     75 
     76  //NETPRINTF(n)("UNZIPPED UPSTREAM: user: %d bandwidth %f\n", userId, outgoingUnzippedBandWidth );
     77 
     78  // count zero bytes
     79  int nZeroBytes = 0;
     80 
     81  for ( int i = 0; i < length; i++ )
     82    if ( data[i] == '\0' )
     83      nZeroBytes++;
     84 
     85  //NETPRINTF(n)( "ZEROBYTES: %d (%f%%)\n", nZeroBytes, ((float)100)*nZeroBytes/length );
     86}
     87
     88/**
     89 * process unzipped incoming packet
     90 * @param data pointer to packet data
     91 * @param length length of packet
     92 * @param stateId packet's state id
     93 * @param ackedState state which was acked by this packet
     94 */
     95void ConnectionMonitor::processUnzippedIncomingPacket( byte * data, int length, int stateId, int ackedState )
     96{
     97  int tick = SDL_GetTicks();
     98 
     99  nIncomingPackets++;
     100 
     101  lastPacketTick = tick;
     102 
     103  // calculate ping
     104  if ( sentStateTicks.find( ackedState ) != sentStateTicks.end() )
    119105  {
    120   totalLostPackets += currentPacketID - lastPacketID;
    121 }
    122 
    123   totalPacketloss = (totalLostPackets/totalReceivedPackets)*100 ;
    124   */
    125 }
    126 
    127 
    128 
    129 /* Display connectoin statistic*/
    130 void ConnectionMonitor::displayStatistic()
    131 {
    132 //   PRINT(0)("============================================\n");
    133 //   PRINT(0)("Connection Monitor Network Statistics:\n");
    134 //   PRINT(0)("Total received packets:",totalReceivedPackets);
    135 //   PRINT(0)("Average datarate :\n",averageDatarate);
    136 //   PRINT(0)("Total lost packets:",totalLostPackets);
    137 //   PRINT(0)("Packetloss [%] :\n",totalPacketloss);
    138 //
    139 //   PRINT(0)("Current datarate :\n",currentDatarate);
    140 //   PRINT(0)("Delays of the last few packets :\n");
    141 //   for(int i=1 ;i <= packetToAverage-1;i++)
    142 //     PRINT(0)("%i ",lastFewDelays[i]);
    143 //
    144 //   PRINT(0)("============================================\n");
    145 
    146 }
    147 
     106    ackDelay.push_back( tick - sentStateTicks[ackedState] );
     107  }
     108 
     109  while ( sentStateTicks.begin() != sentStateTicks.end() && sentStateTicks.begin()->first <= ackedState )
     110    sentStateTicks.erase( sentStateTicks.begin() );
     111     
     112  while ( ackDelay.size() > N_PACKETS_FOR_PING )
     113    ackDelay.erase( ackDelay.begin() );
     114     
     115  ping = 0;
     116     
     117  for ( std::list<int>::iterator it = ackDelay.begin(); it != ackDelay.end(); it++ )
     118    ping += *it;
     119     
     120  if ( ackDelay.size() == 0 )
     121    ping = -1;
     122  else
     123    ping /= ackDelay.size();
     124     
     125  //NETPRINTF(n)("PING: user: %d ping: %d\n", userId, ping );
     126 
     127  // calculate bandwidth
     128  incomingUnzippedPacketHistory[tick] = length;
     129  incomingUnzippedBandWidth = calculateBandWidth( incomingUnzippedPacketHistory, tick );
     130 
     131  //NETPRINTF(n)("UNZIPPED DOWNSTREAM: user: %d bandwidth %f\n", userId, incomingUnzippedBandWidth );
     132 
     133}
     134
     135/**
     136 * calculate bandwidth out of packethistory
     137 * @param packetHistory packet history
     138 * @param tick current tick from SDL_GetTicks
     139 * @return bandwidth in bytes/sec
     140 */
     141float ConnectionMonitor::calculateBandWidth( std::map< int, int > packetHistory, int tick )
     142{
     143  // delete old packets
     144  while ( packetHistory.begin()->first < tick - MSECS_TO_CALC_BWIDTH )
     145    packetHistory.erase( packetHistory.begin() );
     146 
     147  float res = 0.0f;
     148 
     149  for ( std::map<int,int>::iterator it = packetHistory.begin(); it != packetHistory.end(); it++ )
     150  {
     151    res += it->second;
     152  }
     153 
     154  if ( packetHistory.size() <= 1 || tick - packetHistory.begin()->first == 0 )
     155    res = 0.0f;
     156  else
     157    res /= (float)((tick - packetHistory.begin()->first)*( 1 + 1/((float)(packetHistory.size()-1)) ));
     158 
     159  res *= 1000.0f;
     160 
     161  return res;
     162}
     163
     164
     165/**
     166 * process zipped outgoing packet
     167 * @param data pointer to packet data
     168 * @param length length of packet
     169 * @param stateId packet's state id
     170 */
     171void ConnectionMonitor::processZippedOutgoingPacket( byte * data, int length, int stateId )
     172{
     173  int tick = SDL_GetTicks();
     174 
     175  nZOutgoingPackets++;
     176 
     177  // calculate bandwidth
     178  outgoingZippedPacketHistory[tick] = length;
     179  outgoingZippedBandWidth = calculateBandWidth( outgoingZippedPacketHistory, tick );
     180 
     181  //NETPRINTF(n)("UPSTREAM: user: %d bandwidth %f nOutgoingPackets %d\n", userId, outgoingZippedBandWidth, nOutgoingPackets );
     182
     183  if ( lastPrintTick < tick-1000 )
     184  {
     185    printStatis();
     186    lastPrintTick = tick;
     187  }
     188}
     189
     190
     191/**
     192 * process zipped incoming packet
     193 * @param data pointer to packet data
     194 * @param length length of packet
     195 * @param stateId packet's state id
     196 * @param ackedState state which was acked by this packet
     197 */
     198void ConnectionMonitor::processZippedIncomingPacket( byte * data, int length, int stateId, int ackedState )
     199{
     200  int tick = SDL_GetTicks();
     201 
     202  nZIncomingPackets++;
     203 
     204  // calculate bandwidth
     205  incomingZippedPacketHistory[tick] = length;
     206  incomingZippedBandWidth = calculateBandWidth( incomingZippedPacketHistory, tick );
     207 
     208  //NETPRINTF(n)("DOWNSTREAM: user: %d bandwidth %f nIncomingPackets %d\n", userId, incomingZippedBandWidth, nIncomingPackets );
     209 
     210}
     211
     212
     213/**
     214 * check if client sent no packets for SECS_TO_TIMEOUT
     215 * @return true if last packet recieved \< NOW() - SECS_TO_TIMEOUT
     216 */
     217bool ConnectionMonitor::hasTimedOut( )
     218{
     219  if ( lastPacketTick + SECS_TO_TIMEOUT*1000 < SDL_GetTicks() && nIncomingPackets > 0 )
     220    return true;
     221 
     222  if ( nIncomingPackets == 0 && nOutgoingPackets >= NETWORK_FREQUENCY*SECS_TO_TIMEOUT )
     223    return true;
     224 
     225  return false;
     226}
     227
     228
     229
     230/**
     231 * prints bandwith usage, ping and other important things to telnet-console
     232 */
     233void ConnectionMonitor::printStatis( )
     234{
     235  NETPRINT(n)("=========NETWORKSTATS FOR USER %d=========\n", userId);
     236  NETPRINT(n)("PING = %d\n", ping);
     237  NETPRINT(n)("BANDWIDTH: UP: %f (%f) DOWN %f (%f)\n", outgoingZippedBandWidth, outgoingUnzippedBandWidth, incomingZippedBandWidth, incomingUnzippedBandWidth);
     238  NETPRINT(n)("==========================================");
     239}
     240
     241
  • trunk/src/lib/network/connection_monitor.h

    r6981 r7954  
    1010#include "netdefs.h"
    1111
     12#include <map>
     13
     14#define N_PACKETS_FOR_PING 20
     15#define MSECS_TO_CALC_BWIDTH 1000
     16#define SECS_TO_TIMEOUT 10
     17
    1218class ConnectionMonitor : virtual public BaseObject
    13   {
     19{
    1420  public:
    15     ConnectionMonitor();
     21    ConnectionMonitor( int userId );
    1622    virtual ~ConnectionMonitor();
    1723
    18     void                processPacket(byte* packet, unsigned int packetLength);
     24    void processUnzippedOutgoingPacket( byte * data, int length, int stateId );
     25    void processUnzippedIncomingPacket( byte * data, int length, int stateId, int ackedState );
     26   
     27    void processZippedOutgoingPacket( byte * data, int length, int stateId );
     28    void processZippedIncomingPacket( byte * data, int length, int stateId, int ackedState );
     29   
     30    void calculatePing();
     31   
     32    bool hasTimedOut();
     33   
     34    void printStatis();
     35   
     36  private:
     37    float calculateBandWidth( std::map<int,int> packetHistory, int tick );
     38   
     39    int userId;       //!< user's id
    1940
     41    std::map<int,int>   sentStateTicks;
     42   
     43    std::map<int,int>   incomingUnzippedPacketHistory;
     44    std::map<int,int>   outgoingUnzippedPacketHistory;
     45   
     46    std::map<int,int>   incomingZippedPacketHistory;
     47    std::map<int,int>   outgoingZippedPacketHistory;
     48   
     49    std::list<int>      ackDelay;
     50    int                 ping;
    2051
    21   private:
    22 
    23 
    24     void                displayStatistic();
    25     void                computeCurrentDatarate();
    26     void                doUDPRelatedStuff();
    27 
    28     /*Data of the lifetime of the ConnectionMonitor Object*/
    29     unsigned int        packetToAverage;
    30     char*               protocollType;
    31 
    32     unsigned int        totalReceivedPackets;
    33     float               averageDatarate;
    34     unsigned int        totalLostPackets;
    35     float               totalPacketloss;
    36     unsigned int        startTime;
    37 
    38     /*Data of the current packet*/
    39     unsigned int        currentPacketID;
    40     unsigned int        currentPacketTick;
    41     unsigned int        lastPacketID;
    42     unsigned int        lastPacketTick;
    43     unsigned int        currentDelay;
    44 
    45     /*Data of the last n packets (n is specified by paxketsToAverage)*/
    46     unsigned int        sizeOfLastFewPackets;
    47     unsigned int        currentDatarate;
    48     byte**              lastFewPackets;
    49     unsigned int*       lastFewDelays;
    50     unsigned int        packetCounter;
    51 
     52    float               incomingUnzippedBandWidth;
     53    float               outgoingUnzippedBandWidth;
     54   
     55    float               incomingZippedBandWidth;
     56    float               outgoingZippedBandWidth;
     57   
     58    int                 nIncomingPackets;
     59    int                 nOutgoingPackets;
     60   
     61    int                 nZIncomingPackets;
     62    int                 nZOutgoingPackets;
     63   
     64    int                 lastPacketTick;
     65   
     66    int                 lastPrintTick;
    5267  };
    5368
  • trunk/src/lib/network/converter.cc

    r7230 r7954  
    489489  {
    490490    PRINTF(1)("something went wrong length > remaining bytes in buffer\n" );
     491   
     492    //TODO remove this
     493    for ( int i = -1000; i < 1001; i++ )
     494    {
     495      if ( ( a[i] > 'a' && a[i] < 'z' ) || ( a[i] > 'A' && a[i] < 'Z' ) )
     496        printf("%c", a[i]);
     497      else
     498        printf(".");
     499    }
     500    printf("\n");
     501   
    491502    s = "";
    492503    return -1;
    493504  }
    494505
    495   s[0] = '\0';
     506  s = "";
    496507  s.append( (char*)a+n, length );
    497508
  • trunk/src/lib/network/data_stream.cc

    r5822 r7954  
    1616/* include Data_stream Header */
    1717#include "data_stream.h"
    18 
    19 
    2018
    2119
  • trunk/src/lib/network/handshake.cc

    r6815 r7954  
    2424#include <cassert>
    2525
    26 Handshake::Handshake( bool server, int clientId, int networkGameManagerId )
     26Handshake::Handshake( bool server, int clientId, int networkGameManagerId, int messageManagerId )
    2727  : Synchronizeable()
    2828{
     
    3131
    3232  this->setIsServer(server);
    33   this->clientId = clientId;
    34   this->networkGameManagerId = networkGameManagerId;
    35   this->state = 0;
    36   this->isOk = false;
    37   this->setOwner(0);
     33 
     34  orxId_handler = registerVarId( new SynchronizeableInt( &localState.orxId, &remoteState.orxId, "orxonoxId", PERMISSION_ALL ) );
     35  version_handler = registerVarId( new SynchronizeableInt( &localState.version, &remoteState.version, "version", PERMISSION_ALL ) );
     36  netManId_handler = registerVarId( new SynchronizeableInt( &localState.networkManagerId, &remoteState.networkManagerId, "networkManagerId", PERMISSION_ALL ) );
     37  msgManId_handler = registerVarId( new SynchronizeableInt( &localState.messageManagerId, &remoteState.messageManagerId, "messageManagerId", PERMISSION_ALL ) );
     38  hostId_handler = registerVarId( new SynchronizeableInt( &localState.hostId, &remoteState.hostId, "hostId", PERMISSION_ALL ) );
     39  completed_handler = registerVarId( new SynchronizeableInt( &localState.completed, &remoteState.completed, "completed", PERMISSION_ALL ) );
     40  error_handler = registerVarId( new SynchronizeableInt( &localState.error, &remoteState.error, "error", PERMISSION_ALL ) );
     41  errorString_handler = registerVarId( new SynchronizeableString( &localState.errorString, &remoteState.errorString, "errorString", PERMISSION_ALL ) );
     42 
     43  candel_id = registerVarId( new SynchronizeableInt( &localState.canDel, &remoteState.canDel, "canDel", PERMISSION_ALL ) );
     44 
     45  localState.completed = 0;
     46  localState.error = 0;
     47  localState.errorString = "";
     48  localState.hostId = clientId;
     49  localState.networkManagerId = networkGameManagerId;
     50  this->localState.messageManagerId = messageManagerId;
     51  localState.orxId = _ORXONOX_ID;
     52  localState.version = _ORXONOX_VERSION;
     53  localState.canDel = 0;
     54 
     55  remoteState.completed = 0;
     56  remoteState.error = 0;
     57  remoteState.errorString = "";
     58  remoteState.hostId = -1;
     59  remoteState.networkManagerId = -1;
     60  remoteState.messageManagerId = -1;
     61  remoteState.orxId = 0;
     62  remoteState.version = 0;
     63  remoteState.canDel = 0;
    3864
    3965  this->setSynchronized(true);
    40   PRINTF(5)("Handshake created clientId = %d\n", clientId);
     66  PRINTF(0)("Handshake created clientId = %d\n", clientId);
    4167}
    4268
    43 int Handshake::writeBytes( const byte * data, int length, int sender)
     69/**
     70 * handler for changes in synced vars
     71 * @param id id's which have changed
     72 */
     73void Handshake::varChangeHandler( std::list< int > & id )
    4474{
    45   PRINTF(5)("Handshake::writeBytes states = %d %d %d %d (%d)\n", hasState( HS_RECVD_INIT ), hasState( HS_RECVD_VER ), hasState( HS_RECVD_HID ), hasState( HS_COMPLETED ), state);
     75  for ( std::list<int>::iterator it = id.begin(); it != id.end(); it++ )
     76  {
     77    if ( *it == orxId_handler )
     78    {
     79      if ( remoteState.orxId != _ORXONOX_ID )
     80      {
     81        localState.error = 1;
     82        localState.completed = 1;
     83        localState.errorString = "Seems not to be orxonox!";
     84        continue;
     85      }
    4686
    47   SYNCHELP_READ_BEGIN();
     87    }
     88     
     89    if ( *it == version_handler )
     90    {
     91      if ( remoteState.version != _ORXONOX_VERSION )
     92      {
     93        localState.error = 2;
     94        localState.completed = 1;
     95        localState.errorString = "Versions of server and client do not match!";
     96        continue;
     97      }
    4898
    49   if ( hasState( HS_COMPLETED ) )
    50        return 0;
    51 
    52   if ( !hasState( HS_RECVD_INIT ) )
    53   {
    54     if ( length != _INITIAL_DATA_LENGTH )
     99    }
     100   
     101    if ( *it == candel_id )
    55102    {
    56       PRINTF(0)("initial packet has wrong size %d instead of %d\n", length, _INITIAL_DATA_LENGTH);
    57       setState( HS_COMPLETED );
    58       return 0;
     103      PRINTF(0)("handshake finished candel changed\n");
    59104    }
    60 
    61     if ( strncmp((char*)data, _INITIAL_DATA, length) )
    62     {
    63       PRINTF(0)("initial packed does not match\n");
    64       setState( HS_COMPLETED );
    65       return length;
    66     }
    67 
    68     setState( HS_RECVD_INIT );
    69     PRINTF(0)("got valid initial packet from client %d\n", clientId);
    70     return length;
     105   
    71106  }
    72 
    73   if ( hasState( HS_RECVD_INIT ) && !hasState( HS_RECVD_VER ) )
    74   {
    75     if ( length != _ORXONOX_VERSION_LENGTH )
    76     {
    77       PRINTF(0)("version number packet has wrong size %d instead of %d\n", length, _ORXONOX_VERSION_LENGTH);
    78       setState( HS_COMPLETED );
    79       return 0;
    80     }
    81 
    82     if ( strncmp((char*)data, _ORXONOX_VERSION, length) )
    83     {
    84       PRINTF(0)("versions do not match\n");
    85       setState( HS_COMPLETED );
    86       return length;
    87     }
    88 
    89     setState( HS_RECVD_VER );
    90 
    91     PRINTF(0)("client %d's version does match\n", clientId);
    92     return length;
    93   }
    94 
    95   if ( !isServer() && hasState( HS_RECVD_VER ) && !hasState( HS_RECVD_HID ) )
    96   {
    97     /*if ( length != INTSIZE+INTSIZE )
    98     {
    99       PRINTF(0)("hostID packet has wrong size %d instead of %d\n", length, INTSIZE+INTSIZE);
    100       setState( HS_COMPLETED );
    101       return 0;
    102   }*/
    103 
    104     setState( HS_COMPLETED );
    105     setState( HS_RECVD_HID );
    106     this->isOk = true;
    107     SYNCHELP_READ_INT( this->newHostId, NWT_HS_HOST_ID );
    108     SYNCHELP_READ_INT( this->newNetworkGameManagerId, NWT_HS_NGM_ID );
    109 
    110     if ( newHostId == 0 )
    111     {
    112       setState( HS_WAS_REJECT );
    113       isOk = false;
    114       PRINTF(0)("Server did not accept handshake!\n");
    115     }
    116     else
    117     {
    118       PRINTF(0)("got my hostID: %d and networkGameManagerId: %d\n", newHostId, newNetworkGameManagerId);
    119     }
    120     return SYNCHELP_READ_N;
    121   }
    122 
     107 
     108  if (
     109      remoteState.orxId == _ORXONOX_ID &&
     110      remoteState.version == _ORXONOX_VERSION
     111     )
     112    localState.completed = 1;
    123113}
    124114
    125 int Handshake::readBytes( byte * data, int maxLength, int * reciever )
    126 {
    127   PRINTF(5)("Handshake::readBytes states = %d %d %d %d (%d)\n", hasState( HS_SENT_INIT ), hasState( HS_SENT_VER ), hasState( HS_SENT_HID ), hasState( HS_COMPLETED ), state);
    128 
    129   SYNCHELP_WRITE_BEGIN();
    130 
    131   if ( hasState( HS_COMPLETED ) )
    132     return 0;
    133 
    134   if ( !hasState( HS_SENT_INIT ) )
    135   {
    136     if ( maxLength < _INITIAL_DATA_LENGTH )
    137     {
    138       PRINTF(0)("buffer too small for _INITIAL_DATA");
    139       setState( HS_COMPLETED );
    140       return 0;
    141     }
    142 
    143     setState( HS_SENT_INIT );
    144     memcpy(data, _INITIAL_DATA, _INITIAL_DATA_LENGTH);
    145     if ( this->isServer() )
    146       *reciever = clientId;
    147     return _INITIAL_DATA_LENGTH;
    148   }
    149 
    150   if ( hasState( HS_RECVD_INIT ) && hasState( HS_SENT_INIT ) && !hasState( HS_SENT_VER ) )
    151   {
    152     if ( maxLength < _ORXONOX_VERSION_LENGTH )
    153     {
    154       PRINTF(0)("buffer too small for version number");
    155       setState( HS_COMPLETED );
    156       return 0;
    157     }
    158 
    159     setState( HS_SENT_VER );
    160     memcpy(data, _ORXONOX_VERSION, _ORXONOX_VERSION_LENGTH);
    161     if ( this->isServer() )
    162       *reciever = clientId;
    163     return _ORXONOX_VERSION_LENGTH;
    164   }
    165 
    166   if ( isServer() && hasState( HS_RECVD_VER) && hasState( HS_SENT_VER ) && !hasState( HS_SENT_HID ) )
    167   {
    168     if ( maxLength < 2 )
    169     {
    170       PRINTF(0)("buffer too small for ID");
    171       setState( HS_COMPLETED );
    172       return 0;
    173     }
    174 
    175     setState( HS_SENT_HID );
    176     setState( HS_COMPLETED );
    177 
    178     if ( hasState( HS_DO_REJECT ) )
    179     {
    180       isOk = false;
    181       //memcpy(data, (byte*)0, 4);
    182       SYNCHELP_WRITE_INT( 0, NWT_HS_HOST_ID);
    183       SYNCHELP_WRITE_INT( 0, NWT_HS_NGM_ID);
    184     }
    185     else
    186     {
    187       isOk = true;
    188       //memcpy(data, &clientId, 4);
    189       SYNCHELP_WRITE_INT( clientId, NWT_HS_HOST_ID );
    190       SYNCHELP_WRITE_INT( networkGameManagerId, NWT_HS_NGM_ID );
    191     }
    192     *reciever = clientId;
    193     return SYNCHELP_WRITE_N;
    194   }
    195 
    196   return 0;
    197 }
    198 
    199 void Handshake::writeDebug( ) const
    200 {
    201 }
    202 
    203 void Handshake::readDebug( ) const
    204 {
    205 }
  • trunk/src/lib/network/handshake.h

    r6341 r7954  
    1010#include "synchronizeable.h"
    1111
    12 #define _INITIAL_DATA "orxonox"
    13 #define _INITIAL_DATA_LENGTH 7
     12#define _ORXONOX_ID 0xF91337A0
    1413
    15 #define _ORXONOX_VERSION "\x00\x00\x00\x01"
    16 #define _ORXONOX_VERSION_LENGTH 4
     14#define _ORXONOX_VERSION 1
    1715
    18 typedef enum HandshakeState {
    19   HS_SENT_INIT  = 0x00000001,
    20   HS_RECVD_INIT = 0x00000002,
    21   HS_SENT_VER   = 0x00000004,
    22   HS_RECVD_VER  = 0x00000008,
    23   HS_SENT_HID   = 0x00000010,
    24   HS_RECVD_HID  = 0x00000020,
    25   HS_COMPLETED  = 0x00000040,
    26 
    27   HS_DO_REJECT  = 0x00010000,
    28   HS_WAS_REJECT = 0x00020000,
    29 
    30   NUM_STATES
     16struct HandshakeState {
     17  int orxId;
     18  int version;
     19 
     20  int networkManagerId;
     21  int messageManagerId;
     22  int hostId;
     23 
     24  int completed;
     25  int canDel;
     26 
     27  int error;
     28 
     29  std::string errorString;
    3130};
    3231
     
    3433{
    3534  public:
    36     Handshake(bool server, int clientId = 0, int networkGameManagerId = 0);
    37     inline bool       completed(){ return hasState( HS_COMPLETED ); }
    38     inline bool       ok(){ return isOk; }
    39     inline int        getHostId(){ return newHostId; }
    40     inline int        getNetworkGameManagerId(){ return newNetworkGameManagerId; }
    41 
    42     inline void       doReject(){ setState(HS_DO_REJECT); }
    43 
    44     virtual int       writeBytes(const byte* data, int length, int sender);
    45     virtual int       readBytes(byte* data, int maxLength, int * reciever);
    46     virtual void      writeDebug() const;
    47     virtual void      readDebug() const;
     35    Handshake( bool server, int clientId = 0, int networkGameManagerId = 0, int messageManagerId = 0 );
     36    inline bool       completed(){ return localState.completed != 0 && remoteState.completed != 0; }
     37    inline bool       ok(){ return localState.error == 0 && remoteState.error == 0; }
     38    inline int        getHostId(){ return remoteState.hostId; }
     39    inline int        getNetworkGameManagerId(){ return remoteState.networkManagerId; }
     40    inline int        getMessageManagerId(){ return remoteState.messageManagerId; }
     41    inline void       doReject( std::string reason ){ localState.error = 1; localState.errorString = "the server rejected your connection ["+ reason +"]"; }
     42    inline bool       canDel(){ return localState.canDel == 1 && remoteState.canDel == 1; }
     43    inline bool       allowDel(){ return localState.canDel == 1; }
     44    inline void       del(){ localState.canDel = 1; }
     45   
     46    virtual void varChangeHandler( std::list<int> & id );
    4847
    4948  private:
    50     int               state;
    51     int               clientId;
    52     int               networkGameManagerId;
    53     int               newHostId;
    54     int               newNetworkGameManagerId;
    55     bool              isOk;
    56 
    57     inline bool       hasState( int a ){ return (state & a) == a; }
    58     inline void       setState( int a ){ state = state | a; }
    59     inline void       unsetState( int a ){ state = state & (~a); }
     49    HandshakeState localState;
     50    HandshakeState remoteState;
     51   
     52    int netManId_handler;
     53    int msgManId_handler;
     54    int hostId_handler;
     55    int completed_handler;
     56    int error_handler;
     57    int errorString_handler;
     58    int orxId_handler;
     59    int version_handler;
     60    int candel_id;
    6061
    6162};
  • trunk/src/lib/network/netdefs.h

    r6695 r7954  
    1919#define MAX_CONNECTIONS 1000
    2020
     21#define NETWORK_FREQUENCY 33
     22
    2123
    2224typedef unsigned char byte;
     
    2830} NodeType;
    2931
     32typedef enum ConnectionType {
     33  NET_UDP = 0,
     34  NET_TCP
     35};
     36
    3037
    3138typedef enum {
  • trunk/src/lib/network/network_game_manager.cc

    r7354 r7954  
    2727#include "shared_network_data.h"
    2828#include "converter.h"
     29#include "message_manager.h"
    2930
    3031#include "playable.h"
     
    5253  this->setClassID(CL_NETWORK_GAME_MANAGER, "NetworkGameManager");
    5354
    54   hasRequestedWorld = false;
    5555  this->setSynchronized(true);
     56 
     57  MessageManager::getInstance()->registerMessageHandler( MSGID_YOU_ARE, youAreHandler, NULL );
    5658}
    5759
     
    6163NetworkGameManager::~NetworkGameManager()
    6264{
     65#if 0
    6366  for ( int i = 0; i<outBuffer.size(); i++)
    6467  {
     
    6669      delete outBuffer[i].buffer;
    6770  }
    68 
    69 }
    70 
    71 
     71#endif
     72
     73}
     74
     75#if 0
    7276int NetworkGameManager::writeBytes(const byte* data, int length, int sender)
    7377{
     
    141145    {
    142146      sendEntityList( sender );
    143       continue;
    144     }
    145     else if ( b == NET_REQUEST_SYNC )
    146     {
    147       if ( !handleRequestSync( i, data, length, sender ) )
    148         return i;
    149147      continue;
    150148    }
     
    160158  return i;
    161159}
    162 
     160#endif
     161
     162#if 0
    163163int NetworkGameManager::readBytes(byte* data, int maxLength, int * reciever)
    164164{
     
    192192  return 0;
    193193}
    194 
     194#endif
     195
     196#if 0
    195197void NetworkGameManager::writeDebug() const
    196198{
     
    200202{
    201203}
     204#endif
    202205
    203206
     
    211214  if ( this->isServer())
    212215  {
    213     if ( SharedNetworkData::getInstance()->getNewUniqueID() < 0 )
     216    int res = this->executeCreateEntity( classID, SharedNetworkData::getInstance()->getNewUniqueID(), owner );
     217   
     218    if ( res < 0 )
    214219    {
    215220      PRINTF(1)("Cannot create entity! There are no more uniqueIDs left!\n");
    216221      return -1;
    217222    }
    218     return this->executeCreateEntity( classID, SharedNetworkData::getInstance()->getNewUniqueID(), owner );
     223   
     224    return res;
    219225  }
    220226  else
    221227  {
     228#if 0
    222229    this->requestCreateEntity( classID );
     230#endif
    223231    return -1;
    224232  }
     
    288296  else
    289297  {
     298#if 0
    290299    this->requestRemoveEntity( uniqueID );
    291   }
    292 }
    293 
    294 
    295 
     300#endif
     301  }
     302}
     303
     304
     305#if 0
    296306/*!
    297307 * Creates the needed entity on the server if possible
     
    311321  }
    312322}
    313 
     323#endif
     324
     325#if 0
    314326/*!
    315327 * Removes the specified entity on the server
     
    329341  }
    330342}
     343#endif
    331344
    332345/*!
     
    337350int NetworkGameManager::executeCreateEntity(ClassID classID, int uniqueID, int owner)
    338351{
     352#if 0
    339353  for ( int i = 0; i<outBuffer.size(); i++)
    340354  {
     
    351365      return -1;
    352366  }
    353 
     367#endif
    354368  PRINTF(0)("ExecuteCreateEntity: server side: classID: %x, uniqueID: %i, owner: %i\n", classID, uniqueID, owner);
    355369  doCreateEntity( classID, uniqueID, owner );
     
    365379void NetworkGameManager::executeRemoveEntity(int uniqueID)
    366380{
     381#if 0
    367382  for ( int i = 0; i<outBuffer.size(); i++)
    368383  {
     
    375390      return;
    376391  }
     392#endif
    377393
    378394  doRemoveEntity(uniqueID);
     
    388404}
    389405
     406#if 0
    390407/*!
    391408 * Sends the Entities to the new connected client
     
    443460  signalNewPlayer( userID );
    444461}
     462#endif
    445463
    446464
     
    448466bool NetworkGameManager::signalNewPlayer(int userId)
    449467{
    450   if ( userId >= outBuffer.size() )
    451     resizeBufferVector( userId );
    452 
    453468  /* create new playable for Player*/
    454469  PRINTF(0)("Request for creation: %i\n", userId);
     
    456471  PRINTF(0)("Request for creation: userid: %i, uniqueid: %i\n", userId, uniqueId);
    457472  this->sendYouAre(uniqueId, userId);
    458 
    459473}
    460474
     
    464478{
    465479  const std::list<BaseObject*>* playableList = ClassList::getList(CL_PLAYABLE);
     480 
     481  if ( !playableList )
     482    return false;
     483 
    466484  std::list<BaseObject*>::const_iterator it = playableList->begin();
    467485
     
    478496}
    479497
    480 
     498#if 0
    481499/**
    482500 * Creates a buffer for user n
     
    498516  }
    499517}
     518#endif
    500519
    501520/**
     
    532551    s->setSynchronized(true);
    533552    //this->networkStream->connectSynchronizeable( *s );
    534     if ( !isServer() )
    535       s->setIsOutOfSync( true );
     553
    536554    PRINTF(0)("Fabricated %s with id %d\n", s->getClassName(), s->getUniqueID());
    537555
     
    601619}
    602620
    603 /**
    604  * Tell the synchronizeable that a user's synchronizeable is out of sync
    605  * @param uniqueID: unique ID assigned with the entity which is out of sync
    606  * @param userID: user ID who's synchronizeable is out of sync
    607  */
    608 void NetworkGameManager::doRequestSync( int uniqueID, int userID )
    609 {
    610   SynchronizeableList::const_iterator it,e;
    611   it = this->networkStream->getSyncBegin();
    612   e = this->networkStream->getSyncEnd();
    613 
    614   while ( it != e )
    615   {
    616     if ( (*it)->getUniqueID() == uniqueID )
    617     {
    618       (*it)->requestSync( userID );
    619       break;
    620     }
    621     it++;
    622   }
    623 }
    624 
     621#if 0
    625622/**
    626623 * Copies length bytes to the clientBuffer with error checking
     
    641638  return true;
    642639}
    643 
     640#endif
     641
     642#if 0
    644643/**
    645644 * Reads data from clientBuffer with error checking
     
    660659  return true;
    661660}
     661#endif
    662662
    663663/**
     
    687687      } else
    688688      {
    689         PRINTF(1)("UniqueID is not a Playable\n");
     689        PRINTF(1)("UniqueID %d is not a Playable\n", uniqueID);
    690690      }
    691691    }
     
    697697  assert(player != NULL);
    698698
    699   s->setIsOutOfSync( true );
    700 
    701699  PRINTF(0)("uniqueID = %d\n", s->getUniqueID());
    702700
     
    715713  if ( !isServer() )
    716714    return;
    717 
    718   if ( userID != 0 )
    719   {
    720     if ( !writeToClientBuffer( outBuffer[userID], (byte)NET_YOU_ARE_ENTITY ) )
    721       return;
    722 
    723     if ( !writeToClientBuffer( outBuffer[userID], uniqueID ) )
    724       return;
    725   }
    726   else
    727   {
    728     doYouAre(uniqueID);
    729   }
     715 
     716  byte buf[INTSIZE];
     717 
     718  Converter::intToByteArray( uniqueID, buf, INTSIZE );
     719 
     720  MessageManager::getInstance()->sendMessage( MSGID_YOU_ARE, buf, INTSIZE, RT_USER, userID, MP_HIGHBANDWIDTH);
    730721}
    731722
     
    902893  return true;
    903894}
    904 
    905 bool NetworkGameManager::handleRequestSync( int & i, const byte * data, int length, int sender )
    906 {
    907   if ( INTSIZE > length-i )
    908   {
    909     PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n");
    910     return false;
    911   }
    912   int uniqueID;
    913   i += Converter::byteArrayToInt( &data[i], &uniqueID );
    914 
    915   PRINTF(0)("handleRequestSync %d %d\n", uniqueID, sender);
    916   doRequestSync( uniqueID, sender );
    917 
    918   return true;
    919 }
    920 
    921895
    922896/**
     
    958932}
    959933
    960 
     934bool NetworkGameManager::youAreHandler( MessageId messageId, byte * data, int dataLength, void * someData, int userId )
     935{
     936  assert( dataLength == INTSIZE );
     937  int uniqueId;
     938 
     939  Converter::byteArrayToInt( data, &uniqueId );
     940 
     941  SynchronizeableList::const_iterator it = NetworkGameManager::getInstance()->networkStream->getSyncBegin();
     942
     943  Playable *p = NULL;
     944  Synchronizeable *s = NULL;
     945
     946  for ( ; it !=NetworkGameManager::getInstance()->networkStream->getSyncEnd(); it++ )
     947  {
     948    if ( (*it)->getUniqueID()==uniqueId )
     949    {
     950      break;
     951    }
     952  }
     953 
     954  if ( it == NetworkGameManager::getInstance()->networkStream->getSyncEnd() )
     955    return false;
     956 
     957  NetworkGameManager::getInstance()->doYouAre( uniqueId );
     958 
     959  return true;
     960}
     961
     962#if 0
    961963bool NetworkGameManager::writeToClientBuffer( clientBuffer & cb, byte b )
    962964{
     
    971973  return true;
    972974}
     975
    973976
    974977bool NetworkGameManager::writeToClientBuffer( clientBuffer & cb, int i )
     
    985988  return true;
    986989}
    987 
    988 void NetworkGameManager::sync( int uniqueID, int owner )
    989 {
    990   /*if ( owner==this->getHostID() )
    991   return;*/
    992 
    993   if ( !isServer() )
    994     executeRequestSync( uniqueID, 0 );
    995   else
    996     executeRequestSync( uniqueID, owner );
    997 }
    998 
    999 void NetworkGameManager::executeRequestSync( int uniqueID, int user )
    1000 {
    1001   PRINTF(0)("executeRequestSync %d %d\n", uniqueID, user);
    1002   if ( user >= outBuffer.size() )
    1003     resizeBufferVector( user );
    1004 
    1005   if ( !writeToClientBuffer( outBuffer[user], (byte)NET_REQUEST_SYNC ) )
    1006     return;
    1007   if ( !writeToClientBuffer( outBuffer[user], uniqueID ) )
    1008     return;
    1009 }
    1010 
     990#endif
     991
     992
  • trunk/src/lib/network/network_game_manager.h

    r6981 r7954  
    1212/* include base_object.h since all classes are derived from this one */
    1313#include "synchronizeable.h"
     14#include "message_manager.h"
    1415
    1516
    1617class TiXmlElement;
    1718class PNode;
    18 
    19 /**
    20  * protocol definition
    21  *
    22  *  CREATE_ENTITY:       >> CLASS_ID, UNIQUE_ID, OWNER
    23  *  REMOVE_ENTITY:       >> UNIQUE_ID
    24  *
    25  *  CREATE_ENTITY_LIST:  >> NUMBER, [CLASS_ID, UNIQUE_ID, OWNER][0..NUMBER]
    26  *  REMOVE_ENTITY_LIST:  >> NUMBER, [UNIQUE_ID][0..NUMBER]
    27  *
    28  *  REQUEST_CREATE:      >> CLASS_ID
    29  *                       << [Sync Info]
    30  *  REQUEST_REMOVE:      >> UNIQUE_ID
    31  *                       << [Sync Info]
    32  *
    33  *  //REQUEST_CREATE_LIST: NUMBER, [CLASS_ID][0..NUMBER]
    34  *  //REQUEST_CREATE_LIST: NUMBER, [UNIQUE_ID][0..NUMBER]
    35  *
    36  *  REQUEST_ENTITY_LIST: //request the whole world :D
    37  *  REQUEST_SYNC:        >> UNIQUE_ID
    38  *                       << [Sync Info]
    39  *  //REQUEST_SYNC_LIST:   NUMBER, [UNIQUE_ID][0..NUMBER]
    40  *
    41  *  YOU_ARE_ENTITY:      >> UNIQUE_ID
    42  *
    43  *  REQUEST_PNODE_PATH   >> UNIQUE_ID_START   UNIQUE_ID_STOP
    44  *                       << UNIQUE_ID_1   UNIQUE_ID_2   UNIQUE_ID_3 ...   UNIQUE_ID_N
    45  *
    46  *  SEND_PNODE_PATH      >> UNIQUE_ID_START   UNIQUE_ID_STOP NUMBER [UNIQUE_ID][0..NUMBER]
    47  */
    4819
    4920typedef enum NetworkGameManagerProtocol {
     
    5425  NET_REQUEST_CREATE,
    5526  NET_REQUEST_REMOVE,
    56   NET_REQUEST_SYNC,
    5727  NET_YOU_ARE_ENTITY,
    5828  NET_REQUEST_ENTITY_LIST,
     
    8151    { if (!NetworkGameManager::singletonRef) NetworkGameManager::singletonRef = new NetworkGameManager(); return NetworkGameManager::singletonRef; }
    8252
     53#if 0
    8354    virtual int writeBytes(const byte* data, int length, int sender);
    8455    virtual int readBytes(byte* data, int maxLength, int * reciever);
    8556    virtual void writeDebug() const;
    8657    virtual void readDebug() const;
     58#endif
    8759
    8860    int createEntity( ClassID classID, int owner = 0 );
     
    9163    void sendYouAre( int uniqueID, int userID );
    9264
    93     void sync(int uniqueID, int owner);
    94 
     65#if 0
    9566    void sendEntityList(int userID);
     67#endif
    9668
    9769    bool signalNewPlayer(int userId);
     
    10173  private:
    10274    NetworkGameManager();
     75   
     76    static bool youAreHandler(MessageId messageId, byte * data, int dataLength, void * someData, int userId );
    10377
    10478
     
    11185    bool handleRemoveEntityList( int& i, const byte* data, int length, int sender );
    11286    bool handleYouAreEntity( int& i, const byte* data, int length, int sender );
    113     bool handleRequestSync( int& i, const byte* data, int length, int sender );
    11487    bool handleRequestPNodePath(int& i, const byte* data, int length, int sender);
    11588    bool handleSendPNodePath(int& i, const byte* data, int length, int sender);
     
    11790
    11891    /* some network handlers helper functions */
    119     void requestCreateEntity(ClassID classID);
     92//    void requestCreateEntity(ClassID classID);
    12093    int executeCreateEntity(ClassID classID, int uniqueID = 0, int owner = 0);
    12194    BaseObject* doCreateEntity(ClassID classID, int uniqueID, int owner);
    12295
    123     void requestRemoveEntity(int uniqueID);
     96//    void requestRemoveEntity(int uniqueID);
    12497    void executeRemoveEntity(int uniqueID);
    12598    void doRemoveEntity(int uniqueID);
    12699
    127     void executeRequestSync( int uniqueID, int user );
    128     void doRequestSync(int uniqueID, int userID);
    129 
    130100    void doYouAre( int uniqueID );
    131101
    132     void requestPNodePath(const PNode* node1, const PNode* node2);
     102//    void requestPNodePath(const PNode* node1, const PNode* node2);
    133103    void executeRequestPNodePath(const PNode* node2, const PNode* node2);
    134104    void doRequestPNodePath(const PNode* node1, const PNode* node2);
    135105
    136106    bool canCreateEntity(ClassID classID);
     107#if 0
     108    void resizeBufferVector(int n);
    137109
    138     void resizeBufferVector(int n);
    139110
    140111    bool writeToClientBuffer( clientBuffer &cb, byte*data, int length );
     
    142113    bool writeToClientBuffer( clientBuffer &cb, int i );
    143114    bool readFromClientBuffer( clientBuffer &cb, byte*data, int length );
    144 
     115#endif
    145116
    146117  private:
     118#if 0
    147119    std::vector<clientBuffer>     outBuffer;
    148120    //clientBuffer                  allOutBuffer;
     121#endif
    149122    static NetworkGameManager*    singletonRef;
    150     bool                          hasRequestedWorld;
    151123};
    152124
  • trunk/src/lib/network/network_manager.cc

    r7256 r7954  
    2828#include "shared_network_data.h"
    2929#include "network_stream.h"
     30#include "preferences.h"
     31#include "network_log.h"
    3032
    3133
     
    5254  this->defaultSyncStream = NULL;
    5355  this->sharedNetworkData = SharedNetworkData::getInstance();
     56  this->elapsedTime = 0.0f;
     57 
     58   
     59  int port = Preferences::getInstance()->getInt( "network", "telnetport", 0 );
     60 
     61  if ( port > 0 )
     62    NetworkLog::getInstance()->listen( port );
    5463
    5564  PRINTF(0)("NetworkManager created\n");
     
    7281  this->netStreamList = ClassList::getList(CL_SYNCHRONIZEABLE);
    7382  PRINTF(0)("NetworkManager initzalized\n");
     83
    7484}
    7585
     
    90100int NetworkManager::establishConnection(const std::string & name, unsigned int port)
    91101{
    92   IPaddress ipAddress;
    93   int error = SDLNet_ResolveHost(&ipAddress, name.c_str(), port);
    94   if( error == -1) {
    95     printf("\n\nerror on address resolution, program inconsistency\n\n");
    96     return -1;
    97   }
    98 
    99   this->defaultSyncStream = new NetworkStream(ipAddress);
     102  this->defaultSyncStream = new NetworkStream( name, port );
    100103  this->sharedNetworkData->setDefaultSyncStream(this->defaultSyncStream);
    101104  this->defaultSyncStream->startHandshake();
     
    130133/**
    131134 *  sync the network
     135 *  @param dtS: the seceonds elapsed since the last synchronize call
    132136 */
    133 void NetworkManager::synchronize()
     137void NetworkManager::synchronize( float dtS)
    134138{
     139  this->elapsedTime += dtS;
     140  if( likely(this->elapsedTime < 1.0f / NETWORK_FREQUENCY))
     141    return;
     142  this->elapsedTime = 0.0f;
     143
    135144  if (this->netStreamList != NULL || (this->netStreamList = ClassList::getList(CL_NETWORK_STREAM)) != NULL)
    136145  {
  • trunk/src/lib/network/network_manager.h

    r7256 r7954  
    4545
    4646    void connectSynchronizeable(Synchronizeable& sync);
    47     void synchronize();
     47    void synchronize(float dtS);
    4848
    4949    void debug();
     
    6161
    6262    SharedNetworkData*               sharedNetworkData;       //!< reference to the shared data
     63    float                            elapsedTime;             //!< elapsed time since the last network update
    6364};
    6465
  • trunk/src/lib/network/network_socket.cc

    r7440 r7954  
    2121#define DEBUG_MODULE_NETWORK
    2222
    23 #include "converter.h"
    24 
    2523/* include your own header */
    2624#include "network_socket.h"
     
    3432NetworkSocket::NetworkSocket()
    3533{
    36   this->init();
     34  bOk = true;
    3735}
    3836
    39 /**
    40  * Constructor to connect directly
    41  */
    42 NetworkSocket::NetworkSocket(IPaddress ip)
     37NetworkSocket::~ NetworkSocket( )
    4338{
    44   this->init();
    45   connectToServer(ip);
    46 }
    47 
    48 
    49 NetworkSocket::NetworkSocket( TCPsocket sock )
    50 {
    51   this->init();
    52   this->tcpSocket = sock;
    53 
    54   readThread = SDL_CreateThread(thread_read, (void*)this);
    55   writeThread = SDL_CreateThread(thread_write, (void*)this);
    56 }
    57 
    58 void NetworkSocket::init()
    59 {
    60   /* set the class id for the base object */
    61   this->setClassID(CL_NETWORK_SOCKET, "NetworkSocket");
    62 
    63   tcpSocket = NULL;
    64   incomingBufferLength = 0;
    65   outgoingBufferLength = 0;
    66 
    67   readThread = NULL;
    68   writeThread = NULL;
    69 
    70 
    71   thread_write_running = false;
    72   thread_read_running = false;
    73 
    74   incomingBufferMutex = SDL_CreateMutex();
    75   outgoingBufferMutex = SDL_CreateMutex();
    76 
    77 
    78   socketMutex = SDL_CreateMutex();
    79   terminateThread = false;
    80 
    81   /* Init SDL_net */
    82   //NOTE: do we need to call SDLNet_Init for all instances?
    83   if(SDLNet_Init()==-1)
    84   {
    85     PRINTF(1)("SDLNet_Init: %s\n", SDLNet_GetError());
    86     return;
    87   }
    88   else
    89     PRINTF(5)("SDL_net initialized\n");
    90 
    91   PRINTF(0)("NetworkSocket created\n");
    92 
    9339}
    9440
    9541
    9642
    97 /**
    98  * Default destructor
    99  * dont use this from outside: use destroy() instead!!
    100  */
    101 NetworkSocket::~NetworkSocket( )
    102 {
    103   this->terminateThread = true;
    104   /* Quit SDL_net */
    105   // NOTE: what if other instances of NetworkSocket running?
    106   SDLNet_Quit();
    107   PRINTF(5)("SDL_net shutdown\n");
    108 
    109   SDL_DestroyMutex(incomingBufferMutex);
    110   SDL_DestroyMutex(outgoingBufferMutex);
    111   SDL_DestroyMutex(socketMutex);
    112   SDL_DestroyMutex(threadTerminationMutex);
    113 }
    114 
    115 /**
    116  * This function establishes a TCP/UDP connection to a given server (function argument).
    117  * It is called by the NetworkStream. It creates a TCP/UDP socket for the connection.
    118  * @param ip
    119  */
    120 void NetworkSocket::connectToServer(IPaddress ip)
    121 {
    122   //HACK this will cause segfault
    123 #warning remove this
    124   int * a;
    125   *a = 99;
    126   //check if not already connected or listening
    127   if (tcpSocket)
    128   {
    129     PRINTF(1)("NetworkSocket::listen: tcpSocket!=NULL! maybe you already called listen or connectToServer or did not call disconnectServer()!");
    130   }
    131 
    132   /* Connect to the host and port contained in ip using a TCP connection. */
    133   tcpSocket = SDLNet_TCP_Open(&ip);
    134   if(!tcpSocket)
    135   {
    136     PRINTF(1)("SDLNet_TCP_Open: %s\n", SDLNet_GetError());
    137     return;
    138   }
    139 
    140   readThread = SDL_CreateThread(thread_read, (void*)this);
    141   writeThread = SDL_CreateThread(thread_write, (void*)this);
    142 }
    143 
    144 
    145 /**
    146  * DTears down a TCP/UDP connection.
    147  */
    148 void NetworkSocket::disconnectServer( )
    149 {
    150   terminateThread = true;
    151   /* Close the connection */
    152 
    153   SDL_mutexP(socketMutex);
    154   SDLNet_TCP_Close(tcpSocket);
    155   tcpSocket = NULL;
    156   SDL_mutexV(socketMutex);
    157 }
    158 
    159 
    160 /**
    161  * This function writes some bytes (data) to the network connection (if the connection is already
    162  * estabilhed) otherwise it just does nothing (silently discarding the data). And writes some
    163  * warnings
    164  * @param data: pointer to the data to send
    165  * @param length: n bytes to send
    166  * @return the number successfully written bytes
    167  */
    168 int NetworkSocket::writeBytes(byte * data, int length)
    169 {
    170   PRINTF(5)("NetworkSocket::writeBytes()\n");
    171 #ifdef _USE_OUTGOING_BUFFER
    172 
    173 #define min(a,b) (a<b)?a:b
    174   int nbytes = min(_OUTGOING_BUFFER_SIZE - outgoingBufferLength, length);
    175 #undef min
    176 
    177   if (!tcpSocket || data==NULL || nbytes<=0)
    178   {
    179     assert(_OUTGOING_BUFFER_SIZE - outgoingBufferLength > 0);
    180     return 0;
    181   }
    182 
    183   SDL_mutexP(outgoingBufferMutex);
    184 
    185   memcpy(outgoingBuffer + outgoingBufferLength, data, nbytes);
    186   outgoingBufferLength += nbytes;
    187 
    188   SDL_mutexV(outgoingBufferMutex);
    189 
    190 
    191   return nbytes;
    192 #else
    193   SDL_mutexP(socketMutex);
    194 
    195   if (!tcpSocket || data==NULL)
    196     return 0;
    197 
    198   int res = SDLNet_TCP_Send(tcpSocket, data, length);
    199 
    200   SDL_mutexV(socketMutex);
    201 
    202   if (res<length)
    203     PRINTF(1)("SDLNet_TCP_Send: %s\n", SDLNet_GetError());
    204 
    205   return res;
    206 #endif
    207 }
    208 
    209 /**
    210  * Reads in the bytes from the network interface and passes it to the NetworkStream.
    211  * This function must internaly be implemented/connected as a thread, since the read
    212  * functions of many network libraries are blocking an would therefore block the whole
    213  * program.
    214  * From outside, the thread shouldn't be accessible at all.
    215  * @param data: pointer to memory, big enough to store length bytes
    216  * @param length: n bytes to read
    217  * @return the number successfully read bytes. -1 on error. may be less than length!
    218  */
    219 int NetworkSocket::readBytes(byte * data, int length)
    220 {
    221   PRINTF(5)("NetworkSocket::readBytes()\n");
    222   if (data==NULL)
    223     return 0;
    224 
    225   int nbytes = (length<incomingBufferLength) ? length : incomingBufferLength;
    226 
    227 
    228   //printf("readBytes: nbytes = %d; length=%d; incomingBufferLength=%d\n", nbytes, length, incomingBufferLength);
    229 
    230   // just in case ...
    231   if (nbytes<0)
    232     return -1;
    233 
    234   if (nbytes==0)
    235       return 0;
    236 
    237   SDL_mutexP(incomingBufferMutex);
    238 
    239   memcpy(data, incomingBuffer, nbytes);
    240 
    241   //important: use memmove because the memory areas may overlap
    242   memmove(incomingBuffer, incomingBuffer+nbytes, incomingBufferLength-nbytes);
    243   incomingBufferLength -= nbytes;
    244 
    245   SDL_mutexV(incomingBufferMutex);
    246 
    247   return nbytes;
    248 }
    249 
    250 /**
    251  * Reads in the bytes form the network interface and passes it to the NetworkStream.
    252  * It only reads the bytes if there are enough bytes in our buffer.
    253  * @param data: pointer to memory, big enough to store length bytes
    254  * @param length: n bytes to read
    255  * @return the number successfully read bytes. -1 on error. 0 if there are not enough bytes in our buffer.
    256  */
    257 int NetworkSocket::readBlock(byte * data, int length)
    258 {
    259   printf("NetworkSocket: got %i bytes, NetworkStream requested %i bytes\n", this->incomingBufferLength, length);
    260   if (incomingBufferLength >= length)
    261     return readBytes(data, length);
    262   else return 0;
    263 }
    264 
    265 
    266 /**
    267  * used to create a thread to read from socket
    268  * @param data: pointer to NetworkSocket
    269  */
    270 int NetworkSocket::thread_read( void * data )
    271 {
    272   int nbytesread = 0;
    273   int nbytestoread = 0;
    274   char buffer[_LOCAL_BUFFER_SIZE];
    275   NetworkSocket * self = (NetworkSocket*)data;
    276 
    277   self->thread_read_running = true;
    278 
    279   while (!self->terminateThread)
    280   {
    281 #define min(a,b) (a<b)?a:b
    282     nbytestoread = min(_INCOMING_BUFFER_SIZE - self->incomingBufferLength, _LOCAL_BUFFER_SIZE);
    283 #undef min
    284 
    285     //if buffer is full
    286     if (nbytestoread<=0 || !self->tcpSocket)
    287     {
    288       SDL_Delay(_MSECONDS_SLEEP_FULL_BUFFER);
    289       continue;
    290     }
    291 
    292     nbytesread = SDLNet_TCP_Recv(self->tcpSocket, buffer, nbytestoread);
    293 
    294     SDL_mutexP(self->incomingBufferMutex);
    295 
    296     if (nbytesread<=0)
    297     {
    298       if (nbytesread<0)
    299         printf("SDLNet_TCP_Recv: %s\n", SDLNet_GetError());
    300 
    301       SDL_mutexP(self->socketMutex);
    302 
    303       SDLNet_TCP_Close(self->tcpSocket);
    304       self->tcpSocket = NULL;
    305 
    306       SDL_mutexV(self->socketMutex);
    307       SDL_mutexV(self->incomingBufferMutex);
    308       continue;
    309     }
    310 
    311     //printf("thread_read: nbytesread=%d\n", nbytesread);
    312 
    313     memcpy(self->incomingBuffer+self->incomingBufferLength, buffer, nbytesread);
    314     self->incomingBufferLength += nbytesread;
    315 
    316     SDL_mutexV(self->incomingBufferMutex);
    317   }
    318 
    319   SDL_mutexP(self->threadTerminationMutex);
    320   self->thread_read_running = false;
    321 
    322   if ( !self->thread_write_running )
    323   {
    324     //delete self;
    325     SDL_mutexV(self->threadTerminationMutex);
    326   }
    327   else
    328   {
    329     SDL_mutexV(self->threadTerminationMutex);
    330   }
    331 
    332 
    333 #ifdef DONTEXITTHREADS
    334   while ( true )
    335   {
    336     SDL_Delay(1000);
    337   }
    338 #endif
    339  
    340   PRINTF(0)("QUIT READ THREAD\n");
    341  
    342   return 0;
    343 }
    344 
    345 int NetworkSocket::thread_write( void * data )
    346 {
    347   int nbyteswrite = 0;
    348   int nbytestowrite = 0;
    349   char buffer[_LOCAL_BUFFER_SIZE];
    350   NetworkSocket * self = (NetworkSocket*)data;
    351 
    352   self->thread_write_running = true;
    353 
    354   while (!self->terminateThread)
    355   {
    356 #define min(a,b) (a<b)?a:b
    357     nbytestowrite = min(self->outgoingBufferLength, _LOCAL_BUFFER_SIZE);
    358 #undef min
    359 
    360 //     printf("thread_write nbytes=%d listening=%d\n", nbytestowrite, (int)self->_isListening);
    361 
    362     //if buffer is full
    363     if (nbytestowrite<=0 || !self->tcpSocket)
    364     {
    365       SDL_Delay(_MSECONDS_SLEEP_EMPTY_BUFFER);
    366       continue;
    367     }
    368 
    369     SDL_mutexP(self->outgoingBufferMutex);
    370 
    371     //printf("a\n");
    372 
    373     memcpy(buffer, self->outgoingBuffer, nbytestowrite);
    374     self->outgoingBufferLength -= nbytestowrite;
    375     memmove(self->outgoingBuffer, self->outgoingBuffer+nbytestowrite, self->outgoingBufferLength);
    376 
    377     SDL_mutexV(self->outgoingBufferMutex);
    378 
    379     nbyteswrite = SDLNet_TCP_Send(self->tcpSocket, buffer, nbytestowrite);
    380 
    381     if (nbyteswrite<=0)
    382     {
    383       printf("SDLNet_TCP_Recv: %s\n", SDLNet_GetError());
    384 
    385       SDL_mutexP(self->socketMutex);
    386 
    387       SDLNet_TCP_Close(self->tcpSocket);
    388       self->tcpSocket = NULL;
    389 
    390       SDL_mutexV(self->socketMutex);
    391       continue;
    392     }
    393 
    394   }
    395 
    396   SDL_mutexP(self->threadTerminationMutex);
    397   self->thread_write_running = false;
    398 
    399   if ( !self->thread_read_running )
    400   {
    401     //delete self;
    402     SDL_mutexV(self->threadTerminationMutex);
    403   }
    404   else
    405   {
    406     SDL_mutexV(self->threadTerminationMutex);
    407   }
    408 
    409 #ifdef DONTEXITTHREADS
    410   while ( true )
    411   {
    412   SDL_Delay(1000);
    413   }
    414 #endif
    415 
    416   PRINTF(0)("QUIT WRITE THREAD\n");
    417 
    418   return 0;
    419  
    420 }
    421 
    422 bool NetworkSocket::writePacket( byte * data, int length )
    423 {
    424   PRINTF(5)("NetworkSocket::writePacket() size=%d\n", length);
    425 
    426   if ( length > 1024 )
    427   PRINTF(2)("WARNING SENDING BIG PACKET SIZE = %d\n", length);
    428 
    429   byte blen[INTSIZE];
    430 
    431   Converter::intToByteArray( length, blen, INTSIZE );
    432 
    433   writeBytes(blen, INTSIZE);
    434   writeBytes(data, length);
    435 }
    436 
    437 int NetworkSocket::readPacket( byte * data, int maxLength )
    438 {
    439   PRINTF(5)("NetworkSocket::readPacket()\n");
    440   if (incomingBufferLength<INTSIZE)
    441   {
    442     return 0;
    443   }
    444 
    445   int blen;
    446   Converter::byteArrayToInt( incomingBuffer, &blen );
    447 
    448   if (blen>maxLength)
    449   {
    450     PRINTF(1)("Buffersize is too small (%d) for packet (%d).\n", maxLength, blen);
    451     assert(false);
    452     return 0;
    453   }
    454 
    455   if (blen>incomingBufferLength)
    456   {
    457     return 0;
    458   }
    459 
    460   byte t[INTSIZE];
    461   readBytes(t, INTSIZE);
    462   int res = readBytes(data, blen);
    463 
    464   if (res!=blen)
    465     return -1;
    466   else
    467     return blen;
    468 
    469 }
    470 
    471 
  • trunk/src/lib/network/network_socket.h

    r6994 r7954  
    88#define _NETWORK_SOCKET
    99
    10 //TODO HACK else gdb will not work on server
    11 #define DONTEXITTHREADS
    12 
    13 //if you want to use outgoing buffer define _USE_OUTGOING_BUFFER
    14 #define _USE_OUTGOING_BUFFER
    15 
    16 #define _INCOMING_BUFFER_SIZE 2024000
    17 #define _OUTGOING_BUFFER_SIZE 2024000
    18 #define _LOCAL_BUFFER_SIZE 1024
    19 //sleep if incoming buffer is full
    20 #define _MSECONDS_SLEEP_FULL_BUFFER 10
    21 //sleep if outgoing buffer is empty
    22 #define _MSECONDS_SLEEP_EMPTY_BUFFER 10
    23 
    24 
    25 /* contains memmove and memcpy */
    26 #include <string.h>
    27 
    28 #ifdef HAVE_SDL_H
    29  #include <SDL_thread.h>
    30 #else
    31  #include <SDL/SDL_thread.h>
    32 #endif
    3310/* include this file, it contains some default definitions */
    3411#include "netdefs.h"
     
    3815#include "base_object.h"
    3916
    40 /* using namespace std is default, this needs to be here */
    41 using namespace std;
    42 
    4317class NetworkSocket : public BaseObject
    4418{
     19  public:
     20    NetworkSocket();
     21    virtual ~NetworkSocket();
    4522
    46 private:
    47 //  IPaddress serverAddress;
    48 //  unsigned int port;
    49   TCPsocket tcpSocket;
    50 //  UDPsocket udpSocket;
     23    /**
     24     * connect to server on host with port port
     25     * @param host hostname might be xxx.xxx.xxx.xxx or localhost ...
     26     * @param port port to connect to
     27     */
     28    virtual void connectToServer( std::string host, int port ) = 0;
     29   
     30    /**
     31     * disconnect from server
     32     */
     33    virtual void disconnectServer() = 0;
    5134
    52   byte incomingBuffer[_INCOMING_BUFFER_SIZE];
    53 #ifdef _USE_OUTGOING_BUFFER
    54   byte outgoingBuffer[_OUTGOING_BUFFER_SIZE];
    55 #endif
    56   int incomingBufferLength;
    57 #ifdef _USE_OUTGOING_BUFFER
    58   int outgoingBufferLength;
    59 #endif
     35    /**
     36     * send packet to connected socket. will be recieved as whole packet
     37     * @param data pointer to data to send
     38     * @param length lengt of packet to send
     39     * @return true on success
     40     */
     41    virtual bool writePacket(byte * data, int length) = 0;
     42   
     43    /**
     44     * read a packet sent by another NetworkSocket
     45     * @param data data will be copied here
     46     * @param maxLength readPacket will not read more than maxLength
     47     * @return bytes read. on error less than zero
     48     */
     49    virtual int readPacket(byte * data, int maxLength) = 0;
    6050
    61   SDL_mutex * incomingBufferMutex;
    62 #ifdef _USE_OUTGOING_BUFFER
    63   SDL_mutex * outgoingBufferMutex;
    64 #endif
    65   SDL_mutex * socketMutex;
    66   bool terminateThread;
    67 
    68   SDL_mutex* threadTerminationMutex;
    69   static int thread_read(void * data);
    70   bool thread_read_running;
    71   bool thread_write_running;
    72 
    73   SDL_Thread*            readThread;
    74   SDL_Thread*            writeThread;
    75 
    76 #ifdef _USE_OUTGOING_BUFFER
    77   static int thread_write(void * data);
    78 #endif
    79 
    80   int writeBytes(byte * data, int length);
    81   int readBytes(byte * data, int length);
    82   int readBlock(byte * data, int length);
    83 
    84   void init();
    85 
    86 public:
    87 
    88   NetworkSocket();
    89   virtual ~NetworkSocket();
    90   NetworkSocket(IPaddress ip);
    91   NetworkSocket(TCPsocket sock);
    92   void destroy() { terminateThread = true; };
    93 
    94 
    95   void connectToServer(IPaddress ip);
    96   void disconnectServer();
    97 
    98   bool writePacket(byte * data, int length);
    99   int readPacket(byte * data, int maxLength);
    100 
    101   inline bool isOk() { return tcpSocket!=NULL; }
     51    /**
     52     * check if socket is ok
     53     * @return true if socket is ok
     54     */
     55    inline bool isOk() { return this->bOk; }
     56 
     57  protected:
     58    bool bOk;            //!< check for socket status
    10259
    10360};
  • trunk/src/lib/network/network_stream.cc

    r6959 r7954  
    2323#include "base_object.h"
    2424#include "network_protocol.h"
    25 #include "network_socket.h"
     25#include "udp_socket.h"
     26#include "udp_server_socket.h"
    2627#include "connection_monitor.h"
    2728#include "synchronizeable.h"
    2829#include "network_game_manager.h"
    2930#include "shared_network_data.h"
     31#include "message_manager.h"
     32#include "preferences.h"
     33#include "zip.h"
     34
     35#include "src/lib/util/loading/resource_manager.h"
     36
     37#include "network_log.h"
     38
     39
     40#include "lib/util/loading/factory.h"
    3041
    3142#include "debug.h"
     
    4960  /* initialize the references */
    5061  this->type = NET_CLIENT;
    51   this->networkProtocol = new NetworkProtocol();
    52   this->connectionMonitor = new ConnectionMonitor();
    53 }
    54 
    55 
    56 NetworkStream::NetworkStream(IPaddress& address)
     62}
     63
     64
     65NetworkStream::NetworkStream( std::string host, int port )
    5766{
    5867  this->type = NET_CLIENT;
    5968  this->init();
    60   this->networkSockets.push_back(new NetworkSocket(address));
    61   this->networkProtocol = new NetworkProtocol();
    62   this->connectionMonitor = new ConnectionMonitor();
    63   this->maxConnections = 1;
    64 }
    65 
    66 
    67 NetworkStream::NetworkStream(unsigned int port)
     69  this->peers[0].socket = new UdpSocket( host, port );
     70  this->peers[0].userId = 0;
     71  this->peers[0].isServer = true;
     72  this->peers[0].connectionMonitor = new ConnectionMonitor( 0 );
     73}
     74
     75
     76NetworkStream::NetworkStream( int port )
    6877{
    6978  this->type = NET_SERVER;
    7079  this->init();
    71   this->serverSocket = new ServerSocket(port);
    72   this->networkProtocol = new NetworkProtocol();
    73   this->connectionMonitor = new ConnectionMonitor();
    74   this->networkSockets.push_back( NULL );
    75   this->networkSockets[0] = NULL; //TODO: remove this
    76   this->handshakes.push_back( NULL );
     80  this->serverSocket = new UdpServerSocket(port);
    7781  this->bActive = true;
    7882}
     
    8791  this->networkGameManager = NULL;
    8892  myHostId = 0;
     93  currentState = 0;
     94 
     95  remainingBytesToWriteToDict = Preferences::getInstance()->getInt( "compression", "writedict", 0 );
     96 
     97  assert( Zip::getInstance()->loadDictionary( "testdict" ) );
    8998}
    9099
     
    98107  }
    99108
    100   for (NetworkSocketVector::iterator i = networkSockets.begin(); i!=networkSockets.end(); i++)
    101   {
    102     if ( *i )
    103     {
    104       (*i)->disconnectServer();
    105       (*i)->destroy();
    106     }
    107   }
    108 
    109   for (HandshakeVector::iterator i = handshakes.begin(); i!=handshakes.end(); i++)
    110   {
    111     if ( *i )
    112     {
    113       delete (*i);
    114     }
    115   }
    116 
    117   delete connectionMonitor;
    118   delete networkProtocol;
     109  for ( PeerList::iterator i = peers.begin(); i!=peers.end(); i++)
     110  {
     111    if ( i->second.socket )
     112    {
     113      i->second.socket->disconnectServer();
     114      delete i->second.socket;
     115      i->second.socket = NULL;
     116    }
     117   
     118    if ( i->second.handshake )
     119    {
     120      delete i->second.handshake;
     121      i->second.handshake = NULL;
     122    }
     123  }
     124 
     125  if ( serverSocket )
     126  {
     127    delete serverSocket;
     128    serverSocket = NULL;
     129  }
     130
    119131}
    120132
     
    125137  // setUniqueID( maxCon+2 ) because we need one id for every handshake
    126138  // and one for handshake to reject client maxCon+1
    127   this->networkGameManager->setUniqueID( this->maxConnections + 2 );
    128   //this->connectSynchronizeable( *(this->networkGameManager) );
    129   this->setMaxConnections( 10 );
     139  this->networkGameManager->setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
     140  MessageManager::getInstance()->setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
    130141}
    131142
     
    135146  Handshake* hs = new Handshake(false);
    136147  hs->setUniqueID( 0 );
    137   this->handshakes.push_back(hs);
     148  assert( peers[0].handshake == NULL );
     149  peers[0].handshake = hs;
     150//   peers[0].handshake->setSynchronized( true );
    138151  //this->connectSynchronizeable(*hs);
    139   PRINTF(0)("NetworkStream: %s\n", hs->getName());
     152  //this->connectSynchronizeable(*hs);
     153  PRINTF(0)("NetworkStream: Handshake created: %s\n", hs->getName());
    140154}
    141155
     
    146160  sync.setNetworkStream( this );
    147161
    148   if( this->networkSockets.size()>0 )
    149     this->bActive = true;
     162  this->bActive = true;
    150163}
    151164
     
    157170  if (disconnectSynchro != this->synchronizeables.end())
    158171    this->synchronizeables.erase(disconnectSynchro);
    159 
    160   if( this->networkSockets.size()<=0 )
    161     this->bActive = false;
     172 
     173  oldSynchronizeables[sync.getUniqueID()] = SDL_GetTicks();
    162174}
    163175
     
    165177void NetworkStream::processData()
    166178{
     179  currentState++;
     180 
    167181  if ( this->type == NET_SERVER )
     182  {
     183    if ( serverSocket )
     184      serverSocket->update();
     185   
    168186    this->updateConnectionList();
     187  }
    169188  else
    170189  {
    171     if ( networkSockets[0] && !networkSockets[0]->isOk() )
     190    if ( peers[0].socket && ( !peers[0].socket->isOk() || peers[0].connectionMonitor->hasTimedOut() ) )
    172191    {
    173192      PRINTF(1)("lost connection to server\n");
    174193
    175       //delete networkSockets[i];
    176       networkSockets[0]->disconnectServer();
    177       networkSockets[0]->destroy();
    178       networkSockets[0] = NULL;
    179 
    180       if ( handshakes[0] )
    181         delete handshakes[0];
    182       handshakes[0] = NULL;
    183     }
    184   }
    185 
    186   for (int i = 0; i<handshakes.size(); i++)
    187   {
    188     if ( handshakes[i] )
    189     {
    190       if ( handshakes[i]->completed() )
     194      peers[0].socket->disconnectServer();
     195      delete peers[0].socket;
     196      peers[0].socket = NULL;
     197
     198      if ( peers[0].handshake )
     199        delete peers[0].handshake;
     200      peers[0].handshake = NULL;
     201    }
     202  }
     203
     204  cleanUpOldSyncList();
     205  handleHandshakes();
     206 
     207  // order of up/downstream is important!!!!
     208  // don't change it
     209  handleDownstream();
     210  handleUpstream();
     211
     212}
     213
     214void NetworkStream::updateConnectionList( )
     215{
     216  //check for new connections
     217
     218  NetworkSocket* tempNetworkSocket = serverSocket->getNewSocket();
     219
     220  if ( tempNetworkSocket )
     221  {
     222    int clientId;
     223    if ( freeSocketSlots.size() >0 )
     224    {
     225      clientId = freeSocketSlots.back();
     226      freeSocketSlots.pop_back();
     227      peers[clientId].socket = tempNetworkSocket;
     228      peers[clientId].handshake = new Handshake(true, clientId, this->networkGameManager->getUniqueID(), MessageManager::getInstance()->getUniqueID() );
     229      peers[clientId].connectionMonitor = new ConnectionMonitor( clientId );
     230      peers[clientId].handshake->setUniqueID(clientId);
     231      peers[clientId].userId = clientId;
     232      peers[clientId].isServer = false;
     233    } else
     234    {
     235      clientId = 1;
     236     
     237      for ( PeerList::iterator it = peers.begin(); it != peers.end(); it++ )
     238        if ( it->first >= clientId )
     239          clientId = it->first + 1;
     240     
     241      peers[clientId].socket = tempNetworkSocket;
     242      peers[clientId].handshake = new Handshake(true, clientId, this->networkGameManager->getUniqueID(), MessageManager::getInstance()->getUniqueID());
     243      peers[clientId].handshake->setUniqueID(clientId);
     244      peers[clientId].connectionMonitor = new ConnectionMonitor( clientId );
     245      peers[clientId].userId = clientId;
     246      peers[clientId].isServer = false;
     247     
     248      PRINTF(0)("num sync: %d\n", synchronizeables.size());
     249    }
     250
     251    if ( clientId > MAX_CONNECTIONS )
     252    {
     253      peers[clientId].handshake->doReject( "too many connections" );
     254      PRINTF(0)("Will reject client %d because there are to many connections!\n", clientId);
     255    }
     256    else
     257
     258    PRINTF(0)("New Client: %d\n", clientId);
     259
     260    //this->connectSynchronizeable(*handshakes[clientId]);
     261  }
     262
     263  //check if connections are ok else remove them
     264  for ( PeerList::iterator it = peers.begin(); it != peers.end(); it++ )
     265  {
     266    if ( 
     267          it->second.socket &&
     268          (
     269            !it->second.socket->isOk()  ||
     270            it->second.connectionMonitor->hasTimedOut()
     271          )
     272       )
     273    {
     274      std::string reason = "disconnected";
     275      if ( it->second.connectionMonitor->hasTimedOut() )
     276        reason = "timeout";
     277      PRINTF(0)("Client is gone: %d (%s)\n", it->second.userId, reason.c_str());
     278     
     279      assert(false);
     280
     281      it->second.socket->disconnectServer();
     282      delete it->second.socket;
     283      it->second.socket = NULL;
     284
     285      if ( it->second.handshake )
     286        delete it->second.handshake;
     287      it->second.handshake = NULL;
     288     
     289      for ( SynchronizeableList::iterator it2 = synchronizeables.begin(); it2 != synchronizeables.end(); it2++ )
    191290      {
    192         if ( handshakes[i]->ok() )
     291        (*it2)->cleanUpUser( it->second.userId );
     292      }
     293
     294      NetworkGameManager::getInstance()->signalLeftPlayer(it->second.userId);
     295
     296      freeSocketSlots.push_back( it->second.userId );
     297
     298    }
     299  }
     300
     301
     302}
     303
     304void NetworkStream::debug()
     305{
     306  if( this->isServer())
     307    PRINT(0)(" Host ist Server with ID: %i\n", this->myHostId);
     308  else
     309    PRINT(0)(" Host ist Client with ID: %i\n", this->myHostId);
     310
     311  PRINT(0)(" Got %i connected Synchronizeables, showing active Syncs:\n", this->synchronizeables.size());
     312  for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
     313  {
     314    if( (*it)->beSynchronized() == true)
     315      PRINT(0)("  Synchronizeable of class: %s::%s, with unique ID: %i, Synchronize: %i\n", (*it)->getClassName(), (*it)->getName(),
     316               (*it)->getUniqueID(), (*it)->beSynchronized());
     317  }
     318  PRINT(0)(" Maximal Connections: %i\n", MAX_CONNECTIONS );
     319
     320}
     321
     322
     323int NetworkStream::getSyncCount()
     324{
     325  int n = 0;
     326  for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
     327    if( (*it)->beSynchronized() == true)
     328      ++n;
     329
     330  //return synchronizeables.size();
     331  return n;
     332}
     333
     334/**
     335 * check if handshakes completed
     336 */
     337void NetworkStream::handleHandshakes( )
     338{
     339  for ( PeerList::iterator it = peers.begin(); it != peers.end(); it++ )
     340  {
     341    if ( it->second.handshake )
     342    {
     343      if ( it->second.handshake->completed() )
     344      {
     345        if ( it->second.handshake->ok() )
    193346        {
    194           if ( type != NET_SERVER )
    195           {
    196             SharedNetworkData::getInstance()->setHostID( handshakes[i]->getHostId() );
    197             myHostId = SharedNetworkData::getInstance()->getHostID();
    198 
    199             this->networkGameManager = NetworkGameManager::getInstance();
    200             this->networkGameManager->setUniqueID( handshakes[i]->getNetworkGameManagerId() );
    201             //this->connectSynchronizeable( *(this->networkGameManager) );
     347          if ( !it->second.handshake->allowDel() )
     348          {
     349            if ( type != NET_SERVER )
     350            {
     351              SharedNetworkData::getInstance()->setHostID( it->second.handshake->getHostId() );
     352              myHostId = SharedNetworkData::getInstance()->getHostID();
     353
     354              this->networkGameManager = NetworkGameManager::getInstance();
     355              this->networkGameManager->setUniqueID( it->second.handshake->getNetworkGameManagerId() );
     356              MessageManager::getInstance()->setUniqueID( it->second.handshake->getMessageManagerId() );
     357            }
     358             
     359
     360            PRINT(0)("handshake finished id=%d\n", it->second.handshake->getNetworkGameManagerId());
     361
     362            it->second.handshake->del();
    202363          }
    203364          else
    204365          {
    205 
    206           }
    207           PRINT(0)("handshake finished id=%d\n", handshakes[i]->getNetworkGameManagerId());
    208 
    209 
    210           delete handshakes[i];
    211           handshakes[i] = NULL;
     366            if ( it->second.handshake->canDel() )
     367            {
     368              if ( type == NET_SERVER )
     369              {
     370                handleNewClient( it->second.userId );
     371              }
     372             
     373              PRINT(0)("handshake finished delete it\n");
     374              delete it->second.handshake;
     375              it->second.handshake = NULL;
     376            }
     377          }
     378
    212379        }
    213380        else
    214381        {
    215382          PRINT(1)("handshake failed!\n");
    216           networkSockets[i]->disconnectServer();
    217           delete handshakes[i];
    218           handshakes[i] = NULL;
    219           //TODO: handle error
     383          it->second.socket->disconnectServer();
    220384        }
    221385      }
    222386    }
    223387  }
    224 
    225 
    226   /* DOWNSTREAM */
    227 
    228 
    229 
    230   int dataLength;
    231   int reciever;
    232   Header header;
    233   int counter;
    234 
    235   for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
    236   {
    237     counter = 0;
    238 
    239     if ( (*it)!=NULL && (*it)->beSynchronized() /*&& (*it)->getOwner() == myHostId*/ )
    240     {
    241       do {
    242         counter++;
    243 
    244         //check for endless loop
    245         if ( counter > 50 )
     388}
     389
     390/**
     391 * handle upstream network traffic
     392 */
     393void NetworkStream::handleUpstream( )
     394{
     395  int offset;
     396  int n;
     397 
     398  for ( PeerList::iterator peer = peers.begin(); peer != peers.end(); peer++ )
     399  {
     400    offset = INTSIZE; //make already space for length
     401   
     402    if ( !peer->second.socket )
     403      continue;
     404   
     405    n = Converter::intToByteArray( currentState, buf + offset, UDP_PACKET_SIZE - offset );
     406    assert( n == INTSIZE );
     407    offset += n;
     408   
     409    n = Converter::intToByteArray( peer->second.lastAckedState, buf + offset, UDP_PACKET_SIZE - offset );
     410    assert( n == INTSIZE );
     411    offset += n;
     412   
     413    n = Converter::intToByteArray( peer->second.lastRecvedState, buf + offset, UDP_PACKET_SIZE - offset );
     414    assert( n == INTSIZE );
     415    offset += n;
     416   
     417    for ( SynchronizeableList::iterator it = synchronizeables.begin(); it != synchronizeables.end(); it++ )
     418    {
     419      int oldOffset = offset;
     420      Synchronizeable & sync = **it;
     421     
     422      if ( !sync.beSynchronized() || sync.getUniqueID() < 0 )
     423        continue;
     424
     425      //if handshake not finished only sync handshake
     426      if ( peer->second.handshake && sync.getLeafClassID() != CL_HANDSHAKE )
     427        continue;
     428     
     429      if ( isServer() && sync.getLeafClassID() == CL_HANDSHAKE && sync.getUniqueID() != peer->second.userId )
     430        continue;
     431     
     432      //do not sync null parent
     433      if ( sync.getLeafClassID() == CL_NULL_PARENT )
     434        continue;
     435
     436      assert( offset + INTSIZE <= UDP_PACKET_SIZE );
     437     
     438      //server fakes uniqueid=0 for handshake
     439      if ( this->isServer() && sync.getUniqueID() < MAX_CONNECTIONS - 1 )
     440        n = Converter::intToByteArray( 0, buf + offset, UDP_PACKET_SIZE - offset );
     441      else
     442        n = Converter::intToByteArray( sync.getUniqueID(), buf + offset, UDP_PACKET_SIZE - offset );
     443      assert( n == INTSIZE );
     444      offset += n;
     445     
     446      //make space for size
     447      offset += INTSIZE;
     448
     449      n = sync.getStateDiff( peer->second.userId, buf + offset, UDP_PACKET_SIZE-offset, currentState, peer->second.lastAckedState, -1000 );
     450      offset += n;
     451      //NETPRINTF(0)("GGGGGEEEEETTTTT: %s (%d) %d\n",sync.getClassName(), sync.getUniqueID(), n);
     452     
     453      assert( Converter::intToByteArray( n, buf + offset - n - INTSIZE, INTSIZE ) == INTSIZE );
     454     
     455      //check if all bytes == 0 -> remove data
     456      //TODO not all synchronizeables like this maybe add Synchronizeable::canRemoveZeroDiff()
     457      bool allZero = true;
     458      for ( int i = 0; i < n; i++ )
     459      {
     460         if ( buf[i+oldOffset+2*INTSIZE] != 0 )
     461           allZero = false;
     462      }
     463
     464      if ( allZero )
     465      {
     466        //NETPRINTF(n)("REMOVE ZERO DIFF: %s (%d)\n", sync.getClassName(), sync.getUniqueID());
     467        offset = oldOffset;
     468      }
     469
     470     
     471    }
     472   
     473    for ( SynchronizeableList::iterator it = synchronizeables.begin(); it != synchronizeables.end(); it++ )
     474    {
     475      Synchronizeable & sync = **it;
     476     
     477      if ( !sync.beSynchronized() || sync.getUniqueID() < 0 )
     478        continue;
     479     
     480      sync.handleSentState( peer->second.userId, currentState, peer->second.lastAckedState );
     481    }
     482   
     483    assert( Converter::intToByteArray( offset, buf, INTSIZE ) == INTSIZE );
     484   
     485    int compLength = Zip::getInstance()->zip( buf, offset, compBuf, UDP_PACKET_SIZE );
     486   
     487    if ( compLength < 0 )
     488    {
     489      PRINTF(1)("compression failed!\n");
     490      continue;
     491    }
     492   
     493    assert( peer->second.socket->writePacket( compBuf, compLength ) );
     494   
     495    if ( this->remainingBytesToWriteToDict > 0 )
     496      writeToNewDict( buf, offset );
     497   
     498    peer->second.connectionMonitor->processUnzippedOutgoingPacket( buf, offset, currentState );
     499    peer->second.connectionMonitor->processZippedOutgoingPacket( compBuf, compLength, currentState );
     500   
     501    //NETPRINTF(n)("send packet: %d userId = %d\n", offset, peer->second.userId);
     502  }
     503}
     504
     505/**
     506 * handle downstream network traffic
     507 */
     508void NetworkStream::handleDownstream( )
     509{
     510  int offset = 0;
     511 
     512  int length = 0;
     513  int packetLength = 0;
     514  int compLength = 0;
     515  int uniqueId = 0;
     516  int state = 0;
     517  int ackedState = 0;
     518  int fromState = 0;
     519  int syncDataLength = 0;
     520 
     521  for ( PeerList::iterator peer = peers.begin(); peer != peers.end(); peer++ )
     522  {
     523   
     524    if ( !peer->second.socket )
     525      continue;
     526
     527    while ( 0 < (compLength = peer->second.socket->readPacket( compBuf, UDP_PACKET_SIZE )) )
     528    {
     529      //TODO tell monitor about zipped packet. because dropped packets dont count to bandwidth
     530      //PRINTF(0)("GGGGGOOOOOOOOOOTTTTTTTT: %d\n", compLength);
     531      packetLength = Zip::getInstance()->unZip( compBuf, compLength, buf, UDP_PACKET_SIZE );
     532     
     533      if ( packetLength < 4*INTSIZE )
     534      {
     535        if ( packetLength != 0 )
     536          PRINTF(1)("got too small packet: %d\n", packetLength);
     537        continue;
     538      }
     539     
     540      if ( this->remainingBytesToWriteToDict > 0 )
     541        writeToNewDict( buf, packetLength );
     542   
     543      assert( Converter::byteArrayToInt( buf, &length ) == INTSIZE );
     544      assert( Converter::byteArrayToInt( buf + INTSIZE, &state ) == INTSIZE );
     545      assert( Converter::byteArrayToInt( buf + 2*INTSIZE, &fromState ) == INTSIZE );
     546      assert( Converter::byteArrayToInt( buf + 3*INTSIZE, &ackedState ) == INTSIZE );
     547      //NETPRINTF(n)("ackedstate: %d\n", ackedState);
     548      offset = 4*INTSIZE;
     549
     550      //NETPRINTF(n)("got packet: %d, %d\n", length, packetLength);
     551   
     552    //if this is an old state drop it
     553      if ( state <= peer->second.lastRecvedState )
     554        continue;
     555   
     556      if ( packetLength != length )
     557      {
     558        PRINTF(1)("real packet length (%d) and transmitted packet length (%d) do not match!\n", packetLength, length);
     559        peer->second.socket->disconnectServer();
     560        continue;
     561      }
     562     
     563      while ( offset + 2*INTSIZE < length )
     564      {
     565        assert( offset > 0 );
     566        assert( Converter::byteArrayToInt( buf + offset, &uniqueId ) == INTSIZE );
     567        offset += INTSIZE;
     568     
     569        assert( Converter::byteArrayToInt( buf + offset, &syncDataLength ) == INTSIZE );
     570        offset += INTSIZE;
     571       
     572        assert( syncDataLength > 0 );
     573        assert( syncDataLength < 10000 );
     574     
     575        Synchronizeable * sync = NULL;
     576       
     577        for ( SynchronizeableList::iterator it = synchronizeables.begin(); it != synchronizeables.end(); it++ )
     578        {
     579        //                                        client thinks his handshake has id 0!!!!!
     580          if ( (*it)->getUniqueID() == uniqueId || ( uniqueId == 0 && (*it)->getUniqueID() == peer->second.userId ) )
     581          {
     582            sync = *it;
     583            break;
     584          }
     585        }
     586       
     587        if ( sync == NULL )
    246588        {
    247           PRINTF(1)("there seems to be an error in readBytes of %s\n", (*it)->getClassName());
    248           assert(false);
     589          PRINTF(0)("could not find sync with id %d. try to create it\n", uniqueId);
     590          if ( oldSynchronizeables.find( uniqueId ) != oldSynchronizeables.end() )
     591          {
     592            offset += syncDataLength;
     593            continue;
     594          }
     595         
     596          if ( !peers[peer->second.userId].isServer )
     597          {
     598            offset += syncDataLength;
     599            continue;
     600          }
     601         
     602          int leafClassId;
     603          if ( INTSIZE > length - offset )
     604          {
     605            offset += syncDataLength;
     606            continue;
     607          }
     608
     609          Converter::byteArrayToInt( buf + offset, &leafClassId );
     610         
     611          assert( leafClassId != 0 );
     612       
     613          BaseObject * b = NULL;
     614          /* These are some small exeptions in creation: Not all objects can/should be created via Factory */
     615          /* Exception 1: NullParent */
     616          if( leafClassId == CL_NULL_PARENT || leafClassId == CL_SYNCHRONIZEABLE || leafClassId == CL_NETWORK_GAME_MANAGER )
     617          {
     618            PRINTF(1)("Can not create Class with ID %x!\n", (int)leafClassId);
     619            offset += syncDataLength;
     620            continue;
     621          }
     622          else
     623            b = Factory::fabricate( (ClassID)leafClassId );
     624
     625          if ( !b )
     626          {
     627            PRINTF(1)("Could not fabricate Object with classID %x\n", leafClassId);
     628            offset += syncDataLength;
     629            continue;
     630          }
     631
     632          if ( b->isA(CL_SYNCHRONIZEABLE) )
     633          {
     634            sync = dynamic_cast<Synchronizeable*>(b);
     635            sync->setUniqueID( uniqueId );
     636            sync->setSynchronized(true);
     637 
     638            PRINTF(0)("Fabricated %s with id %d\n", sync->getClassName(), sync->getUniqueID());
     639          }
     640          else
     641          {
     642            PRINTF(1)("Class with ID %x is not a synchronizeable!\n", (int)leafClassId);
     643            delete b;
     644            offset += syncDataLength;
     645            continue;
     646          }
    249647        }
    250648
    251         reciever = 0;
    252         dataLength = (*it)->readBytes(downBuffer, DATA_STREAM_BUFFER_SIZE, &reciever);
    253 
    254         if ( dataLength<=0 ){
    255           reciever = 0;
     649        int n = sync->setStateDiff( peer->second.userId, buf+offset, syncDataLength, state, fromState );
     650        offset += n;
     651        //NETPRINTF(0)("SSSSSEEEEETTTTT: %s %d\n",sync->getClassName(), n);
     652
     653      }
     654     
     655      if ( offset != length )
     656      {
     657        PRINTF(0)("offset (%d) != length (%d)\n", offset, length);
     658        peer->second.socket->disconnectServer();
     659      }
     660     
     661      //TODO REMOVE THIS
     662      int saveOffset = offset;
     663     
     664      for ( SynchronizeableList::iterator it = synchronizeables.begin(); it != synchronizeables.end(); it++ )
     665      {
     666        Synchronizeable & sync = **it;
     667     
     668        if ( !sync.beSynchronized() || sync.getUniqueID() < 0 )
    256669          continue;
    257         }
    258 
    259         dataLength = networkProtocol->createHeader((byte*)downBuffer, dataLength, DATA_STREAM_BUFFER_SIZE, static_cast<const Synchronizeable&>(*(*it)));
    260 
    261         Header* header = (Header*)downBuffer;
    262         if ( header->synchronizeableID < this->maxConnections+2 )
    263         {
    264           //if ( !isServer() ) PRINTF(0)("RESET UNIQUEID FROM %d TO 0 maxCon=%d\n", header->synchronizeableID, this->maxConnections);
    265           header->synchronizeableID = 0;
    266         }
    267         else
    268         {
    269           //if ( !isServer() ) PRINTF(0)("UNIQUEID=%d\n", header->synchronizeableID);
    270         }
    271 
    272         if ( dataLength<=0 )
    273           continue;
    274 
    275         if ( reciever!=0 )
    276         {
    277           if ( reciever < 0)
    278           {
    279             for ( int i = 0; i<networkSockets.size(); i++)
    280             {
    281               if ( i!=abs(reciever) && networkSockets[i] != NULL )
    282               {
    283                 PRINTF(0)("write %d bytes to socket %d uniqueid %d reciever %d\n", dataLength, i, (*it)->getUniqueID(), reciever);
    284                 networkSockets[i]->writePacket(downBuffer, dataLength);
    285               }
    286             }
    287           }
    288           else
    289           {
    290             if ( networkSockets[reciever] != NULL )
    291             {
    292               PRINTF(5)("write %d bytes to socket %d\n", dataLength, reciever);
    293               networkSockets[reciever]->writePacket(downBuffer, dataLength);
    294             }
    295             else
    296             {
    297               PRINTF(1)("networkSockets[reciever] == NULL\n");
    298             }
    299           }
    300         }
    301         else
    302         {
    303           for ( int i = 0; i<networkSockets.size(); i++)
    304           {
    305             if ( networkSockets[i] != NULL )
    306             {
    307               PRINTF(5)("write %d bytes to socket %d\n", dataLength, i);
    308               networkSockets[i]->writePacket(downBuffer, dataLength);
    309             }
    310           }
    311         }
    312 
    313       } while( reciever!=0 );
    314     }
    315   }
    316 
    317   /* UPSTREAM */
    318 
    319   for ( int i = 0; i<networkSockets.size(); i++)
    320   {
    321     if ( networkSockets[i] )
    322     {
    323       do {
    324         dataLength = networkSockets[i]->readPacket(upBuffer, DATA_STREAM_BUFFER_SIZE);
    325 
    326         if ( dataLength<=0 )
    327           continue;
    328 
    329         header = networkProtocol->extractHeader(upBuffer, dataLength);
    330         dataLength -= sizeof(header);
    331 
    332         PRINTF(5)("read %d bytes from socket uniqueID = %d\n", dataLength, header.synchronizeableID);
    333 
    334         if ( dataLength != header.length )
    335         {
    336           PRINTF(1)("packetsize in header and real packetsize do not match! %d:%d\n", dataLength, header.length);
    337           continue;
    338         }
    339 
    340         if ( header.synchronizeableID == 0 )
    341         {
    342           header.synchronizeableID = i;
    343         }
    344 
    345         for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
    346         {
    347           if ( *it && (*it)->getUniqueID()==header.synchronizeableID )
    348           {
    349             if ( (*it)->writeBytes(upBuffer+sizeof(header), dataLength, i) != header.length )
    350             {
    351               PRINTF(1)("%s did not read all the data id = %d!\n", (*it)->getClassName(), (*it)->getUniqueID());
    352               break;
    353             }
    354             continue;
    355           }
    356         }
    357 
    358       } while ( dataLength>0 );
    359     }
    360   }
    361 }
    362 
    363 void NetworkStream::updateConnectionList( )
    364 {
    365   //check for new connections
    366 
    367   NetworkSocket* tempNetworkSocket = serverSocket->getNewSocket();
    368 
    369   if ( tempNetworkSocket )
    370   {
    371     int clientId;
    372     if ( freeSocketSlots.size() >0 )
    373     {
    374       clientId = freeSocketSlots.back();
    375       freeSocketSlots.pop_back();
    376       networkSockets[clientId] = tempNetworkSocket;
    377       handshakes[clientId] = new Handshake(true, clientId, this->networkGameManager->getUniqueID());
    378       handshakes[clientId]->setUniqueID(clientId);
    379     } else
    380     {
    381       clientId = networkSockets.size();
    382       networkSockets.push_back(tempNetworkSocket);
    383       Handshake* tHs = new Handshake(true, clientId, this->networkGameManager->getUniqueID());
    384       tHs->setUniqueID(clientId);
    385       handshakes.push_back(tHs);
    386     }
    387 
    388     if ( clientId > this->maxConnections )
    389     {
    390       handshakes[clientId]->doReject();
    391       PRINTF(0)("Will reject client %d because there are to many connections!\n", clientId);
    392     }
    393     else
    394 
    395     PRINTF(0)("New Client: %d\n", clientId);
    396 
    397     //this->connectSynchronizeable(*handshakes[clientId]);
    398   }
    399 
    400 
    401   //check if connections are ok else remove them
    402   for ( int i = 1; i<networkSockets.size(); i++)
    403   {
    404     if ( networkSockets[i] && !networkSockets[i]->isOk() )
    405     {
    406       //TODO: tell EntityManager that this player left the game
    407       PRINTF(0)("Client is gone: %d\n", i);
    408 
    409       //delete networkSockets[i];
    410       networkSockets[i]->disconnectServer();
    411       networkSockets[i]->destroy();
    412       networkSockets[i] = NULL;
    413 
    414       if ( handshakes[i] )
    415         delete handshakes[i];
    416       handshakes[i] = NULL;
    417 
    418 
    419       NetworkGameManager::getInstance()->signalLeftPlayer(i);
    420 
    421       if ( i == networkSockets.size()-1 )
    422       {
    423         networkSockets.pop_back();
    424         handshakes.pop_back();
     670     
     671        sync.handleRecvState( peer->second.userId, state, fromState );
    425672      }
    426       else
    427       {
    428         freeSocketSlots.push_back(i);
    429       }
    430     }
    431   }
    432 
    433 
    434 }
    435 
    436 void NetworkStream::setMaxConnections( int n )
    437 {
    438   if ( !this->isServer() )
    439   {
    440     PRINTF(1)("Cannot set maxConnections because I am no server.\n");
    441   }
    442   if ( this->networkSockets.size() > 1 )
    443   {
    444     PRINTF(1)("Cannot set maxConnections because there are already %d connections.\n", this->networkSockets.size());
     673     
     674      peer->second.connectionMonitor->processZippedIncomingPacket( compBuf, compLength, state, ackedState );
     675      peer->second.connectionMonitor->processUnzippedIncomingPacket( buf, offset, state, ackedState );
     676   
     677      assert( peer->second.lastAckedState <= ackedState );
     678      peer->second.lastAckedState = ackedState;
     679     
     680      assert( peer->second.lastRecvedState < state );
     681      peer->second.lastRecvedState = state;
     682     
     683      assert( saveOffset == offset );
     684     
     685    }
     686 
     687  }
     688 
     689}
     690
     691/**
     692 * is executed when a handshake has finished
     693 * @todo create playable for new user
     694 */
     695void NetworkStream::handleNewClient( int userId )
     696{
     697  MessageManager::getInstance()->initUser( userId );
     698 
     699  networkGameManager->signalNewPlayer( userId );
     700}
     701
     702/**
     703 * removes old items from oldSynchronizeables
     704 */
     705void NetworkStream::cleanUpOldSyncList( )
     706{
     707  int now = SDL_GetTicks();
     708 
     709  for ( std::map<int,int>::iterator it = oldSynchronizeables.begin(); it != oldSynchronizeables.end();  )
     710  {
     711    if ( it->second < now - 10*1000 )
     712    {
     713      std::map<int,int>::iterator delIt = it;
     714      it++;
     715      oldSynchronizeables.erase( delIt );
     716      continue;
     717    }
     718    it++;
     719  }
     720}
     721
     722/**
     723 * writes data to DATA/dicts/newdict
     724 * @param data pointer to data
     725 * @param length length
     726 */
     727void NetworkStream::writeToNewDict( byte * data, int length )
     728{
     729  if ( remainingBytesToWriteToDict <= 0 )
    445730    return;
    446   }
    447 
    448   if ( n > MAX_CONNECTIONS )
    449   {
    450     PRINTF(1)("Cannot set maxConnectiosn to %d because of hardcoded limit %d\n", n, MAX_CONNECTIONS);
     731 
     732  if ( length > remainingBytesToWriteToDict )
     733    length = remainingBytesToWriteToDict;
     734 
     735  std::string fileName = ResourceManager::getInstance()->getDataDir();
     736  fileName += "/dicts/newdict";
     737 
     738  FILE * f = fopen( fileName.c_str(), "a" );
     739 
     740  if ( !f )
     741  {
     742    PRINTF(2)("could not open %s\n", fileName.c_str());
     743    remainingBytesToWriteToDict = 0;
    451744    return;
    452745  }
    453 
    454   this->maxConnections = n;
    455   this->networkGameManager->setUniqueID( n+2 );
    456 }
    457 
    458 
    459 
    460 void NetworkStream::debug()
    461 {
    462   if( this->isServer())
    463     PRINT(0)(" Host ist Server with ID: %i\n", this->myHostId);
    464   else
    465     PRINT(0)(" Host ist Client with ID: %i\n", this->myHostId);
    466 
    467   PRINT(0)(" Got %i connected Synchronizeables, showing active Syncs:\n", this->synchronizeables.size());
    468   for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
    469   {
    470     if( (*it)->beSynchronized() == true)
    471       PRINT(0)("  Synchronizeable of class: %s::%s, with unique ID: %i, Synchronize: %i\n", (*it)->getClassName(), (*it)->getName(),
    472                (*it)->getUniqueID(), (*it)->beSynchronized());
    473   }
    474   PRINT(0)(" Maximal Connections: %i\n", this->maxConnections);
    475 
    476 }
    477 
    478 
    479 int NetworkStream::getSyncCount()
    480 {
    481   int n = 0;
    482   for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
    483     if( (*it)->beSynchronized() == true)
    484       ++n;
    485 
    486   //return synchronizeables.size();
    487   return n;
    488 }
    489 
    490 
    491 
    492 
    493 
    494 
     746 
     747  if ( fwrite( data, 1, length, f ) != length )
     748  {
     749    PRINTF(2)("could not write to file\n");
     750    fclose( f );
     751    return;
     752  }
     753 
     754  fclose( f );
     755 
     756  remainingBytesToWriteToDict -= length; 
     757}
     758
     759
     760
     761
     762
     763
  • trunk/src/lib/network/network_stream.h

    r6981 r7954  
    99#include <vector>
    1010#include <list>
     11#include <map>
    1112
    1213#include "data_stream.h"
    13 #include "network_protocol.h"
    1414#include "server_socket.h"
    1515#include "handshake.h"
     16#include "connection_monitor.h"
     17#include "udp_server_socket.h"
    1618
    1719class Synchronizeable;
    1820class NetworkSocket;
    1921class ServerSocket;
    20 class ConnectionMonitor;
    21 class NetworkProtocol;
    2222class NetworkGameManager;
    2323
     24class PeerInfo
     25{
     26  public:
     27    PeerInfo() { clear(); }
     28    void clear() { userId = 0; isServer = false; socket = NULL; handshake = NULL; lastAckedState = 0; lastRecvedState = 0; connectionMonitor = NULL; }
     29    int                 userId;
     30    bool                isServer;
     31    NetworkSocket *     socket;
     32    Handshake *         handshake;
     33    ConnectionMonitor * connectionMonitor;
     34    int                 lastAckedState;
     35    int                 lastRecvedState;
     36};
     37
    2438typedef std::list<Synchronizeable*>  SynchronizeableList;
    25 typedef std::vector<NetworkSocket*>  NetworkSocketVector;
    26 typedef std::vector<Handshake*>      HandshakeVector;
     39typedef std::map<int,PeerInfo>       PeerList;
    2740
    2841
     
    3245  public:
    3346    NetworkStream();
    34     NetworkStream(IPaddress& address);
    35     NetworkStream(unsigned int port);
     47    NetworkStream( std::string host, int port);
     48    NetworkStream( int port );
    3649
    3750    virtual ~NetworkStream();
     
    4760    inline bool isActive() const { return this->bActive; }
    4861
    49     inline int getMaxConnections(){ return maxConnections; }
    50     void setMaxConnections( int n );
     62    inline int getMaxConnections(){ return MAX_CONNECTIONS; }
    5163
    5264    virtual void processData();
     
    5668    int getSyncCount();
    5769
    58     inline bool isUserIdActive( int userID ) { if (userID>=networkSockets.size()) return false; else return networkSockets[userID]!=NULL; }
     70    inline bool isUserIdActive( int userID ) { return (peers.find(userID) != peers.end()); }
     71    inline bool isUserServer( int userID ){ if ( !isUserIdActive(userID) ) return false; return peers[userID].isServer; }
    5972
    6073    void debug();
     74   
     75    inline PeerInfo & getPeerInfo( int userId ) { return peers[userId]; }
    6176
    6277
    6378  private:
    6479    void updateConnectionList();
     80    void handleHandshakes();
     81    void handleUpstream();
     82    void handleDownstream();
     83    void handleNewClient( int userId );
     84    void cleanUpOldSyncList();
     85   
     86    void writeToNewDict( byte * data, int length );
    6587
    6688
    6789  private:
    68     NetworkProtocol*           networkProtocol;
    69     ConnectionMonitor*         connectionMonitor;
    7090    SynchronizeableList        synchronizeables;
    71     NetworkSocketVector        networkSockets;
    72     HandshakeVector            handshakes;
     91    PeerList                   peers;
    7392    ServerSocket*              serverSocket;
    7493    int                        type;
    75     Header                     packetHeader;
    7694    bool                       bActive;
    7795    std::list<int>             freeSocketSlots;
    7896
    7997    int                        myHostId;
    80     int                        maxConnections;
     98   
     99    int                        currentState;                //!< current state id
    81100
    82101    NetworkGameManager*        networkGameManager;
     102
     103    std::map<int,int>          oldSynchronizeables;         //!< used to save recently deleted sync ids to not recreate them
     104   
     105    byte                       buf[UDP_PACKET_SIZE];        //!< used by handleUp/Downstream
     106    byte                       compBuf[UDP_PACKET_SIZE];    //!< used by handleUp/Downstream
     107
     108    int                        remainingBytesToWriteToDict; //!< if > 0 NetworkStream will write packets to DATA/dicts/newdict
    83109};
    84110#endif /* _NETWORK_STREAM */
  • trunk/src/lib/network/server_socket.cc

    r6139 r7954  
    2626#include "debug.h"
    2727
    28 ServerSocket::ServerSocket(  )
     28
     29/**
     30 * constructor
     31 * @param port port to assign to socket
     32 */
     33ServerSocket::ServerSocket( int port )
    2934{
    30   init();
     35  bOk = true;
    3136}
    3237
    33 ServerSocket::ServerSocket( unsigned int port )
     38ServerSocket::~ ServerSocket( )
    3439{
    35   init();
    36   listen(port);
    3740}
    38 
    39 /**
    40  * Default destructor
    41  */
    42 ServerSocket::~ServerSocket( )
    43 {
    44   /* Quit SDL_net */
    45   // NOTE: what if other instances of NetworkSocket running?
    46   SDLNet_Quit();
    47   PRINTF(5)("SDL_net shutdown\n");
    48 
    49   _isListening = false;
    50 }
    51 
    52 void ServerSocket::init( )
    53 {
    54   /* set the class id for the base object */
    55   this->setClassID(CL_SERVER_SOCKET, "ServerSocket");
    56 
    57   terminateThread = false;
    58   listenSocket = NULL;
    59   _isListening = false;
    60 
    61   if(SDLNet_Init()==-1)
    62   {
    63     PRINTF(1)("SDLNet_Init: %s\n", SDLNet_GetError());
    64     return;
    65   }
    66   else
    67     PRINTF(5)("SDL_net initialized\n");
    68 
    69   PRINTF(0)("ServerSocket created\n");
    70 }
    71 
    72 
    73 /**
    74  * Tells the NetworkSocket to listen on a specific port for incoming connections.
    75  * NetworkSocket::writeBytes(...) will have no effect until there is a valuable connection.
    76  * @param port
    77  */
    78 bool ServerSocket::listen(unsigned int port)
    79 {
    80   PRINTF(0)("ServerSocket::listen()\n");
    81   _isListening = true;
    82   //check if not already connected or listening
    83   if (listenSocket)
    84   {
    85     PRINTF(1)("ServerSocket::listen: tcpSocket!=NULL! maybe you already called listen or did not call close()!\n");
    86     _isListening = false;
    87     return false;
    88   }
    89 
    90   IPaddress ip;
    91 
    92   if (SDLNet_ResolveHost(&ip, NULL, port)==-1)
    93   {
    94     PRINTF(1)("SDLNet_ResolveHost: %s\n", SDLNet_GetError());
    95     _isListening = false;
    96     return false;
    97   }
    98 
    99   listenSocket = SDLNet_TCP_Open(&ip);
    100 
    101   if (!listenSocket)
    102   {
    103     PRINTF(1)("SDLNet_TCP_Open: %s\n", SDLNet_GetError());
    104     _isListening = false;
    105     return false;
    106   }
    107 
    108   return true;
    109 }
    110 
    111 
    112 NetworkSocket* ServerSocket::getNewSocket( )
    113 {
    114   if ( !listenSocket )
    115   {
    116     PRINTF(1)("listenSocket == NULL! Maybe you forgot to call listen()\n");
    117     close();
    118     return NULL;
    119   }
    120 
    121   TCPsocket sock = SDLNet_TCP_Accept(listenSocket);
    122 
    123   if ( !sock )
    124   {
    125     return NULL;
    126   }
    127   else
    128   {
    129     return new NetworkSocket(sock);
    130   }
    131 }
    132 
    133 void ServerSocket::close( )
    134 {
    135   if ( listenSocket )
    136   {
    137     SDLNet_TCP_Close( listenSocket );
    138     listenSocket = NULL;
    139   }
    140 
    141   _isListening = false;
    142 }
    143 
  • trunk/src/lib/network/server_socket.h

    r6981 r7954  
    88#define _SERVER_SOCKET
    99
    10 #ifdef HAVE_SDL_H
    11 #include <SDL_thread.h>
    12 #else
    13 #include <SDL/SDL_thread.h>
    14 #endif
    1510/* include this file, it contains some default definitions */
    1611#include "netdefs.h"
     
    2116#include "network_socket.h"
    2217
    23 //sleep when waiting for connections
    24 #define _MSECONDS_SLEEP_LISTEN 100
    2518
    2619class ServerSocket : public BaseObject
    2720{
    28   private:
    29     TCPsocket listenSocket;
    30     bool terminateThread;
     21  public:
     22    ServerSocket( int port);
    3123
    32     bool _isListening;
     24    virtual ~ServerSocket();
    3325
    34     void init();
     26    virtual bool listen( unsigned int port ) = 0;
     27    virtual NetworkSocket* getNewSocket( void ) = 0;
     28    virtual void close() = 0;
     29    virtual void update() = 0;
     30    virtual bool isOk() { return this->bOk; };
    3531
    36   public:
    37     ServerSocket();
    38     ServerSocket( unsigned int port );
    39     virtual ~ServerSocket();
    40     bool listen( unsigned int port );
    41     NetworkSocket* getNewSocket( void );
    42     void close();
    43     inline bool isOk(){ return listenSocket!=NULL; }
     32  protected:
     33    bool bOk;
     34
    4435};
    4536
  • trunk/src/lib/network/synchronizeable.cc

    r6753 r7954  
    2020#include "network_stream.h"
    2121#include "netdefs.h"
     22#include "network_log.h"
    2223
    2324#include "state.h"
     
    3637  this->setClassID(CL_SYNCHRONIZEABLE, "Synchronizeable");
    3738  this->owner = -1;
    38   this->state = 0;
    3939  this->hostID = SharedNetworkData::getInstance()->getHostID();
    4040  this->setIsServer(this->hostID == 0);
    4141  this->uniqueID = NET_UID_UNASSIGNED;
    4242  this->networkStream = NULL;
    43   this->setRequestedSync( false );
    44   this->setIsOutOfSync( !(this->isServer()) );
    4543  this->bSynchronize = false;
    46 
     44 
    4745  if( State::isOnline())
    4846  {
     
    5250    this->setUniqueID(SharedNetworkData::getInstance()->getNewUniqueID());
    5351  }
     52
     53  /* make sure loadClassId is first synced var because this is read by networkStream */
     54  assert( syncVarList.size() == 0 );
     55  mLeafClassId = this->registerVarId( new SynchronizeableInt( (int*)&this->getLeafClassID(), (int*)&this->getLeafClassID(), "leafClassId" ) );
     56   
     57  this->registerVar( new SynchronizeableInt( &this->owner, &this->owner, "owner" ) );
     58  this->registerVar( new SynchronizeableString( &this->objectName, &this->objectName, "objectName" ) );
    5459}
    5560
     
    6469    this->networkStream->disconnectSynchronizeable(*this);
    6570}
    66 
    67 
    68 /**
    69  *  write data to NetworkStream
    70  */
    71 int Synchronizeable::writeBytes(const byte* data, int length, int sender)
    72 {
    73   PRINTF(5)("Synchronizeable::writeBytes was called\n");
    74 }
    75 
    76 
    77 /**
    78  *  read data from NetworkStream
    79  */
    80 int Synchronizeable::readBytes(byte* data, int maxLength, int * reciever)
    81 {
    82   PRINTF(5)("Synchronizeable::readBytes was called\n");
    83 }
    84 
    85 
    86 void Synchronizeable::writeDebug() const
    87 {}
    88 
    89 
    90 void Synchronizeable::readDebug() const
    91 {}
    92 
    9371
    9472/**
     
    10684
    10785/**
    108  * Sets the outofsync flag to a given value
    109  * @param outOfSync: the boolean value which the outofsync flag is to set to
    110  */
    111 void Synchronizeable::setIsOutOfSync(bool outOfSync)
    112 {
    113   if( outOfSync )
    114     this->state = this->state | STATE_OUTOFSYNC;
    115   else
    116     this->state = this->state & (~STATE_OUTOFSYNC);
    117   //PRINTF(0)("isoutofsync %s %d\n", this->getClassName(), state);
    118 }
    119 
    120 
    121 /**
    12286 * Determines if the server flag is set
    12387 * @return true, if the server flag is true, false else
     
    12993
    13094
    131 /**
    132  * Determines if the outofsync flag is set
    133  * @return true, if the outofsync flag is true, false else
    134  */
    135 bool Synchronizeable::isOutOfSync()
    136 {
    137   return (this->state & STATE_OUTOFSYNC) >0;
    138 }
    139 
    140 
    141 /**
    142  * Determines if the requestedSync flag is set
    143  * @return true, if the requestedSync flag is true, false else
    144  */
    145 bool Synchronizeable::requestedSync()
    146 {
    147   return (this->state & STATE_REQUESTEDSYNC) >0;
    148 }
    149 
    150 
    151 /**
    152  * Sets the requestedsync flag to a given value
    153  * @param requestedSync: the boolean value which the requestedsync flag is to set to
    154  */
    155 void Synchronizeable::setRequestedSync( bool requestedSync )
    156 {
    157   if( requestedSync )
    158     this->state = this->state | STATE_REQUESTEDSYNC;
     95
     96int Synchronizeable::getStateDiff( int userId, byte* data, int maxLength, int stateId, int fromStateId, int priorityTH )
     97{
     98  //make sure this user has his history
     99  if ( sentStates.size() <= userId )
     100    sentStates.resize( userId+1 );
     101
     102  //calculate needed memory
     103  int neededSize = 0;
     104
     105  for ( SyncVarList::iterator it = syncVarList.begin(); it != syncVarList.end(); it++ )
     106    neededSize += (*it)->getSize();
     107
     108  if ( !( neededSize <= maxLength ) )
     109  {
     110    PRINTF(0)( "%d > %d\n", neededSize, maxLength );
     111    assert(false);
     112  }
     113
     114  //remove older states from history than fromStateId
     115  StateHistory::iterator it = sentStates[userId].begin();
     116
     117  while ( it != sentStates[userId].end() && (*it)->stateId < fromStateId )
     118    it++;
     119
     120  if ( it != sentStates[userId].begin() )
     121  {
     122    for ( StateHistory::iterator it2 = sentStates[userId].begin(); it2 != it; it2++ )
     123    {
     124      if ( (*it2)->data != NULL )
     125      {
     126        delete [] (*it2)->data;
     127        (*it2)->data = NULL;
     128      }
     129    }
     130    sentStates[userId].erase( sentStates[userId].begin(), it );
     131  }
     132
     133  //find state to create diff from
     134  StateHistoryEntry * stateFrom = NULL;
     135
     136  it = sentStates[userId].begin();
     137  while ( it != sentStates[userId].end() && (*it)->stateId != fromStateId )
     138    it++;
     139 
     140//  if ( getLeafClassID() == CL_SPACE_SHIP )
     141//  {
     142//    PRINTF(0)("getStateDiff:SpaceShip from: %d stateId: %d\n", (it == sentStates[userId].end())?-1:fromStateId, stateId);
     143//  }
     144
     145  if ( it == sentStates[userId].end() )
     146  {
     147    StateHistoryEntry * initialEntry = new StateHistoryEntry();
     148
     149    initialEntry->stateId = fromStateId;
     150    initialEntry->dataLength = 0;
     151    initialEntry->data = NULL;
     152
     153    stateFrom = initialEntry;
     154  }
    159155  else
    160     this->state = this->state & (~STATE_REQUESTEDSYNC);
    161 }
    162 
    163 
    164 
     156    stateFrom = (*it);
     157
     158  StateHistoryEntry * stateTo = new StateHistoryEntry();
     159
     160  stateTo->stateId = stateId;
     161  stateTo->dataLength = neededSize;
     162  stateTo->data = new byte[ neededSize ];
     163
     164  std::list<int>::iterator sizeIter = stateFrom->sizeList.begin();
     165
     166  int i = 0;
     167  int n;
     168 
     169  bool hasPermission;
     170
     171  // now do the actual synchronization: kick all variables to write into a common buffer
     172  for ( SyncVarList::iterator it = syncVarList.begin(); it != syncVarList.end(); it++ )
     173  {
     174    hasPermission = (
     175            this->isServer() && (*it)->checkPermission( PERMISSION_SERVER ) ||
     176            this->owner == this->hostID && (*it)->checkPermission( PERMISSION_OWNER ) ||
     177            (*it)->checkPermission( PERMISSION_ALL )
     178                    );
     179   
     180    if ( ( hasPermission && (*it)->getPriority() >= priorityTH ) || sizeIter == stateFrom->sizeList.end() )
     181    {
     182      n = (*it)->writeToBuf( stateTo->data+i, stateTo->dataLength - i );
     183      //NETPRINTF(0)("getvar %s %d\n", (*it)->getName().c_str(), n);
     184      stateTo->sizeList.push_back( n );
     185      //(*it)->debug();
     186      i += n;
     187    }
     188    else
     189    {
     190      for ( int j = 0; j<(*sizeIter); j++ )
     191      {
     192        assert( i < stateFrom->dataLength );
     193        stateTo->data[i] = stateFrom->data[i];
     194        i++;
     195      }
     196      //NETPRINTF(0)("getvar %s %d\n", (*it)->getName().c_str(), *sizeIter);
     197      stateTo->sizeList.push_back( (*sizeIter) );
     198    }
     199
     200    if ( sizeIter != stateFrom->sizeList.end() )
     201      sizeIter++;
     202  }
     203
     204  sentStates[userId].push_back( stateTo );
     205 
     206  assert( i == neededSize );
     207
     208  //write diff to data
     209  for ( i = 0; i<neededSize; i++ )
     210  {
     211    if ( i < stateFrom->dataLength )
     212      data[i] = stateTo->data[i] - stateFrom->data[i];
     213    else
     214      data[i] = stateTo->data[i];
     215  }
     216
     217  return neededSize;
     218}
     219
     220/**
     221 * sets a new state out of a diff created on another host
     222 * @param userId hostId of user who send me that diff
     223 * @param data pointer to diff
     224 * @param length length of diff
     225 * @param stateId id of current state
     226 * @param fromStateId id of the base state id
     227 * @return number bytes read
     228 * @todo check for permissions
     229 */
     230int Synchronizeable::setStateDiff( int userId, byte* data, int length, int stateId, int fromStateId )
     231{
     232  //make sure this user has his history
     233  if ( recvStates.size() <= userId )
     234    recvStates.resize( userId+1 );
     235
     236  //create new state
     237  StateHistoryEntry * stateTo = new StateHistoryEntry();
     238  stateTo->stateId = stateId;
     239  stateTo->dataLength = length;
     240  stateTo->data = new byte[ length ];
     241
     242
     243  //find state to apply diff to
     244  StateHistoryEntry * stateFrom = NULL;
     245
     246  StateHistory::iterator it = recvStates[userId].begin();
     247  while ( it != recvStates[userId].end() && (*it)->stateId != fromStateId )
     248    it++;
     249
     250 
     251//  if ( getLeafClassID() == CL_SPACE_SHIP )
     252//  {
     253//    PRINTF(0)("setStateDiff:SpaceShip from: %d stateId: %d\n", (it == recvStates[userId].end())?-1:fromStateId, stateId);
     254//  }
     255
     256  if ( it == recvStates[userId].end() )
     257  {
     258    StateHistoryEntry * initialEntry = new StateHistoryEntry();
     259
     260    initialEntry->stateId = fromStateId;
     261    initialEntry->dataLength = 0;
     262    initialEntry->data = NULL;
     263
     264    stateFrom = initialEntry;
     265  }
     266  else
     267    stateFrom = (*it);
     268 
     269  //apply diff
     270  for ( int i = 0; i<length; i++ )
     271  {
     272    if ( i < stateFrom->dataLength )
     273      stateTo->data[i] = stateFrom->data[i] + data[i];
     274    else
     275      stateTo->data[i] = data[i];
     276   
     277  }
     278 
     279  //add state to state history
     280  recvStates[userId].push_back( stateTo );
     281 
     282  int i = 0;
     283  int n = 0;
     284  std::list<int> changes;
     285 
     286  for ( SyncVarList::iterator it = syncVarList.begin(); it != syncVarList.end(); it++ )
     287  {
     288    if (
     289        (*it)->checkPermission( PERMISSION_SERVER ) && networkStream->isUserServer( userId ) ||
     290        (*it)->checkPermission( PERMISSION_OWNER ) && this->owner == userId ||
     291        (*it)->checkPermission( PERMISSION_ALL )
     292       )
     293    {
     294      n = (*it)->readFromBuf( stateTo->data + i, stateTo->dataLength - i );
     295      i += n;
     296      //NETPRINTF(0)("%s::setvar %s %d\n", getClassName(), (*it)->getName().c_str(), n);
     297      //(*it)->debug();
     298      if ( (*it)->getHasChanged() )
     299      {
     300        changes.push_back( (*it)->getVarId() );
     301      }
     302    }
     303    else
     304    {
     305//      PRINTF(0)("DONT SET VAR BECAUSE OF PERMISSION: %s %d %d %d %d %d %d\n", (*it)->getName().c_str(), (*it)->checkPermission( PERMISSION_SERVER ), (*it)->checkPermission( PERMISSION_OWNER ), (*it)->checkPermission( PERMISSION_ALL ), networkStream->isUserServer( userId ), this->owner, userId );
     306      n = (*it)->getSizeFromBuf( stateTo->data + i, stateTo->dataLength - i );
     307      //NETPRINTF(0)("%s::setvar %s %d\n", getClassName(), (*it)->getName().c_str(), n);
     308      //(*it)->debug();
     309      i += n;
     310    }
     311  }
     312
     313  this->varChangeHandler( changes );
     314 
     315  return i;
     316}
     317
     318 /**
     319 * override this function to be notified on change
     320 * of your registred variables.
     321 * @param id id's which have changed
     322 */
     323void Synchronizeable::varChangeHandler( std::list<int> & id )
     324{
     325}
     326
     327/**
     328 * registers a varable to be synchronized over network
     329 * @param var see src/lib/network/synchronizeable_var/ for available classes
     330 */
     331void Synchronizeable::registerVar( SynchronizeableVar * var )
     332{
     333  PRINTF(0)("ADDING VAR: %s\n", var->getName().c_str());
     334  syncVarList.push_back( var );
     335}
     336
     337/**
     338 * registers a varable to be synchronized over network
     339 * return value is passed to varChangeHandler on change
     340 * @param var see src/lib/network/synchronizeable_var/ for available classes
     341 * @return handle passed to varChangeHandler on changes
     342 */
     343int Synchronizeable::registerVarId( SynchronizeableVar * var )
     344{
     345  PRINTF(0)("ADDING VAR: %s\n", var->getName().c_str());
     346  syncVarList.push_back( var );
     347  var->setWatched( true );
     348  var->setVarId( syncVarList.size()-1 );
     349  return syncVarList.size()-1;
     350}
     351
     352/**
     353 * removed user's states from memory
     354 * @param userId user to clean
     355 */
     356void Synchronizeable::cleanUpUser( int userId )
     357{
     358  for ( UserStateHistory::iterator it = sentStates.begin(); it != sentStates.end(); it++ )
     359  {
     360    for ( StateHistory::iterator it2 = it->begin(); it2 != it->end(); it2++ )
     361    {
     362      if ( (*it2)->data )
     363        delete [] (*it2)->data;
     364      (*it2)->data = NULL;
     365     
     366      delete *it2;
     367    }
     368  }
     369 
     370  sentStates.clear();
     371 
     372  for ( UserStateHistory::iterator it = recvStates.begin(); it != recvStates.end(); it++ )
     373  {
     374    for ( StateHistory::iterator it2 = it->begin(); it2 != it->end(); it2++ )
     375    {
     376      if ( (*it2)->data )
     377        delete [] (*it2)->data;
     378      (*it2)->data = NULL;
     379     
     380      delete *it2;
     381    }
     382  }
     383 
     384  recvStates.clear();
     385}
     386
     387/**
     388 * this function is called after recieving a state.
     389 * @param userId
     390 * @param stateId
     391 * @param fromStateId
     392 */
     393void Synchronizeable::handleRecvState( int userId, int stateId, int fromStateId )
     394{
     395   //make sure this user has his history
     396  if ( recvStates.size() <= userId )
     397    recvStates.resize( userId+1 );
     398 
     399  //remove old states
     400  StateHistory::iterator it = recvStates[userId].begin();
     401
     402#if 0
     403  while ( it != recvStates[userId].end() && (*it)->stateId < fromStateId )
     404    it++;
     405
     406  if ( it != recvStates[userId].begin() )
     407  {
     408    for ( StateHistory::iterator it2 = recvStates[userId].begin(); it2 != it; it2++ )
     409    {
     410      if ( (*it2)->data != NULL )
     411      {
     412        delete [] (*it2)->data;
     413        (*it2)->data = NULL;
     414      }
     415    }
     416    recvStates[userId].erase( recvStates[userId].begin(), it );
     417  }
     418#endif
     419
     420  for ( it = recvStates[userId].begin(); it != recvStates[userId].end();  )
     421  {
     422    if ( (*it)->stateId < fromStateId )
     423    {
     424      StateHistory::iterator delIt = it;
     425      it ++;
     426     
     427      if ( (*delIt)->data )
     428        delete [] (*delIt)->data;
     429      recvStates[userId].erase( delIt );
     430     
     431      continue;
     432    }
     433    it++;
     434  }
     435 
     436  StateHistory::iterator fromState = recvStates[userId].end();
     437  StateHistory::iterator toState = recvStates[userId].end();
     438 
     439  for ( it = recvStates[userId].begin(); it != recvStates[userId].end(); it++ )
     440  {
     441    if ( (*it)->stateId == stateId )
     442      toState = it;
     443    if ( (*it)->stateId == fromStateId )
     444      fromState = it;
     445   
     446    if ( fromState != recvStates[userId].end() && toState != recvStates[userId].end() )
     447      break;
     448  }
     449 
     450  // setStateDiff was not called and i know fromStateId
     451  if ( fromState != recvStates[userId].end() && toState == recvStates[userId].end() )
     452  {
     453    StateHistoryEntry * entry = new StateHistoryEntry;
     454   
     455    entry->dataLength = (*fromState)->dataLength;
     456    if ( entry->dataLength > 0 )
     457    {
     458      entry->data = new byte[entry->dataLength];
     459         
     460      assert( (*fromState)->data );
     461      memcpy( entry->data, (*fromState)->data, entry->dataLength );
     462    }
     463    else
     464      entry->data = NULL;
     465   
     466    entry->sizeList = (*fromState)->sizeList;
     467    entry->stateId = stateId;
     468   
     469    recvStates[userId].push_back(entry);
     470  }
     471}
     472
     473/**
     474 * this function is called after sending a state
     475 * @param userId
     476 * @param stateId
     477 * @param fromStateId
     478 */
     479void Synchronizeable::handleSentState( int userId, int stateId, int fromStateId )
     480{
     481   //make sure this user has his history
     482  if ( sentStates.size() <= userId )
     483    sentStates.resize( userId+1 );
     484
     485   //remove old states
     486  StateHistory::iterator it = sentStates[userId].begin();
     487
     488  for ( it = sentStates[userId].begin(); it != sentStates[userId].end();  )
     489  {
     490    if ( (*it)->stateId < fromStateId )
     491    {
     492      StateHistory::iterator delIt = it;
     493      it ++;
     494     
     495      if ( (*delIt)->data )
     496        delete [] (*delIt)->data;
     497      sentStates[userId].erase( delIt );
     498     
     499      continue;
     500    }
     501    it++;
     502  }
     503
     504 
     505  StateHistory::iterator fromState = sentStates[userId].end();
     506  StateHistory::iterator toState = sentStates[userId].end();
     507 
     508  for ( it = sentStates[userId].begin(); it != sentStates[userId].end(); it++ )
     509  {
     510    if ( (*it)->stateId == stateId )
     511      toState = it;
     512    if ( (*it)->stateId == fromStateId )
     513      fromState = it;
     514   
     515    if ( fromState != sentStates[userId].end() && toState != sentStates[userId].end() )
     516      break;
     517  }
     518
     519 
     520  // getStateDiff was not called and i know fromStateId
     521  if ( fromState != sentStates[userId].end() && toState == sentStates[userId].end() )
     522  {
     523    StateHistoryEntry * entry = new StateHistoryEntry;
     524   
     525    entry->dataLength = (*fromState)->dataLength;
     526    if ( entry->dataLength > 0 )
     527    {
     528      entry->data = new byte[entry->dataLength];
     529     
     530      assert( (*fromState)->data );
     531      memcpy( entry->data, (*fromState)->data, entry->dataLength );
     532    }
     533    else
     534      entry->data = NULL;
     535   
     536    entry->sizeList = (*fromState)->sizeList;
     537    entry->stateId = stateId;
     538   
     539    sentStates[userId].push_back(entry);
     540  }
     541 
     542}
     543
     544
     545
  • trunk/src/lib/network/synchronizeable.h

    r7230 r7954  
    11/*!
    2  * @file connection_monitor.h
     2 * @file synchronizeable.h
    33    \brief interface for all classes that have to be synchronized
    44 */
     
    1010#include "netdefs.h"
    1111#include "converter.h"
    12 
     12#include "vector.h"
     13#include "quaternion.h"
     14#include "synchronizeable_var/synchronizeable_var.h"
     15#include "synchronizeable_var/synchronizeable_vector.h"
     16#include "synchronizeable_var/synchronizeable_quaternion.h"
     17#include "synchronizeable_var/synchronizeable_string.h"
     18#include "synchronizeable_var/synchronizeable_int.h"
     19#include "synchronizeable_var/synchronizeable_float.h"
     20#include "synchronizeable_var/synchronizeable_bool.h"
     21#include "synchronizeable_var/synchronizeable_uint.h"
    1322
    1423
     
    1827//State constants: They have to be of the form 2^n
    1928#define STATE_SERVER 1
    20 #define STATE_OUTOFSYNC 2
    21 #define STATE_REQUESTEDSYNC 4
    2229
    23 enum {
    24   NWT_SS_WE_STATE = 1000000,
    25   NWT_SS_B,
    26   NWT_SS_FLAGS,
    27   NWT_SS_MOUSEDIRX,
    28   NWT_SS_MOUSEDIRY,
    29   NWT_SS_MOUSEDIRZ,
    30   NWT_SS_MOUSEDIRW,
    31   NWT_SS_PN_SYNC,
    32   NWT_SS_VELX,
    33   NWT_SS_VELY,
    34   NWT_SS_VELZ,
    35   NWT_SS_PL_SYNC,
    36   NWT_SS_CO_N,
    37   NWT_SS_CO_CLID,
    38 
    39   NWT_HS_HOST_ID,
    40   NWT_HS_NGM_ID,
    41 
    42   NWT_PL_B,
    43   NWT_PL_FLAGS,
    44   NWT_PL_SCORE,
    45 
    46   NWT_PN_BO_WRITESTATE,
    47   NWT_PN_PARENTMODE,
    48   NWT_PN_COORX,
    49   NWT_PN_COORY,
    50   NWT_PN_COORZ,
    51   NWT_PN_ROTX,
    52   NWT_PN_ROTY,
    53   NWT_PN_ROTZ,
    54   NWT_PN_ROTV,
    55 
    56   NWT_PN_FLAGS,
    57   NWT_PN_SCOORX,
    58   NWT_PN_SCOORY,
    59   NWT_PN_SCOORZ,
    60   NWT_PN_SROTX,
    61   NWT_PN_SROTY,
    62   NWT_PN_SROTZ,
    63   NWT_PN_SROTV,
    64 
    65   NWT_BO_NAME,
    66 
    67   NWT_WE_PN_WRITESTATE,
    68   NWT_WE_PN_MODELFILENAME,
    69   NWT_WE_PN_SCALING,
    70 
    71   NWT_GT_WE_STATE,
    72 
    73   NWT_SB_WE_STATE,
    74   NWT_SB_SIZE,
    75   NWT_SB_TEXTURENAME,
    76 
    77   NWT_TER_WE_STATE,
    78 
    79   NWT_PU_WE_STATE,
    80 
    81   NWT_TPU_WE_STATE,
    82 
    83   NWT_LPU_WE_STATE,
    84 
    85   NWT_WPU_WE_STATE,
    86 
    87   NWT_PPU_WE_STATE,
    88   NWT_PPU_TYPE,
    89   NWT_PPU_VALUE,
    90   NWT_PPU_MINVALUE,
    91   NWT_PPU_MAXVALUE,
    92 
    93   NWT_WAT_STATE,
    94   NWT_WAT_WE_STATE,
    95   NWT_WAT_SIZEX,
    96   NWT_WAT_SIZEY,
    97   NWT_WAT_RESX,
    98   NWT_WAT_RESY,
    99   NWT_WAT_HEIGHT
     30struct StateHistoryEntry
     31{
     32  int             stateId;
     33  byte *          data;
     34  int             dataLength;
     35  std::list<int>  sizeList;
    10036};
    10137
     38typedef std::list<StateHistoryEntry*> StateHistory;
    10239
    103 //macros to help writing data in byte buffer
    104 /*
    105  * Important: these macros must be used in
    106  *     SYNCHELP_READ_*:  virtual void      writeBytes(const byte* data, int length, int sender);
    107  *     SYNCHELP_WRITE_*: virtual int       readBytes(byte* data, int maxLength, int * reciever);
    108  * with the same argument names!
    109  *
    110  * id is one int out of that enum on top of this comment it is used to identify
    111  * read/write. when you read a value you have to use exactly the same as you used
    112  * to write or you will see an assertion failing.
    113  *
    114  * SYNCHELP_WRITE_BEGIN()
    115  * SYNCHELP_WRITE_INT(i,id)
    116  * SYNCHELP_WRITE_FLOAT(f,id)
    117  * SYNCHELP_WRITE_BYTE(b,id)
    118  * SYNCHELP_WRITE_STRING(s,id)
    119  * SYNCHELP_WRITE_N
    120  *
    121  * SYNCHELP_READ_BEGIN()
    122  * SYNCHELP_READ_INT(i,id)
    123  * SYNCHELP_READ_FLOAT(f,id)
    124  * SYNCHELP_READ_STRING(s,l,id) l = size of buffer s
    125  * SYNCHELP_READ_STRINGM(s,id)  allocates memory for string! you have to delete this later
    126  * SYNCHELP_READ_BYTE(b,id)
    127  * SYNCHELP_READ_REMAINING() returns the remaining buffer size
    128  * SYNCHELP_READ_NEXTBYTE()  reads the next byte but it is not removed from the buffer
    129  * SYNCHELP_READ_N
    130  *
    131  *
    132  *
    133  * Example 1:
    134  *  SYNCHELP_READ_BEGIN();
    135  *  SYNCHELP_READ_FLOAT(size);
    136  *  SYNCHELP_READ_STRING( textureName, 1024 ); //1024 is the length of textureName
    137  *  delete[] textureName;
    138  *  textureName = NULL;
    139  *  SYNCHELP_READ_STRINGM( texturename );      //this will call new char[strlen()+1]
    140  *
    141  * Example 2:
    142  *  SYNCHELP_WRITE_BEGIN();
    143  *  SYNCHELP_WRITE_FLOAT(this->size);
    144  *  SYNCHELP_WRITE_STRING(this->textureName);
    145  *  return SYNCHELP_WRITE_N;
    146  *
    147  */
     40typedef std::vector<StateHistory> UserStateHistory;
    14841
    149 #define SYNCHELP_WRITE_DEBUG(n) {\
    150   __synchelp_write_n = Converter::intToByteArray( n, data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
    151   assert( __synchelp_write_n == INTSIZE ); \
    152   __synchelp_write_i += __synchelp_write_n; \
    153 }
    154 
    155 #define SYNCHELP_READ_DEBUG(n) {  \
    156   int nn; \
    157   __synchelp_read_n = Converter::byteArrayToInt( data+__synchelp_read_i, &nn );  \
    158   assert( __synchelp_read_n == INTSIZE ); \
    159   if ( n != nn ) { \
    160     PRINTF(1)("Check your code! read/writes not in right order! read %d instead of %d\n", nn, n); \
    161     assert( false ); \
    162   } \
    163   __synchelp_read_i += __synchelp_read_n; \
    164 }
    165 
    166 #define SYNCHELP_WRITE_BEGIN()    int __synchelp_write_i = 0; \
    167                                   int __synchelp_write_n
    168 #define SYNCHELP_WRITE_INT(i,n) { SYNCHELP_WRITE_DEBUG(n); \
    169                                 __synchelp_write_n = \
    170                                 Converter::intToByteArray( i, data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
    171                                 assert( __synchelp_write_n == INTSIZE ); \
    172                                 if ( __synchelp_write_n <= 0) \
    173 { \
    174                                   PRINTF(1)("Buffer is too small to store a int\n"); \
    175                                   return 0; \
    176 } \
    177                                 __synchelp_write_i += __synchelp_write_n; \
    178 }
    179 #define SYNCHELP_WRITE_FLOAT(f,n) { SYNCHELP_WRITE_DEBUG(n); \
    180                                 __synchelp_write_n = \
    181                                 Converter::floatToByteArray( f, data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
    182                                 assert( __synchelp_write_n == FLOATSIZE ); \
    183                                 if ( __synchelp_write_n <= 0) \
    184 { \
    185                                   PRINTF(1)("Buffer is too small to store a float\n"); \
    186                                   return 0; \
    187 } \
    188                                 __synchelp_write_i += __synchelp_write_n; \
    189 }
    190 #define SYNCHELP_WRITE_BYTE(b,n) { SYNCHELP_WRITE_DEBUG(n); \
    191                                 \
    192                                 if (maxLength - __synchelp_write_i < 1) \
    193 { \
    194                                   PRINTF(1)("Buffer is too small to store string\n"); \
    195                                   return 0; \
    196 } \
    197                                 data[__synchelp_write_i] = b; \
    198                                 __synchelp_write_i++; \
    199 }
    200 #define SYNCHELP_WRITE_STRING(s,n) { SYNCHELP_WRITE_DEBUG(n); \
    201                                 __synchelp_write_n = \
    202                                 Converter::stringToByteArray( s, data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
    203                                 assert( __synchelp_write_n == ((std::string)s).length()+INTSIZE ); \
    204                                 if ( __synchelp_write_n <= 0) \
    205 { \
    206                                   PRINTF(1)("Buffer is too small to store string\n"); \
    207                                   return 0; \
    208 } \
    209                                 __synchelp_write_i += __synchelp_write_n; \
    210 }
    211 #define SYNCHELP_WRITE_N        __synchelp_write_i
    212 #define SYNCHELP_WRITE_FKT(f,n)   { SYNCHELP_WRITE_DEBUG(n); \
    213                                   PRINTF(0)("calling %s with %d left\n", #f, maxLength - __synchelp_write_i);  \
    214                                   byte * spos = data+__synchelp_write_i;  \
    215                                   if (maxLength - __synchelp_write_i < INTSIZE) \
    216 { \
    217                                     PRINTF(1)("Buffer is too small to store more data\n"); \
    218                                     return 0; \
    219 } \
    220                                   __synchelp_write_i += INTSIZE; \
    221                                   __synchelp_write_n = \
    222                                   f( data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
    223                                   __synchelp_write_i += __synchelp_write_n;  \
    224                                   Converter::intToByteArray( __synchelp_write_n, spos, INTSIZE ); \
    225                                 }
    226 
    227 
    228 #define SYNCHELP_READ_BEGIN()     int __synchelp_read_i = 0; \
    229                                   int __synchelp_read_n
    230 
    231 #define SYNCHELP_READ_INT(i,n)       { SYNCHELP_READ_DEBUG(n); \
    232                                     if ( length-__synchelp_read_i < INTSIZE ) \
    233 { \
    234                                       PRINTF(1)("There is not enough data to read an int\n");  \
    235                                       return 0; \
    236 } \
    237                                     __synchelp_read_n = Converter::byteArrayToInt( data+__synchelp_read_i, &i );  \
    238                                     assert( __synchelp_read_n == INTSIZE ); \
    239                                     __synchelp_read_i += __synchelp_read_n; \
    240 }
    241 #define SYNCHELP_READ_FLOAT(f,n)    { SYNCHELP_READ_DEBUG(n); \
    242                                     if ( length-__synchelp_read_i < FLOATSIZE ) \
    243 { \
    244                                       PRINTF(1)("There is not enough data to read a flaot\n");  \
    245                                       return 0; \
    246 } \
    247                                     __synchelp_read_n = Converter::byteArrayToFloat( data+__synchelp_read_i, &f );  \
    248                                     assert( __synchelp_read_n == FLOATSIZE ) ;\
    249                                     __synchelp_read_i += __synchelp_read_n; \
    250 }
    251 #define SYNCHELP_READ_STRING(s,n)    {SYNCHELP_READ_DEBUG(n); \
    252                                     __synchelp_read_n = Converter::byteArrayToString( data+__synchelp_read_i, s, length-__synchelp_read_i );  \
    253                                     assert( __synchelp_read_n == s.length()+INTSIZE ) ;\
    254                                     if ( __synchelp_read_n <0 )  \
    255 { \
    256                                       PRINTF(1)("There is not enough data to read string\n");  \
    257                                       return 0; \
    258 } \
    259                                     __synchelp_read_i += __synchelp_read_n; \
    260 }
    261 #if 0 //not needed any more
    262 #define SYNCHELP_READ_STRINGM(s,n)    { SYNCHELP_READ_DEBUG(n); \
    263                                     __synchelp_read_n = Converter::byteArrayToStringM( data+__synchelp_read_i, s );  \
    264                                     assert( __synchelp_read_n == strlen(s)+INTSIZE ) ;\
    265                                     if ( __synchelp_read_n <0 )  \
    266 { \
    267                                       PRINTF(1)("There is not enough data to read string\n");  \
    268                                       return 0; \
    269 } \
    270                                     __synchelp_read_i += __synchelp_read_n; \
    271 }
    272 #endif
    273 #define SYNCHELP_READ_BYTE(b,n)      { SYNCHELP_READ_DEBUG(n); \
    274                                     if ( length-__synchelp_read_i < 1 ) \
    275 { \
    276                                       PRINTF(1)("There is not enough data to read a byte\n");  \
    277                                       return 0; \
    278 } \
    279                                     b = data[__synchelp_read_i]; \
    280                                     __synchelp_read_i ++;  \
    281 }
    282 #define SYNCHELP_READ_FKT(f,n)   { SYNCHELP_READ_DEBUG(n); \
    283                                   int s; \
    284                                   if ( length-__synchelp_read_i < INTSIZE ) \
    285 { \
    286                                       PRINTF(1)("There is not enough data to read an int\n");  \
    287                                       return 0; \
    288 } \
    289                                     __synchelp_read_n = Converter::byteArrayToInt( data+__synchelp_read_i, &s );  \
    290                                     assert( __synchelp_read_n == INTSIZE ); \
    291                                     __synchelp_read_i += __synchelp_read_n; \
    292                                   __synchelp_read_i += \
    293                                   f( data+__synchelp_read_i, s, sender); \
    294                                   }
    295 #define SYNCHELP_READ_REMAINING() ( length-__synchelp_read_i )
    296 #define SYNCHELP_READ_NEXTBYTE() ( data[__synchelp_read_i] )
    297 #define SYNCHELP_READ_N           __synchelp_read_i
     42typedef std::vector<SynchronizeableVar*> SyncVarList;
    29843
    29944class NetworkStream;
    300 
    30145
    30246class Synchronizeable : virtual public BaseObject
     
    30751    virtual ~Synchronizeable();
    30852
    309     virtual int       writeBytes(const byte* data, int length, int sender);
    310     virtual int       readBytes(byte* data, int maxLength, int * reciever);
    311     virtual void      writeDebug() const;
    312     virtual void      readDebug() const;
     53    void setIsServer( bool isServer );
     54    bool isServer();
    31355
    314     void setIsServer( bool isServer );
    315     void setIsOutOfSync( bool outOfSync );
    316     void setRequestedSync( bool requestedSync );
    317     bool isServer();
    318     bool isOutOfSync();
    319     bool requestedSync();
     56    virtual void varChangeHandler( std::list<int> & id );
     57
     58    virtual int getStateDiff( int userId, byte* data, int maxLength, int stateId, int fromStateId, int priorityTH );
     59    virtual int setStateDiff( int userId, byte* data, int length, int stateId, int fromStateId );
     60    virtual void cleanUpUser( int userId );
     61    virtual void handleSentState( int userId, int stateId, int fromStateId );
     62    virtual void handleRecvState( int userId, int stateId, int fromStateId );
     63
     64    void registerVar( SynchronizeableVar * var );
     65    int registerVarId( SynchronizeableVar * var );
    32066
    32167    inline void setUniqueID( int id ){ uniqueID = id; }
     
    32672    inline void setOwner(int owner){ this->owner = owner; }
    32773
    328     /** @returns true if this Synchronizeable has to be synchronized over network */
     74    /** @returns true if this Synchronizeable wants to be synchronized over network */
    32975    inline bool beSynchronized() { return this->bSynchronize; }
    33076    /** @param bSynchronize sets the Synchronizeable to be sunchronized or not */
    33177    inline void setSynchronized(bool bSynchronize) { this->bSynchronize = bSynchronize; }
    332 
    333     inline void requestSync( int hostID ){ this->synchronizeRequests.push_back( hostID ); }
    334     inline int getRequestSync( void ){ if ( this->synchronizeRequests.size()>0 ){ int n = *(synchronizeRequests.begin()); synchronizeRequests.pop_front(); return n; } else { return -1; } };
    33578
    33679    inline void setNetworkStream(NetworkStream* stream) { this->networkStream = stream; }
     
    33982
    34083  protected:
    341     NetworkStream*    networkStream;
     84    NetworkStream*    networkStream;  //!< reference network stream we are connected to
    34285    int               state;
    34386
     87  private:
     88    int               uniqueID;       //!< unique id assigned to synchronizeable
     89    int               mLeafClassId;   //!< store leafClassId to send via states
     90    int               owner;          //!< hostId of owner ( 0 if none / server )
     91    int               hostID;         //!< my own host id
     92    bool              bSynchronize;   //!< do we need beeing synchronized?
    34493
    345   private:
    346     int               uniqueID;
    347     int               owner;
    348     int               hostID;
    349     bool              bSynchronize;
     94    SyncVarList       syncVarList;    //!< list containing variables to synchronize
    35095
    351     std::list<int>    synchronizeRequests;
     96    UserStateHistory  sentStates;     //!< store already sent states to create diffs from, offset corresponds to the user id
     97    UserStateHistory  recvStates;     //!< store recieved states to apply diffs, offset corresponds to the user id
    35298
    35399};
Note: See TracChangeset for help on using the changeset viewer.