- Timestamp:
- May 29, 2006, 3:28:41 PM (19 years ago)
- Location:
- trunk/src
- Files:
-
- 60 edited
- 31 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/defs/class_id.h
r7927 r7954 366 366 CL_HANDSHAKE = 0x00000d06, 367 367 CL_NETWORK_GAME_MANAGER = 0x00000d07, 368 CL_MESSAGE_MANAGER = 0x00000d08, 369 CL_SIMPLE_SYNC = 0x00000d09, 368 370 369 371 -
trunk/src/lib/BuildLibs.am
r7661 r7954 11 11 $(LIB_PREFIX)/sound/libORXsound.a \ 12 12 $(LIB_PREFIX)/event/libORXevent.a \ 13 $(LIB_PREFIX)/physics/libORXphysics.a \14 13 $(LIB_PREFIX)/particles/libORXparticles.a \ 15 14 $(LIB_PREFIX)/collision_detection/libORXcd.a \ … … 20 19 $(LIB_PREFIX)/parser/cmdline_parser/libCmdLineParser.a \ 21 20 $(LIB_PREFIX)/parser/ini_parser/libIniParser.a \ 21 $(LIB_PREFIX)/physics/libORXphysics.a \ 22 $(LIB_PREFIX)/shell/libORXshell.a \ 22 23 $(LIB_PREFIX)/math/libORXmath.a \ 23 24 $(LIB_PREFIX)/libORXlibs.a -
trunk/src/lib/coord/p_node.cc
r7725 r7954 53 53 if (parent != NULL) 54 54 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" ) ); 55 58 } 56 59 … … 1077 1080 1078 1081 /** 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 */ 1085 void 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 186 186 float distance(const PNode* node) const { return (this->getAbsCoor() - node->getAbsCoor()).len(); }; 187 187 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 194 188 private: 195 189 /** tells the child that the parent's Coordinate has changed */ … … 243 237 float roty; 244 238 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 ); 245 248 }; 246 249 -
trunk/src/lib/graphics/importer/height_map.cc
r7526 r7954 603 603 PRINTF(0)("c: %f \n" ,c); 604 604 605 605 606 height -= ( (a/c)*(x) + (b/c)*(y)); 606 607 607 PRINTF(0)("height: %f \n" ,height );608 // PRINTF(0)("height: %f \n" ,height ); 608 609 return (height + offsetZ); 609 } 610 611 } -
trunk/src/lib/lang/base_object.cc
r7661 r7954 82 82 assert (!(this->classID & classID & !CL_MASK_SUBSUPER_CLASS_IDA )); 83 83 84 this->leafClassID = classID; 84 85 this->classID |= (long)classID; 85 86 this->className = className; … … 105 106 * Factory::fabricate(Object->getLeafClassID()); 106 107 */ 107 ClassIDBaseObject::getLeafClassID() const108 const ClassID& BaseObject::getLeafClassID() const 108 109 { 109 assert (this->classList != NULL); 110 return this->classList->getLeafClassID(); 110 return this->leafClassID; 111 111 } 112 112 … … 176 176 177 177 } 178 179 /**180 * Writes data from network containing information about the state181 * @param data pointer to data182 * @param length length of data183 * @param sender hostID of sender184 */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 host196 * @param data pointer to data197 * @param maxLength max length of data198 * @return the number of bytes writen199 */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 42 42 /** @returns the classID of the corresponding Object */ 43 43 inline int getClassID() const { return this->classID; }; 44 ClassIDgetLeafClassID() const;44 const ClassID& getLeafClassID() const; 45 45 46 46 bool isA (ClassID classID) const; … … 52 52 bool operator==(ClassID classID) { return this->isA(classID); }; 53 53 54 int writeState(const byte* data, int length, int sender);55 int readState(byte* data, int maxLength );56 57 54 protected: 58 55 void setClassID(ClassID classID, const std::string& className); 56 std::string objectName; //!< The name of this object 59 57 60 58 private: 61 59 std::string className; //!< the name of the class 62 60 long classID; //!< this is the id from the class_id.h enumeration 63 std::string objectName; //!< The name of this object61 ClassID leafClassID; //!< The Leaf Class ID 64 62 65 63 ClassList* classList; //!< Pointer to the ClassList this Object is inside of -
trunk/src/lib/network/Makefile.am
r7026 r7954 13 13 network_protocol.cc \ 14 14 server_socket.cc \ 15 tcp_server_socket.cc \ 16 tcp_socket.cc \ 17 udp_server_socket.cc \ 18 udp_socket.cc \ 15 19 handshake.cc \ 16 20 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 18 34 19 35 … … 29 45 network_protocol.h \ 30 46 server_socket.h \ 47 tcp_server_socket.h \ 48 tcp_socket.h \ 49 udp_server_socket.h \ 50 udp_socket.h \ 31 51 handshake.h \ 32 52 network_game_manager.h \ 33 53 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 35 67 36 68 -
trunk/src/lib/network/connection_monitor.cc
r5822 r7954 10 10 11 11 ### File Specific: 12 main-programmer: Silvan Nellen12 main-programmer: Christoph Renner 13 13 co-programmer: ... 14 14 */ 15 15 16 16 #include "connection_monitor.h" 17 #include "network_log.h" 18 17 19 #include <debug.h> 18 20 #include <SDL/SDL.h> … … 22 24 using namespace std; 23 25 24 ConnectionMonitor::ConnectionMonitor() 25 { 26 26 /** 27 * constructor 28 * @param userId user's id 29 */ 30 ConnectionMonitor::ConnectionMonitor( int userId ) 31 { 27 32 /* set the class id for the base object and add ist to class list*/ 28 33 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 */ 53 ConnectionMonitor::~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 */ 63 void 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 */ 95 void 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() ) 119 105 { 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 */ 141 float 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 */ 171 void 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 */ 198 void 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 */ 217 bool 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 */ 233 void 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 10 10 #include "netdefs.h" 11 11 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 12 18 class ConnectionMonitor : virtual public BaseObject 13 19 { 14 20 public: 15 ConnectionMonitor( );21 ConnectionMonitor( int userId ); 16 22 virtual ~ConnectionMonitor(); 17 23 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 19 40 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; 20 51 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; 52 67 }; 53 68 -
trunk/src/lib/network/converter.cc
r7230 r7954 489 489 { 490 490 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 491 502 s = ""; 492 503 return -1; 493 504 } 494 505 495 s [0] = '\0';506 s = ""; 496 507 s.append( (char*)a+n, length ); 497 508 -
trunk/src/lib/network/data_stream.cc
r5822 r7954 16 16 /* include Data_stream Header */ 17 17 #include "data_stream.h" 18 19 20 18 21 19 -
trunk/src/lib/network/handshake.cc
r6815 r7954 24 24 #include <cassert> 25 25 26 Handshake::Handshake( bool server, int clientId, int networkGameManagerId )26 Handshake::Handshake( bool server, int clientId, int networkGameManagerId, int messageManagerId ) 27 27 : Synchronizeable() 28 28 { … … 31 31 32 32 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; 38 64 39 65 this->setSynchronized(true); 40 PRINTF( 5)("Handshake created clientId = %d\n", clientId);66 PRINTF(0)("Handshake created clientId = %d\n", clientId); 41 67 } 42 68 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 */ 73 void Handshake::varChangeHandler( std::list< int > & id ) 44 74 { 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 } 46 86 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 } 48 98 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 ) 55 102 { 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"); 59 104 } 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 71 106 } 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; 123 113 } 124 114 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 else186 {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( ) const200 {201 }202 203 void Handshake::readDebug( ) const204 {205 } -
trunk/src/lib/network/handshake.h
r6341 r7954 10 10 #include "synchronizeable.h" 11 11 12 #define _INITIAL_DATA "orxonox" 13 #define _INITIAL_DATA_LENGTH 7 12 #define _ORXONOX_ID 0xF91337A0 14 13 15 #define _ORXONOX_VERSION "\x00\x00\x00\x01" 16 #define _ORXONOX_VERSION_LENGTH 4 14 #define _ORXONOX_VERSION 1 17 15 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 16 struct 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; 31 30 }; 32 31 … … 34 33 { 35 34 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 ); 48 47 49 48 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; 60 61 61 62 }; -
trunk/src/lib/network/netdefs.h
r6695 r7954 19 19 #define MAX_CONNECTIONS 1000 20 20 21 #define NETWORK_FREQUENCY 33 22 21 23 22 24 typedef unsigned char byte; … … 28 30 } NodeType; 29 31 32 typedef enum ConnectionType { 33 NET_UDP = 0, 34 NET_TCP 35 }; 36 30 37 31 38 typedef enum { -
trunk/src/lib/network/network_game_manager.cc
r7354 r7954 27 27 #include "shared_network_data.h" 28 28 #include "converter.h" 29 #include "message_manager.h" 29 30 30 31 #include "playable.h" … … 52 53 this->setClassID(CL_NETWORK_GAME_MANAGER, "NetworkGameManager"); 53 54 54 hasRequestedWorld = false;55 55 this->setSynchronized(true); 56 57 MessageManager::getInstance()->registerMessageHandler( MSGID_YOU_ARE, youAreHandler, NULL ); 56 58 } 57 59 … … 61 63 NetworkGameManager::~NetworkGameManager() 62 64 { 65 #if 0 63 66 for ( int i = 0; i<outBuffer.size(); i++) 64 67 { … … 66 69 delete outBuffer[i].buffer; 67 70 } 68 69 } 70 71 71 #endif 72 73 } 74 75 #if 0 72 76 int NetworkGameManager::writeBytes(const byte* data, int length, int sender) 73 77 { … … 141 145 { 142 146 sendEntityList( sender ); 143 continue;144 }145 else if ( b == NET_REQUEST_SYNC )146 {147 if ( !handleRequestSync( i, data, length, sender ) )148 return i;149 147 continue; 150 148 } … … 160 158 return i; 161 159 } 162 160 #endif 161 162 #if 0 163 163 int NetworkGameManager::readBytes(byte* data, int maxLength, int * reciever) 164 164 { … … 192 192 return 0; 193 193 } 194 194 #endif 195 196 #if 0 195 197 void NetworkGameManager::writeDebug() const 196 198 { … … 200 202 { 201 203 } 204 #endif 202 205 203 206 … … 211 214 if ( this->isServer()) 212 215 { 213 if ( SharedNetworkData::getInstance()->getNewUniqueID() < 0 ) 216 int res = this->executeCreateEntity( classID, SharedNetworkData::getInstance()->getNewUniqueID(), owner ); 217 218 if ( res < 0 ) 214 219 { 215 220 PRINTF(1)("Cannot create entity! There are no more uniqueIDs left!\n"); 216 221 return -1; 217 222 } 218 return this->executeCreateEntity( classID, SharedNetworkData::getInstance()->getNewUniqueID(), owner ); 223 224 return res; 219 225 } 220 226 else 221 227 { 228 #if 0 222 229 this->requestCreateEntity( classID ); 230 #endif 223 231 return -1; 224 232 } … … 288 296 else 289 297 { 298 #if 0 290 299 this->requestRemoveEntity( uniqueID ); 291 } 292 } 293 294 295 300 #endif 301 } 302 } 303 304 305 #if 0 296 306 /*! 297 307 * Creates the needed entity on the server if possible … … 311 321 } 312 322 } 313 323 #endif 324 325 #if 0 314 326 /*! 315 327 * Removes the specified entity on the server … … 329 341 } 330 342 } 343 #endif 331 344 332 345 /*! … … 337 350 int NetworkGameManager::executeCreateEntity(ClassID classID, int uniqueID, int owner) 338 351 { 352 #if 0 339 353 for ( int i = 0; i<outBuffer.size(); i++) 340 354 { … … 351 365 return -1; 352 366 } 353 367 #endif 354 368 PRINTF(0)("ExecuteCreateEntity: server side: classID: %x, uniqueID: %i, owner: %i\n", classID, uniqueID, owner); 355 369 doCreateEntity( classID, uniqueID, owner ); … … 365 379 void NetworkGameManager::executeRemoveEntity(int uniqueID) 366 380 { 381 #if 0 367 382 for ( int i = 0; i<outBuffer.size(); i++) 368 383 { … … 375 390 return; 376 391 } 392 #endif 377 393 378 394 doRemoveEntity(uniqueID); … … 388 404 } 389 405 406 #if 0 390 407 /*! 391 408 * Sends the Entities to the new connected client … … 443 460 signalNewPlayer( userID ); 444 461 } 462 #endif 445 463 446 464 … … 448 466 bool NetworkGameManager::signalNewPlayer(int userId) 449 467 { 450 if ( userId >= outBuffer.size() )451 resizeBufferVector( userId );452 453 468 /* create new playable for Player*/ 454 469 PRINTF(0)("Request for creation: %i\n", userId); … … 456 471 PRINTF(0)("Request for creation: userid: %i, uniqueid: %i\n", userId, uniqueId); 457 472 this->sendYouAre(uniqueId, userId); 458 459 473 } 460 474 … … 464 478 { 465 479 const std::list<BaseObject*>* playableList = ClassList::getList(CL_PLAYABLE); 480 481 if ( !playableList ) 482 return false; 483 466 484 std::list<BaseObject*>::const_iterator it = playableList->begin(); 467 485 … … 478 496 } 479 497 480 498 #if 0 481 499 /** 482 500 * Creates a buffer for user n … … 498 516 } 499 517 } 518 #endif 500 519 501 520 /** … … 532 551 s->setSynchronized(true); 533 552 //this->networkStream->connectSynchronizeable( *s ); 534 if ( !isServer() ) 535 s->setIsOutOfSync( true ); 553 536 554 PRINTF(0)("Fabricated %s with id %d\n", s->getClassName(), s->getUniqueID()); 537 555 … … 601 619 } 602 620 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 625 622 /** 626 623 * Copies length bytes to the clientBuffer with error checking … … 641 638 return true; 642 639 } 643 640 #endif 641 642 #if 0 644 643 /** 645 644 * Reads data from clientBuffer with error checking … … 660 659 return true; 661 660 } 661 #endif 662 662 663 663 /** … … 687 687 } else 688 688 { 689 PRINTF(1)("UniqueID is not a Playable\n");689 PRINTF(1)("UniqueID %d is not a Playable\n", uniqueID); 690 690 } 691 691 } … … 697 697 assert(player != NULL); 698 698 699 s->setIsOutOfSync( true );700 701 699 PRINTF(0)("uniqueID = %d\n", s->getUniqueID()); 702 700 … … 715 713 if ( !isServer() ) 716 714 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); 730 721 } 731 722 … … 902 893 return true; 903 894 } 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 921 895 922 896 /** … … 958 932 } 959 933 960 934 bool 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 961 963 bool NetworkGameManager::writeToClientBuffer( clientBuffer & cb, byte b ) 962 964 { … … 971 973 return true; 972 974 } 975 973 976 974 977 bool NetworkGameManager::writeToClientBuffer( clientBuffer & cb, int i ) … … 985 988 return true; 986 989 } 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 12 12 /* include base_object.h since all classes are derived from this one */ 13 13 #include "synchronizeable.h" 14 #include "message_manager.h" 14 15 15 16 16 17 class TiXmlElement; 17 18 class PNode; 18 19 /**20 * protocol definition21 *22 * CREATE_ENTITY: >> CLASS_ID, UNIQUE_ID, OWNER23 * REMOVE_ENTITY: >> UNIQUE_ID24 *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_ID29 * << [Sync Info]30 * REQUEST_REMOVE: >> UNIQUE_ID31 * << [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 :D37 * REQUEST_SYNC: >> UNIQUE_ID38 * << [Sync Info]39 * //REQUEST_SYNC_LIST: NUMBER, [UNIQUE_ID][0..NUMBER]40 *41 * YOU_ARE_ENTITY: >> UNIQUE_ID42 *43 * REQUEST_PNODE_PATH >> UNIQUE_ID_START UNIQUE_ID_STOP44 * << UNIQUE_ID_1 UNIQUE_ID_2 UNIQUE_ID_3 ... UNIQUE_ID_N45 *46 * SEND_PNODE_PATH >> UNIQUE_ID_START UNIQUE_ID_STOP NUMBER [UNIQUE_ID][0..NUMBER]47 */48 19 49 20 typedef enum NetworkGameManagerProtocol { … … 54 25 NET_REQUEST_CREATE, 55 26 NET_REQUEST_REMOVE, 56 NET_REQUEST_SYNC,57 27 NET_YOU_ARE_ENTITY, 58 28 NET_REQUEST_ENTITY_LIST, … … 81 51 { if (!NetworkGameManager::singletonRef) NetworkGameManager::singletonRef = new NetworkGameManager(); return NetworkGameManager::singletonRef; } 82 52 53 #if 0 83 54 virtual int writeBytes(const byte* data, int length, int sender); 84 55 virtual int readBytes(byte* data, int maxLength, int * reciever); 85 56 virtual void writeDebug() const; 86 57 virtual void readDebug() const; 58 #endif 87 59 88 60 int createEntity( ClassID classID, int owner = 0 ); … … 91 63 void sendYouAre( int uniqueID, int userID ); 92 64 93 void sync(int uniqueID, int owner); 94 65 #if 0 95 66 void sendEntityList(int userID); 67 #endif 96 68 97 69 bool signalNewPlayer(int userId); … … 101 73 private: 102 74 NetworkGameManager(); 75 76 static bool youAreHandler(MessageId messageId, byte * data, int dataLength, void * someData, int userId ); 103 77 104 78 … … 111 85 bool handleRemoveEntityList( int& i, const byte* data, int length, int sender ); 112 86 bool handleYouAreEntity( int& i, const byte* data, int length, int sender ); 113 bool handleRequestSync( int& i, const byte* data, int length, int sender );114 87 bool handleRequestPNodePath(int& i, const byte* data, int length, int sender); 115 88 bool handleSendPNodePath(int& i, const byte* data, int length, int sender); … … 117 90 118 91 /* some network handlers helper functions */ 119 void requestCreateEntity(ClassID classID);92 // void requestCreateEntity(ClassID classID); 120 93 int executeCreateEntity(ClassID classID, int uniqueID = 0, int owner = 0); 121 94 BaseObject* doCreateEntity(ClassID classID, int uniqueID, int owner); 122 95 123 void requestRemoveEntity(int uniqueID);96 // void requestRemoveEntity(int uniqueID); 124 97 void executeRemoveEntity(int uniqueID); 125 98 void doRemoveEntity(int uniqueID); 126 99 127 void executeRequestSync( int uniqueID, int user );128 void doRequestSync(int uniqueID, int userID);129 130 100 void doYouAre( int uniqueID ); 131 101 132 void requestPNodePath(const PNode* node1, const PNode* node2);102 // void requestPNodePath(const PNode* node1, const PNode* node2); 133 103 void executeRequestPNodePath(const PNode* node2, const PNode* node2); 134 104 void doRequestPNodePath(const PNode* node1, const PNode* node2); 135 105 136 106 bool canCreateEntity(ClassID classID); 107 #if 0 108 void resizeBufferVector(int n); 137 109 138 void resizeBufferVector(int n);139 110 140 111 bool writeToClientBuffer( clientBuffer &cb, byte*data, int length ); … … 142 113 bool writeToClientBuffer( clientBuffer &cb, int i ); 143 114 bool readFromClientBuffer( clientBuffer &cb, byte*data, int length ); 144 115 #endif 145 116 146 117 private: 118 #if 0 147 119 std::vector<clientBuffer> outBuffer; 148 120 //clientBuffer allOutBuffer; 121 #endif 149 122 static NetworkGameManager* singletonRef; 150 bool hasRequestedWorld;151 123 }; 152 124 -
trunk/src/lib/network/network_manager.cc
r7256 r7954 28 28 #include "shared_network_data.h" 29 29 #include "network_stream.h" 30 #include "preferences.h" 31 #include "network_log.h" 30 32 31 33 … … 52 54 this->defaultSyncStream = NULL; 53 55 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 ); 54 63 55 64 PRINTF(0)("NetworkManager created\n"); … … 72 81 this->netStreamList = ClassList::getList(CL_SYNCHRONIZEABLE); 73 82 PRINTF(0)("NetworkManager initzalized\n"); 83 74 84 } 75 85 … … 90 100 int NetworkManager::establishConnection(const std::string & name, unsigned int port) 91 101 { 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 ); 100 103 this->sharedNetworkData->setDefaultSyncStream(this->defaultSyncStream); 101 104 this->defaultSyncStream->startHandshake(); … … 130 133 /** 131 134 * sync the network 135 * @param dtS: the seceonds elapsed since the last synchronize call 132 136 */ 133 void NetworkManager::synchronize( )137 void NetworkManager::synchronize( float dtS) 134 138 { 139 this->elapsedTime += dtS; 140 if( likely(this->elapsedTime < 1.0f / NETWORK_FREQUENCY)) 141 return; 142 this->elapsedTime = 0.0f; 143 135 144 if (this->netStreamList != NULL || (this->netStreamList = ClassList::getList(CL_NETWORK_STREAM)) != NULL) 136 145 { -
trunk/src/lib/network/network_manager.h
r7256 r7954 45 45 46 46 void connectSynchronizeable(Synchronizeable& sync); 47 void synchronize( );47 void synchronize(float dtS); 48 48 49 49 void debug(); … … 61 61 62 62 SharedNetworkData* sharedNetworkData; //!< reference to the shared data 63 float elapsedTime; //!< elapsed time since the last network update 63 64 }; 64 65 -
trunk/src/lib/network/network_socket.cc
r7440 r7954 21 21 #define DEBUG_MODULE_NETWORK 22 22 23 #include "converter.h"24 25 23 /* include your own header */ 26 24 #include "network_socket.h" … … 34 32 NetworkSocket::NetworkSocket() 35 33 { 36 this->init();34 bOk = true; 37 35 } 38 36 39 /** 40 * Constructor to connect directly 41 */ 42 NetworkSocket::NetworkSocket(IPaddress ip) 37 NetworkSocket::~ NetworkSocket( ) 43 38 { 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 else89 PRINTF(5)("SDL_net initialized\n");90 91 PRINTF(0)("NetworkSocket created\n");92 93 39 } 94 40 95 41 96 42 97 /**98 * Default destructor99 * 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 ip119 */120 void NetworkSocket::connectToServer(IPaddress ip)121 {122 //HACK this will cause segfault123 #warning remove this124 int * a;125 *a = 99;126 //check if not already connected or listening127 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 already162 * estabilhed) otherwise it just does nothing (silently discarding the data). And writes some163 * warnings164 * @param data: pointer to the data to send165 * @param length: n bytes to send166 * @return the number successfully written bytes167 */168 int NetworkSocket::writeBytes(byte * data, int length)169 {170 PRINTF(5)("NetworkSocket::writeBytes()\n");171 #ifdef _USE_OUTGOING_BUFFER172 173 #define min(a,b) (a<b)?a:b174 int nbytes = min(_OUTGOING_BUFFER_SIZE - outgoingBufferLength, length);175 #undef min176 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 #else193 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 #endif207 }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 read212 * functions of many network libraries are blocking an would therefore block the whole213 * program.214 * From outside, the thread shouldn't be accessible at all.215 * @param data: pointer to memory, big enough to store length bytes216 * @param length: n bytes to read217 * @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 overlap242 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 bytes254 * @param length: n bytes to read255 * @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 socket268 * @param data: pointer to NetworkSocket269 */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:b282 nbytestoread = min(_INCOMING_BUFFER_SIZE - self->incomingBufferLength, _LOCAL_BUFFER_SIZE);283 #undef min284 285 //if buffer is full286 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 else328 {329 SDL_mutexV(self->threadTerminationMutex);330 }331 332 333 #ifdef DONTEXITTHREADS334 while ( true )335 {336 SDL_Delay(1000);337 }338 #endif339 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:b357 nbytestowrite = min(self->outgoingBufferLength, _LOCAL_BUFFER_SIZE);358 #undef min359 360 // printf("thread_write nbytes=%d listening=%d\n", nbytestowrite, (int)self->_isListening);361 362 //if buffer is full363 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 else405 {406 SDL_mutexV(self->threadTerminationMutex);407 }408 409 #ifdef DONTEXITTHREADS410 while ( true )411 {412 SDL_Delay(1000);413 }414 #endif415 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 else467 return blen;468 469 }470 471 -
trunk/src/lib/network/network_socket.h
r6994 r7954 8 8 #define _NETWORK_SOCKET 9 9 10 //TODO HACK else gdb will not work on server11 #define DONTEXITTHREADS12 13 //if you want to use outgoing buffer define _USE_OUTGOING_BUFFER14 #define _USE_OUTGOING_BUFFER15 16 #define _INCOMING_BUFFER_SIZE 202400017 #define _OUTGOING_BUFFER_SIZE 202400018 #define _LOCAL_BUFFER_SIZE 102419 //sleep if incoming buffer is full20 #define _MSECONDS_SLEEP_FULL_BUFFER 1021 //sleep if outgoing buffer is empty22 #define _MSECONDS_SLEEP_EMPTY_BUFFER 1023 24 25 /* contains memmove and memcpy */26 #include <string.h>27 28 #ifdef HAVE_SDL_H29 #include <SDL_thread.h>30 #else31 #include <SDL/SDL_thread.h>32 #endif33 10 /* include this file, it contains some default definitions */ 34 11 #include "netdefs.h" … … 38 15 #include "base_object.h" 39 16 40 /* using namespace std is default, this needs to be here */41 using namespace std;42 43 17 class NetworkSocket : public BaseObject 44 18 { 19 public: 20 NetworkSocket(); 21 virtual ~NetworkSocket(); 45 22 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; 51 34 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; 60 50 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 102 59 103 60 }; -
trunk/src/lib/network/network_stream.cc
r6959 r7954 23 23 #include "base_object.h" 24 24 #include "network_protocol.h" 25 #include "network_socket.h" 25 #include "udp_socket.h" 26 #include "udp_server_socket.h" 26 27 #include "connection_monitor.h" 27 28 #include "synchronizeable.h" 28 29 #include "network_game_manager.h" 29 30 #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" 30 41 31 42 #include "debug.h" … … 49 60 /* initialize the references */ 50 61 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 65 NetworkStream::NetworkStream( std::string host, int port ) 57 66 { 58 67 this->type = NET_CLIENT; 59 68 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 76 NetworkStream::NetworkStream( int port ) 68 77 { 69 78 this->type = NET_SERVER; 70 79 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); 77 81 this->bActive = true; 78 82 } … … 87 91 this->networkGameManager = NULL; 88 92 myHostId = 0; 93 currentState = 0; 94 95 remainingBytesToWriteToDict = Preferences::getInstance()->getInt( "compression", "writedict", 0 ); 96 97 assert( Zip::getInstance()->loadDictionary( "testdict" ) ); 89 98 } 90 99 … … 98 107 } 99 108 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 119 131 } 120 132 … … 125 137 // setUniqueID( maxCon+2 ) because we need one id for every handshake 126 138 // 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() ); 130 141 } 131 142 … … 135 146 Handshake* hs = new Handshake(false); 136 147 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 ); 138 151 //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()); 140 154 } 141 155 … … 146 160 sync.setNetworkStream( this ); 147 161 148 if( this->networkSockets.size()>0 ) 149 this->bActive = true; 162 this->bActive = true; 150 163 } 151 164 … … 157 170 if (disconnectSynchro != this->synchronizeables.end()) 158 171 this->synchronizeables.erase(disconnectSynchro); 159 160 if( this->networkSockets.size()<=0 ) 161 this->bActive = false; 172 173 oldSynchronizeables[sync.getUniqueID()] = SDL_GetTicks(); 162 174 } 163 175 … … 165 177 void NetworkStream::processData() 166 178 { 179 currentState++; 180 167 181 if ( this->type == NET_SERVER ) 182 { 183 if ( serverSocket ) 184 serverSocket->update(); 185 168 186 this->updateConnectionList(); 187 } 169 188 else 170 189 { 171 if ( networkSockets[0] && !networkSockets[0]->isOk() )190 if ( peers[0].socket && ( !peers[0].socket->isOk() || peers[0].connectionMonitor->hasTimedOut() ) ) 172 191 { 173 192 PRINTF(1)("lost connection to server\n"); 174 193 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 214 void 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++ ) 191 290 { 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 304 void 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 323 int 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 */ 337 void 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() ) 193 346 { 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(); 202 363 } 203 364 else 204 365 { 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 212 379 } 213 380 else 214 381 { 215 382 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(); 220 384 } 221 385 } 222 386 } 223 387 } 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 */ 393 void 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 */ 508 void 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 ) 246 588 { 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 } 249 647 } 250 648 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 ) 256 669 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 ); 425 672 } 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 */ 695 void 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 */ 705 void 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 */ 727 void NetworkStream::writeToNewDict( byte * data, int length ) 728 { 729 if ( remainingBytesToWriteToDict <= 0 ) 445 730 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; 451 744 return; 452 745 } 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 9 9 #include <vector> 10 10 #include <list> 11 #include <map> 11 12 12 13 #include "data_stream.h" 13 #include "network_protocol.h"14 14 #include "server_socket.h" 15 15 #include "handshake.h" 16 #include "connection_monitor.h" 17 #include "udp_server_socket.h" 16 18 17 19 class Synchronizeable; 18 20 class NetworkSocket; 19 21 class ServerSocket; 20 class ConnectionMonitor;21 class NetworkProtocol;22 22 class NetworkGameManager; 23 23 24 class 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 24 38 typedef std::list<Synchronizeable*> SynchronizeableList; 25 typedef std::vector<NetworkSocket*> NetworkSocketVector; 26 typedef std::vector<Handshake*> HandshakeVector; 39 typedef std::map<int,PeerInfo> PeerList; 27 40 28 41 … … 32 45 public: 33 46 NetworkStream(); 34 NetworkStream( IPaddress& address);35 NetworkStream( unsigned int port);47 NetworkStream( std::string host, int port); 48 NetworkStream( int port ); 36 49 37 50 virtual ~NetworkStream(); … … 47 60 inline bool isActive() const { return this->bActive; } 48 61 49 inline int getMaxConnections(){ return maxConnections; } 50 void setMaxConnections( int n ); 62 inline int getMaxConnections(){ return MAX_CONNECTIONS; } 51 63 52 64 virtual void processData(); … … 56 68 int getSyncCount(); 57 69 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; } 59 72 60 73 void debug(); 74 75 inline PeerInfo & getPeerInfo( int userId ) { return peers[userId]; } 61 76 62 77 63 78 private: 64 79 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 ); 65 87 66 88 67 89 private: 68 NetworkProtocol* networkProtocol;69 ConnectionMonitor* connectionMonitor;70 90 SynchronizeableList synchronizeables; 71 NetworkSocketVector networkSockets; 72 HandshakeVector handshakes; 91 PeerList peers; 73 92 ServerSocket* serverSocket; 74 93 int type; 75 Header packetHeader;76 94 bool bActive; 77 95 std::list<int> freeSocketSlots; 78 96 79 97 int myHostId; 80 int maxConnections; 98 99 int currentState; //!< current state id 81 100 82 101 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 83 109 }; 84 110 #endif /* _NETWORK_STREAM */ -
trunk/src/lib/network/server_socket.cc
r6139 r7954 26 26 #include "debug.h" 27 27 28 ServerSocket::ServerSocket( ) 28 29 /** 30 * constructor 31 * @param port port to assign to socket 32 */ 33 ServerSocket::ServerSocket( int port ) 29 34 { 30 init();35 bOk = true; 31 36 } 32 37 33 ServerSocket:: ServerSocket( unsigned int port)38 ServerSocket::~ ServerSocket( ) 34 39 { 35 init();36 listen(port);37 40 } 38 39 /**40 * Default destructor41 */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 else67 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 port77 */78 bool ServerSocket::listen(unsigned int port)79 {80 PRINTF(0)("ServerSocket::listen()\n");81 _isListening = true;82 //check if not already connected or listening83 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 else128 {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 8 8 #define _SERVER_SOCKET 9 9 10 #ifdef HAVE_SDL_H11 #include <SDL_thread.h>12 #else13 #include <SDL/SDL_thread.h>14 #endif15 10 /* include this file, it contains some default definitions */ 16 11 #include "netdefs.h" … … 21 16 #include "network_socket.h" 22 17 23 //sleep when waiting for connections24 #define _MSECONDS_SLEEP_LISTEN 10025 18 26 19 class ServerSocket : public BaseObject 27 20 { 28 private: 29 TCPsocket listenSocket; 30 bool terminateThread; 21 public: 22 ServerSocket( int port); 31 23 32 bool _isListening;24 virtual ~ServerSocket(); 33 25 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; }; 35 31 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 44 35 }; 45 36 -
trunk/src/lib/network/synchronizeable.cc
r6753 r7954 20 20 #include "network_stream.h" 21 21 #include "netdefs.h" 22 #include "network_log.h" 22 23 23 24 #include "state.h" … … 36 37 this->setClassID(CL_SYNCHRONIZEABLE, "Synchronizeable"); 37 38 this->owner = -1; 38 this->state = 0;39 39 this->hostID = SharedNetworkData::getInstance()->getHostID(); 40 40 this->setIsServer(this->hostID == 0); 41 41 this->uniqueID = NET_UID_UNASSIGNED; 42 42 this->networkStream = NULL; 43 this->setRequestedSync( false );44 this->setIsOutOfSync( !(this->isServer()) );45 43 this->bSynchronize = false; 46 44 47 45 if( State::isOnline()) 48 46 { … … 52 50 this->setUniqueID(SharedNetworkData::getInstance()->getNewUniqueID()); 53 51 } 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" ) ); 54 59 } 55 60 … … 64 69 this->networkStream->disconnectSynchronizeable(*this); 65 70 } 66 67 68 /**69 * write data to NetworkStream70 */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 NetworkStream79 */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() const87 {}88 89 90 void Synchronizeable::readDebug() const91 {}92 93 71 94 72 /** … … 106 84 107 85 /** 108 * Sets the outofsync flag to a given value109 * @param outOfSync: the boolean value which the outofsync flag is to set to110 */111 void Synchronizeable::setIsOutOfSync(bool outOfSync)112 {113 if( outOfSync )114 this->state = this->state | STATE_OUTOFSYNC;115 else116 this->state = this->state & (~STATE_OUTOFSYNC);117 //PRINTF(0)("isoutofsync %s %d\n", this->getClassName(), state);118 }119 120 121 /**122 86 * Determines if the server flag is set 123 87 * @return true, if the server flag is true, false else … … 129 93 130 94 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 96 int 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 } 159 155 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 */ 230 int 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 */ 323 void 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 */ 331 void 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 */ 343 int 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 */ 356 void 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 */ 393 void 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 */ 479 void 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 1 1 /*! 2 * @file connection_monitor.h2 * @file synchronizeable.h 3 3 \brief interface for all classes that have to be synchronized 4 4 */ … … 10 10 #include "netdefs.h" 11 11 #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" 13 22 14 23 … … 18 27 //State constants: They have to be of the form 2^n 19 28 #define STATE_SERVER 1 20 #define STATE_OUTOFSYNC 221 #define STATE_REQUESTEDSYNC 422 29 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 30 struct StateHistoryEntry 31 { 32 int stateId; 33 byte * data; 34 int dataLength; 35 std::list<int> sizeList; 100 36 }; 101 37 38 typedef std::list<StateHistoryEntry*> StateHistory; 102 39 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 */ 40 typedef std::vector<StateHistory> UserStateHistory; 148 41 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 42 typedef std::vector<SynchronizeableVar*> SyncVarList; 298 43 299 44 class NetworkStream; 300 301 45 302 46 class Synchronizeable : virtual public BaseObject … … 307 51 virtual ~Synchronizeable(); 308 52 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(); 313 55 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 ); 320 66 321 67 inline void setUniqueID( int id ){ uniqueID = id; } … … 326 72 inline void setOwner(int owner){ this->owner = owner; } 327 73 328 /** @returns true if this Synchronizeable has to be synchronized over network */74 /** @returns true if this Synchronizeable wants to be synchronized over network */ 329 75 inline bool beSynchronized() { return this->bSynchronize; } 330 76 /** @param bSynchronize sets the Synchronizeable to be sunchronized or not */ 331 77 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; } };335 78 336 79 inline void setNetworkStream(NetworkStream* stream) { this->networkStream = stream; } … … 339 82 340 83 protected: 341 NetworkStream* networkStream; 84 NetworkStream* networkStream; //!< reference network stream we are connected to 342 85 int state; 343 86 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? 344 93 345 private: 346 int uniqueID; 347 int owner; 348 int hostID; 349 bool bSynchronize; 94 SyncVarList syncVarList; //!< list containing variables to synchronize 350 95 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 352 98 353 99 }; -
trunk/src/orxonox.cc
r7729 r7954 91 91 REGISTER_ARG_FLAG( _, write_bt_to_file, "misc", "bt-to-file", "Write backtrace to file", "1"); 92 92 #endif 93 94 REGISTER_ARG_ARG( t, telnetport, "network","telnetport", "Port to use for network debug output", "port" ); 95 REGISTER_ARG_ARG( _, write_dict, "compression", "writedict", "write packets to DATA/dicts/newdict", "numBytes" ); 96 93 97 94 98 /** -
trunk/src/story_entities/multi_player_world.cc
r7287 r7954 81 81 void MultiPlayerWorld::synchronize() 82 82 { 83 NetworkManager::getInstance()->synchronize( );83 NetworkManager::getInstance()->synchronize(this->dtS); 84 84 } 85 85 -
trunk/src/story_entities/multi_player_world_data.cc
r7370 r7954 226 226 PNode::getNullParent()->init(); 227 227 } 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 228 245 State::setPlayer(this->localPlayer); 229 246 } -
trunk/src/subprojects/network/Makefile.am
r7160 r7954 1 1 MAINSRCDIR=../.. 2 2 include $(MAINSRCDIR)/defs/include_paths.am 3 4 LIB_PREFIX=$(MAINSRCDIR)/lib 5 include $(MAINSRCDIR)/lib/BuildLibs.am 6 3 7 4 8 bin_PROGRAMS = network 5 9 6 10 7 network_CPPFLAGS = -DNO_SHELL -DNO_SHELL_COMMAND 11 network_CPPFLAGS = 12 #-DNO_SHELL -DNO_SHELL_COMMAND 8 13 9 DEPENDENCIES = \14 network_DEPENDENCIES = \ 10 15 $(MAINSRCDIR)/world_entities/libORXwe.a \ 11 16 $(libORXlibs_a_LIBRARIES_) \ 12 17 $(MAINSRCDIR)/util/libORXutils.a 13 18 14 LDADD = \19 network_LDADD = \ 15 20 $(MAINSRCDIR)/util/libORXutils.a \ 16 21 $(libORXlibs_a_LIBRARIES_) \ -
trunk/src/subprojects/network/network_unit_test.cc
r6424 r7954 9 9 #include "network_socket.h" 10 10 #include "server_socket.h" 11 #include "udp_server_socket.h" 12 #include "udp_socket.h" 11 13 #include "network_stream.h" 12 14 #include "synchronizeable.h" 13 15 #include "converter.h" 16 #include "state.h" 17 #include "shared_network_data.h" 18 #include "message_manager.h" 19 #include "network_log.h" 14 20 15 21 #include "simple_sync.h" … … 36 42 int testSocket(int argc, char** argv) 37 43 { 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 } 50 65 51 66 char buf[1024]; … … 70 85 n = server2->writePacket((byte*)str4, strlen(str4)+1); 71 86 printf("%d bytes send from server2\n", n); 72 SDL_Delay(1000); 87 SDL_Delay(10); 88 89 server.update(); 73 90 74 91 printf("read from server1\n"); … … 103 120 104 121 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); 105 168 106 169 //sending bigger packets than 255 is not supported 107 170 #if 0 108 171 printf("try to send more than 255 bytes\n"); 109 172 printf("result: %d\n", client1->writePacket((byte*)buf, 1000)); … … 113 176 printf("try to read with a too small buffer\n"); 114 177 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 116 185 return 0; 117 186 } … … 124 193 printf("=================\n"); 125 194 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") ); 128 197 129 198 unsigned int port = 9999; … … 144 213 if(error == -1) 145 214 printf("\n\nerror on address resolution, program inconsistancy\n\n"); 146 nm->establishConnection(ip, *clientSync); 215 nm->establishConnection("localhost", port); 216 nm->connectSynchronizeable( *clientSync ); 147 217 /* adding some break for connection setup */ 148 218 SDL_Delay(20); … … 151 221 for( int i = 0; i < 3; i++) 152 222 { 153 nm->synchronize( );223 nm->synchronize( 1000 ); 154 224 /* simulate the network delay */ 155 225 SDL_Delay(50); … … 168 238 } 169 239 170 240 bool testCB( MessageId messageId, byte * data, int dataLength, void * someData, int userId ) 241 { 242 printf("GOT MESSAGE: %s\n", data); 243 return true; 244 } 171 245 172 246 /** … … 178 252 int startServer(int argc, char** argv) 179 253 { 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); 189 259 190 260 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 194 274 SDL_Delay(20); 195 275 196 276 for(;;) 197 277 { 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(); 200 282 } 201 283 … … 210 292 int startClient(int argc, char** argv) 211 293 { 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 341 int startListen(int argc, char** argv) 342 { 212 343 if( argc < 3) 213 344 { 214 345 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"); 217 348 return 0; 218 349 } … … 228 359 229 360 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 ); 233 365 234 366 for(;;) 235 367 { 236 netMan->synchronize( );237 SDL_Delay( 500);368 netMan->synchronize( 1000 ); 369 SDL_Delay(10); 238 370 } 239 371 … … 245 377 } 246 378 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 286 379 void testFloatConverter(float f) 287 380 { 381 #if 0 288 382 char* s = Converter::floatToBinString(f); 289 383 printf("%f = ", f); … … 293 387 printf("Byte Array: "); 294 388 for (int i = 0; i < 4; i++) 295 printf("%i ", res[i]);389 // printf("%i ", res[i]); 296 390 printf("\n"); 297 391 298 392 float b = Converter::byteArrayToFloat(res); 299 393 printf("ReConvert: %f \n", b); 394 #endif 300 395 } 301 396 302 397 void testFloatConverter2(float f) 303 398 { 399 #if 0 304 400 char* s = Converter::floatToBinString(f); 305 401 printf("### %f = ", f); … … 314 410 float b = Converter::_byteArrayToFloat(res); 315 411 printf("ReConvert: %f \n", b); 412 #endif 316 413 } 317 414 int converter(int argc, char** argv) … … 435 532 436 533 437 bool ShellBuffer::addBufferLineStatic(const char* line, ...)438 {534 //bool ShellBuffer::addBufferLineStatic(const char* line, ...) 535 //{ 439 536 //va_list arguments; 440 537 //vprintf(line, arguments); 441 printf("%s", line);442 }538 // printf("%s", line); 539 //} -
trunk/src/subprojects/network/simple_sync.cc
r6634 r7954 22 22 #include "simple_sync.h" 23 23 24 #include "class_id.h" 25 #include "fast_factory.h" 26 #include "lib/util/loading/factory.h" 27 24 28 #include "debug.h" 29 30 CREATE_FACTORY(SimpleSync, CL_SIMPLE_SYNC); 25 31 26 32 … … 28 34 * default constructor 29 35 */ 30 SimpleSync::SimpleSync(const char* name) 31 : Synchronizeable() 36 SimpleSync::SimpleSync( std::string name ) 32 37 { 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" ) ); 50 45 } 51 46 … … 56 51 SimpleSync::~SimpleSync() 57 52 { 58 if( this->outData) 59 delete[] this->outData; 60 if( this->inData) 61 delete[] this->inData; 53 } 54 55 void SimpleSync::debug( ) 56 { 57 printf("IN: %d OUT: %d\n", in, out); 58 printf("str: %s\n", syncStr.c_str()); 59 } 60 61 SimpleSync::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" ) ); 62 70 } 63 71 64 72 65 /**66 * write data to Synchronizeable67 */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 }83 73 84 74 85 /**86 * read data from Synchronizeable87 */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() const105 {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() const116 {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 13 13 { 14 14 public: 15 SimpleSync(const char* name); 15 SimpleSync( std::string name); 16 SimpleSync(const TiXmlElement* root = NULL); 16 17 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(); 20 20 21 21 22 22 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; 33 27 }; 34 28 -
trunk/src/util/multiplayer_team_deathmatch.cc
r7810 r7954 203 203 if ( terrz < terrain->getHeight( terrx, terry ) && ss->getAbsCoor().x > -1000 ) 204 204 { 205 //PRINTF(0)("COLLLLLLIIIIIDDDDEEEE\n"); 206 ss->networkCollisionList.push_back( 1234567890 ); 207 ss->doCollideNetwork( 1234567890 ); 205 //TODO handle this 208 206 } 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 211 208 212 209 float dist = (dynamic_cast<Playable*>(*it)->getAbsCoor() - big_left).len(); … … 222 219 if((*it)->isA(CL_SPACE_SHIP)) 223 220 { 224 dynamic_cast<SpaceShip*>(*it)->networkCollisionList.push_back(1163692); 225 dynamic_cast<SpaceShip*>(*it)->doCollideNetwork(11636922); 221 //TODO handle this 226 222 } 227 223 } -
trunk/src/world_entities/environments/water.cc
r7370 r7954 59 59 // To test the Wave equation 60 60 //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" ) ); 61 67 } 62 68 … … 291 297 292 298 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 */ 304 void 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 38 38 void draw() const; 39 39 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 ); 46 42 47 43 private: … … 56 52 Material waterMaterial; 57 53 Shader* waterShader; 54 58 55 float height; //!< The hight of the Water 56 int height_handle; //!< Handle to notify about changes of height 59 57 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 62 64 63 65 float phase; -
trunk/src/world_entities/npcs/ground_turret.cc
r7193 r7954 180 180 Explosion::explode(this, Vector(10,10,10)); 181 181 } 182 183 /**184 * Writes data from network containing information about the state185 * @param data pointer to data186 * @param length length of data187 * @param sender hostID of sender188 */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 host203 * @param data pointer to data204 * @param maxLength max length of data205 * @return the number of bytes writen206 */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 30 30 virtual void tick(float time); 31 31 32 virtual int writeBytes(const byte* data, int length, int sender);33 virtual int readBytes(byte* data, int maxLength, int * reciever);34 35 32 private: 36 33 PNode weaponHolder[2]; -
trunk/src/world_entities/playable.cc
r7868 r7954 62 62 63 63 this->score = 0; 64 this->oldScore = 0;65 64 this->collider = NULL; 66 65 67 66 this->bDead = false; 67 68 registerVar( new SynchronizeableInt( &score, &score, "score" ) ); 69 registerVar( new SynchronizeableBool( &bFire, &bFire, "bFire", PERMISSION_OWNER)); 68 70 } 69 71 … … 484 486 485 487 486 #define DATA_FLAGS 1487 #define DATA_SCORE 2488 489 #define FLAGS_bFire 1490 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 561 488 562 489 /** -
trunk/src/world_entities/playable.h
r7412 r7954 81 81 virtual void tick(float dt); 82 82 83 // NETWORK84 int writeSync(const byte* data, int length, int sender);85 int readSync(byte* data, int maxLength );86 bool needsReadSync();87 88 89 83 // Transformations: 90 84 static Playable::Playmode stringToPlaymode(const std::string& playmode); … … 115 109 int oldFlags; //!< Used for synchronisation 116 110 117 int score; 118 int oldScore; 111 int score; //!< players score 119 112 120 113 bool bDead; -
trunk/src/world_entities/power_ups/laser_power_up.cc
r7193 r7954 120 120 } 121 121 122 int LaserPowerUp::writeBytes( const byte * data, int length, int sender )123 {124 setRequestedSync( false );125 setIsOutOfSync( false );126 122 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 26 26 virtual void draw() const; 27 27 28 virtual int writeBytes(const byte* data, int length, int sender);29 virtual int readBytes(byte* data, int maxLength, int * reciever );30 31 28 private: 32 29 void init(); -
trunk/src/world_entities/power_ups/param_power_up.cc
r7221 r7954 43 43 if( root != NULL) 44 44 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" ) ); 45 50 } 46 51 … … 119 124 } 120 125 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 32 32 float getValue(); 33 33 34 virtual int writeBytes(const byte* data, int length, int sender);35 virtual int readBytes(byte* data, int maxLength, int * reciever );36 37 34 protected: 38 35 virtual void respawn(); -
trunk/src/world_entities/power_ups/power_up.cc
r7460 r7954 201 201 202 202 203 /********************************************************************************************204 NETWORK STUFF205 ********************************************************************************************/206 207 208 /**209 * data copied in data will bee sent to another host210 * @param data pointer to data211 * @param maxLength max length of data212 * @return the number of bytes writen213 */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 state224 * @param data pointer to data225 * @param length length of data226 * @param sender hostID of sender227 */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 34 34 void setRespawnTime(const float respawn); 35 35 36 int writeState(const byte* data, int length, int sender);37 int readState(byte* data, int maxLength );38 39 36 protected: 40 37 PowerUp(float r, float g, float b); -
trunk/src/world_entities/power_ups/turret_power_up.cc
r7193 r7954 115 115 glPopMatrix(); 116 116 } 117 118 119 120 121 /********************************************************************************************122 NETWORK STUFF123 ********************************************************************************************/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 24 24 virtual void draw() const; 25 25 26 virtual int writeBytes(const byte* data, int length, int sender);27 virtual int readBytes(byte* data, int maxLength, int * reciever );28 29 26 private: 30 27 void init(); -
trunk/src/world_entities/power_ups/weapon_power_up.cc
r7370 r7954 103 103 } 104 104 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 24 24 void setWeaponClass(const std::string& name); 25 25 26 virtual int writeBytes(const byte* data, int length, int sender);27 virtual int readBytes(byte* data, int maxLength, int * reciever );28 29 26 bool process(WeaponManager* manager); 30 27 -
trunk/src/world_entities/skybox.cc
r7919 r7954 95 95 { 96 96 this->rebuild(); 97 98 textureName_handle = registerVarId( new SynchronizeableString( &textureName, &textureName, "textureName") ); 99 size_handle = registerVarId( new SynchronizeableFloat( &size, &size, "size" ) ); 97 100 } 98 101 … … 290 293 } 291 294 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() ) 295 void SkyBox::varChangeHandler( std::list< int > & id ) 296 { 297 bool somethinChanged = false; 298 299 if ( std::find( id.begin(), id.end(), textureName_handle ) != id.end() ) 303 300 { 304 textureName = ""; 301 somethinChanged = true; 302 setTexture( textureName ); 305 303 } 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() ) 321 306 { 322 (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() ); 323 setRequestedSync( true ); 307 somethinChanged = true; 324 308 } 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 58 58 static void disableCubeMap(); 59 59 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 ); 64 61 65 62 private: … … 72 69 float textureSize; //!< this is the length of a texture (assumes a square texture) 73 70 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 74 74 75 75 }; -
trunk/src/world_entities/space_ships/hover.cc
r7868 r7954 175 175 this->getWeaponManager().getFixedTarget()->setParent(&this->cameraNode); 176 176 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 ) ); 177 188 } 178 189 -
trunk/src/world_entities/space_ships/space_ship.cc
r7868 r7954 93 93 if (root != NULL) 94 94 this->loadParams(root); 95 else96 {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 else105 {106 this->loadModel( "models/ships/fighter.obj" );107 this->toList(OM_GROUP_01);108 }109 }110 95 111 96 } … … 234 219 this->burstSystem->setColor(0.5, .5,.5,.8,.8); 235 220 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 ) ); 237 233 } 238 234 … … 306 302 if ( isServer() ) 307 303 { 308 networkCollisionList.push_back( entity->getHealth() ); 309 doCollideNetwork( entity->getHealth() ); 304 //TODO handle this 310 305 } 311 306 } … … 349 344 350 345 // spaceship controlled movement 351 if (this->getOwner() == this->getHostID())346 //if (this->getOwner() == this->getHostID()) 352 347 this->calculateVelocity(time); 353 348 … … 509 504 510 505 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 43 43 virtual void process(const Event &event); 44 44 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 it49 void doCollideNetwork( float energy );50 std::list<float> networkCollisionList;51 52 45 private: 53 46 void init(); -
trunk/src/world_entities/terrain.cc
r7221 r7954 423 423 } 424 424 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( ) const460 {}461 462 void Terrain::readDebug( ) const463 {}464 465 425 float Terrain::getHeight(float x, float y) 466 426 { -
trunk/src/world_entities/terrain.h
r7221 r7954 33 33 virtual ~Terrain(); 34 34 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 40 35 void init(); 41 36 virtual void loadParams(const TiXmlElement* root); -
trunk/src/world_entities/world_entity.cc
r7927 r7954 70 70 this->toList(OM_NULL); 71 71 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" ) ); 73 74 } 74 75 … … 132 133 this->modelLODName = fileName; 133 134 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 134 145 if (!fileName.empty()) 135 146 { … … 524 535 525 536 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 */ 541 void 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 99 99 OrxGui::GLGuiWidget* getHealthWidget(); 100 100 bool hasHealthWidget() const { return this->healthWidget; }; 101 102 virtual void varChangeHandler( std::list<int> & id ); 101 103 102 104 /* --- Misc Stuff Block --- */ … … 133 135 ObjectManager::EntityList::iterator objectListIterator; //!< The iterator position of this Entity in the given list of the ObjectManager. 134 136 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 136 145 CollisionHandle** collisionHandles; 137 146
Note: See TracChangeset
for help on using the changeset viewer.