Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 7954 in orxonox.OLD


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

trunk: merged the network branche back to trunk.

Location:
trunk
Files:
61 edited
31 copied

Legend:

Unmodified
Added
Removed
  • trunk/configure.ac

    r7919 r7954  
    601601# FIXME: Replace `main' with a function in `-lm':
    602602 AC_CHECK_LIB([m], [main])
    603 
     603 AX_CHECK_REQUIRED_HEADER_LIB([zlib.h], [z], [zlibVersion],,, [http://www.zlib.net])
    604604
    605605# Checks for header files.
  • trunk/src/defs/class_id.h

    r7927 r7954  
    366366  CL_HANDSHAKE                  =    0x00000d06,
    367367  CL_NETWORK_GAME_MANAGER       =    0x00000d07,
     368  CL_MESSAGE_MANAGER            =    0x00000d08,
     369  CL_SIMPLE_SYNC                =    0x00000d09,
    368370
    369371
  • trunk/src/lib/BuildLibs.am

    r7661 r7954  
    1111                $(LIB_PREFIX)/sound/libORXsound.a \
    1212                $(LIB_PREFIX)/event/libORXevent.a \
    13                 $(LIB_PREFIX)/physics/libORXphysics.a \
    1413                $(LIB_PREFIX)/particles/libORXparticles.a \
    1514                $(LIB_PREFIX)/collision_detection/libORXcd.a \
     
    2019                $(LIB_PREFIX)/parser/cmdline_parser/libCmdLineParser.a \
    2120                $(LIB_PREFIX)/parser/ini_parser/libIniParser.a \
     21                $(LIB_PREFIX)/physics/libORXphysics.a \
     22                $(LIB_PREFIX)/shell/libORXshell.a \
    2223                $(LIB_PREFIX)/math/libORXmath.a \
    2324                $(LIB_PREFIX)/libORXlibs.a
  • trunk/src/lib/coord/p_node.cc

    r7725 r7954  
    5353  if (parent != NULL)
    5454    parent->addChild(this);
     55
     56  this->relCoordinate_handle = this->registerVarId( new SynchronizeableVector( &relCoordinate, &relCoordinate_write, "coordinate" ) );
     57  this->relDirection_handle = this->registerVarId( new SynchronizeableQuaternion( &relDirection, &relDirection_write, "direction" ) );
    5558}
    5659
     
    10771080
    10781081/**
    1079  * Writes data from network containing information about the state
    1080  * @param data pointer to data
    1081  * @param length length of data
    1082  * @param sender hostID of sender
    1083  */
    1084 int PNode::writeState( const byte * data, int length, int sender )
    1085 {
    1086   SYNCHELP_READ_BEGIN();
    1087 
    1088   SYNCHELP_READ_FKT( BaseObject::writeState, NWT_PN_BO_WRITESTATE );
    1089 
    1090   //   char * parentName = NULL;
    1091   //   SYNCHELP_READ_STRINGM( parentName );
    1092   //
    1093   //   if ( strcmp(parentName, "")==0 )
    1094   //   {
    1095   //     setParent( (char*)NULL );
    1096   //   }
    1097   //   else
    1098   //   {
    1099   //     setParent( parentName );
    1100   //   }
    1101   //
    1102   //  delete[] parentName;
    1103 
    1104   int parentMode;
    1105   SYNCHELP_READ_INT( parentMode, NWT_PN_PARENTMODE );
    1106   this->setParentMode((PARENT_MODE)parentMode);
    1107 
    1108   float f1, f2, f3, f4;
    1109 
    1110   SYNCHELP_READ_FLOAT( f1, NWT_PN_COORX );
    1111   SYNCHELP_READ_FLOAT( f2, NWT_PN_COORY );
    1112   SYNCHELP_READ_FLOAT( f3, NWT_PN_COORZ );
    1113   this->setRelCoor( f1, f2, f3 );
    1114 
    1115 
    1116   SYNCHELP_READ_FLOAT( f1, NWT_PN_ROTV );
    1117   SYNCHELP_READ_FLOAT( f2, NWT_PN_ROTX );
    1118   SYNCHELP_READ_FLOAT( f3, NWT_PN_ROTY );
    1119   SYNCHELP_READ_FLOAT( f4, NWT_PN_ROTZ );
    1120   this->setRelDir( Quaternion( Vector(f2, f3, f4), f1 ) );
    1121 
    1122   //   int n;
    1123   //   char * childName;
    1124   //
    1125   //   PRINTF(0)("JKLO %d %d %d %d\n", data[__synchelp_read_i], data[__synchelp_read_i+1], data[__synchelp_read_i+2], data[__synchelp_read_i+3]);
    1126   //   SYNCHELP_READ_INT( n );
    1127   //   PRINTF(0)("read %s:n=%d\n", this->getName(), n);
    1128   //
    1129   //   for (int i = 0; i<n; i++)
    1130   //   {
    1131   //     SYNCHELP_READ_STRINGM( childName );
    1132   //     PRINTF(0)("RCVD CHILD = %s\n", childName);
    1133   //     addChild( childName );
    1134   //     delete childName;
    1135   //     childName = NULL;
    1136   //   }
    1137 
    1138   return SYNCHELP_READ_N;
    1139 }
    1140 
    1141 /**
    1142  * data copied in data will bee sent to another host
    1143  * @param data pointer to data
    1144  * @param maxLength max length of data
    1145  * @return the number of bytes writen
    1146  */
    1147 int PNode::readState( byte * data, int maxLength )
    1148 {
    1149   SYNCHELP_WRITE_BEGIN();
    1150 
    1151   SYNCHELP_WRITE_FKT( BaseObject::readState, NWT_PN_BO_WRITESTATE );
    1152 
    1153   //   if ( this->parent )
    1154   //   {
    1155   //     SYNCHELP_WRITE_STRING( parent->getName() );
    1156   //   }
    1157   //   else
    1158   //   {
    1159   //     SYNCHELP_WRITE_STRING( "" );
    1160   //   }
    1161 
    1162   SYNCHELP_WRITE_INT( this->parentMode, NWT_PN_PARENTMODE );
    1163 
    1164   SYNCHELP_WRITE_FLOAT( this->relCoordinate.x, NWT_PN_COORX );
    1165   SYNCHELP_WRITE_FLOAT( this->relCoordinate.y, NWT_PN_COORY );
    1166   SYNCHELP_WRITE_FLOAT( this->relCoordinate.z, NWT_PN_COORZ );
    1167 
    1168   SYNCHELP_WRITE_FLOAT( this->relDirection.w, NWT_PN_ROTV );
    1169   SYNCHELP_WRITE_FLOAT( this->relDirection.v.x, NWT_PN_ROTX );
    1170   SYNCHELP_WRITE_FLOAT( this->relDirection.v.y, NWT_PN_ROTY );
    1171   SYNCHELP_WRITE_FLOAT( this->relDirection.v.z, NWT_PN_ROTZ );
    1172 
    1173   //   int n = children.size();
    1174   //   //check if camera is in children
    1175   //   for (std::std::list<PNode*>::const_iterator it = children.begin(); it!=children.end(); it++)
    1176   //   {
    1177   //     if ( (*it)->isA(CL_CAMERA) )
    1178   //       n--;
    1179   //   }
    1180   //   PRINTF(0)("write %s:n=%d\n", this->getName(), n);
    1181   //   SYNCHELP_WRITE_INT( n );
    1182   //   PRINTF(0)("ASDF %d %d %d %d\n", data[__synchelp_write_i-4], data[__synchelp_write_i-3], data[__synchelp_write_i-2], data[__synchelp_write_i-1]);
    1183   //
    1184   //
    1185   //   for (std::list<PNode*>::const_iterator it = children.begin(); it!=children.end(); it++)
    1186   //   {
    1187   //     //dont add camera because there is only one camera attached to local player
    1188   //     if ( !(*it)->isA(CL_CAMERA) )
    1189   //     {
    1190   //       PRINTF(0)("SENDING CHILD: %s\n", (*it)->getName());
    1191   //       SYNCHELP_WRITE_STRING( (*it)->getName() );
    1192   //     }
    1193   //   }
    1194 
    1195   return SYNCHELP_WRITE_N;
    1196 }
    1197 
    1198 #define __FLAG_COOR 1
    1199 #define __FLAG_ROT  2
    1200 
    1201 #define __OFFSET_POS 1
    1202 #define __OFFSET_ROT 0.05
    1203 
    1204 /**
    1205  * Writes data from network containing information about the state which has changed
    1206  * @param data pointer to data
    1207  * @param length length of data
    1208  * @param sender hostID of sender
    1209  */
    1210 int PNode::writeSync( const byte * data, int length, int sender )
    1211 {
    1212   SYNCHELP_READ_BEGIN();
    1213 
    1214   if ( this->getHostID()==this->getOwner() )
    1215   {
    1216     return SYNCHELP_READ_N;
    1217   }
    1218 
    1219   byte flags = 0;
    1220   SYNCHELP_READ_BYTE( flags, NWT_PN_FLAGS );
    1221   //PRINTF(0)("%s::FLAGS = %d\n", this->getName(), flags);
    1222 
    1223   float f1, f2, f3, f4;
    1224 
    1225   if ( flags & __FLAG_COOR )
    1226   {
    1227     SYNCHELP_READ_FLOAT( f1, NWT_PN_SCOORX );
    1228     SYNCHELP_READ_FLOAT( f2, NWT_PN_SCOORY );
    1229     SYNCHELP_READ_FLOAT( f3, NWT_PN_SCOORZ );
    1230     PRINTF(0)("RCVD COOR: %f %f %f\n", f1, f2, f3);
    1231     this->setRelCoor( f1, f2, f3 );
    1232   }
    1233 
    1234   if ( flags & __FLAG_ROT )
    1235   {
    1236     SYNCHELP_READ_FLOAT( f1, NWT_PN_SROTV );
    1237     SYNCHELP_READ_FLOAT( f2, NWT_PN_SROTX );
    1238     SYNCHELP_READ_FLOAT( f3, NWT_PN_SROTY );
    1239     SYNCHELP_READ_FLOAT( f4, NWT_PN_SROTZ );
    1240     PRINTF(0)("RCVD QUAT: %f %f %f %f\n", f1, f2, f3, f4);
    1241     //this->setRelDir( Quaternion( Vector(f2, f3, f4), f1 ) );
    1242     Quaternion q;
    1243     q.w = f1;
    1244     q.v.x = f2;
    1245     q.v.y = f3;
    1246     q.v.z = f4;
    1247     this->setAbsDir( q );
    1248   }
    1249 
    1250   return SYNCHELP_READ_N;
    1251 }
    1252 
    1253 /**
    1254  * data copied in data will bee sent to another host
    1255  * @param data pointer to data
    1256  * @param maxLength max length of data
    1257  * @return the number of bytes writen
    1258  */
    1259 int PNode::readSync( byte * data, int maxLength )
    1260 {
    1261   //WARNING: if you change this file make sure you also change needsReadSync
    1262   SYNCHELP_WRITE_BEGIN();
    1263 
    1264   if ( this->getHostID()!=0 && this->getHostID()!=this->getOwner() )
    1265   {
    1266     return SYNCHELP_WRITE_N;
    1267   }
    1268 
    1269   byte flags = 0;
    1270   if ( fabs( coorx - relCoordinate.x ) > __OFFSET_POS*0.05*this->velocity.len() ||
    1271        fabs( coory - relCoordinate.y ) > __OFFSET_POS*0.05*this->velocity.len() ||
    1272        fabs( coorz - relCoordinate.z ) > __OFFSET_POS*0.05*this->velocity.len() )
    1273     flags |= __FLAG_COOR;
    1274 
    1275   if ( fabs( rotw - absDirection.w ) > __OFFSET_ROT ||
    1276        fabs( rotx - absDirection.v.x ) > __OFFSET_ROT ||
    1277        fabs( roty - absDirection.v.y ) > __OFFSET_ROT ||
    1278        fabs( rotz - absDirection.v.z ) > __OFFSET_ROT )
    1279     flags |= __FLAG_ROT;
    1280 
    1281 
    1282   SYNCHELP_WRITE_BYTE( flags, NWT_PN_FLAGS );
    1283   PRINTF(0)("FLAGS = %d\n", flags);
    1284 
    1285   if ( flags & __FLAG_COOR )
    1286   {
    1287 
    1288     PRINTF(0)("SEND COOR: %f %f %f\n", this->relCoordinate.x, this->relCoordinate.y, this->relCoordinate.z);
    1289 
    1290     SYNCHELP_WRITE_FLOAT( this->relCoordinate.x, NWT_PN_SCOORX );
    1291     SYNCHELP_WRITE_FLOAT( this->relCoordinate.y, NWT_PN_SCOORY );
    1292     SYNCHELP_WRITE_FLOAT( this->relCoordinate.z, NWT_PN_SCOORZ );
    1293 
    1294     coorx = relCoordinate.x;
    1295     coory = relCoordinate.y;
    1296     coorz = relCoordinate.z;
    1297   }
    1298 
    1299   if ( flags & __FLAG_ROT )
    1300   {
    1301 
    1302     PRINTF(0)("SEND QUAT: %f %f %f %f\n", this->absDirection.w, this->absDirection.v.x, this->absDirection.v.y, this->absDirection.v.z);
    1303 
    1304     SYNCHELP_WRITE_FLOAT( this->absDirection.w, NWT_PN_SROTV );
    1305     SYNCHELP_WRITE_FLOAT( this->absDirection.v.x, NWT_PN_SROTX );
    1306     SYNCHELP_WRITE_FLOAT( this->absDirection.v.y, NWT_PN_SROTY );
    1307     SYNCHELP_WRITE_FLOAT( this->absDirection.v.z, NWT_PN_SROTZ );
    1308 
    1309     rotw = absDirection.w;
    1310     rotx = absDirection.v.x;
    1311     roty = absDirection.v.y;
    1312     rotz = absDirection.v.z;
    1313   }
    1314 
    1315   return SYNCHELP_WRITE_N;
    1316 }
    1317 
    1318 bool PNode::needsReadSync( )
    1319 {
    1320   if ( fabs( coorx - relCoordinate.x ) > __OFFSET_POS*0.05*this->velocity.len() ||
    1321        fabs( coory - relCoordinate.y ) > __OFFSET_POS*0.05*this->velocity.len() ||
    1322        fabs( coorz - relCoordinate.z ) > __OFFSET_POS*0.05*this->velocity.len() )
    1323     return true;
    1324 
    1325   if ( fabs( rotw - absDirection.w ) > __OFFSET_ROT ||
    1326        fabs( rotx - absDirection.v.x ) > __OFFSET_ROT ||
    1327        fabs( roty - absDirection.v.y ) > __OFFSET_ROT ||
    1328        fabs( rotz - absDirection.v.z ) > __OFFSET_ROT )
    1329     return true;
    1330 
    1331   return false;
    1332 }
     1082 * handles changes in synchronizable variables
     1083 * @param id id's which changed
     1084 */
     1085void PNode::varChangeHandler( std::list< int > & id )
     1086{
     1087  if ( std::find( id.begin(), id.end(), relCoordinate_handle ) != id.end() )
     1088  {
     1089    setRelCoor( relCoordinate_write );
     1090  }
     1091
     1092  if ( std::find( id.begin(), id.end(), relDirection_handle ) != id.end() )
     1093  {
     1094    setRelDir( relDirection_write );
     1095  }
     1096}
     1097
     1098
  • trunk/src/lib/coord/p_node.h

    r7725 r7954  
    186186  float distance(const PNode* node) const { return (this->getAbsCoor() - node->getAbsCoor()).len(); };
    187187
    188   int       writeState(const byte* data, int length, int sender);
    189   int       readState(byte* data, int maxLength );
    190   int       writeSync(const byte* data, int length, int sender);
    191   int       readSync(byte* data, int maxLength );
    192   bool      needsReadSync();
    193 
    194188 private:
    195189  /** tells the child that the parent's Coordinate has changed */
     
    243237    float roty;
    244238    float rotz;
     239   
     240  private:
     241    int relCoordinate_handle;
     242    int relDirection_handle;
     243    Vector relCoordinate_write;
     244    Quaternion relDirection_write;
     245   
     246  public:
     247    virtual void varChangeHandler( std::list<int> & id );
    245248};
    246249
  • trunk/src/lib/graphics/importer/height_map.cc

    r7526 r7954  
    603603  PRINTF(0)("c: %f \n" ,c);
    604604
     605
    605606  height -= ( (a/c)*(x) + (b/c)*(y));
    606607
    607   PRINTF(0)("height: %f \n" ,height );
     608  // PRINTF(0)("height: %f \n" ,height );
    608609  return (height + offsetZ);
    609 }
     610
     611}
  • trunk/src/lib/lang/base_object.cc

    r7661 r7954  
    8282  assert (!(this->classID & classID & !CL_MASK_SUBSUPER_CLASS_IDA ));
    8383
     84  this->leafClassID = classID;
    8485  this->classID |= (long)classID;
    8586  this->className = className;
     
    105106 * Factory::fabricate(Object->getLeafClassID());
    106107 */
    107 ClassID BaseObject::getLeafClassID() const
     108const ClassID& BaseObject::getLeafClassID() const
    108109{
    109   assert (this->classList != NULL);
    110   return this->classList->getLeafClassID();
     110  return this->leafClassID;
    111111}
    112112
     
    176176
    177177}
    178 
    179 /**
    180  * Writes data from network containing information about the state
    181  * @param data pointer to data
    182  * @param length length of data
    183  * @param sender hostID of sender
    184  */
    185 int BaseObject::writeState( const byte * data, int length, int sender )
    186 {
    187   SYNCHELP_READ_BEGIN();
    188 
    189   SYNCHELP_READ_STRING( this->objectName, NWT_BO_NAME );
    190 
    191   return SYNCHELP_READ_N;
    192 }
    193 
    194 /**
    195  * data copied in data will bee sent to another host
    196  * @param data pointer to data
    197  * @param maxLength max length of data
    198  * @return the number of bytes writen
    199  */
    200 int BaseObject::readState( byte * data, int maxLength )
    201 {
    202   SYNCHELP_WRITE_BEGIN();
    203 
    204   //PRINTF(0)("objectname = %s\n", this->objectName);
    205   SYNCHELP_WRITE_STRING( this->objectName, NWT_BO_NAME );
    206 
    207   return SYNCHELP_WRITE_N;
    208 }
  • trunk/src/lib/lang/base_object.h

    r7779 r7954  
    4242  /** @returns the classID of the corresponding Object */
    4343  inline int getClassID() const { return this->classID; };
    44   ClassID    getLeafClassID() const;
     44  const ClassID& getLeafClassID() const;
    4545
    4646  bool isA (ClassID classID) const;
     
    5252  bool operator==(ClassID classID) { return this->isA(classID); };
    5353
    54   int       writeState(const byte* data, int length, int sender);
    55   int       readState(byte* data, int maxLength );
    56 
    5754 protected:
    5855   void setClassID(ClassID classID, const std::string& className);
     56   std::string        objectName;        //!< The name of this object
    5957
    6058 private:
    6159    std::string        className;        //!< the name of the class
    6260    long               classID;          //!< this is the id from the class_id.h enumeration
    63     std::string        objectName;       //!< The name of this object
     61    ClassID            leafClassID;      //!< The Leaf Class ID
    6462
    6563    ClassList*         classList;        //!< Pointer to the ClassList this Object is inside of
  • 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};
  • trunk/src/orxonox.cc

    r7729 r7954  
    9191REGISTER_ARG_FLAG( _, write_bt_to_file, "misc", "bt-to-file", "Write backtrace to file", "1");
    9292#endif
     93
     94REGISTER_ARG_ARG(  t, telnetport,  "network","telnetport",        "Port to use for network debug output",               "port" );
     95REGISTER_ARG_ARG(  _, write_dict,  "compression", "writedict",    "write packets to DATA/dicts/newdict",               "numBytes" );
     96
    9397
    9498/**
  • trunk/src/story_entities/multi_player_world.cc

    r7287 r7954  
    8181void MultiPlayerWorld::synchronize()
    8282{
    83   NetworkManager::getInstance()->synchronize();
     83  NetworkManager::getInstance()->synchronize(this->dtS);
    8484}
    8585
  • trunk/src/story_entities/multi_player_world_data.cc

    r7370 r7954  
    226226    PNode::getNullParent()->init();
    227227  }
     228    // Fill the EntityLists. Tick then Draw:
     229  this->tickLists.push_back(OM_DEAD_TICK);
     230  this->tickLists.push_back(OM_ENVIRON);
     231  this->tickLists.push_back(OM_COMMON);
     232  this->tickLists.push_back(OM_GROUP_00);
     233  this->tickLists.push_back(OM_GROUP_00_PROJ);
     234  this->tickLists.push_back(OM_GROUP_01);
     235  this->tickLists.push_back(OM_GROUP_01_PROJ);
     236
     237  this->drawLists.push_back(OM_ENVIRON_NOTICK);
     238  this->drawLists.push_back(OM_ENVIRON);
     239  this->drawLists.push_back(OM_COMMON);
     240  this->drawLists.push_back(OM_GROUP_00);
     241  this->drawLists.push_back(OM_GROUP_00_PROJ);
     242  this->drawLists.push_back(OM_GROUP_01);
     243  this->drawLists.push_back(OM_GROUP_01_PROJ);
     244 
    228245  State::setPlayer(this->localPlayer);
    229246}
  • trunk/src/subprojects/network/Makefile.am

    r7160 r7954  
    11MAINSRCDIR=../..
    22include $(MAINSRCDIR)/defs/include_paths.am
     3
     4LIB_PREFIX=$(MAINSRCDIR)/lib
     5include $(MAINSRCDIR)/lib/BuildLibs.am
     6
    37
    48bin_PROGRAMS = network
    59
    610
    7 network_CPPFLAGS = -DNO_SHELL -DNO_SHELL_COMMAND
     11network_CPPFLAGS =
     12#-DNO_SHELL -DNO_SHELL_COMMAND
    813
    9 DEPENDENCIES = \
     14network_DEPENDENCIES = \
    1015                $(MAINSRCDIR)/world_entities/libORXwe.a \
    1116                $(libORXlibs_a_LIBRARIES_) \
    1217                $(MAINSRCDIR)/util/libORXutils.a
    1318
    14 LDADD = \
     19network_LDADD = \
    1520                $(MAINSRCDIR)/util/libORXutils.a \
    1621                $(libORXlibs_a_LIBRARIES_) \
  • trunk/src/subprojects/network/network_unit_test.cc

    r6424 r7954  
    99#include "network_socket.h"
    1010#include "server_socket.h"
     11#include "udp_server_socket.h"
     12#include "udp_socket.h"
    1113#include "network_stream.h"
    1214#include "synchronizeable.h"
    1315#include "converter.h"
     16#include "state.h"
     17#include "shared_network_data.h"
     18#include "message_manager.h"
     19#include "network_log.h"
    1420
    1521#include "simple_sync.h"
     
    3642int testSocket(int argc, char** argv)
    3743{
    38   IPaddress ip;
    39   SDLNet_ResolveHost(&ip, "127.0.0.1", 9999);
    40   ServerSocket server;
    41   server.listen(9999);
    42 
    43   NetworkSocket* client1 = new NetworkSocket(ip);
    44 
    45   NetworkSocket* server1 = server.getNewSocket();
    46 
    47   NetworkSocket* client2 = new NetworkSocket(ip);
    48 
    49   NetworkSocket* server2 = server.getNewSocket();
     44  UdpServerSocket server(9999);
     45
     46  NetworkSocket* client1 = new UdpSocket("localhost", 9999);
     47
     48  NetworkSocket* server1 = NULL;
     49  while ( server1 == NULL )
     50  {
     51    server.update();
     52    server1 = server.getNewSocket();
     53  }
     54 
     55  assert( server1->isOk() );
     56
     57  NetworkSocket* client2 = new UdpSocket("localhost", 9999);
     58
     59  NetworkSocket* server2 = NULL;
     60  while ( server2 == NULL )
     61  {
     62    server.update();
     63    server2 = server.getNewSocket();
     64  }
    5065
    5166  char buf[1024];
     
    7085  n = server2->writePacket((byte*)str4, strlen(str4)+1);
    7186  printf("%d bytes send from server2\n", n);
    72   SDL_Delay(1000);
     87  SDL_Delay(10);
     88 
     89  server.update();
    7390
    7491  printf("read from server1\n");
     
    103120
    104121  printf("data: '%s'\n", buf);
     122 
     123 
     124  //22222222222222222222222222222222222222222
     125  n = client1->writePacket((byte*)str1, strlen(str1)+1);
     126  printf("%d bytes send from client1\n", n);
     127  n = server1->writePacket((byte*)str2, strlen(str2)+1);
     128  printf("%d bytes send from server1\n", n);
     129  n = client2->writePacket((byte*)str3, strlen(str3)+1);
     130  printf("%d bytes send from client2\n", n);
     131  n = server2->writePacket((byte*)str4, strlen(str4)+1);
     132  printf("%d bytes send from server2\n", n);
     133  SDL_Delay(10);
     134 
     135  server.update();
     136
     137  printf("read from server1\n");
     138  n = server1->readPacket((byte*)buf, 1024);
     139  printf("read %d bytes\n", n);
     140  if (n<0)
     141    return -1;
     142
     143  printf("data: '%s'\n", buf);
     144
     145  printf("read from server2\n");
     146  n = server2->readPacket((byte*)buf, 1024);
     147  printf("read %d bytes\n", n);
     148  if (n<0)
     149    return -1;
     150
     151  printf("data: '%s'\n", buf);
     152
     153  printf("read from client1\n");
     154  n = client1->readPacket((byte*)buf, 1024);
     155  printf("read %d bytes\n", n);
     156  if (n<0)
     157    return -1;
     158
     159  printf("data: '%s'\n", buf);
     160
     161  printf("read from client2\n");
     162  n = client2->readPacket((byte*)buf, 1024);
     163  printf("read %d bytes\n", n);
     164  if (n<0)
     165    return -1;
     166
     167  printf("data: '%s'\n", buf);
    105168
    106169  //sending bigger packets than 255 is not supported
    107 
     170#if 0
    108171  printf("try to send more than 255 bytes\n");
    109172  printf("result: %d\n", client1->writePacket((byte*)buf, 1000));
     
    113176  printf("try to read with a too small buffer\n");
    114177  printf("result: %d\n", client1->readPacket((byte*)buf, strlen(str1)));
    115 
     178#endif
     179
     180  delete client1;
     181  delete client2;
     182  delete server1;
     183  delete server2;
     184 
    116185  return 0;
    117186}
     
    124193  printf("=================\n");
    125194
    126   Synchronizeable* clientSync = new SimpleSync("Client\0");
    127   Synchronizeable* serverSync = new SimpleSync("Server\0");
     195  Synchronizeable* clientSync = new SimpleSync( std::string("Client") );
     196  Synchronizeable* serverSync = new SimpleSync( std::string("Server") );
    128197
    129198  unsigned int port = 9999;
     
    144213  if(error == -1)
    145214    printf("\n\nerror on address resolution, program inconsistancy\n\n");
    146   nm->establishConnection(ip, *clientSync);
     215  nm->establishConnection("localhost", port);
     216  nm->connectSynchronizeable( *clientSync );
    147217  /* adding some break for connection setup */
    148218  SDL_Delay(20);
     
    151221  for( int i = 0; i < 3; i++)
    152222  {
    153     nm->synchronize();
     223    nm->synchronize( 1000 );
    154224    /* simulate the network delay */
    155225    SDL_Delay(50);
     
    168238}
    169239
    170 
     240bool testCB( MessageId messageId, byte * data, int dataLength, void * someData, int userId )
     241{
     242  printf("GOT MESSAGE: %s\n", data);
     243  return true;
     244}
    171245
    172246/**
     
    178252int startServer(int argc, char** argv)
    179253{
    180   if( argc <= 2)
    181   {
    182     printf(" Wrong arguments try following notations:\n");
    183     printf("   --server [port number]\n");
    184     return 0;
    185   }
    186 
    187   int port = atoi(argv[2]);
    188   printf("Starting Server on port %i\n", port);
     254
     255
     256  State::setOnline(true);
     257  SharedNetworkData::getInstance()->setGameServer( true );
     258  printf("Starting Server on port %i\n", 9999);
    189259
    190260  NetworkManager* netMan = NetworkManager::getInstance();
    191   Synchronizeable* ss = new SimpleSync("Server\0");
    192 
    193   netMan->createServer(/**ss, */port);
     261 
     262  netMan->initialize();
     263 
     264  netMan->createServer(/**ss, */ 9999);
     265 
     266  SimpleSync* ss = new SimpleSync("Server");
     267  ss->setSynchronized( true );
     268 
     269  NetworkLog::getInstance()->listen( 8888 );
     270
     271  //MessageManager::getInstance()->initUser( 1 );
     272  MessageManager::getInstance()->registerMessageHandler( TESTMESSAGEID, testCB, NULL );
     273 
    194274  SDL_Delay(20);
    195275
    196276  for(;;)
    197277  {
    198     netMan->synchronize();
    199     SDL_Delay(1000);
     278    MessageManager::getInstance()->sendMessage( TESTMESSAGEID, (byte*)"server to client", 18, RT_ALL, 0, MP_HIGHBANDWIDTH );
     279    netMan->synchronize( 100 );
     280    SDL_Delay(100);
     281    ss->debug();
    200282  }
    201283
     
    210292int startClient(int argc, char** argv)
    211293{
     294
     295
     296  State::setOnline(true);
     297  NetworkManager* netMan = NetworkManager::getInstance();
     298 
     299
     300  netMan->initialize();
     301 
     302  std::string host;
     303 
     304  if ( argc > 2 )
     305    host = argv[2];
     306  else
     307    host = "localhost";
     308 
     309  netMan->establishConnection(host, 9999);
     310 
     311//  SimpleSync* ss = new SimpleSync("SimpleSync");
     312//  ss->setSynchronized( true );
     313//  netMan->connectSynchronizeable( *ss );
     314 
     315  NetworkLog::getInstance()->listen( 7777 );
     316
     317  SimpleSync * ss = NULL;
     318 
     319  //MessageManager::getInstance()->initUser( 0 );
     320  MessageManager::getInstance()->registerMessageHandler( TESTMESSAGEID, testCB, NULL );
     321 
     322  for(;;)
     323  {
     324    netMan->synchronize( 100 );
     325    MessageManager::getInstance()->sendMessage( TESTMESSAGEID, (byte*)"client to server", 18, RT_ALL, 0, MP_HIGHBANDWIDTH );
     326    ss = dynamic_cast<SimpleSync*>(ClassList::getObject( "Server", CL_SIMPLE_SYNC ) );
     327    SDL_Delay(100);
     328    if (ss)
     329      ss->debug();
     330  }
     331
     332
     333  delete netMan;
     334  delete ss;
     335
     336  return 0;
     337}
     338
     339
     340
     341int startListen(int argc, char** argv)
     342{
    212343  if( argc < 3)
    213344  {
    214345    printf(" Wrong arguments try following notations:\n");
    215     printf("   --client [server ip] [port number]\n");
    216     printf("   --client [server name] [port number]\n");
     346    printf("   --listen [server ip] [port number]\n");
     347    printf("   --listen [server name] [port number]\n");
    217348    return 0;
    218349  }
     
    228359
    229360  NetworkManager* netMan = NetworkManager::getInstance();
    230   Synchronizeable* ss = new SimpleSync("Client\0");
    231 
    232   netMan->establishConnection((const char*)"localhost", port/*,ip, *ss*/);
     361  Synchronizeable* ss = new SimpleSync("SimpleSync\0");
     362
     363  netMan->establishConnection( name, port );
     364  netMan->connectSynchronizeable( *ss );
    233365
    234366  for(;;)
    235367  {
    236     netMan->synchronize();
    237     SDL_Delay(500);
     368    netMan->synchronize( 1000 );
     369    SDL_Delay(10);
    238370  }
    239371
     
    245377}
    246378
    247 
    248 
    249 int startListen(int argc, char** argv)
    250 {
    251   if( argc < 3)
    252   {
    253     printf(" Wrong arguments try following notations:\n");
    254     printf("   --listen [server ip] [port number]\n");
    255     printf("   --listen [server name] [port number]\n");
    256     return 0;
    257   }
    258 
    259   char* name = argv[2];
    260   int port = atoi(argv[3]);
    261   printf("Connecting to %s, on port %i\n", name, port);
    262 
    263   IPaddress ip;
    264   int error = SDLNet_ResolveHost(&ip, name, port);
    265   if(error == -1)
    266     printf("\n\nerror on address resolution, program inconsistancy\n\n");
    267 
    268   NetworkManager* netMan = NetworkManager::getInstance();
    269   Synchronizeable* ss = new ReadSync("WriteSync\0");
    270 
    271   netMan->establishConnection(ip, *ss);
    272 
    273   for(;;)
    274   {
    275     netMan->synchronize();
    276     SDL_Delay(10);
    277   }
    278 
    279 
    280   delete netMan;
    281   delete ss;
    282 
    283   return 0;
    284 }
    285 
    286379void testFloatConverter(float f)
    287380{
     381#if 0
    288382  char* s = Converter::floatToBinString(f);
    289383  printf("%f = ", f);
     
    293387  printf("Byte Array: ");
    294388  for (int i = 0; i < 4; i++)
    295     printf("%i  ", res[i]);
     389//    printf("%i  ", res[i]);
    296390  printf("\n");
    297391
    298392  float b = Converter::byteArrayToFloat(res);
    299393  printf("ReConvert: %f \n", b);
     394#endif
    300395}
    301396
    302397void testFloatConverter2(float f)
    303398{
     399#if 0
    304400  char* s = Converter::floatToBinString(f);
    305401  printf("### %f = ", f);
     
    314410  float b = Converter::_byteArrayToFloat(res);
    315411  printf("ReConvert: %f \n", b);
     412#endif
    316413}
    317414int converter(int argc, char** argv)
     
    435532
    436533
    437 bool ShellBuffer::addBufferLineStatic(const char* line, ...)
    438 {
     534//bool ShellBuffer::addBufferLineStatic(const char* line, ...)
     535//{
    439536  //va_list arguments;
    440537  //vprintf(line, arguments);
    441   printf("%s", line);
    442 }
     538  //  printf("%s", line);
     539//}
  • trunk/src/subprojects/network/simple_sync.cc

    r6634 r7954  
    2222#include "simple_sync.h"
    2323
     24#include "class_id.h"
     25#include "fast_factory.h"
     26#include "lib/util/loading/factory.h"
     27
    2428#include "debug.h"
     29
     30CREATE_FACTORY(SimpleSync, CL_SIMPLE_SYNC);
    2531
    2632
     
    2834 *  default constructor
    2935 */
    30 SimpleSync::SimpleSync(const char* name)
    31   : Synchronizeable()
     36SimpleSync::SimpleSync( std::string name )
    3237{
    33   /* define the local buffer size */
    34   this->outLength = 10;
    35   this->recLength = 0;
    36   this->inLength = 40;
    37   this->outData = new byte[this->outLength];
    38   this->inData = new byte[this->inLength];
    39 
    40   /* init the buffer data */
    41   for( int i = 0; i < this->outLength; i++)
    42   {
    43     this->outData[i] = i;
    44   }
    45   for( int i = 0; i < this->inLength; i++)
    46   {
    47     this->inData[i] = 0;
    48   }
    49 
     38  setName( name );
     39  this->setClassID( CL_SIMPLE_SYNC, "SimpleSync" );
     40  in = 0;
     41  out = 1;
     42  syncStr = "hallo test test";
     43  id = this->registerVarId( new SynchronizeableInt( &in, &out, "var", PERMISSION_ALL ) );
     44  registerVar( new SynchronizeableString( &syncStr, &syncStr, "syncStr" ) );
    5045}
    5146
     
    5651SimpleSync::~SimpleSync()
    5752{
    58   if( this->outData)
    59     delete[] this->outData;
    60   if( this->inData)
    61     delete[] this->inData;
     53}
     54
     55void SimpleSync::debug( )
     56{
     57  printf("IN: %d OUT: %d\n", in, out);
     58  printf("str: %s\n", syncStr.c_str());
     59}
     60
     61SimpleSync::SimpleSync( const TiXmlElement * root )
     62{
     63  setName( "" );
     64  this->setClassID( CL_SIMPLE_SYNC, "SimpleSync" );
     65  in = 0;
     66  out = 1;
     67  syncStr = "hallo test test";
     68  id = this->registerVarId( new SynchronizeableInt( &in, &out, "var", PERMISSION_ALL ) );
     69  registerVar( new SynchronizeableString( &syncStr, &syncStr, "syncStr" ) );
    6270}
    6371
    6472
    65 /**
    66  *  write data to Synchronizeable
    67  */
    68 int SimpleSync::writeBytes(const byte* data, int length, int sender)
    69 {
    70   PRINTF(0)("SimpleSync: got %i bytes of data\n", length);
    71   this->recLength = length;
    72   if(this->inLength < length)
    73     PRINTF(0)("ERROR: local buffer is smaller than the data to receive.\n");
    74 
    75   /* copy the data localy */
    76   for( int i = 0; i < length; i++)
    77   {
    78     this->inData[i] = data[i];
    79   }
    80   /* and debug output */
    81   this->writeDebug();
    82 }
    8373
    8474
    85 /**
    86  *  read data from Synchronizeable
    87  */
    88 int SimpleSync::readBytes(byte* data, int maxLength, int * reciever)
    89 {
    90   PRINTF(0)("SimpleSync: sent %i bytes of data\n", this->outLength);
    91 
    92   /* debug msg */
    93   this->readDebug();
    94 
    95   /* write the test message */
    96   for( int i = 0; i < this->outLength; i++)
    97     data[i] = this->outData[i];
    98 
    99   /* return the length of the test */
    100   return this->outLength;
    101 }
    102 
    103 
    104 void SimpleSync::writeDebug() const
    105 {
    106   PRINTF(0)("Write in bytes: \t(0 <-) |");
    107   for(int i = 0; i < this->recLength; i++)
    108   {
    109     PRINT(0)(" [%u] ",this->inData[i]);
    110   }
    111   PRINT(0)("|\n");
    112 }
    113 
    114 
    115 void SimpleSync::readDebug() const
    116 {
    117   PRINTF(0)("Read out bytes: \t(0 ->) |");
    118   for(int i = 0; i < this->outLength; i++)
    119   {
    120     PRINT(0)(" [%u] ",this->outData[i]);
    121   }
    122   PRINT(0)("|\n");
    123 }
  • trunk/src/subprojects/network/simple_sync.h

    r6981 r7954  
    1313  {
    1414  public:
    15     SimpleSync(const char* name);
     15    SimpleSync( std::string name);
     16    SimpleSync(const TiXmlElement* root = NULL);
    1617    virtual ~SimpleSync();
    17 
    18     virtual int writeBytes(const byte* data, int length, int sender);
    19     virtual int readBytes(byte* data, int maxLength, int * reciever);
     18   
     19    void debug();
    2020
    2121
    2222  private:
    23     virtual void writeDebug() const;
    24     virtual void readDebug() const;
    25 
    26 
    27   private:
    28     byte* inData;
    29     int   inLength;
    30     int   recLength;
    31     byte* outData;
    32     int   outLength;
     23    int in;
     24    int out;
     25    std::string syncStr;
     26    int id;
    3327  };
    3428
  • trunk/src/util/multiplayer_team_deathmatch.cc

    r7810 r7954  
    203203      if ( terrz < terrain->getHeight( terrx, terry ) && ss->getAbsCoor().x > -1000 )
    204204      {
    205         //PRINTF(0)("COLLLLLLIIIIIDDDDEEEE\n");
    206         ss->networkCollisionList.push_back( 1234567890 );
    207         ss->doCollideNetwork( 1234567890 );
     205        //TODO handle this
    208206      }
    209       //PRINTF(0)("x = %f, y = %f, z = %f, height = %f\n", terrx, terry, terrz, terrain->getHeight( terrx, terry ));
    210       //ss->setRelCoorSoft( ss->getAbsCoor().x, terrain->getHeight( terrx, terry )-offsety, ss->getAbsCoor().z );
     207
    211208
    212209      float dist = (dynamic_cast<Playable*>(*it)->getAbsCoor() - big_left).len();
     
    222219        if((*it)->isA(CL_SPACE_SHIP))
    223220        {
    224           dynamic_cast<SpaceShip*>(*it)->networkCollisionList.push_back(1163692);
    225           dynamic_cast<SpaceShip*>(*it)->doCollideNetwork(11636922);
     221          //TODO handle this
    226222        }
    227223      }
  • trunk/src/world_entities/environments/water.cc

    r7370 r7954  
    5959  // To test the Wave equation
    6060  //this->wave(5.0,4.0, 1, 10);
     61 
     62  height_handle = registerVarId( new SynchronizeableFloat( &height, &height, "height" ) );
     63  resX_handle = registerVarId( new SynchronizeableUInt( &resX, &resX, "resX" ) );
     64  resY_handle = registerVarId( new SynchronizeableUInt( &resY, &resY, "resY" ) );
     65  sizeX_handle = registerVarId( new SynchronizeableFloat( &sizeX, &sizeX, "sizeX" ) );
     66  sizeY_handle = registerVarId( new SynchronizeableFloat( &sizeY, &sizeY, "sizeY" ) );
    6167}
    6268
     
    291297
    292298
    293 /**
    294  * Writes data from network containing information about the state
    295  * @param data pointer to data
    296  * @param length length of data
    297  * @param sender hostID of sender
    298  */
    299 int Water::writeBytes( const byte * data, int length, int sender )
    300 {
    301   setRequestedSync( false );
    302   setIsOutOfSync( false );
    303 
    304   SYNCHELP_READ_BEGIN();
    305 
    306   SYNCHELP_READ_FKT( Water::writeState, NWT_WAT_STATE );
    307 
    308   return SYNCHELP_READ_N;
    309 }
    310 
    311 
    312 /**
    313  * data copied in data will bee sent to another host
    314  * @param data pointer to data
    315  * @param maxLength max length of data
    316  * @return the number of bytes writen
    317  */
    318 int Water::readBytes( byte * data, int maxLength, int * reciever )
    319 {
    320   SYNCHELP_WRITE_BEGIN();
    321 
    322   if ( isOutOfSync() && !requestedSync() && this->getHostID()!=this->getOwner() )
    323   {
    324     (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
    325     setRequestedSync( true );
    326   }
    327 
    328   int rec = this->getRequestSync();
    329   if ( rec > 0 )
    330   {
    331     *reciever = rec;
    332     SYNCHELP_WRITE_FKT( Water::readState, NWT_WAT_STATE );
    333   }
    334 
    335   *reciever = 0;
    336   return SYNCHELP_WRITE_N;
    337 }
    338 
    339 
    340 
    341 /**
    342  * data copied in data will bee sent to another host
    343  * @param data pointer to data
    344  * @param maxLength max length of data
    345  * @return the number of bytes writen
    346  */
    347 int Water::readState( byte * data, int maxLength )
    348 {
    349   SYNCHELP_WRITE_BEGIN();
    350 
    351   SYNCHELP_WRITE_FKT( WorldEntity::readState, NWT_WAT_WE_STATE );
    352 
    353   // sync the size
    354   SYNCHELP_WRITE_FLOAT( this->sizeX, NWT_WAT_SIZEX );
    355   SYNCHELP_WRITE_FLOAT( this->sizeY, NWT_WAT_SIZEY );
    356 
    357   //sync resolution
    358   SYNCHELP_WRITE_INT( this->resX, NWT_WAT_RESX );
    359   SYNCHELP_WRITE_INT( this->resY, NWT_WAT_RESY );
    360 
    361   //sync the height
    362   SYNCHELP_WRITE_FLOAT( this->height, NWT_WAT_HEIGHT );
    363 
    364   return SYNCHELP_WRITE_N;
    365 }
    366 
    367 
    368 /**
    369  * Writes data from network containing information about the state
    370  * @param data pointer to data
    371  * @param length length of data
    372  * @param sender hostID of sender
    373  */
    374 int Water::writeState( const byte * data, int length, int sender )
    375 {
    376   SYNCHELP_READ_BEGIN();
    377 
    378   SYNCHELP_READ_FKT( WorldEntity::writeState, NWT_WAT_WE_STATE );
    379 
    380   float f1, f2;
    381   int i1, i2;
    382 
    383   //read the size
    384   SYNCHELP_READ_FLOAT( f1, NWT_WAT_SIZEX );
    385   SYNCHELP_READ_FLOAT( f2, NWT_WAT_SIZEY );
    386   this->sizeX = f1;
    387   this->sizeY = f2;
    388   PRINTF(0)("Setting Water to size: %f x %f\n", f1, f2);
    389 
    390   //read the resolution
    391   SYNCHELP_READ_INT( i1, NWT_WAT_RESX );
    392   SYNCHELP_READ_INT( i2, NWT_WAT_RESY );
    393   this->resX = i1;
    394   this->resY = i2;
    395   PRINTF(0)("Setting Water to resolution: %i x %i\n", i1, i2);
    396 
    397   //read the height
    398   SYNCHELP_READ_FLOAT( f1, NWT_WAT_HEIGHT );
    399   this->height = f1;
    400 
    401   this->rebuildGrid();
    402 
    403   return SYNCHELP_READ_N;
    404 }
    405 
    406 
     299
     300/**
     301 * function to handle changes in synced vars
     302 * @param id ids which have changed
     303 */
     304void Water::varChangeHandler( std::list< int > & id )
     305{
     306  if ( std::find( id.begin(), id.end(), height_handle ) != id.end() ||
     307       std::find( id.begin(), id.end(), resX_handle ) != id.end() ||
     308       std::find( id.begin(), id.end(), resY_handle ) != id.end() ||
     309       std::find( id.begin(), id.end(), sizeX_handle ) != id.end() ||
     310       std::find( id.begin(), id.end(), sizeY_handle ) != id.end()
     311     )
     312  {
     313    this->rebuildGrid();
     314  }
     315 
     316  WorldEntity::varChangeHandler( id );
     317}
  • trunk/src/world_entities/environments/water.h

    r7125 r7954  
    3838   void draw() const;
    3939   void tick(float dt);
    40 
    41    virtual int writeBytes(const byte* data, int length, int sender);
    42    virtual int readBytes(byte* data, int maxLength, int * reciever);
    43 
    44    int writeState( const byte * data, int length, int sender );
    45    int readState( byte * data, int maxLength );
     40   
     41   virtual void varChangeHandler( std::list<int> & id );
    4642
    4743  private:
     
    5652    Material        waterMaterial;
    5753    Shader*         waterShader;
     54   
    5855    float           height;          //!< The hight of the Water
     56    int             height_handle;   //!< Handle to notify about changes of height
    5957
    60     unsigned int    resX, resY;
    61     float           sizeX, sizeY;
     58    unsigned int    resX, resY;      //!< Grid resolution
     59    int             resX_handle;     //!< Handle to notify about changes of resX
     60    int             resY_handle;     //!< Handle to notify about changes of resY
     61    float           sizeX, sizeY;    //!< waters size
     62    int             sizeX_handle;    //!< Handle to notify about changes of sizeX
     63    int             sizeY_handle;    //!< Handle to notify about changes of sizeY
    6264
    6365    float phase;
  • trunk/src/world_entities/npcs/ground_turret.cc

    r7193 r7954  
    180180  Explosion::explode(this, Vector(10,10,10));
    181181}
    182 
    183 /**
    184  * Writes data from network containing information about the state
    185  * @param data pointer to data
    186  * @param length length of data
    187  * @param sender hostID of sender
    188  */
    189 int GroundTurret::writeBytes( const byte * data, int length, int sender )
    190 {
    191   setRequestedSync( false );
    192   setIsOutOfSync( false );
    193 
    194   SYNCHELP_READ_BEGIN();
    195 
    196   SYNCHELP_READ_FKT( WorldEntity::writeState, NWT_GT_WE_STATE );
    197 
    198   return SYNCHELP_READ_N;
    199 }
    200 
    201 /**
    202  * data copied in data will bee sent to another host
    203  * @param data pointer to data
    204  * @param maxLength max length of data
    205  * @return the number of bytes writen
    206  */
    207 int GroundTurret::readBytes( byte * data, int maxLength, int * reciever )
    208 {
    209   SYNCHELP_WRITE_BEGIN();
    210 
    211   if ( isOutOfSync() && !requestedSync() && this->getHostID()!=this->getOwner() )
    212   {
    213     (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
    214     setRequestedSync( true );
    215   }
    216 
    217   int rec = this->getRequestSync();
    218   if ( rec > 0 )
    219   {
    220     *reciever = rec;
    221 
    222     SYNCHELP_WRITE_FKT( WorldEntity::readState, NWT_GT_WE_STATE );
    223 
    224   }
    225 
    226   *reciever = 0;
    227   return SYNCHELP_WRITE_N;
    228 }
  • trunk/src/world_entities/npcs/ground_turret.h

    r7102 r7954  
    3030  virtual void tick(float time);
    3131
    32   virtual int writeBytes(const byte* data, int length, int sender);
    33   virtual int readBytes(byte* data, int maxLength, int * reciever);
    34 
    3532 private:
    3633   PNode  weaponHolder[2];
  • trunk/src/world_entities/playable.cc

    r7868 r7954  
    6262
    6363  this->score = 0;
    64   this->oldScore = 0;
    6564  this->collider = NULL;
    6665
    6766  this->bDead = false;
     67
     68  registerVar( new SynchronizeableInt( &score, &score, "score" ) );
     69  registerVar( new SynchronizeableBool( &bFire, &bFire, "bFire", PERMISSION_OWNER));
    6870}
    6971
     
    484486
    485487
    486 #define DATA_FLAGS    1
    487 #define DATA_SCORE    2
    488 
    489 #define FLAGS_bFire   1
    490 
    491 int Playable::writeSync( const byte * data, int length, int sender )
    492 {
    493   SYNCHELP_READ_BEGIN();
    494 
    495   byte b;
    496   SYNCHELP_READ_BYTE( b, NWT_PL_B );
    497 
    498   byte flags;
    499 
    500   if ( b == DATA_FLAGS )
    501   {
    502     SYNCHELP_READ_BYTE( flags, NWT_PL_FLAGS );
    503 
    504     bFire = (flags & FLAGS_bFire) != 0;
    505 
    506     return SYNCHELP_READ_N;
    507   }
    508 
    509   if ( b == DATA_SCORE )
    510   {
    511     int newScore;
    512     SYNCHELP_READ_BYTE( newScore, NWT_PL_SCORE );
    513     setScore( newScore );
    514 
    515     return SYNCHELP_READ_N;
    516   }
    517 
    518   return SYNCHELP_READ_N;
    519 }
    520 
    521 int Playable::readSync( byte * data, int maxLength )
    522 {
    523   SYNCHELP_WRITE_BEGIN();
    524 
    525   if ( score != oldScore && isServer() )
    526   {
    527     SYNCHELP_WRITE_BYTE( DATA_SCORE, NWT_PL_B);
    528     SYNCHELP_WRITE_INT( score, NWT_PL_SCORE );
    529     oldScore = score;
    530 
    531     return SYNCHELP_WRITE_N;
    532   }
    533 
    534   byte flags = 0;
    535 
    536   if ( bFire )
    537     flags |= FLAGS_bFire;
    538 
    539 
    540   SYNCHELP_WRITE_BYTE( DATA_FLAGS, NWT_PL_B);
    541   SYNCHELP_WRITE_BYTE( flags, NWT_PL_FLAGS );
    542   oldFlags = flags;
    543 
    544 
    545   return SYNCHELP_WRITE_N;
    546 }
    547 
    548 bool Playable::needsReadSync( )
    549 {
    550   if ( score != oldScore && isServer() )
    551     return true;
    552 
    553   byte flags = 0;
    554 
    555   if ( bFire )
    556     flags |= FLAGS_bFire;
    557 
    558   return flags!=oldFlags;
    559 }
    560 
    561488
    562489/**
  • trunk/src/world_entities/playable.h

    r7412 r7954  
    8181  virtual void tick(float dt);
    8282
    83   // NETWORK
    84   int       writeSync(const byte* data, int length, int sender);
    85   int       readSync(byte* data, int maxLength );
    86   bool      needsReadSync();
    87 
    88 
    8983  // Transformations:
    9084  static Playable::Playmode stringToPlaymode(const std::string& playmode);
     
    115109  int                   oldFlags;           //!< Used for synchronisation
    116110
    117   int                   score;
    118   int                   oldScore;
     111  int                   score;              //!< players score
    119112
    120113  bool                  bDead;
  • trunk/src/world_entities/power_ups/laser_power_up.cc

    r7193 r7954  
    120120}
    121121
    122 int LaserPowerUp::writeBytes( const byte * data, int length, int sender )
    123 {
    124   setRequestedSync( false );
    125   setIsOutOfSync( false );
    126122
    127   SYNCHELP_READ_BEGIN();
    128 
    129   SYNCHELP_READ_FKT( PowerUp::writeState, NWT_LPU_WE_STATE );
    130 
    131   return SYNCHELP_READ_N;
    132 }
    133 
    134 
    135 
    136 int LaserPowerUp::readBytes( byte * data, int maxLength, int * reciever )
    137 {
    138   if ( isOutOfSync() && !requestedSync() && this->getHostID()!=this->getOwner() )
    139   {
    140     (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
    141     setRequestedSync( true );
    142   }
    143 
    144   int rec = this->getRequestSync();
    145   if ( rec > 0 )
    146   {
    147     *reciever = rec;
    148 
    149     SYNCHELP_WRITE_BEGIN();
    150 
    151     SYNCHELP_WRITE_FKT( PowerUp::readState, NWT_LPU_WE_STATE );
    152 
    153     return SYNCHELP_WRITE_N;
    154   }
    155 
    156   *reciever = 0;
    157   return 0;
    158 }
    159 
  • trunk/src/world_entities/power_ups/laser_power_up.h

    r6512 r7954  
    2626  virtual void draw() const;
    2727
    28   virtual int writeBytes(const byte* data, int length, int sender);
    29   virtual int readBytes(byte* data, int maxLength, int * reciever );
    30 
    3128  private:
    3229   void init();
  • trunk/src/world_entities/power_ups/param_power_up.cc

    r7221 r7954  
    4343  if( root != NULL)
    4444    this->loadParams(root);
     45 
     46  registerVar( new SynchronizeableInt( (int*)&type, (int*)&type, "type" ) );
     47  registerVar( new SynchronizeableFloat( &value, &value, "value" ) );
     48  registerVar( new SynchronizeableFloat( &max_value, &max_value, "max_value" ) );
     49  registerVar( new SynchronizeableFloat( &min_value, &min_value, "min_value" ) );
    4550}
    4651
     
    119124}
    120125
    121 int ParamPowerUp::writeBytes( const byte * data, int length, int sender )
    122 {
    123   setRequestedSync( false );
    124   setIsOutOfSync( false );
    125 
    126   SYNCHELP_READ_BEGIN();
    127 
    128   SYNCHELP_READ_FKT( PowerUp::writeState, NWT_PPU_WE_STATE );
    129 
    130   int i;
    131   SYNCHELP_READ_INT( i, NWT_PPU_TYPE );
    132   this->type = (EnumParamPowerUpType)i;
    133   SYNCHELP_READ_FLOAT( this->value, NWT_PPU_VALUE );
    134 
    135   if ( this->value != 0 )
    136   {
    137     SYNCHELP_READ_FLOAT( this->min_value, NWT_PPU_MINVALUE );
    138     SYNCHELP_READ_FLOAT( this->max_value, NWT_PPU_MAXVALUE );
    139     respawn();
    140   }
    141 
    142   return SYNCHELP_READ_N;
    143 }
    144 
    145 
    146 
    147 int ParamPowerUp::readBytes( byte * data, int maxLength, int * reciever )
    148 {
    149   if ( isOutOfSync() && !requestedSync() && this->getHostID()!=this->getOwner() )
    150   {
    151     (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
    152     setRequestedSync( true );
    153   }
    154 
    155   int rec = this->getRequestSync();
    156   if ( rec > 0 )
    157   {
    158     *reciever = rec;
    159 
    160     SYNCHELP_WRITE_BEGIN();
    161 
    162     SYNCHELP_WRITE_FKT( PowerUp::readState, NWT_PPU_WE_STATE );
    163 
    164     int i = (int)this->type;
    165     SYNCHELP_WRITE_INT( i, NWT_PPU_TYPE );
    166     SYNCHELP_WRITE_FLOAT( this->value, NWT_PPU_VALUE );
    167 
    168     if ( this->value != 0 )
    169     {
    170       SYNCHELP_WRITE_FLOAT( this->min_value, NWT_PPU_MINVALUE );
    171       SYNCHELP_WRITE_FLOAT( this->max_value, NWT_PPU_MAXVALUE );
    172     }
    173 
    174     return SYNCHELP_WRITE_N;
    175   }
    176 
    177   *reciever = 0;
    178   return 0;
    179 }
    180 
  • trunk/src/world_entities/power_ups/param_power_up.h

    r7221 r7954  
    3232  float getValue();
    3333
    34   virtual int writeBytes(const byte* data, int length, int sender);
    35   virtual int readBytes(byte* data, int maxLength, int * reciever );
    36 
    3734protected:
    3835  virtual void respawn();
  • trunk/src/world_entities/power_ups/power_up.cc

    r7460 r7954  
    201201
    202202
    203 /********************************************************************************************
    204  NETWORK STUFF
    205  ********************************************************************************************/
    206 
    207 
    208 /**
    209  * data copied in data will bee sent to another host
    210  * @param data pointer to data
    211  * @param maxLength max length of data
    212  * @return the number of bytes writen
    213  */
    214 int PowerUp::readState( byte * data, int maxLength )
    215 {
    216   SYNCHELP_WRITE_BEGIN();
    217   SYNCHELP_WRITE_FKT( WorldEntity::readState, NWT_PU_WE_STATE );
    218   return SYNCHELP_WRITE_N;
    219 }
    220 
    221 
    222 /**
    223  * Writes data from network containing information about the state
    224  * @param data pointer to data
    225  * @param length length of data
    226  * @param sender hostID of sender
    227  */
    228 int PowerUp::writeState( const byte * data, int length, int sender )
    229 {
    230   SYNCHELP_READ_BEGIN();
    231   SYNCHELP_READ_FKT( WorldEntity::writeState, NWT_PU_WE_STATE );
    232   return SYNCHELP_READ_N;
    233 }
    234 
  • trunk/src/world_entities/power_ups/power_up.h

    r7460 r7954  
    3434  void setRespawnTime(const float respawn);
    3535
    36   int       writeState(const byte* data, int length, int sender);
    37   int       readState(byte* data, int maxLength );
    38 
    3936protected:
    4037  PowerUp(float r, float g, float b);
  • trunk/src/world_entities/power_ups/turret_power_up.cc

    r7193 r7954  
    115115  glPopMatrix();
    116116}
    117 
    118 
    119 
    120 
    121 /********************************************************************************************
    122  NETWORK STUFF
    123  ********************************************************************************************/
    124 
    125 
    126 int TurretPowerUp::writeBytes( const byte * data, int length, int sender )
    127 {
    128   setRequestedSync( false );
    129   setIsOutOfSync( false );
    130 
    131   SYNCHELP_READ_BEGIN();
    132 
    133   SYNCHELP_READ_FKT( PowerUp::writeState, NWT_TPU_WE_STATE );
    134 
    135   return SYNCHELP_READ_N;
    136 }
    137 
    138 
    139 int TurretPowerUp::readBytes( byte * data, int maxLength, int * reciever )
    140 {
    141   if ( isOutOfSync() && !requestedSync() && this->getHostID()!=this->getOwner() )
    142   {
    143     (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
    144     setRequestedSync( true );
    145   }
    146 
    147   int rec = this->getRequestSync();
    148   if ( rec > 0 )
    149   {
    150     *reciever = rec;
    151 
    152     SYNCHELP_WRITE_BEGIN();
    153 
    154     SYNCHELP_WRITE_FKT( PowerUp::readState, NWT_TPU_WE_STATE );
    155 
    156     return SYNCHELP_WRITE_N;
    157   }
    158 
    159   *reciever = 0;
    160   return 0;
    161 }
  • trunk/src/world_entities/power_ups/turret_power_up.h

    r7065 r7954  
    2424  virtual void draw() const;
    2525
    26   virtual int writeBytes(const byte* data, int length, int sender);
    27   virtual int readBytes(byte* data, int maxLength, int * reciever );
    28 
    2926  private:
    3027   void init();
  • trunk/src/world_entities/power_ups/weapon_power_up.cc

    r7370 r7954  
    103103}
    104104
    105 int WeaponPowerUp::writeBytes( const byte * data, int length, int sender )
    106 {
    107   setRequestedSync( false );
    108   setIsOutOfSync( false );
    109 
    110   SYNCHELP_READ_BEGIN();
    111 
    112   SYNCHELP_READ_FKT( PowerUp::writeState, NWT_WPU_WE_STATE );
    113 
    114   //TODO: sync weapon class ( see loadParams )
    115 
    116   return SYNCHELP_READ_N;
    117 }
    118 
    119 
    120 
    121 int WeaponPowerUp::readBytes( byte * data, int maxLength, int * reciever )
    122 {
    123   if ( isOutOfSync() && !requestedSync() && this->getHostID()!=this->getOwner() )
    124   {
    125     (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
    126     setRequestedSync( true );
    127   }
    128 
    129   int rec = this->getRequestSync();
    130   if ( rec > 0 )
    131   {
    132     *reciever = rec;
    133 
    134     SYNCHELP_WRITE_BEGIN();
    135 
    136     SYNCHELP_WRITE_FKT( PowerUp::readState, NWT_WPU_WE_STATE );
    137 
    138     //TODO: sync weapon class ( see loadParams )
    139 
    140     return SYNCHELP_WRITE_N;
    141   }
    142 
    143   *reciever = 0;
    144   return 0;
    145 }
  • trunk/src/world_entities/power_ups/weapon_power_up.h

    r7221 r7954  
    2424  void setWeaponClass(const std::string& name);
    2525
    26   virtual int writeBytes(const byte* data, int length, int sender);
    27   virtual int readBytes(byte* data, int maxLength, int * reciever );
    28 
    2926  bool process(WeaponManager* manager);
    3027
  • trunk/src/world_entities/skybox.cc

    r7919 r7954  
    9595{
    9696  this->rebuild();
     97 
     98  textureName_handle = registerVarId( new SynchronizeableString( &textureName, &textureName, "textureName") );
     99  size_handle = registerVarId( new SynchronizeableFloat( &size, &size, "size" ) );
    97100}
    98101
     
    290293}
    291294
    292 int SkyBox::writeBytes( const byte * data, int length, int sender )
    293 {
    294   setRequestedSync( false );
    295   setIsOutOfSync( false );
    296 
    297   SYNCHELP_READ_BEGIN();
    298 
    299   SYNCHELP_READ_FKT( WorldEntity::writeState, NWT_SB_WE_STATE );
    300 
    301   SYNCHELP_READ_FLOAT( size, NWT_SB_SIZE );
    302   if ( !this->textureName.empty() )
     295void SkyBox::varChangeHandler( std::list< int > & id )
     296{
     297  bool somethinChanged = false;
     298 
     299  if ( std::find( id.begin(), id.end(), textureName_handle ) != id.end() )
    303300  {
    304     textureName = "";
     301    somethinChanged = true;
     302    setTexture( textureName );
    305303  }
    306   std::string texName;
    307   SYNCHELP_READ_STRING( texName, NWT_SB_TEXTURENAME );
    308 
    309   this->setSize( size );
    310   this->setTextureAndType( texName, "jpg" );
    311   this->rebuild();
    312 
    313   return SYNCHELP_READ_N;
    314 }
    315 
    316 
    317 
    318 int SkyBox::readBytes( byte * data, int maxLength, int * reciever )
    319 {
    320   if ( isOutOfSync() && !requestedSync() && this->getHostID()!=this->getOwner() )
     304 
     305  if ( std::find( id.begin(), id.end(), size_handle ) != id.end() )
    321306  {
    322     (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
    323     setRequestedSync( true );
     307    somethinChanged = true;
    324308  }
    325 
    326   int rec = this->getRequestSync();
    327   if ( rec > 0 )
    328   {
    329     *reciever = rec;
    330 
    331     SYNCHELP_WRITE_BEGIN();
    332 
    333     SYNCHELP_WRITE_FKT( WorldEntity::readState, NWT_SB_WE_STATE );
    334 
    335     SYNCHELP_WRITE_FLOAT(this->size, NWT_SB_SIZE);
    336     SYNCHELP_WRITE_STRING(this->textureName, NWT_SB_TEXTURENAME);
    337 
    338     return SYNCHELP_WRITE_N;
    339   }
    340 
    341   *reciever = 0;
    342   return 0;
    343 }
    344 
    345 void SkyBox::writeDebug( ) const
    346 {
    347 }
    348 
    349 void SkyBox::readDebug( ) const
    350 {
    351 }
     309 
     310  rebuild();
     311 
     312  WorldEntity::varChangeHandler( id );
     313}
  • trunk/src/world_entities/skybox.h

    r7328 r7954  
    5858  static void disableCubeMap();
    5959
    60   virtual int       writeBytes(const byte* data, int length, int sender);
    61   virtual int       readBytes(byte* data, int maxLength, int * reciever);
    62   virtual void      writeDebug() const;
    63   virtual void      readDebug() const;
     60  virtual void varChangeHandler( std::list<int> & id );
    6461
    6562 private:
     
    7269  float           textureSize;     //!< this is the length of a texture (assumes a square texture)
    7370  std::string     textureName;     //!< Name of the Texture
     71 
     72  int textureName_handle;          //!< used to notify about changes of textureName
     73  int size_handle;                 //!< used to notify about changes of size
    7474
    7575};
  • trunk/src/world_entities/space_ships/hover.cc

    r7868 r7954  
    175175  this->getWeaponManager().getFixedTarget()->setParent(&this->cameraNode);
    176176  this->getWeaponManager().getFixedTarget()->setRelCoor(1000,0,0);
     177 
     178  // NETWORK THINGS
     179 
     180  registerVar( new SynchronizeableBool( &bForward, &bForward, "bForward", PERMISSION_OWNER ) );
     181  registerVar( new SynchronizeableBool( &bBackward, &bBackward, "bBackward", PERMISSION_OWNER ) );
     182  registerVar( new SynchronizeableBool( &bLeft, &bLeft, "bLeft", PERMISSION_OWNER ) );
     183  registerVar( new SynchronizeableBool( &bRight, &bRight, "bRight", PERMISSION_OWNER ) );
     184  registerVar( new SynchronizeableBool( &bAscend, &bAscend, "bAscend", PERMISSION_OWNER ) );
     185  registerVar( new SynchronizeableBool( &bDescend, &bDescend, "bDescend", PERMISSION_OWNER ) );
     186 
     187  registerVar( new SynchronizeableFloat( &rotation, &rotation, "rotation", PERMISSION_OWNER ) );
    177188}
    178189
  • trunk/src/world_entities/space_ships/space_ship.cc

    r7868 r7954  
    9393  if (root != NULL)
    9494    this->loadParams(root);
    95   else
    96   {
    97     //this->loadModel("models/ships/reap_#.obj");
    98     //TODO HACK this is only for network multiplayer games.
    99     if( this->getOwner()%2 == 0)
    100     {
    101       this->loadModel("models/ships/reap_#.obj");
    102       this->toList(OM_GROUP_00);
    103     }
    104     else
    105     {
    106       this->loadModel( "models/ships/fighter.obj" );
    107       this->toList(OM_GROUP_01);
    108     }
    109   }
    11095
    11196}
     
    234219  this->burstSystem->setColor(0.5, .5,.5,.8,.8);
    235220  this->burstSystem->setColor(1.0, .8,.8,.8,.0);
    236 
     221 
     222  registerVar( new SynchronizeableVector( &velocity, &velocity, "velocity" ) );
     223  registerVar( new SynchronizeableQuaternion( &mouseDir, &mouseDir, "mousedir", PERMISSION_OWNER ) );
     224
     225  registerVar( new SynchronizeableBool( &bUp, &bUp, "bUp", PERMISSION_OWNER ) );
     226  registerVar( new SynchronizeableBool( &bDown, &bDown, "bDown", PERMISSION_OWNER ) );
     227  registerVar( new SynchronizeableBool( &bLeft, &bLeft, "bLeft", PERMISSION_OWNER ) );
     228  registerVar( new SynchronizeableBool( &bRight, &bRight, "bRight", PERMISSION_OWNER ) );
     229  registerVar( new SynchronizeableBool( &bAscend, &bAscend, "bAscend", PERMISSION_OWNER ) );
     230  registerVar( new SynchronizeableBool( &bDescend, &bDescend, "bDescend", PERMISSION_OWNER ) );
     231  registerVar( new SynchronizeableBool( &bRollL, &bRollL, "bRollL", PERMISSION_OWNER ) );
     232  registerVar( new SynchronizeableBool( &bRollR, &bRollR, "bRollR", PERMISSION_OWNER ) );
    237233}
    238234
     
    306302    if ( isServer() )
    307303    {
    308       networkCollisionList.push_back( entity->getHealth() );
    309       doCollideNetwork( entity->getHealth() );
     304      //TODO handle this
    310305    }
    311306  }
     
    349344
    350345  // spaceship controlled movement
    351   if (this->getOwner() == this->getHostID())
     346  //if (this->getOwner() == this->getHostID())
    352347    this->calculateVelocity(time);
    353348
     
    509504
    510505
    511 #define MASK_bUp         1
    512 #define MASK_bDown       2
    513 #define MASK_bLeft       4
    514 #define MASK_bRight      8
    515 #define MASK_bAscend    16
    516 #define MASK_bDescend   32
    517 #define MASK_bRollL     64
    518 #define MASK_bRollR    128
    519 
    520 #define DATA_state       1
    521 #define DATA_flags       2
    522 #define DATA_mouse       3
    523 #define DATA_sync        4
    524 #define DATA_velocity    5
    525 #define DATA_playables   6
    526 #define DATA_collision   7
    527 
    528 int SpaceShip::writeBytes( const byte * data, int length, int sender )
    529 {
    530   SYNCHELP_READ_BEGIN();
    531 
    532   byte b;
    533 
    534   while ( SYNCHELP_READ_REMAINING()>0 )
    535   {
    536     SYNCHELP_READ_BYTE( b, NWT_SS_B );
    537 
    538     if ( b == DATA_state )
    539     {
    540       setRequestedSync( false );
    541       setIsOutOfSync( false );
    542       SYNCHELP_READ_FKT( WorldEntity::writeState, NWT_SS_WE_STATE );
    543 
    544       continue;
    545     }
    546 
    547     if ( b == DATA_flags )
    548     {
    549       if ( this->getOwner() != this->getHostID() )
    550       {
    551         byte flags = 0;
    552         SYNCHELP_READ_BYTE( flags, NWT_SS_FLAGS );
    553 
    554         bUp = (flags & MASK_bUp) != 0;
    555         bDown = (flags & MASK_bDown) != 0;
    556         bLeft = (flags & MASK_bLeft) != 0;
    557         bRight = (flags & MASK_bRight) != 0;
    558         bAscend = (flags & MASK_bAscend) != 0;
    559         bDescend = (flags & MASK_bDescend) != 0;
    560         bRollL = (flags & MASK_bRollL) != 0;
    561         bRollR = (flags & MASK_bRollR) != 0;
    562 
    563       }
    564       else
    565         assert(false);
    566 
    567       continue;
    568     }
    569 
    570     if ( b == DATA_mouse )
    571     {
    572       if ( this->getOwner() != this->getHostID() )
    573       {
    574         SYNCHELP_READ_FLOAT( mouseDir.w, NWT_SS_MOUSEDIRW );
    575         SYNCHELP_READ_FLOAT( mouseDir.v.x, NWT_SS_MOUSEDIRX );
    576         SYNCHELP_READ_FLOAT( mouseDir.v.y, NWT_SS_MOUSEDIRY );
    577         SYNCHELP_READ_FLOAT( mouseDir.v.z, NWT_SS_MOUSEDIRZ );
    578       }
    579       else
    580         assert(false);
    581 
    582       continue;
    583     }
    584 
    585     if ( b == DATA_sync )
    586     {
    587       if ( this->getOwner() != this->getHostID() )
    588       {
    589         SYNCHELP_READ_FKT( PNode::writeSync, NWT_SS_PN_SYNC );
    590       }
    591       else
    592         assert(false);
    593 
    594       continue;
    595     }
    596 
    597     if ( b == DATA_velocity )
    598     {
    599       if ( this->getOwner() != this->getHostID() )
    600       {
    601         SYNCHELP_READ_FLOAT( velocity.x, NWT_SS_VELX );
    602         SYNCHELP_READ_FLOAT( velocity.y, NWT_SS_VELY );
    603         SYNCHELP_READ_FLOAT( velocity.z, NWT_SS_VELZ );
    604       }
    605       else
    606         assert(false);
    607 
    608       continue;
    609     }
    610 
    611     if ( b == DATA_playables )
    612     {
    613       if ( this->getOwner() != this->getHostID() )
    614       {
    615         SYNCHELP_READ_FKT( Playable::writeSync, NWT_SS_PL_SYNC );
    616       }
    617       else
    618         assert(false);
    619     }
    620 
    621     if ( b == DATA_collision )
    622     {
    623       int n;
    624       float energy;
    625       SYNCHELP_READ_INT( n, NWT_SS_CO_N );
    626 
    627       for ( int i = 0; i<n; i++ )
    628       {
    629         SYNCHELP_READ_FLOAT( energy, NWT_SS_CO_CLID );
    630         doCollideNetwork( energy );
    631       }
    632     }
    633   }
    634 
    635   return SYNCHELP_READ_N;
    636 }
    637 
    638 
    639 
    640 int SpaceShip::readBytes( byte * data, int maxLength, int * reciever )
    641 {
    642   SYNCHELP_WRITE_BEGIN();
    643 
    644   if ( isOutOfSync() && !requestedSync() /*&& this->getHostID()!=this->getOwner()*/ )
    645   {
    646     (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
    647     setRequestedSync( true );
    648     PRINTF(0)("REQUESTED STATE %d\n", this->getUniqueID());
    649   }
    650 
    651   int rec = this->getRequestSync();
    652   if ( rec > 0 )
    653   {
    654     *reciever = rec;
    655 
    656     PRINTF(0)("SEND STATE %d %d\n", this->getUniqueID(), rec);
    657 
    658     SYNCHELP_WRITE_BYTE( (byte)DATA_state, NWT_SS_B );
    659 
    660     SYNCHELP_WRITE_FKT( WorldEntity::readState, NWT_SS_WE_STATE );
    661 
    662     return SYNCHELP_WRITE_N;
    663   }
    664 
    665   *reciever = 0 - this->getOwner();
    666   //TODO: implement with SYNCHELP_WRITE_SENT()
    667   bool sentSomething = false;
    668 
    669   if ( PNode::needsReadSync() && ( this->getHostID()==0 || this->getOwner() == this->getHostID() ) )
    670   {
    671     PRINTF(0)("sending PNode::readSync\n");
    672     SYNCHELP_WRITE_BYTE( DATA_sync, NWT_SS_B );
    673     SYNCHELP_WRITE_FKT( PNode::readSync, NWT_SS_PN_SYNC );
    674     sentSomething = true;
    675   }
    676 
    677   if ( this->getHostID()==0 || this->getHostID()==this->getOwner() )
    678   {
    679     byte mask = 0;
    680 
    681     if ( bUp )
    682       mask |= MASK_bUp;
    683     if ( bDown )
    684       mask |= MASK_bDown;
    685     if ( bLeft )
    686       mask |= MASK_bLeft;
    687     if ( bRight )
    688       mask |= MASK_bRight;
    689     if ( bAscend )
    690       mask |= MASK_bAscend;
    691     if ( bRollL )
    692       mask |= MASK_bRollL;
    693     if ( bRollR )
    694       mask |= MASK_bRollR;
    695 
    696 
    697     if ( mask != oldMask )
    698     {
    699       oldMask = mask;
    700       PRINTF(0)("sending mask\n");
    701       sentSomething = true;
    702       SYNCHELP_WRITE_BYTE( DATA_flags, NWT_SS_B );
    703       SYNCHELP_WRITE_BYTE( mask, NWT_SS_FLAGS );
    704     }
    705 #define __OFFSET_MDIR_W 0.01
    706 #define __OFFSET_MDIR_V 0.01
    707     if ( fabs( oldMouseDir.w - mouseDir.w ) > __OFFSET_MDIR_W ||
    708          fabs( oldMouseDir.v.x - mouseDir.v.x ) > __OFFSET_MDIR_V ||
    709          fabs( oldMouseDir.v.y - mouseDir.v.y ) > __OFFSET_MDIR_V ||
    710          fabs( oldMouseDir.v.z - mouseDir.v.z ) > __OFFSET_MDIR_V )
    711     {
    712       oldMouseDir = mouseDir;
    713 
    714       SYNCHELP_WRITE_BYTE( DATA_mouse, NWT_SS_B );
    715       PRINTF(0)("SENDING mousedir\n");
    716       sentSomething = true;
    717       SYNCHELP_WRITE_FLOAT( mouseDir.w, NWT_SS_MOUSEDIRW );
    718       SYNCHELP_WRITE_FLOAT( mouseDir.v.x, NWT_SS_MOUSEDIRX );
    719       SYNCHELP_WRITE_FLOAT( mouseDir.v.y, NWT_SS_MOUSEDIRY );
    720       SYNCHELP_WRITE_FLOAT( mouseDir.v.z, NWT_SS_MOUSEDIRZ );
    721     }
    722 #define __OFFSET_VEL 0.05
    723     if ( fabs( oldVelocity.x - velocity.x ) > __OFFSET_VEL*fabs(oldVelocity.x)+0.1 ||
    724          fabs( oldVelocity.y - velocity.y ) > __OFFSET_VEL*fabs(oldVelocity.y)+0.1 ||
    725          fabs( oldVelocity.z - velocity.z ) > __OFFSET_VEL*fabs(oldVelocity.z)+0.1 )
    726     {
    727       oldVelocity.x = velocity.x;
    728       oldVelocity.y = velocity.y;
    729       oldVelocity.z = velocity.z;
    730       PRINTF(0)("SENDING velocity\n");
    731       sentSomething = true;
    732       SYNCHELP_WRITE_BYTE( DATA_velocity, NWT_SS_B );
    733       SYNCHELP_WRITE_FLOAT( velocity.x, NWT_SS_VELX );
    734       SYNCHELP_WRITE_FLOAT( velocity.y, NWT_SS_VELY );
    735       SYNCHELP_WRITE_FLOAT( velocity.z, NWT_SS_VELZ );
    736     }
    737 
    738     while ( Playable::needsReadSync() )
    739     {
    740       sentSomething = true;
    741       PRINTF(0)("SYNCHELP_WRITE_FKT( Playable::readSync, NWT_SS_PL_SYNC )\n");
    742       SYNCHELP_WRITE_BYTE( DATA_playables, NWT_SS_B );
    743       SYNCHELP_WRITE_FKT( Playable::readSync, NWT_SS_PL_SYNC );
    744     }
    745 
    746   }
    747 
    748   if ( !sentSomething )
    749   {
    750     *reciever = 0;
    751 
    752     if ( networkCollisionList.size()>0 )
    753     {
    754       SYNCHELP_WRITE_BYTE( DATA_collision, NWT_SS_B );
    755 
    756       SYNCHELP_WRITE_INT( networkCollisionList.size(), NWT_SS_CO_N );
    757 
    758       for ( std::list<float>::iterator it = networkCollisionList.begin(); it!=networkCollisionList.end(); it++ )
    759       {
    760         SYNCHELP_WRITE_FLOAT( *it, NWT_SS_CO_CLID );
    761       }
    762 
    763       networkCollisionList.clear();
    764     }
    765   }
    766 
    767   return SYNCHELP_WRITE_N;
    768 }
    769 
    770 
    771 void SpaceShip::doCollideNetwork( float energy )
    772 {
    773   this->decreaseHealth( energy );
    774   if( this->getHealth() <= 0)
    775   {
    776     this->die();
    777   }
    778 }
    779 
    780 
    781 
     506
     507
  • trunk/src/world_entities/space_ships/space_ship.h

    r7346 r7954  
    4343    virtual void process(const Event &event);
    4444
    45     virtual int       writeBytes(const byte* data, int length, int sender);
    46     virtual int       readBytes(byte* data, int maxLength, int * reciever);
    47 
    48     //HACK HACK HACK HACK make this private or remove it
    49     void doCollideNetwork( float energy );
    50     std::list<float>        networkCollisionList;
    51 
    5245  private:
    5346    void init();
  • trunk/src/world_entities/terrain.cc

    r7221 r7954  
    423423}
    424424
    425 int Terrain::writeBytes( const byte * data, int length, int sender )
    426 {
    427   setRequestedSync( false );
    428   setIsOutOfSync( false );
    429 
    430   SYNCHELP_READ_BEGIN();
    431   SYNCHELP_READ_FKT( WorldEntity::writeState, NWT_TER_WE_STATE );
    432 
    433   return SYNCHELP_READ_N;
    434 }
    435 
    436 int Terrain::readBytes( byte * data, int maxLength, int * reciever )
    437 {
    438   if ( isOutOfSync() && !requestedSync() && this->getHostID()!=this->getOwner() )
    439   {
    440     (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
    441     setRequestedSync( true );
    442   }
    443 
    444   int rec = this->getRequestSync();
    445   if ( rec > 0 )
    446   {
    447     *reciever = rec;
    448 
    449     SYNCHELP_WRITE_BEGIN();
    450     SYNCHELP_WRITE_FKT( WorldEntity::readState, NWT_TER_WE_STATE );
    451     return SYNCHELP_WRITE_N;
    452 
    453   }
    454 
    455   *reciever = 0;
    456   return 0;
    457 }
    458 
    459 void Terrain::writeDebug( ) const
    460   {}
    461 
    462 void Terrain::readDebug( ) const
    463   {}
    464 
    465425float Terrain::getHeight(float x, float y)
    466426{
  • trunk/src/world_entities/terrain.h

    r7221 r7954  
    3333  virtual ~Terrain();
    3434
    35   virtual int       writeBytes(const byte* data, int length, int sender);
    36   virtual int       readBytes(byte* data, int maxLength, int * reciever);
    37   virtual void      writeDebug() const;
    38   virtual void      readDebug() const;
    39 
    4035  void init();
    4136  virtual void loadParams(const TiXmlElement* root);
  • trunk/src/world_entities/world_entity.cc

    r7927 r7954  
    7070  this->toList(OM_NULL);
    7171
    72   //this->collisionHandles = new *CollisionHandle[CREngine::CR_NUMBER]();
     72  modelFileName_handle = registerVarId( new SynchronizeableString( &modelFileName, &modelFileName, "modelFileName" ) );
     73  scaling_handle = registerVarId( new SynchronizeableFloat( &scaling, &scaling, "scaling" ) );
    7374}
    7475
     
    132133  this->modelLODName = fileName;
    133134  this->scaling = scaling;
     135
     136  std::string name = fileName;
     137
     138  if (  name.find( ResourceManager::getInstance()->getDataDir() ) == 0 )
     139  {
     140    name.erase(ResourceManager::getInstance()->getDataDir().size());
     141  }
     142
     143  this->modelFileName = name;
     144
    134145  if (!fileName.empty())
    135146  {
     
    524535
    525536
    526 
    527 
    528 /********************************************************************************************
    529  NETWORK STUFF
    530  ********************************************************************************************/
    531 
    532 
    533 /**
    534  * Writes data from network containing information about the state
    535  * @param data pointer to data
    536  * @param length length of data
    537  * @param sender hostID of sender
    538  */
    539 int WorldEntity::writeState( const byte * data, int length, int sender )
    540 {
    541   std::string modelFileName;
    542   SYNCHELP_READ_BEGIN();
    543 
    544   SYNCHELP_READ_FKT( PNode::writeState, NWT_WE_PN_WRITESTATE );
    545 
    546   SYNCHELP_READ_STRING( modelFileName, NWT_WE_PN_MODELFILENAME );
    547   SYNCHELP_READ_FLOAT( scaling, NWT_WE_PN_SCALING );
    548   //check if modelFileName is relative to datadir or absolute
    549 
    550 
    551   PRINTF(0)("================ LOADING MODEL %s, %f\n", modelFileName.c_str(), scaling);
    552 
    553   if ( modelFileName != "" )
    554   {
    555     loadModel( modelFileName, scaling);
    556     PRINTF(0)("modelfilename: %s\n", getModel( 0 )->getName());
    557   }
    558 
    559   /*SYNCHELP_READ_STRINGM( modelFileName );
    560 
    561   if ( strcmp(modelFileName, "") )
    562     if ( strstr(modelFileName, ResourceManager::getInstance()->getDataDir()) )
    563     {
    564       this->md2TextureFileName = new char[strlen(modelFileName)-strlen(ResourceManager::getInstance()->getDataDir())+1];
    565       strcpy((char*)this->md2TextureFileName, modelFileName+strlen(ResourceManager::getInstance()->getDataDir()));
    566     }
    567     else
    568     {
    569       this->md2TextureFileName = modelFileName;
    570     }
    571   */
    572 
    573   return SYNCHELP_READ_N;
    574 }
    575 
    576 
    577 /**
    578  * data copied in data will bee sent to another host
    579  * @param data pointer to data
    580  * @param maxLength max length of data
    581  * @return the number of bytes writen
    582  */
    583 int WorldEntity::readState( byte * data, int maxLength )
    584 {
    585   SYNCHELP_WRITE_BEGIN();
    586 
    587   SYNCHELP_WRITE_FKT( PNode::readState, NWT_WE_PN_WRITESTATE );
    588 
    589   if ( getModel(0) && getModel(0)->getName() != "" )
    590   {
    591     std::string name = getModel( 0 )->getName();
    592 
    593     if (  name.find( ResourceManager::getInstance()->getDataDir() ) == 0 )
    594     {
    595       name.erase(ResourceManager::getInstance()->getDataDir().size());
    596     }
    597 
    598     SYNCHELP_WRITE_STRING( name, NWT_WE_PN_MODELFILENAME );
    599   }
    600   else
    601   {
    602     SYNCHELP_WRITE_STRING("", NWT_WE_PN_MODELFILENAME);
    603   }
    604 
    605   SYNCHELP_WRITE_FLOAT( scaling, NWT_WE_PN_SCALING );
    606   /*if ( this->md2TextureFileName!=NULL && strcmp(this->md2TextureFileName, "") )
    607   {
    608     SYNCHELP_WRITE_STRING(this->md2TextureFileName);
    609   }
    610   else
    611   {
    612     SYNCHELP_WRITE_STRING("");
    613   }*/
    614 
    615   return SYNCHELP_WRITE_N;
    616 }
     537/**
     538 * handler for changes on registred vars
     539 * @param id id's which changed
     540 */
     541void WorldEntity::varChangeHandler( std::list< int > & id )
     542{
     543  if ( std::find( id.begin(), id.end(), modelFileName_handle ) != id.end() ||
     544       std::find( id.begin(), id.end(), scaling_handle ) != id.end()
     545     )
     546  {
     547    loadModel( modelFileName, scaling );
     548  }
     549
     550  PNode::varChangeHandler( id );
     551}
     552
  • trunk/src/world_entities/world_entity.h

    r7927 r7954  
    9999  OrxGui::GLGuiWidget* getHealthWidget();
    100100  bool hasHealthWidget() const { return this->healthWidget; };
     101 
     102  virtual void varChangeHandler( std::list<int> & id );
    101103
    102104  /* --- Misc Stuff Block --- */
     
    133135  ObjectManager::EntityList::iterator objectListIterator; //!< The iterator position of this Entity in the given list of the ObjectManager.
    134136
    135   float                   scaling;
     137 
     138  //network stuff
     139 
     140  float       scaling;                         //!< model's scaling factor
     141  int         scaling_handle;                  //!< handle for syncing var
     142 
     143  std::string modelFileName;                  //!< model's file name
     144  int         modelFileName_handle;           //!< handle for syncing var
    136145  CollisionHandle**       collisionHandles;
    137146
Note: See TracChangeset for help on using the changeset viewer.