Changeset 2662 for code/trunk/src/network
- Timestamp:
- Feb 14, 2009, 10:17:35 PM (16 years ago)
- Location:
- code/trunk
- Files:
-
- 3 deleted
- 21 edited
- 12 copied
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
-
code/trunk/src/network/CMakeLists.txt
r2131 r2662 11 11 PacketBuffer.cc 12 12 Server.cc 13 Synchronisable.cc13 TrafficControl.cc 14 14 Host.cc 15 15 ) 16 16 17 17 ADD_SOURCE_DIRECTORY(NETWORK_SRC_FILES packet) 18 ADD_SOURCE_DIRECTORY(NETWORK_SRC_FILES synchronisable) 19 18 20 19 21 IF(WIN32) -
code/trunk/src/network/Client.cc
r2171 r2662 43 43 #include "Client.h" 44 44 #include "Host.h" 45 #include " Synchronisable.h"45 #include "synchronisable/Synchronisable.h" 46 46 #include "core/CoreIncludes.h" 47 47 #include "packet/Packet.h" -
code/trunk/src/network/ClientConnection.cc
r2171 r2662 172 172 break; 173 173 case ENET_EVENT_TYPE_RECEIVE: 174 COUT(5) << "Cl.Con: receiver-Thread while loop: got new packet" << std::endl;174 //COUT(5) << "Cl.Con: receiver-Thread while loop: got new packet" << std::endl; 175 175 if ( !processData(event) ) COUT(2) << "Current packet was not pushed to packetBuffer -> ev ongoing SegFault" << std::endl; 176 COUT(5) << "Cl.Con: processed Data in receiver-thread while loop" << std::endl;176 //COUT(5) << "Cl.Con: processed Data in receiver-thread while loop" << std::endl; 177 177 event = new ENetEvent; 178 178 break; -
code/trunk/src/network/ClientInformation.cc
r2171 r2662 45 45 namespace orxonox 46 46 { 47 47 48 48 49 ClientInformation *ClientInformation::head_=0; -
code/trunk/src/network/ClientInformation.h
r2171 r2662 46 46 #include <boost/thread/recursive_mutex.hpp> 47 47 48 48 49 // WATCH OUT: THE CLIENTINFORMATION LIST IS NOT THREADSAFE ANYMORE 49 50 50 51 namespace orxonox 51 52 { 52 static const unsigned int GAMESTATEID_INITIAL = (unsigned int)-1;53 static const unsigned int CLIENTID_UNKNOWN = (unsigned int)-2;54 53 55 54 /** -
code/trunk/src/network/ConnectionManager.cc
r2171 r2662 52 52 #include "util/Sleep.h" 53 53 #include "ClientInformation.h" 54 #include " Synchronisable.h"54 #include "synchronisable/Synchronisable.h" 55 55 #include "packet/ClassID.h" 56 56 … … 206 206 // log handling ================ 207 207 case ENET_EVENT_TYPE_CONNECT: 208 COUT(3) << "adding event_type_connect to queue" << std::endl;208 //COUT(3) << "adding event_type_connect to queue" << std::endl; 209 209 case ENET_EVENT_TYPE_DISCONNECT: 210 210 //addClient(event); … … 214 214 case ENET_EVENT_TYPE_RECEIVE: 215 215 //std::cout << "received data" << std::endl; 216 COUT(5) << "Con.Man: receive event has occured" << std::endl;216 //COUT(5) << "Con.Man: receive event has occured" << std::endl; 217 217 // only add, if client has connected yet and not been disconnected 218 218 //if(head_->findClient(&event->peer->address)) -
code/trunk/src/network/GamestateClient.cc
r2171 r2662 35 35 #include "core/BaseObject.h" 36 36 #include "core/Iterator.h" 37 #include "Synchronisable.h" 37 #include "synchronisable/Synchronisable.h" 38 #include "synchronisable/NetworkCallbackManager.h" 38 39 #include "packet/Acknowledgement.h" 39 40 … … 74 75 if(tempGamestate_==NULL) 75 76 return false; 77 bool isDiffed = tempGamestate_->isDiffed(); 76 78 int id = GAMESTATEID_INITIAL; 77 79 packet::Gamestate *processed = processGamestate(tempGamestate_); 78 // assert(processed); 79 if (!processed) 80 return false; 80 assert(processed); 81 82 //now call the queued callbacks 83 NetworkCallbackManager::callCallbacks(); 84 85 if (!processed){ 86 sendAck(0); 87 return false; 88 } 81 89 //successfully loaded data from gamestate. now save gamestate for diff and delete the old gs 82 90 tempGamestate_=NULL; 83 91 gamestateMap_[processed->getID()]=processed; 84 last_diff_ = processed->getID(); 92 if(isDiffed) 93 last_diff_ = processed->getBaseID(); 85 94 id = processed->getID(); 86 95 sendAck(id); … … 153 162 packet::Gamestate *base = gamestateMap_[gs->getBaseID()]; 154 163 if(!base){ 164 COUT(3) << "could not find base gamestate id: " << gs->getBaseID() << endl; 155 165 delete gs; 156 166 return 0; … … 165 175 return gs; 166 176 else 177 { 178 COUT(3) << "could not spread gamestate" << endl; 167 179 return NULL; 180 } 168 181 } 169 182 -
code/trunk/src/network/GamestateManager.cc
r2171 r2662 49 49 #include "core/BaseObject.h" 50 50 #include "ClientInformation.h" 51 #include "Synchronisable.h" 51 #include "synchronisable/Synchronisable.h" 52 #include "synchronisable/NetworkCallbackManager.h" 53 #include "packet/Acknowledgement.h" 52 54 53 55 namespace orxonox 54 56 { 55 GamestateManager::GamestateManager() { 56 id_=0; 57 } 58 59 GamestateManager::~GamestateManager() { 57 GamestateManager::GamestateManager() : 58 reference(0), id_(0) 59 { 60 trafficControl_ = new TrafficControl(); 61 } 62 63 GamestateManager::~GamestateManager() 64 { 65 delete trafficControl_; 60 66 } 61 67 … … 86 92 // now clear the queue 87 93 gamestateQueue.clear(); 94 //and call all queued callbacks 95 NetworkCallbackManager::callCallbacks(); 88 96 return true; 89 97 } … … 91 99 92 100 bool GamestateManager::getSnapshot(){ 101 if ( reference != 0 ) 102 delete reference; 93 103 reference = new packet::Gamestate(); 94 104 if(!reference->collectData(++id_)){ //we have no data to send … … 99 109 } 100 110 101 /**102 * this function is used to keep the memory usage low103 * it tries to delete all the unused gamestates104 *105 *106 */107 /* void GamestateManager::cleanup(){108 std::map<int,int>::iterator it = gamestateUsed.begin();109 while(it!=gamestateUsed.end()){110 if((id_-(*it).first)<KEEP_GAMESTATES)111 break;112 if( (*it).second <= 0 ){113 COUT(5) << "GameStateManager: deleting gamestate with id: " << (*it).first << ", uses: " << (*it).second << std::endl;114 std::map<int, packet::Gamestate *>::iterator tempit = gamestateMap.find((*it).first);115 if( tempit != gamestateMap.end() ){116 packet::Gamestate *temp = tempit->second;117 if(temp){118 delete gamestateMap[(*it).first];119 gamestateMap.erase((*it).first);120 }121 }122 gamestateUsed.erase(it++);123 continue;124 }125 it++;126 }127 }*/128 111 129 112 packet::Gamestate *GamestateManager::popGameState(unsigned int clientID) { … … 134 117 if(!reference) 135 118 return 0; 136 gs = reference->doSelection(clientID); 137 // gs = new packet::Gamestate(*reference); 119 gs = reference->doSelection(clientID, 10000); 138 120 // gs = new packet::Gamestate(*reference); 139 121 // save the (undiffed) gamestate in the clients gamestate map 140 gamestateMap_[clientID] .insert(std::pair<int, packet::Gamestate*>(gs->getID(), gs));122 gamestateMap_[clientID][gs->getID()]=gs; 141 123 //chose wheather the next gamestate is the first or not 142 packet::Gamestate *client= NULL;124 packet::Gamestate *client=0; 143 125 if(gID != GAMESTATEID_INITIAL){ 144 std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(clientID);145 if(clientMap!=gamestateMap_.end()){146 std::map<unsigned int, packet::Gamestate*>::iterator it = clientMap->second.find(gID);147 if(it!=clientMap->second.end())148 126 assert(gamestateMap_.find(clientID)!=gamestateMap_.end()); 127 std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateMap_[clientID].find(gID); 128 if(it!=gamestateMap_[clientID].end()) 129 { 130 client = it->second; 149 131 } 150 132 } … … 152 134 // COUT(3) << "diffing" << std::endl; 153 135 gs = gs->diff(client); 136 // gs = new packet::Gamestate(*gs); 154 137 } 155 138 else{ … … 159 142 bool b = gs->compressData(); 160 143 assert(b); 144 COUT(4) << "sending gamestate with id " << gs->getID(); 145 if(gs->isDiffed()) 146 COUT(4) << " and baseid " << gs->getBaseID() << endl; 147 else 148 COUT(4) << endl; 161 149 return gs; 162 150 } … … 168 156 unsigned int curid = temp->getGamestateID(); 169 157 170 if(gamestateID == 0){158 if(gamestateID == ACKID_NACK){ 171 159 temp->setGamestateID(GAMESTATEID_INITIAL); 160 // now delete all saved gamestates for this client 161 std::map<unsigned int, packet::Gamestate*>::iterator it; 162 for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end(); ){ 163 delete it->second; 164 gamestateMap_[clientID].erase(it++); 165 } 172 166 return true; 173 167 } … … 175 169 assert(curid==(unsigned int)GAMESTATEID_INITIAL || curid<gamestateID); 176 170 COUT(4) << "acking gamestate " << gamestateID << " for clientid: " << clientID << " curid: " << curid << std::endl; 177 std::map<unsigned int, packet::Gamestate*>::iterator it, tempit; 178 for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end() && it->first<gamestateID; it++){ 179 delete it->second; 180 tempit=it++; 181 gamestateMap_[clientID].erase(tempit); 171 std::map<unsigned int, packet::Gamestate*>::iterator it; 172 for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end() && it->first<gamestateID; ){ 173 delete it->second; 174 gamestateMap_[clientID].erase(it++); 182 175 } 183 176 temp->setGamestateID(gamestateID); 177 TrafficControl::processAck(clientID, gamestateID); 184 178 return true; 185 179 } -
code/trunk/src/network/GamestateManager.h
r2171 r2662 43 43 #include "NetworkPrereqs.h" 44 44 #include "GamestateHandler.h" 45 #include "TrafficControl.h" 45 46 #include <map> 46 47 … … 81 82 void removeClient(ClientInformation *client); 82 83 private: 83 // void cleanup(); // "garbage handler"84 84 bool processGamestate(packet::Gamestate *gs); 85 85 … … 89 89 std::map<unsigned int, packet::Gamestate*> gamestateQueue; 90 90 packet::Gamestate *reference; 91 TrafficControl *trafficControl_; 91 92 unsigned int id_; 92 93 }; -
code/trunk/src/network/NetworkPrereqs.h
r2171 r2662 57 57 58 58 //----------------------------------------------------------------------- 59 // Includes 60 //----------------------------------------------------------------------- 61 #include "util/Integers.h" 62 63 //----------------------------------------------------------------------- 64 // Library global contants 65 //----------------------------------------------------------------------- 66 namespace orxonox 67 { 68 static const unsigned int GAMESTATEID_INITIAL = (unsigned int)-1; 69 static const unsigned int CLIENTID_UNKNOWN = (unsigned int)-2; 70 static const uint32_t OBJECTID_UNKNOWN = (uint32_t)(-1); 71 } 72 73 //----------------------------------------------------------------------- 59 74 // Forward declarations 60 75 //----------------------------------------------------------------------- … … 70 85 class GamestateManager; 71 86 class GamestateHandler; 87 class NetworkCallbackBase; 88 template <class T> class NetworkCallback; 89 class NetworkCallbackManager; 72 90 class PacketBuffer; 73 91 class Server; 74 92 class ServerFrameListener; 75 93 class Synchronisable; 94 class SynchronisableVariableBase; 95 template <class T> class SynchronisableVariable; 96 template <class T> class SynchronisableVariableBidirectional; 76 97 struct ClientList; 77 98 struct PacketEnvelope; 78 99 struct QueueItem; 79 100 struct syncData; 80 struct synchronisableVariable; 81 namespace packet{ 101 class obj; 102 class objInfo; 103 104 namespace packet 105 { 82 106 class Gamestate; 83 107 class Packet; -
code/trunk/src/network/Server.cc
r2171 r2662 63 63 { 64 64 const unsigned int MAX_FAILURES = 20; 65 const unsigned int NETWORK_FREQUENCY = 25;66 const float NETWORK_PERIOD = (float)1/NETWORK_FREQUENCY;67 65 68 66 /** … … 218 216 */ 219 217 void Server::updateGamestate() { 218 // if( ClientInformation::getBegin()==NULL ) 219 //no client connected 220 // return; 220 221 gamestates_->update(); 221 222 COUT(5) << "Server: one gamestate update complete, goig to sendGameState" << std::endl; … … 276 277 bool Server::sendObjectDeletes(){ 277 278 ClientInformation *temp = ClientInformation::getBegin(); 279 if( temp == NULL ) 280 //no client connected 281 return true; 278 282 packet::DeleteObjects *del = new packet::DeleteObjects(); 279 283 if(!del->fetchIDs()) -
code/trunk/src/network/Server.h
r2171 r2662 52 52 { 53 53 const int CLIENTID_SERVER = 0; 54 const unsigned int NETWORK_FREQUENCY = 25; 55 const float NETWORK_PERIOD = 1./NETWORK_FREQUENCY; 54 56 55 57 /** -
code/trunk/src/network/packet/Acknowledgement.cc
r2171 r2662 64 64 65 65 bool Acknowledgement::process(){ 66 COUT(0) << "processing ACK with ID: " << getAckID() << endl; 66 67 bool b = GamestateHandler::ackGamestate(getAckID(), clientID_); 67 68 delete this; -
code/trunk/src/network/packet/Acknowledgement.h
r2171 r2662 32 32 #include "Packet.h" 33 33 34 const unsigned int ACKID_NACK = 0; 34 35 35 36 namespace orxonox { -
code/trunk/src/network/packet/DeleteObjects.cc
r2171 r2662 30 30 #include "DeleteObjects.h" 31 31 #include <enet/enet.h> 32 #include "network/ Synchronisable.h"32 #include "network/synchronisable/Synchronisable.h" 33 33 #include "core/CoreIncludes.h" 34 34 #include <assert.h> … … 61 61 if(number==0) 62 62 return false; 63 COUT( 3) << "sending DeleteObjects: ";63 COUT(4) << "sending DeleteObjects: "; 64 64 unsigned int size = sizeof(ENUM::Type) + sizeof(uint32_t)*(number+1); 65 65 data_ = new uint8_t[size]; 66 66 uint8_t *tdata = data_; 67 * (ENUM::Type *)(tdata) = ENUM::DeleteObjects;67 *reinterpret_cast<ENUM::Type*>(tdata) = ENUM::DeleteObjects; 68 68 tdata += sizeof(ENUM::Type); 69 69 *(uint32_t *)tdata = number; … … 72 72 unsigned int temp = Synchronisable::popDeletedObject(); 73 73 // assert(temp<10000); //ugly hack 74 * (uint32_t *)(tdata) = temp;75 COUT( 3) << temp << " ";74 *reinterpret_cast<uint32_t*>(tdata) = temp; 75 COUT(4) << temp << " "; 76 76 tdata += sizeof(uint32_t); 77 77 } 78 COUT( 3) << std::endl;78 COUT(4) << std::endl; 79 79 return true; 80 80 } … … 87 87 bool DeleteObjects::process(){ 88 88 for(unsigned int i=0; i<*(unsigned int *)(data_+_QUANTITY); i++){ 89 COUT( 3) << "deleting object with id: " << *(uint32_t*)(data_+_OBJECTIDS+i*sizeof(uint32_t)) << std::endl;89 COUT(4) << "deleting object with id: " << *(uint32_t*)(data_+_OBJECTIDS+i*sizeof(uint32_t)) << std::endl; 90 90 Synchronisable::deleteObject( *(uint32_t*)(data_+_OBJECTIDS+i*sizeof(uint32_t)) ); 91 91 } -
code/trunk/src/network/packet/Gamestate.cc
r2171 r2662 28 28 29 29 #include "Gamestate.h" 30 #include "network/ClientInformation.h" 31 #include "network/GamestateHandler.h" 30 #include "../GamestateHandler.h" 31 #include "../synchronisable/Synchronisable.h" 32 #include "../TrafficControl.h" 33 #include "core/Core.h" 32 34 #include "core/CoreIncludes.h" 33 35 #include "core/Iterator.h" 34 36 35 37 #include <zlib.h> 36 #include < assert.h>38 #include <cassert> 37 39 38 40 … … 42 44 namespace packet { 43 45 44 #define GAMESTATE_START(data) (data + sizeof(GamestateHeader)) 45 #define GAMESTATE_HEADER(data) ((GamestateHeader *)data) 46 #define HEADER GAMESTATE_HEADER(data_) 47 46 #define GAMESTATE_START(data) (data + GamestateHeader::getSize()) 48 47 49 48 #define PACKET_FLAG_GAMESTATE ENET_PACKET_FLAG_RELIABLE 50 49 50 // Gamestate::Gamestate() 51 // { 52 // flags_ = flags_ | PACKET_FLAG_GAMESTATE; 53 // } 54 51 55 Gamestate::Gamestate() 52 56 { 53 57 flags_ = flags_ | PACKET_FLAG_GAMESTATE; 58 header_ = 0; 54 59 } 55 60 … … 58 63 { 59 64 flags_ = flags_ | PACKET_FLAG_GAMESTATE; 65 header_ = new GamestateHeader(data_); 60 66 } 61 67 … … 64 70 flags_ = flags_ | PACKET_FLAG_GAMESTATE; 65 71 data_=data; 72 header_ = new GamestateHeader(data_); 73 } 74 75 Gamestate::Gamestate(const Gamestate& g) : 76 Packet( *(Packet*)&g ) 77 { 78 flags_ = flags_ | PACKET_FLAG_GAMESTATE; 79 header_ = new GamestateHeader(data_); 66 80 } 67 81 … … 73 87 bool Gamestate::collectData(int id, uint8_t mode) 74 88 { 75 unsigned int tempsize=0, currentsize=0; 89 assert(this->header_==0); // make sure the header didn't exist before 90 uint32_t tempsize=0, currentsize=0; 76 91 assert(data_==0); 77 u nsigned int size = calcGamestateSize(id, mode);92 uint32_t size = calcGamestateSize(id, mode); 78 93 79 94 COUT(4) << "G.ST.Man: producing gamestate with id: " << id << std::endl; 80 95 if(size==0) 81 96 return false; 82 data_ = new u nsigned char[size + sizeof(GamestateHeader)];97 data_ = new uint8_t[size + GamestateHeader::getSize()]; 83 98 if(!data_){ 84 99 COUT(2) << "GameStateManager: could not allocate memory" << std::endl; 85 100 return false; 86 101 } 102 103 // create the header object 104 header_ = new GamestateHeader(data_); 87 105 88 106 //start collect data synchronisable by synchronisable 89 107 uint8_t *mem=data_; 90 mem +=sizeof(GamestateHeader);108 mem += GamestateHeader::getSize(); 91 109 ObjectList<Synchronisable>::iterator it; 92 110 for(it = ObjectList<Synchronisable>::begin(); it; ++it){ 111 112 #ifndef NDEBUG 93 113 tempsize=it->getSize(id, mode); 94 95 114 if(currentsize+tempsize > size){ 96 115 assert(0); // if we don't use multithreading this part shouldn't be neccessary … … 98 117 COUT(3) << "G.St.Man: need additional memory" << std::endl; 99 118 ObjectList<Synchronisable>::iterator temp = it; 100 int addsize=tempsize;119 uint32_t addsize=tempsize; 101 120 while(++temp) 102 121 addsize+=temp->getSize(id, mode); 103 data_ = (uint8_t *)realloc(data_, sizeof(GamestateHeader) + currentsize + addsize);122 data_ = (uint8_t *)realloc(data_, GamestateHeader::getSize() + currentsize + addsize); 104 123 if(!data_) 105 124 return false; 106 125 size = currentsize+addsize; 107 126 }// stop allocate additional memory 108 127 #endif 109 128 110 129 //if(it->doSelection(id)) 111 dataMap_[mem-data_]=(*it); // save the mem location of the synchronisable data 130 if ( it->doSync( id, mode ) ) 131 dataMap_.push_back( obj(it->getObjectID(), it->getCreatorID(), tempsize, mem-data_) ); 132 // dataMap_[mem-data_]=(*it); // save the mem location of the synchronisable data 112 133 if(!it->getData(mem, id, mode)) 113 134 return false; // mem pointer gets automatically increased because of call by reference … … 118 139 119 140 //start write gamestate header 120 HEADER->packetType = ENUM::Gamestate; 121 HEADER->datasize = currentsize; 122 HEADER->id = id; 123 HEADER->diffed = false; 124 HEADER->complete = true; 125 HEADER->compressed = false; 141 header_->setDataSize( currentsize ); 142 header_->setID( id ); 143 header_->setDiffed( false ); 144 header_->setComplete( true ); 145 header_->setCompressed( false ); 126 146 //stop write gamestate header 127 147 … … 133 153 bool Gamestate::spreadData(uint8_t mode) 134 154 { 135 assert(data_); 136 assert(!HEADER->compressed); 137 assert(!HEADER->diffed); 138 uint8_t *mem=data_+sizeof(GamestateHeader); 155 COUT(4) << "processing gamestate with id " << header_->getID() << endl; 156 assert(data_); 157 assert(!header_->isCompressed()); 158 assert(!header_->isDiffed()); 159 uint8_t *mem=data_+GamestateHeader::getSize(); 139 160 // get the start of the Synchronisable list 140 161 //ObjectList<Synchronisable>::iterator it=ObjectList<Synchronisable>::begin(); … … 142 163 143 164 // update the data of the objects we received 144 while(mem < data_+ sizeof(GamestateHeader)+HEADER->datasize){145 synchronisableHeader *objectheader = (synchronisableHeader*)mem;146 147 s = Synchronisable::getSynchronisable( objectheader ->objectID);165 while(mem < data_+GamestateHeader::getSize()+header_->getDataSize()){ 166 SynchronisableHeader objectheader(mem); 167 168 s = Synchronisable::getSynchronisable( objectheader.getObjectID() ); 148 169 if(!s) 149 170 { 150 Synchronisable::fabricate(mem, mode); 171 if (!Core::isMaster()) 172 { 173 Synchronisable::fabricate(mem, mode); 174 } 175 else 176 { 177 mem += objectheader.getDataSize(); 178 } 179 // COUT(0) << "could not fabricate synchronisable: " << objectheader->objectID << " classid: " << objectheader->classID << " creator: " << objectheader->creatorID << endl; 180 // else 181 // COUT(0) << "fabricated: " << objectheader->objectID << " classid: " << objectheader->classID << " creator: " << objectheader->creatorID << endl; 151 182 } 152 183 else … … 157 188 } 158 189 190 // In debug mode, check first, whether there are no duplicate objectIDs 191 #ifndef NDEBUG 192 ObjectList<Synchronisable>::iterator it; 193 for (it = ObjectList<Synchronisable>::begin(); it != ObjectList<Synchronisable>::end(); ++it) { 194 if (it->getObjectID() == OBJECTID_UNKNOWN) { 195 if (it->objectMode_ != 0x0) { 196 COUT(0) << "Found object with OBJECTID_UNKNOWN on the client with objectMode != 0x0!" << std::endl; 197 COUT(0) << "Possible reason for this error: Client created a synchronized object without the Server's approval." << std::endl; 198 COUT(0) << "Objects class: " << it->getIdentifier()->getName() << std::endl; 199 assert(false); 200 } 201 } 202 else { 203 ObjectList<Synchronisable>::iterator it2; 204 for (it2 = ObjectList<Synchronisable>::begin(); it2 != ObjectList<Synchronisable>::end(); ++it2) { 205 if (it->getObjectID() == it2->getObjectID() && *it != *it2) { 206 COUT(0) << "Found duplicate objectIDs on the client!" << std::endl 207 << "Are you sure you don't create a Sychnronisable objcect with 'new' \ 208 that doesn't have objectMode = 0x0?" << std::endl; 209 assert(false); 210 } 211 } 212 } 213 } 214 #endif 215 159 216 return true; 160 217 } 161 218 162 163 164 int Gamestate::getID(){ 165 return HEADER->id; 166 } 167 168 unsigned int Gamestate::getSize() const 169 { 170 assert(data_); 171 if(HEADER->compressed) 172 return HEADER->compsize+sizeof(GamestateHeader); 219 uint32_t Gamestate::getSize() const 220 { 221 assert(data_); 222 if(header_->isCompressed()) 223 return header_->getCompSize()+GamestateHeader::getSize(); 173 224 else 174 225 { 175 return HEADER->datasize+sizeof(GamestateHeader);226 return header_->getDataSize()+GamestateHeader::getSize(); 176 227 } 177 228 } 178 229 179 230 bool Gamestate::operator==(packet::Gamestate gs){ 180 uint8_t *d1 = data_+ sizeof(GamestateHeader);181 uint8_t *d2 = gs.data_+ sizeof(GamestateHeader);231 uint8_t *d1 = data_+GamestateHeader::getSize(); 232 uint8_t *d2 = gs.data_+GamestateHeader::getSize(); 182 233 assert(!isCompressed()); 183 234 assert(!gs.isCompressed()); 184 while(d1<data_+ HEADER->datasize)235 while(d1<data_+header_->getDataSize()) 185 236 { 186 237 if(*d1!=*d2) … … 201 252 bool Gamestate::compressData() 202 253 { 203 assert( HEADER);204 assert(! HEADER->compressed);205 uLongf buffer = (uLongf)((( HEADER->datasize+ 12)*1.01)+1);254 assert(data_); 255 assert(!header_->isCompressed()); 256 uLongf buffer = (uLongf)(((header_->getDataSize() + 12)*1.01)+1); 206 257 if(buffer==0) 207 258 return false; 208 259 209 uint8_t *ndata = new uint8_t[buffer+ sizeof(GamestateHeader)];210 uint8_t *dest = GAMESTATE_START(ndata);260 uint8_t *ndata = new uint8_t[buffer+GamestateHeader::getSize()]; 261 uint8_t *dest = ndata + GamestateHeader::getSize(); 211 262 //unsigned char *dest = new unsigned char[buffer]; 212 uint8_t *source = GAMESTATE_START(data_);263 uint8_t *source = data_ + GamestateHeader::getSize(); 213 264 int retval; 214 retval = compress( dest, &buffer, source, (uLong)( HEADER->datasize) );265 retval = compress( dest, &buffer, source, (uLong)(header_->getDataSize()) ); 215 266 switch ( retval ) { 216 267 case Z_OK: COUT(5) << "G.St.Man: compress: successfully compressed" << std::endl; break; … … 219 270 case Z_DATA_ERROR: COUT(2) << "G.St.Man: compress: data corrupted in gamestate.compress" << std::endl; return false; 220 271 } 221 #ifndef NDEBUG222 //decompress and compare the start and the decompressed data223 uint8_t *rdata = new uint8_t[HEADER->datasize+sizeof(GamestateHeader)];224 uint8_t *d2 = GAMESTATE_START(rdata);225 uLongf length2 = HEADER->datasize;226 uncompress(d2, &length2, dest, buffer);227 for(unsigned int i=0; i<HEADER->datasize; i++){228 assert(*(source+i)==*(d2+i));229 }230 delete[] rdata;231 #endif232 272 233 273 //copy and modify header 234 #ifndef NDEBUG 235 HEADER->crc32 = calcCRC(data_+sizeof(GamestateHeader), HEADER->datasize); 236 #endif 237 *GAMESTATE_HEADER(ndata) = *HEADER; 274 GamestateHeader *temp = header_; 275 header_ = new GamestateHeader(ndata, temp); 276 delete temp; 238 277 //delete old data 239 278 delete[] data_; 240 279 //save new data 241 280 data_ = ndata; 242 HEADER->compsize = buffer; 243 HEADER->compressed = true; 244 assert(HEADER->compressed); 245 COUT(4) << "gamestate compress datasize: " << HEADER->datasize << " compsize: " << HEADER->compsize << std::endl; 281 header_->setCompSize( buffer ); 282 header_->setCompressed( true ); 283 COUT(5) << "gamestate compress datasize: " << header_->getDataSize() << " compsize: " << header_->getCompSize() << std::endl; 246 284 return true; 247 285 } 248 286 bool Gamestate::decompressData() 249 287 { 250 assert( HEADER);251 assert( HEADER->compressed);252 COUT(4) << "GameStateClient: uncompressing gamestate. id: " << HEADER->id << ", baseid: " << HEADER->base_id << ", datasize: " << HEADER->datasize << ", compsize: " << HEADER->compsize<< std::endl;253 u nsigned int datasize = HEADER->datasize;254 u nsigned int compsize = HEADER->compsize;255 u nsigned int bufsize;288 assert(data_); 289 assert(header_->isCompressed()); 290 COUT(4) << "GameStateClient: uncompressing gamestate. id: " << header_->getID() << ", baseid: " << header_->getBaseID() << ", datasize: " << header_->getDataSize() << ", compsize: " << header_->getCompSize() << std::endl; 291 uint32_t datasize = header_->getDataSize(); 292 uint32_t compsize = header_->getCompSize(); 293 uint32_t bufsize; 256 294 // assert(compsize<=datasize); 257 295 bufsize = datasize; 258 296 assert(bufsize!=0); 259 uint8_t *ndata = new uint8_t[bufsize + sizeof(GamestateHeader)];260 uint8_t *dest = ndata + sizeof(GamestateHeader);261 uint8_t *source = data_ + sizeof(GamestateHeader);297 uint8_t *ndata = new uint8_t[bufsize + GamestateHeader::getSize()]; 298 uint8_t *dest = ndata + GamestateHeader::getSize(); 299 uint8_t *source = data_ + GamestateHeader::getSize(); 262 300 int retval; 263 301 uLongf length=bufsize; … … 269 307 case Z_DATA_ERROR: COUT(2) << "data corrupted (zlib)" << std::endl; return false; 270 308 } 271 #ifndef NDEBUG272 assert(HEADER->crc32==calcCRC(ndata+sizeof(GamestateHeader), HEADER->datasize));273 #endif274 309 275 310 //copy over the header 276 *GAMESTATE_HEADER(ndata) = *HEADER; 311 GamestateHeader *temp = header_; 312 header_ = new GamestateHeader( data_, header_ ); 313 delete temp; 277 314 278 315 if (this->bDataENetAllocated_){ … … 289 326 //set new pointers 290 327 data_ = ndata; 291 HEADER->compressed = false;292 assert( HEADER->datasize==datasize);293 assert( HEADER->compsize==compsize);328 header_->setCompressed( false ); 329 assert(header_->getDataSize()==datasize); 330 assert(header_->getCompSize()==compsize); 294 331 return true; 295 332 } … … 297 334 Gamestate *Gamestate::diff(Gamestate *base) 298 335 { 299 assert(HEADER); 300 assert(!HEADER->compressed); 301 assert(!HEADER->diffed); 336 assert(data_); 337 assert(!header_->isCompressed()); 338 assert(!header_->isDiffed()); 339 GamestateHeader diffHeader(base->data_); 302 340 //unsigned char *basep = base->getGs()/*, *gs = getGs()*/; 303 341 uint8_t *basep = GAMESTATE_START(base->data_), *gs = GAMESTATE_START(this->data_); 304 u nsigned int of=0; // pointers offset305 u nsigned int dest_length=0;306 dest_length= HEADER->datasize;342 uint32_t of=0; // pointers offset 343 uint32_t dest_length=0; 344 dest_length=header_->getDataSize(); 307 345 if(dest_length==0) 308 346 return NULL; 309 uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+ sizeof(GamestateHeader)];310 uint8_t *dest = ndata + sizeof(GamestateHeader);311 while(of < GAMESTATE_HEADER(base->data_)->datasize && of < HEADER->datasize){347 uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()]; 348 uint8_t *dest = ndata + GamestateHeader::getSize(); 349 while(of < diffHeader.getDataSize() && of < header_->getDataSize()){ 312 350 *(dest+of)=*(basep+of)^*(gs+of); // do the xor 313 351 ++of; 314 352 } 315 if( GAMESTATE_HEADER(base->data_)->datasize!=HEADER->datasize){353 if(diffHeader.getDataSize()!=header_->getDataSize()){ 316 354 uint8_t n=0; 317 if( GAMESTATE_HEADER(base->data_)->datasize < HEADER->datasize){355 if(diffHeader.getDataSize() < header_->getDataSize()){ 318 356 while(of<dest_length){ 319 357 *(dest+of)=n^*(gs+of); … … 323 361 } 324 362 325 *GAMESTATE_HEADER(ndata) = *HEADER;326 GAMESTATE_HEADER(ndata)->diffed = true;327 GAMESTATE_HEADER(ndata)->base_id = base->getID();328 363 Gamestate *g = new Gamestate(ndata, getClientID()); 364 *(g->header_) = *header_; 365 g->header_->setDiffed( true ); 366 g->header_->setBaseID( base->getID() ); 329 367 g->flags_=flags_; 330 368 g->packetDirection_ = packetDirection_; … … 332 370 } 333 371 334 Gamestate* Gamestate::doSelection(unsigned int clientID ){335 assert(data_); 336 std:: map<unsigned int, Synchronisable *>::iterator it;372 Gamestate* Gamestate::doSelection(unsigned int clientID, unsigned int targetSize){ 373 assert(data_); 374 std::list<obj>::iterator it; 337 375 338 376 // allocate memory for new data 339 uint8_t *gdata = new uint8_t[ HEADER->datasize+sizeof(GamestateHeader)];377 uint8_t *gdata = new uint8_t[header_->getDataSize()+GamestateHeader::getSize()]; 340 378 // create a gamestate out of it 341 379 Gamestate *gs = new Gamestate(gdata); 342 uint8_t *newdata = gdata + sizeof(GamestateHeader);380 uint8_t *newdata = gdata + GamestateHeader::getSize(); 343 381 uint8_t *origdata = GAMESTATE_START(data_); 344 382 345 383 //copy the GamestateHeader 346 *(GamestateHeader*)gdata = *HEADER; 347 348 synchronisableHeader *oldobjectheader, *newobjectheader; 349 unsigned int objectOffset; 384 assert(gs->header_); 385 *(gs->header_) = *header_; 386 387 uint32_t objectOffset; 388 unsigned int objectsize, destsize=0; 389 // TODO: Why is this variable not used? 390 //Synchronisable *object; 391 392 //call TrafficControl 393 TrafficControl::getInstance()->processObjectList( clientID, header_->getID(), &dataMap_ ); 350 394 351 395 //copy in the zeros 352 for(it=dataMap_.begin(); it!=dataMap_.end(); it++){ 353 oldobjectheader = (synchronisableHeader*)origdata; 354 newobjectheader = (synchronisableHeader*)newdata; 355 unsigned int objectsize = oldobjectheader->size; 356 assert(it->second->objectID==oldobjectheader->objectID); 357 *newobjectheader = *oldobjectheader; 358 objectOffset=sizeof(synchronisableHeader); //skip the size and the availableData variables in the objectheader 359 if(it->second->doSelection(HEADER->id)){ 360 assert(newobjectheader->dataAvailable==true); 361 memcpy(newdata+objectOffset, origdata+objectOffset, objectsize-objectOffset); 396 for(it=dataMap_.begin(); it!=dataMap_.end();){ 397 // if((*it).objSize==0) 398 // continue; 399 // if(it->second->getSize(HEADER->id)==0) // merged from objecthierarchy2, doesn't work anymore; TODO: change this 400 // continue; // merged from objecthierarchy2, doesn't work anymore; TODO: change this 401 SynchronisableHeader oldobjectheader(origdata); 402 SynchronisableHeader newobjectheader(newdata); 403 if ( (*it).objSize == 0 ) 404 { 405 ++it; 406 continue; 407 } 408 // object = Synchronisable::getSynchronisable( (*it).objID ); 409 // assert(object->objectID == oldobjectheader->objectID); 410 objectsize = oldobjectheader.getDataSize(); 411 objectOffset=SynchronisableHeader::getSize(); //skip the size and the availableData variables in the objectheader 412 if ( (*it).objID == oldobjectheader.getObjectID() ){ 413 memcpy(newdata, origdata, objectsize); 414 assert(newobjectheader.isDataAvailable()==true); 415 ++it; 362 416 }else{ 363 newobjectheader->dataAvailable=false; 417 newobjectheader = oldobjectheader; 418 newobjectheader.setDataAvailable(false); 364 419 memset(newdata+objectOffset, 0, objectsize-objectOffset); 365 assert(objectOffset==objectsize);366 420 } 367 421 newdata += objectsize; 368 422 origdata += objectsize; 369 } 423 destsize += objectsize; 424 } 425 #ifndef NDEBUG 426 uint32_t origsize = destsize; 427 while ( origsize < header_->getDataSize() ) 428 { 429 SynchronisableHeader oldobjectheader(origdata); 430 objectsize = oldobjectheader.getDataSize(); 431 origdata += objectsize; 432 origsize += objectsize; 433 } 434 assert(origsize==header_->getDataSize()); 435 assert(destsize!=0); 436 #endif 437 gs->header_->setDataSize( destsize ); 370 438 return gs; 371 439 } 372 440 373 441 374 Gamestate* Gamestate::intelligentDiff(Gamestate *base, unsigned int clientID){375 // asserts376 assert(data_);377 assert(base->data_);378 assert(!GAMESTATE_HEADER(base->data_)->diffed);379 assert(!GAMESTATE_HEADER(base->data_)->compressed);380 assert(!HEADER->compressed);381 assert(!HEADER->diffed);382 383 //preparations384 std::map<unsigned int, Synchronisable *>::iterator it;385 uint8_t *origdata, *basedata, *destdata, *ndata;386 unsigned int objectOffset, streamOffset=0; //data offset387 unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize;388 synchronisableHeader *origheader;389 synchronisableHeader *destheader;390 391 origdata = GAMESTATE_START(this->data_);392 basedata = GAMESTATE_START(base->data_);393 ndata = new uint8_t[HEADER->datasize + sizeof(GamestateHeader)];394 destdata = ndata + sizeof(GamestateHeader);395 396 // do the diff397 for(it=dataMap_.begin(); it!=dataMap_.end(); it++){398 assert(streamOffset<HEADER->datasize);399 bool sendData = it->second->doSelection(HEADER->id);400 origheader = (synchronisableHeader *)(origdata+streamOffset);401 destheader = (synchronisableHeader *)(destdata+streamOffset);402 403 //copy and partially diff the object header404 assert(sizeof(synchronisableHeader)==3*sizeof(unsigned int)+sizeof(bool));405 *(uint32_t*)destdata = *(uint32_t*)origdata; //size (do not diff)406 *(bool*)(destdata+sizeof(uint32_t)) = sendData;407 if(sendData){408 *(uint32_t*)(destdata+sizeof(uint32_t)+sizeof(bool)) = *(uint32_t*)(basedata+sizeof(uint32_t)+sizeof(bool)) ^ *(uint32_t*)(origdata+sizeof(uint32_t)+sizeof(bool)); //objectid (diff it)409 *(uint32_t*)(destdata+2*sizeof(uint32_t)+sizeof(bool)) = *(uint32_t*)(basedata+2*sizeof(uint32_t)+sizeof(bool)) ^ *(uint32_t*)(origdata+2*sizeof(uint32_t)+sizeof(bool)); //classid (diff it)410 }else{411 *(uint32_t*)(destdata+sizeof(uint32_t)+sizeof(bool)) = 0;412 *(uint32_t*)(destdata+2*sizeof(uint32_t)+sizeof(bool)) = 0;413 }414 objectOffset=sizeof(synchronisableHeader);415 streamOffset+=sizeof(synchronisableHeader);416 417 //now handle the object data or fill with zeros418 while(objectOffset<origheader->size ){419 420 if(sendData && streamOffset<minsize)421 *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor422 else if(sendData)423 *(destdata+objectOffset)=((uint8_t)0)^*(origdata+objectOffset); // xor with 0 (basestream is too short)424 else425 *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered426 427 objectOffset++;428 streamOffset++;429 }430 destdata+=objectOffset;431 origdata+=objectOffset;432 basedata+=objectOffset;433 }434 435 //copy over the gamestate header and set the diffed flag436 *(GamestateHeader *)ndata = *HEADER; //copy over the header437 Gamestate *gs = new Gamestate(ndata);438 GAMESTATE_HEADER(ndata)->diffed=true;439 return gs;440 }441 442 Gamestate* Gamestate::intelligentUnDiff(Gamestate *base){443 // asserts444 assert(data_);445 assert(base->data_);446 assert(!GAMESTATE_HEADER(base->data_)->diffed);447 assert(!GAMESTATE_HEADER(base->data_)->compressed);448 assert(!HEADER->compressed);449 assert(HEADER->diffed);450 451 //preparations452 std::map<unsigned int, Synchronisable *>::iterator it;453 uint8_t *origdata, *basedata, *destdata, *ndata;454 unsigned int objectOffset, streamOffset=0; //data offset455 unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize;456 synchronisableHeader *origheader;457 synchronisableHeader *destheader;458 459 origdata = GAMESTATE_START(this->data_);460 basedata = GAMESTATE_START(base->data_);461 ndata = new uint8_t[HEADER->datasize + sizeof(GamestateHeader)];462 destdata = ndata + sizeof(GamestateHeader);463 464 // do the undiff465 for(it=dataMap_.begin(); it!=dataMap_.end(); it++){466 assert(streamOffset<HEADER->datasize);467 origheader = (synchronisableHeader *)(origdata+streamOffset);468 destheader = (synchronisableHeader *)(destdata+streamOffset);469 bool sendData;470 471 //copy and partially diff the object header472 assert(sizeof(synchronisableHeader)==3*sizeof(unsigned int)+sizeof(bool));473 *(unsigned int*)destdata = *(unsigned int*)origdata; //size (do not diff)474 *(bool*)(destdata+sizeof(unsigned int)) = *(bool*)(origdata+sizeof(unsigned int));475 sendData = *(bool*)(origdata+sizeof(unsigned int));476 if(sendData){477 *(unsigned int*)(destdata+sizeof(unsigned int)+sizeof(bool)) = *(unsigned int*)(basedata+sizeof(unsigned int)+sizeof(bool)) ^ *(unsigned int*)(origdata+sizeof(unsigned int)+sizeof(bool)); //objectid (diff it)478 *(unsigned int*)(destdata+2*sizeof(unsigned int)+sizeof(bool)) = *(unsigned int*)(basedata+2*sizeof(unsigned int)+sizeof(bool)) ^ *(unsigned int*)(origdata+2*sizeof(unsigned int)+sizeof(bool)); //classid (diff it)479 }else{480 *(unsigned int*)(destdata+sizeof(unsigned int)+sizeof(bool)) = 0;481 *(unsigned int*)(destdata+2*sizeof(unsigned int)+sizeof(bool)) = 0;482 }483 objectOffset=sizeof(synchronisableHeader);484 streamOffset+=sizeof(synchronisableHeader);485 486 //now handle the object data or fill with zeros487 while(objectOffset<origheader->size ){488 489 if(sendData && streamOffset<minsize)490 *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor491 else if(sendData)492 *(destdata+objectOffset)=((unsigned char)0)^*(origdata+objectOffset); // xor with 0 (basestream is too short)493 else494 *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered495 496 objectOffset++;497 streamOffset++;498 }499 destdata+=objectOffset;500 origdata+=objectOffset;501 basedata+=objectOffset;502 }503 504 //copy over the gamestate header and set the diffed flag505 *(GamestateHeader *)ndata = *HEADER; //copy over the header506 Gamestate *gs = new Gamestate(ndata);507 GAMESTATE_HEADER(ndata)->diffed=false;508 return gs;509 }510 511 442 Gamestate *Gamestate::undiff(Gamestate *base) 512 443 { 513 assert(this && base);assert( HEADER);514 assert( HEADER->diffed);515 assert(! HEADER->compressed && !GAMESTATE_HEADER(base->data_)->compressed);444 assert(this && base);assert(data_); 445 assert(header_->isDiffed()); 446 assert(!header_->isCompressed() && !base->header_->isCompressed()); 516 447 //unsigned char *basep = base->getGs()/*, *gs = getGs()*/; 517 448 uint8_t *basep = GAMESTATE_START(base->data_); 518 449 uint8_t *gs = GAMESTATE_START(this->data_); 519 u nsigned int of=0; // pointers offset520 u nsigned int dest_length=0;521 dest_length= HEADER->datasize;450 uint32_t of=0; // pointers offset 451 uint32_t dest_length=0; 452 dest_length=header_->getDataSize(); 522 453 if(dest_length==0) 523 454 return NULL; 524 uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+ sizeof(GamestateHeader)];525 uint8_t *dest = ndata + sizeof(GamestateHeader);526 while(of < GAMESTATE_HEADER(base->data_)->datasize && of < HEADER->datasize){455 uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()]; 456 uint8_t *dest = ndata + GamestateHeader::getSize(); 457 while(of < base->header_->getDataSize() && of < header_->getDataSize()){ 527 458 *(dest+of)=*(basep+of)^*(gs+of); // do the xor 528 459 ++of; 529 460 } 530 if( GAMESTATE_HEADER(base->data_)->datasize!=HEADER->datasize){461 if(base->header_->getDataSize()!=header_->getDataSize()){ 531 462 uint8_t n=0; 532 if( GAMESTATE_HEADER(base->data_)->datasize < HEADER->datasize){463 if(base->header_->getDataSize() < header_->getDataSize()){ 533 464 while(of < dest_length){ 534 465 *(dest+of)=n^*(gs+of); … … 537 468 } 538 469 } 539 *GAMESTATE_HEADER(ndata) = *HEADER;540 GAMESTATE_HEADER(ndata)->diffed = false;541 470 Gamestate *g = new Gamestate(ndata, getClientID()); 471 assert(g->header_); 472 *(g->header_) = *header_; 473 g->header_->setDiffed( false ); 542 474 g->flags_=flags_; 543 475 g->packetDirection_ = packetDirection_; … … 548 480 549 481 550 u nsigned int Gamestate::calcGamestateSize(unsigned int id, uint8_t mode)551 { 552 u nsigned int size=0;482 uint32_t Gamestate::calcGamestateSize(int32_t id, uint8_t mode) 483 { 484 uint32_t size=0; 553 485 // get the start of the Synchronisable list 554 486 ObjectList<Synchronisable>::iterator it; … … 556 488 for(it = ObjectList<Synchronisable>::begin(); it; ++it) 557 489 size+=it->getSize(id, mode); // size of the actual data of the synchronisable 558 // size+=sizeof(GamestateHeader);559 490 return size; 560 491 } 561 492 562 /** 563 * This function removes a Synchronisable out of the universe 564 * @param it iterator of the list pointing to the object 565 * @return iterator pointing to the next object in the list 566 */ 567 void Gamestate::removeObject(ObjectList<Synchronisable>::iterator &it) { 568 ObjectList<Synchronisable>::iterator temp=it; 569 ++it; 570 delete *temp; 571 } 572 573 bool Gamestate::isDiffed(){ 574 return HEADER->diffed; 575 } 576 577 bool Gamestate::isCompressed(){ 578 return HEADER->compressed; 579 } 580 581 int Gamestate::getBaseID(){ 582 return HEADER->base_id; 583 } 584 } 585 586 } 493 } //namespace packet 494 } //namespace orxonox -
code/trunk/src/network/packet/Gamestate.h
r2171 r2662 31 31 #define NETWORK_PACKETGAMESTATE_H 32 32 33 #include " ../NetworkPrereqs.h"33 #include "network/NetworkPrereqs.h" 34 34 35 35 #include "Packet.h" 36 #include "network/Synchronisable.h" 36 #include "network/TrafficControl.h" 37 #include "core/CoreIncludes.h" 37 38 #include <map> 39 #include <list> 38 40 #ifndef NDEBUG 39 41 #include "util/CRC32.h" … … 44 46 namespace packet { 45 47 46 struct _NetworkExport GamestateHeader{ 47 ENUM::Type packetType; 48 int32_t id; // id of the gamestate 49 uint32_t compsize; 50 uint32_t datasize; 51 int32_t base_id; // id of the base-gamestate diffed from 52 bool diffed:1; // wheter diffed or not 53 bool complete:1; // wheter it is a complete gamestate or only partial 54 bool compressed:1; 55 #ifndef NDEBUG 56 uint32_t crc32; 57 #endif 48 class _NetworkExport GamestateHeader{ 49 public: 50 GamestateHeader(uint8_t *data){ assert(data); data_ = data; *(uint32_t*)data_ = ENUM::Gamestate; } 51 GamestateHeader(uint8_t *data, GamestateHeader* h) 52 { assert(data); data_=data; memcpy(data_, h->data_, getSize()); } 53 static inline uint32_t getSize() 54 { return 21; } 55 56 inline int32_t getID() const 57 { assert(data_); return *(int32_t*)(data_+4); } 58 inline void setID(int32_t id) 59 { assert(data_); *(int32_t*)(data_+4) = id; } 60 61 inline int32_t getBaseID() const 62 { assert(data_); return *(int32_t*)(data_+8); } 63 inline void setBaseID(int32_t id) 64 { assert(data_); *(int32_t*)(data_+8) = id; } 65 66 inline uint32_t getDataSize() const 67 { assert(data_); return *(uint32_t*)(data_+12); } 68 inline void setDataSize(uint32_t size) 69 { assert(data_); *(uint32_t*)(data_+12) = size; } 70 71 inline uint32_t getCompSize() const 72 { assert(data_); return *(uint32_t*)(data_+16); } 73 inline void setCompSize(uint32_t size) 74 { assert(data_); *(uint32_t*)(data_+16) = size; } 75 76 inline bool isDiffed() const 77 { assert(data_); return *(int8_t*)(data_+20) & 0x1; } 78 inline void setDiffed(bool b) 79 { assert(data_); *(int8_t*)(data_+20) = (b<<0) | (*(int8_t*)(data_+20) & 0x6 ); } 80 81 inline bool isComplete() const 82 { assert(data_); return *(int8_t*)(data_+20) & 0x2; } 83 inline void setComplete(bool b) 84 { assert(data_); *(int8_t*)(data_+20) = (b<<1) | (*(int8_t*)(data_+20) & 0x5 ); } 85 86 inline bool isCompressed() const 87 { assert(data_); return *(int8_t*)(data_+20) & 0x4; } 88 inline void setCompressed(bool b) 89 { assert(data_); *(int8_t*)(data_+20) = (b<<2) | (*(int8_t*)(data_+20) & 0x3 ); } 90 91 inline void operator=(GamestateHeader& h) 92 { assert(data_); assert(h.data_); memcpy( data_, h.data_, getSize()); } 93 private: 94 uint8_t *data_; 95 //#define GAMESTATE_START(data) (data + sizeof(GamestateHeader)) 96 //#define GAMESTATE_HEADER(data) ((GamestateHeader *)data) 97 //#define HEADER GAMESTATE_HEADER(data_) 98 58 99 }; 59 100 … … 66 107 Gamestate(uint8_t *data, unsigned int clientID); 67 108 Gamestate(uint8_t *data); 109 Gamestate(const Gamestate& g); 68 110 69 111 ~Gamestate(); … … 71 113 bool collectData(int id, uint8_t mode=0x0); 72 114 bool spreadData( uint8_t mode=0x0); 73 in t getID();74 bool isDiffed();75 bool isCompressed();76 in t getBaseID();115 inline int32_t getID() const { return header_->getID(); } 116 inline bool isDiffed() const { return header_->isDiffed(); } 117 inline bool isCompressed() const { return header_->isCompressed(); } 118 inline int32_t getBaseID() const { return header_->getBaseID(); } 77 119 Gamestate *diff(Gamestate *base); 78 Gamestate* intelligentDiff(Gamestate *base, unsigned int clientID);79 120 Gamestate *undiff(Gamestate *base); 80 Gamestate* intelligentUnDiff(Gamestate *base); 81 Gamestate* doSelection(unsigned int clientID); 121 Gamestate* doSelection(unsigned int clientID, unsigned int targetSize); 82 122 bool compressData(); 83 123 bool decompressData(); … … 85 125 // Packet functions 86 126 private: 87 virtual u nsigned int getSize() const;88 virtual bool process();127 virtual uint32_t getSize() const; 128 virtual inline bool process(); 89 129 90 130 bool operator ==(packet::Gamestate gs); 91 131 private: 92 u nsigned int calcGamestateSize(unsigned int id, uint8_t mode=0x0);93 void removeObject(ObjectListIterator<Synchronisable> &it);94 std::map<unsigned int, Synchronisable*> dataMap_;132 uint32_t calcGamestateSize(int32_t id, uint8_t mode=0x0); 133 std::list<obj> dataMap_; 134 GamestateHeader* header_; 95 135 }; 96 136 -
code/trunk/src/network/packet/Packet.cc
r2171 r2662 129 129 return false; 130 130 } 131 // Assures we don't create a packet and destroy it right after in another thread132 // without having a reference in the packetMap_133 boost::recursive_mutex::scoped_lock lock(Packet::packetMap_mutex);134 131 // We deliver ENet the data address so that it doesn't memcpy everything again. 135 132 // --> We have to delete data_ ourselves! … … 138 135 // Add the packet to a global list so we can access it again once enet calls our 139 136 // deletePacket method. We can of course only give a one argument function to the ENet C library. 140 packetMap_[(size_t)(void*)enetPacket_] = this; 137 { 138 // Assures we don't create a packet and destroy it right after in another thread 139 // without having a reference in the packetMap_ 140 boost::recursive_mutex::scoped_lock lock(Packet::packetMap_mutex); 141 packetMap_[(size_t)(void*)enetPacket_] = this; 142 } 141 143 } 142 144 #ifndef NDEBUG -
code/trunk/src/network/packet/Welcome.cc
r2171 r2662 32 32 #include "Welcome.h" 33 33 #include "network/Host.h" 34 #include "network/ Synchronisable.h"34 #include "network/synchronisable/Synchronisable.h" 35 35 #include "core/CoreIncludes.h" 36 36 #include <assert.h> … … 42 42 #define _PACKETID 0 43 43 #define _CLIENTID _PACKETID + sizeof(ENUM::Type) 44 #define _ SHIPID_CLIENTID + sizeof(uint32_t)45 46 Welcome::Welcome( u nsigned int clientID, unsigned int shipID )44 #define _ENDIANTEST _CLIENTID + sizeof(uint32_t) 45 46 Welcome::Welcome( uint32_t clientID, uint32_t shipID ) 47 47 : Packet() 48 48 { … … 52 52 assert(data_); 53 53 *(packet::ENUM::Type *)(data_ + _PACKETID ) = packet::ENUM::Welcome; 54 *(uint32_t *) &data_[ _CLIENTID ] = clientID;55 *(uint32_t *) &data_[ _SHIPID ] = shipID;54 *(uint32_t *)(data_ + _CLIENTID ) = static_cast<uint32_t>(clientID); 55 *(uint32_t *)(data_ + _ENDIANTEST ) = 0xFEDC4321; 56 56 } 57 57 58 Welcome::Welcome( uint8_t* data, u nsigned int clientID )58 Welcome::Welcome( uint8_t* data, uint32_t clientID ) 59 59 : Packet(data, clientID) 60 60 { … … 74 74 75 75 bool Welcome::process(){ 76 u nsigned int shipID,clientID;77 clientID = *(uint32_t *) &data_[ _CLIENTID ];78 shipID = *(uint32_t *)&data_[ _SHIPID ];76 uint32_t clientID; 77 clientID = *(uint32_t *)(data_ + _CLIENTID ); 78 assert(*(uint32_t *)(data_ + _ENDIANTEST ) == 0xFEDC4321); 79 79 Host::setClientID(clientID); 80 Host::setShipID(shipID); 81 COUT(3) << "Welcome set clientId: " << clientID << " shipID: " << shipID << std::endl; 80 COUT(3) << "Welcome set clientId: " << clientID << endl; 82 81 Synchronisable::setClient(true); 83 82 delete this; -
code/trunk/src/network/packet/Welcome.h
r2171 r2662 42 42 { 43 43 public: 44 Welcome( u nsigned int clientID, unsigned int shipID );45 Welcome( uint8_t* data, u nsigned int clientID );44 Welcome( uint32_t clientID, uint32_t shipID ); 45 Welcome( uint8_t* data, uint32_t clientID ); 46 46 virtual ~Welcome(); 47 47 -
code/trunk/src/network/synchronisable/NetworkCallback.h
- Property svn:mergeinfo changed (with no actual effect on merging)
-
code/trunk/src/network/synchronisable/Synchronisable.cc
- Property svn:mergeinfo changed
/code/branches/presentation/src/network/synchronisable/Synchronisable.cc (added) merged: 2655
r2653 r2662 28 28 */ 29 29 30 //31 // C++ Implementation: synchronisable32 //33 // Description:34 //35 //36 // Author: Dumeni, Oliver Scheuss, (C) 200737 //38 // Copyright: See COPYING file that comes with this distribution39 //40 30 41 31 #include "Synchronisable.h" … … 155 145 Synchronisable *Synchronisable::fabricate(uint8_t*& mem, uint8_t mode) 156 146 { 157 synchronisableHeader *header = (synchronisableHeader *)mem;158 159 if(!header ->dataAvailable)160 { 161 mem += header ->size;147 SynchronisableHeader header(mem); 148 149 if(!header.isDataAvailable()) 150 { 151 mem += header.getDataSize(); 162 152 return 0; 163 153 } 164 154 165 COUT(4) << "fabricating object with id: " << header ->objectID<< std::endl;166 167 Identifier* id = ClassByID(header ->classID);155 COUT(4) << "fabricating object with id: " << header.getObjectID() << std::endl; 156 157 Identifier* id = ClassByID(header.getClassID()); 168 158 if (!id) 169 159 { … … 174 164 assert(id); 175 165 BaseObject* creator = 0; 176 if (header ->creatorID!= OBJECTID_UNKNOWN)177 { 178 Synchronisable* synchronisable_creator = Synchronisable::getSynchronisable(header ->creatorID);166 if (header.getCreatorID() != OBJECTID_UNKNOWN) 167 { 168 Synchronisable* synchronisable_creator = Synchronisable::getSynchronisable(header.getCreatorID()); 179 169 if (!synchronisable_creator) 180 170 { 181 mem += header ->size; //.TODO: this suckz.... remove size from header182 //assert(0); // TODO: uncomment this if we have a clean objecthierarchy (with destruction of children of objects) ^^171 mem += header.getDataSize(); //.TODO: this suckz.... remove size from header 172 assert(0); // TODO: uncomment this if we have a clean objecthierarchy (with destruction of children of objects) ^^ 183 173 return 0; 184 174 } … … 186 176 creator = dynamic_cast<BaseObject*>(synchronisable_creator); 187 177 } 188 assert(getSynchronisable(header ->objectID)==0); //make sure no object with this id exists178 assert(getSynchronisable(header.getObjectID())==0); //make sure no object with this id exists 189 179 BaseObject *bo = id->fabricate(creator); 190 180 assert(bo); 191 181 Synchronisable *no = dynamic_cast<Synchronisable *>(bo); 192 182 assert(no); 193 no->objectID=header ->objectID;194 no->creatorID=header ->creatorID; //TODO: remove this195 no->classID=header ->classID;183 no->objectID=header.getObjectID(); 184 no->creatorID=header.getCreatorID(); //TODO: remove this 185 no->classID=header.getClassID(); 196 186 COUT(4) << "fabricate objectID: " << no->objectID << " classID: " << no->classID << std::endl; 197 187 // update data and create object/entity... … … 329 319 330 320 // start copy header 331 synchronisableHeader *header = (synchronisableHeader *)mem;332 header ->size = size;333 header ->objectID = this->objectID;334 header ->creatorID = this->creatorID;335 header ->classID = this->classID;336 header ->dataAvailable = true;337 tempsize += sizeof(synchronisableHeader);338 mem += sizeof(synchronisableHeader);321 SynchronisableHeader header(mem); 322 header.setDataSize( size ); 323 header.setObjectID( this->objectID ); 324 header.setCreatorID( this->creatorID ); 325 header.setClassID( this->classID ); 326 header.setDataAvailable( true ); 327 tempsize += SynchronisableHeader::getSize(); 328 mem += SynchronisableHeader::getSize(); 339 329 // end copy header 340 330 … … 371 361 uint8_t* data=mem; 372 362 // start extract header 373 synchronisableHeader *syncHeader = (synchronisableHeader *)mem;374 assert(syncHeader ->objectID==this->objectID);375 assert(syncHeader ->creatorID==this->creatorID);376 assert( this->classID==syncHeader->classID); //TODO: fix this!!! maybe a problem with the identifier ?377 if(syncHeader ->dataAvailable==false){378 mem += syncHeader ->size;363 SynchronisableHeader syncHeader(mem); 364 assert(syncHeader.getObjectID()==this->objectID); 365 assert(syncHeader.getCreatorID()==this->creatorID); 366 assert(syncHeader.getClassID()==this->classID); 367 if(syncHeader.isDataAvailable()==false){ 368 mem += syncHeader.getDataSize(); 379 369 return true; 380 370 } 381 371 382 mem += sizeof(synchronisableHeader);372 mem += SynchronisableHeader::getSize(); 383 373 // stop extract header 384 374 385 COUT(5) << "Synchronisable: objectID " << syncHeader->objectID << ", classID " << syncHeader->classID << " size: " << syncHeader->size << " synchronising data" << std::endl; 386 for(i=syncList.begin(); i!=syncList.end() && mem <= data+syncHeader->size; i++) 387 { 375 //COUT(5) << "Synchronisable: objectID " << syncHeader.getObjectID() << ", classID " << syncHeader.getClassID() << " size: " << syncHeader.getDataSize() << " synchronising data" << std::endl; 376 for(i=syncList.begin(); i!=syncList.end(); i++) 377 { 378 assert( mem <= data+syncHeader.getDataSize() ); // always make sure we don't exceed the datasize in our stream 388 379 (*i)->putData( mem, mode, forceCallback ); 389 380 } 390 assert(mem == data+syncHeader ->size);381 assert(mem == data+syncHeader.getDataSize()); 391 382 return true; 392 383 } … … 399 390 */ 400 391 uint32_t Synchronisable::getSize(int32_t id, uint8_t mode){ 401 int tsize= sizeof(synchronisableHeader);392 int tsize=SynchronisableHeader::getSize(); 402 393 if(mode==0x0) 403 394 mode=state_; … … 428 419 bool Synchronisable::isMyData(uint8_t* mem) 429 420 { 430 synchronisableHeader *header = (synchronisableHeader *)mem;431 assert(header ->objectID==this->objectID);432 return header ->dataAvailable;421 SynchronisableHeader header(mem); 422 assert(header.getObjectID()==this->objectID); 423 return header.isDataAvailable(); 433 424 } 434 425 - Property svn:mergeinfo changed
-
code/trunk/src/network/synchronisable/Synchronisable.h
- Property svn:mergeinfo changed
/code/branches/presentation/src/network/synchronisable/Synchronisable.h (added) merged: 2655
r2653 r2662 72 72 } 73 73 74 struct _NetworkExport synchronisableHeader{ 75 uint32_t size:31; 76 bool dataAvailable:1; 77 uint32_t objectID; 78 uint32_t creatorID; 79 uint32_t classID; 74 /** 75 * @brief: stores information about a Synchronisable 76 * 77 * This class stores the information about a Synchronisable (objectID, classID, creatorID, dataSize) 78 * in an emulated bitset. 79 * Bit 1 to 31 store the size of the Data the synchronisable consumes in the stream 80 * Bit 32 is a bool and defines whether the data is actually stored or is just filled up with 0 81 * Byte 5 to 8: objectID 82 * Byte 9 to 12: classID 83 * Byte 13 to 16: creatorID 84 */ 85 class _NetworkExport SynchronisableHeader{ 86 private: 87 uint8_t *data_; 88 public: 89 SynchronisableHeader(uint8_t* data) 90 { data_ = data; } 91 inline static uint32_t getSize() 92 { return 16; } 93 inline uint32_t getDataSize() const 94 { return (*(uint32_t*)data_) & 0x7FFFFFFF; } //only use the first 31 bits 95 inline void setDataSize(uint32_t size) 96 { *(uint32_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint32_t*)(data_) & 0x80000000 ); } 97 inline bool isDataAvailable() const 98 { return ( (*(uint32_t*)data_) & 0x80000000 ) == 0x80000000; } 99 inline void setDataAvailable( bool b) 100 { *(uint32_t*)(data_) = (b << 31) | (*(uint32_t*)(data_) & 0x7FFFFFFF ); } 101 inline uint32_t getObjectID() const 102 { return *(uint32_t*)(data_+4); } 103 inline void setObjectID(uint32_t objectID) 104 { *(uint32_t*)(data_+4) = objectID; } 105 inline uint32_t getClassID() const 106 { return *(uint32_t*)(data_+8); } 107 inline void setClassID(uint32_t classID) 108 { *(uint32_t*)(data_+8) = classID; } 109 inline uint32_t getCreatorID() const 110 { return *(uint32_t*)(data_+12); } 111 inline void setCreatorID(uint32_t creatorID) 112 { *(uint32_t*)(data_+12) = creatorID; } 113 inline void operator=(SynchronisableHeader& h) 114 { memcpy(data_, h.data_, getSize()); } 80 115 }; 81 116 … … 83 118 /** 84 119 * This class is the base class of all the Objects in the universe that need to be synchronised over the network 85 120 * Every class, that inherits from this class has to link the DATA THAT NEEDS TO BE SYNCHRONISED into the linked list. 86 121 * @author Oliver Scheuss 87 122 */ - Property svn:mergeinfo changed
Note: See TracChangeset
for help on using the changeset viewer.