Changeset 2087 for code/trunk/src/network
- Timestamp:
- Nov 1, 2008, 7:04:09 PM (16 years ago)
- Location:
- code/trunk
- Files:
-
- 33 edited
- 4 copied
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
-
code/trunk/src/network/CMakeLists.txt
r1907 r2087 1 1 SET( NETWORK_SRC_FILES 2 ChatListener.cc 2 3 Client.cc 3 4 ClientConnection.cc 4 5 ClientInformation.cc 6 ClientConnectionListener.cc 5 7 ConnectionManager.cc 6 8 GamestateManager.cc -
code/trunk/src/network/Client.cc
r1907 r2087 39 39 // 40 40 41 #include <cassert> 42 41 43 #include "Client.h" 42 44 #include "Host.h" … … 44 46 #include "core/CoreIncludes.h" 45 47 #include "packet/Packet.h" 48 46 49 // #include "packet/Acknowledgement.h" 47 50 … … 67 70 * @param port port of the application on the server 68 71 */ 69 Client::Client( std::stringaddress, int port) : client_connection(port, address){72 Client::Client(const std::string& address, int port) : client_connection(port, address){ 70 73 isConnected=false; 71 74 isSynched_=false; … … 114 117 } 115 118 116 bool Client::processChat( std::stringmessage, unsigned int playerID){117 COUT(1) << "Player " << playerID << ": " << message << std::endl;119 bool Client::processChat(const std::string& message, unsigned int playerID){ 120 // COUT(1) << "Player " << playerID << ": " << message << std::endl; 118 121 return true; 119 122 } 120 123 121 124 /** 122 125 * This function implements the method of sending a chat message to the server 123 * @param message message to be sent 126 * @param message message to be sent 124 127 * @return result(true/false) 125 128 */ 126 bool Client::chat( std::stringmessage){129 bool Client::chat(const std::string& message){ 127 130 packet::Chat *m = new packet::Chat(message, Host::getPlayerID()); 128 131 return m->send(); … … 132 135 /** 133 136 * Processes incoming packets, sends a gamestate to the server and does the cleanup 134 * @param time 137 * @param time 135 138 */ 136 139 void Client::tick(float time){ … … 152 155 COUT(5) << "tick packet size " << event->packet->dataLength << std::endl; 153 156 packet::Packet *packet = packet::Packet::createPacket(event->packet, event->peer); 157 // note: packet commits suicide here except for the GameState. That is then deleted by a GamestateHandler 154 158 bool b = packet->process(); 155 159 assert(b); -
code/trunk/src/network/Client.h
r1907 r2087 66 66 public: 67 67 Client(); 68 Client( std::stringaddress, int port);68 Client(const std::string& address, int port); 69 69 Client(const char *address, int port); 70 70 ~Client(); 71 71 72 72 bool establishConnection(); 73 73 bool closeConnection(); 74 74 bool queuePacket(ENetPacket *packet, int clientID); 75 bool processChat(std::string message, unsigned int playerID); 76 virtual bool chat(std::string message); 75 bool processChat(const std::string& message, unsigned int playerID); 76 virtual bool chat(const std::string& message); 77 virtual bool broadcast(const std::string& message) { return false; } 77 78 //bool sendChat(packet::Chat *chat); 78 79 // static void Chat( std::string message ); 80 81 //static void setShipID( unsigned int shipID){ dynamic_cast<Client *>(instance_)->shipID_=shipID; } 82 static void setClientID( unsigned int clientID){ dynamic_cast<Client *>(instance_)->clientID_=clientID; } 83 79 84 80 void tick(float time); 85 81 86 82 private: 87 83 virtual bool isServer_(){return false;} 88 84 89 85 ClientConnection client_connection; 90 86 GamestateClient gamestate; 91 87 bool isConnected; 92 88 bool isSynched_; 93 89 94 90 bool gameStateFailure_; 95 91 }; -
code/trunk/src/network/ClientConnection.cc
r1907 r2087 54 54 boost::recursive_mutex ClientConnection::enet_mutex_; 55 55 56 ClientConnection::ClientConnection(int port, std::stringaddress) {56 ClientConnection::ClientConnection(int port, const std::string& address) { 57 57 quit=false; 58 58 server=NULL; … … 72 72 bool ClientConnection::waitEstablished(int milisec) { 73 73 for(int i=0; i<=milisec && !established; i++) 74 usleep(1000);74 msleep(1); 75 75 76 76 return established; … … 184 184 case ENET_EVENT_TYPE_NONE: 185 185 //receiverThread_->yield(); 186 usleep(1000);186 msleep(1); 187 187 break; 188 188 } -
code/trunk/src/network/ClientConnection.h
r1907 r2087 60 60 61 61 62 class ClientConnection{62 class _NetworkExport ClientConnection{ 63 63 public: 64 ClientConnection(int port, std::stringaddress);64 ClientConnection(int port, const std::string& address); 65 65 ClientConnection(int port, const char* address); 66 66 ~ClientConnection(); … … 96 96 ENetPeer *server; 97 97 boost::thread *receiverThread_; 98 98 99 99 static boost::recursive_mutex enet_mutex_; 100 100 }; -
code/trunk/src/network/ClientInformation.cc
r1735 r2087 45 45 namespace network 46 46 { 47 47 48 48 ClientInformation *ClientInformation::head_=0; 49 49 50 50 ClientInformation::ClientInformation() { 51 51 if(!head_) … … 59 59 60 60 ClientInformation::~ClientInformation() { 61 if(this==head_)62 head_=next();63 61 if(prev()!=0) 64 62 prev()->setNext(this->next()); 65 63 if(next()!=0) 66 64 next()->setPrev(this->prev()); 65 if(this==head_) 66 head_=next(); 67 67 } 68 68 … … 129 129 return true; 130 130 } 131 131 132 132 bool ClientInformation::setPartialGamestateID(int id){ 133 133 if(!this) … … 137 137 } 138 138 139 int ClientInformation::getID() {139 unsigned int ClientInformation::getID() { 140 140 if(!this) 141 141 return CLIENTID_UNKNOWN; … … 150 150 return NULL; 151 151 } 152 152 153 153 int ClientInformation::getFailures(){ 154 154 return failures_; … … 160 160 failures_=0; 161 161 } 162 162 163 163 enet_uint32 ClientInformation::getRTT(){ 164 return peer_->roundTripTime;165 } 166 167 enet_uint32ClientInformation::getPacketLoss(){168 return peer_->packetLoss;169 } 170 171 int ClientInformation::getGamestateID() {164 return this->peer_->roundTripTime; 165 } 166 167 double ClientInformation::getPacketLoss(){ 168 return ((double)this->peer_->packetLoss)/ENET_PEER_PACKET_LOSS_SCALE; 169 } 170 171 unsigned int ClientInformation::getGamestateID() { 172 172 if(this) 173 173 return gamestateID_; 174 174 else 175 return -1;176 } 177 178 int ClientInformation::getPartialGamestateID() {175 return (unsigned int)-1; 176 } 177 178 unsigned int ClientInformation::getPartialGamestateID() { 179 179 if(this) 180 180 return partialGamestateID_; 181 181 else 182 return -1;182 return (unsigned int)-1; 183 183 } 184 184 185 185 ClientInformation *ClientInformation::insertBack(ClientInformation *ins) { 186 186 ClientInformation *temp = head_; 187 if(temp== head_){187 if(temp==ins){ 188 188 return head_; 189 189 } … … 196 196 } 197 197 198 bool ClientInformation::removeClient( int clientID) {199 if( clientID==CLIENTID_UNKNOWN)198 bool ClientInformation::removeClient(unsigned int clientID) { 199 if((unsigned int)clientID==CLIENTID_UNKNOWN) 200 200 return false; 201 201 ClientInformation *temp = head_; … … 229 229 * @return pointer to the last element in the list or 0 if the search was unsuccessfull 230 230 */ 231 ClientInformation *ClientInformation::findClient( int clientID, bool look_backwards) {231 ClientInformation *ClientInformation::findClient(unsigned int clientID, bool look_backwards) { 232 232 ClientInformation *temp = head_; 233 233 while(temp!=0 && temp->getID()!=clientID){ -
code/trunk/src/network/ClientInformation.h
r1735 r2087 46 46 #include <boost/thread/recursive_mutex.hpp> 47 47 48 #define GAMESTATEID_INITIAL -149 #define CLIENTID_UNKNOWN -250 51 48 // WATCH OUT: THE CLIENTINFORMATION LIST IS NOT THREADSAFE ANYMORE 52 49 53 50 namespace network 54 51 { 52 static const unsigned int GAMESTATEID_INITIAL = (unsigned int)-1; 53 static const unsigned int CLIENTID_UNKNOWN = (unsigned int)-2; 54 55 55 /** 56 56 * This class implements a list for client informations 57 57 * @author Oliver Scheuss 58 58 */ 59 class ClientInformation{59 class _NetworkExport ClientInformation{ 60 60 public: 61 61 ClientInformation(); … … 66 66 ClientInformation *prev(); 67 67 static ClientInformation *insertBack(ClientInformation *ins); 68 68 69 69 // set functions 70 70 void setID(int clientID); … … 73 73 bool setPartialGamestateID(int id); 74 74 inline void setShipID(unsigned int id){ShipID_=id;} 75 75 76 76 // get functions 77 77 inline unsigned int getShipID(){return ShipID_;} 78 int getID();79 int getGamestateID();80 int getPartialGamestateID();78 unsigned int getID(); 79 unsigned int getGamestateID(); 80 unsigned int getPartialGamestateID(); 81 81 ENetPeer *getPeer(); 82 82 83 83 int getFailures(); 84 84 void addFailure(); 85 85 void resetFailures(); 86 86 enet_uint32 getRTT(); 87 enet_uint32getPacketLoss();88 89 static bool removeClient( int clientID);87 double getPacketLoss(); 88 89 static bool removeClient(unsigned int clientID); 90 90 static bool removeClient(ENetPeer *peer); 91 static ClientInformation *findClient( int clientID, bool look_backwards=false);91 static ClientInformation *findClient(unsigned int clientID, bool look_backwards=false); 92 92 static ClientInformation *findClient(ENetAddress *address, bool look_backwards=false); 93 93 static ClientInformation *getBegin(){return head_;} … … 99 99 private: 100 100 static ClientInformation *head_; 101 101 102 102 bool setNext(ClientInformation *next); 103 103 bool setPrev(ClientInformation *prev); 104 104 ClientInformation *insertAfter(ClientInformation *ins); 105 105 ClientInformation *insertBefore(ClientInformation *ins); 106 106 107 107 ClientInformation *preve; 108 108 ClientInformation *nexte; 109 109 //actual information: 110 110 ENetPeer *peer_; 111 int clientID_;112 int gamestateID_;113 int partialGamestateID_;111 unsigned int clientID_; 112 unsigned int gamestateID_; 113 unsigned int partialGamestateID_; 114 114 unsigned int ShipID_; // this is the unique objectID 115 115 bool synched_; 116 116 unsigned short failures_; 117 117 118 118 }; 119 119 -
code/trunk/src/network/ConnectionManager.cc
r1907 r2087 49 49 #include "core/BaseObject.h" 50 50 #include "core/Iterator.h" 51 #include "objects/SpaceShip.h"52 51 #include "util/Math.h" 53 52 #include "util/Sleep.h" … … 89 88 } 90 89 91 ConnectionManager::ConnectionManager(int port, std::stringaddress) :receiverThread_(0) {90 ConnectionManager::ConnectionManager(int port, const std::string& address) :receiverThread_(0) { 92 91 assert(instance_==0); 93 92 instance_=this; … … 228 227 case ENET_EVENT_TYPE_NONE: 229 228 //receiverThread_->yield(); 230 usleep(1000);229 msleep(1); 231 230 break; 232 231 } … … 331 330 332 331 333 334 bool ConnectionManager::removeShip(ClientInformation *client){335 unsigned int id=client->getShipID();336 orxonox::ObjectList<orxonox::SpaceShip>::iterator it;337 for(it = orxonox::ObjectList<orxonox::SpaceShip>::begin(); it; ++it){338 if(it->getObjectID()!=id)339 continue;340 delete *it;341 }342 return true;343 }344 345 346 332 void ConnectionManager::disconnectClient(ClientInformation *client){ 347 333 { … … 350 336 lock.unlock(); 351 337 } 352 removeShip(client);353 338 } 354 339 -
code/trunk/src/network/ConnectionManager.h
r1785 r2087 66 66 const int NETWORK_DEFAULT_CHANNEL = 0; 67 67 68 struct ClientList{68 struct _NetworkExport ClientList{ 69 69 ENetEvent *event; 70 70 int ID; … … 72 72 }; 73 73 74 class ConnectionManager{74 class _NetworkExport ConnectionManager{ 75 75 public: 76 76 static boost::recursive_mutex enet_mutex; … … 79 79 ConnectionManager(int port); 80 80 ConnectionManager(int port, const char *address); 81 ConnectionManager(int port, std::stringaddress);81 ConnectionManager(int port, const std::string& address); 82 82 ~ConnectionManager(); 83 83 //ENetPacket *getPacket(ENetAddress &address); // thread1 … … 107 107 int getClientID(ENetAddress address); 108 108 ENetPeer *getClientPeer(int clientID); 109 //bool createShip(ClientInformation *client);110 bool removeShip(ClientInformation *client);111 109 PacketBuffer buffer; 112 110 -
code/trunk/src/network/GamestateClient.cc
r1907 r2087 29 29 #include "GamestateClient.h" 30 30 31 #include <cassert> 31 32 #include <zlib.h> 32 33 … … 40 41 namespace network 41 42 { 42 struct GameStateItem{43 struct _NetworkExport GameStateItem{ 43 44 packet::Gamestate *state; 44 int id;45 unsigned int id; 45 46 }; 46 47 … … 50 51 last_gamestate_=GAMESTATEID_INITIAL-1; 51 52 tempGamestate_=NULL; 52 myShip_=NULL;53 53 } 54 54 … … 56 56 } 57 57 58 bool GamestateClient::ack( int gamestateID,int clientID){58 bool GamestateClient::ack(unsigned int gamestateID, unsigned int clientID){ 59 59 return true; 60 60 } 61 61 62 bool GamestateClient::add(packet::Gamestate *gs, int clientID){62 bool GamestateClient::add(packet::Gamestate *gs, unsigned int clientID){ 63 63 if(tempGamestate_!=NULL){ 64 64 //delete the obsolete gamestate … … 75 75 return false; 76 76 int id = GAMESTATEID_INITIAL; 77 bool b = saveShipCache();78 77 packet::Gamestate *processed = processGamestate(tempGamestate_); 79 if(!processed){80 if(b)81 loadShipCache();82 return false;83 }84 78 // assert(processed); 79 if (!processed) 80 return false; 85 81 //successfully loaded data from gamestate. now save gamestate for diff and delete the old gs 86 82 tempGamestate_=NULL; 87 83 gamestateMap_[processed->getID()]=processed; 88 84 last_diff_ = processed->getID(); 89 if(b)90 loadShipCache();91 85 id = processed->getID(); 92 86 sendAck(id); … … 108 102 packet::Gamestate *GamestateClient::getGamestate(){ 109 103 packet::Gamestate *gs = new packet::Gamestate(); 110 gs->collectData(0); 104 if(!gs->collectData(0)){ 105 delete gs; 106 return 0; 107 } 111 108 return gs; 112 109 } 113 110 114 111 void GamestateClient::cleanup(){ 115 std::map< int, packet::Gamestate*>::iterator temp, it = gamestateMap_.begin();112 std::map<unsigned int, packet::Gamestate*>::iterator temp, it = gamestateMap_.begin(); 116 113 while(it!=gamestateMap_.end()){ 117 114 if(it->first>=last_diff_) … … 126 123 127 124 void GamestateClient::printGamestateMap(){ 128 std::map< int, packet::Gamestate*>::iterator it;125 std::map<unsigned int, packet::Gamestate*>::iterator it; 129 126 COUT(4) << "gamestates: "; 130 127 for(it=gamestateMap_.begin(); it!=gamestateMap_.end(); it++){ … … 134 131 135 132 } 136 133 137 134 bool GamestateClient::sendAck(unsigned int gamestateID){ 138 135 packet::Acknowledgement *ack = new packet::Acknowledgement(gamestateID, 0); … … 142 139 } 143 140 else{ 144 COUT( 3) << "acked a gamestate: " << gamestateID << std::endl;141 COUT(5) << "acked a gamestate: " << gamestateID << std::endl; 145 142 return true; 146 143 } 147 }148 149 bool GamestateClient::saveShipCache(){150 if(myShip_==NULL){151 myShip_ = orxonox::SpaceShip::getLocalShip();152 // COUT(2) << "myShip_: " << myShip_ << " getLocalShip(): " << orxonox::SpaceShip::getLocalShip() << std::endl;153 if(!myShip_)154 return false;155 }156 if(myShip_){157 // unsigned char *data = new unsigned char[myShip_->getSize()];158 int size=myShip_->getSize(0, 0x1);159 if(size==0)160 return false;161 shipCache_ = new unsigned char [size];162 unsigned char *temp = shipCache_;163 if(!myShip_->getData(temp, 0, 0x1))164 COUT(3) << "could not save shipCache" << std::endl;165 return true;166 }else167 return false;168 }169 170 bool GamestateClient::loadShipCache(){171 myShip_=orxonox::SpaceShip::getLocalShip(); //TODO: remove this (only a hack)172 if(myShip_ && shipCache_){173 assert(myShip_->getIdentifier());174 unsigned char *temp = shipCache_;175 myShip_->updateData(temp, 0x2);176 delete shipCache_;177 return true;178 }else179 return false;180 144 } 181 145 … … 196 160 delete gs; 197 161 gs=undiffed; 198 COUT( 3) << "successfully undiffed gamestate id: " << undiffed->getID() << std::endl;162 COUT(5) << "successfully undiffed gamestate id: " << undiffed->getID() << std::endl; 199 163 } 200 164 if(gs->spreadData()) -
code/trunk/src/network/GamestateClient.h
r1769 r2087 46 46 #include "core/CorePrereqs.h" 47 47 #include "packet/Gamestate.h" 48 #include "objects/SpaceShip.h"49 48 #include "GamestateHandler.h" 50 49 51 #define GAMESTATEID_INITIAL -1 50 const unsigned int GAMESTATEID_INITIAL = (unsigned int)-1; 52 51 53 52 namespace network 54 53 { 55 class GamestateClient: public GamestateHandler54 class _NetworkExport GamestateClient: public GamestateHandler 56 55 { 57 56 public: … … 59 58 ~GamestateClient(); 60 59 61 bool add(packet::Gamestate *gs, int clientID);62 bool ack( int gamestateID,int clientID);60 bool add(packet::Gamestate *gs, unsigned int clientID); 61 bool ack(unsigned int gamestateID, unsigned int clientID); 63 62 64 63 bool processGamestates(); … … 70 69 void printGamestateMap(); 71 70 bool sendAck(unsigned int gamestateID); 72 bool saveShipCache();73 bool loadShipCache();74 71 75 int last_diff_;76 int last_gamestate_;77 std::map< int, packet::Gamestate *> gamestateMap_;72 unsigned int last_diff_; 73 unsigned int last_gamestate_; 74 std::map<unsigned int, packet::Gamestate *> gamestateMap_; 78 75 packet::Gamestate *tempGamestate_; // we save the received gamestates here during processQueue 79 orxonox::SpaceShip *myShip_;80 76 unsigned char *shipCache_; 81 77 -
code/trunk/src/network/GamestateHandler.h
r1763 r2087 39 39 @author Oliver Scheuss 40 40 */ 41 class GamestateHandler{41 class _NetworkExport GamestateHandler{ 42 42 private: 43 virtual bool add(packet::Gamestate *gs, int clientID)=0;44 virtual bool ack( int gamestateID,int clientID)=0;43 virtual bool add(packet::Gamestate *gs, unsigned int clientID)=0; 44 virtual bool ack(unsigned int gamestateID, unsigned int clientID)=0; 45 45 46 46 static GamestateHandler *instance_; … … 52 52 53 53 public: 54 static bool addGamestate(packet::Gamestate *gs, int clientID){ return instance_->add(gs, clientID); }55 static bool ackGamestate( int gamestateID,int clientID){ return instance_->ack(gamestateID, clientID); }54 static bool addGamestate(packet::Gamestate *gs, unsigned int clientID){ return instance_->add(gs, clientID); } 55 static bool ackGamestate(unsigned int gamestateID, unsigned int clientID){ return instance_->ack(gamestateID, clientID); } 56 56 }; 57 57 -
code/trunk/src/network/GamestateManager.cc
r1907 r2087 64 64 return getSnapshot(); 65 65 } 66 67 bool GamestateManager::add(packet::Gamestate *gs, int clientID){66 67 bool GamestateManager::add(packet::Gamestate *gs, unsigned int clientID){ 68 68 assert(gs); 69 std::map< int, packet::Gamestate*>::iterator it = gamestateQueue.find(clientID);69 std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateQueue.find(clientID); 70 70 if(it!=gamestateQueue.end()){ 71 71 // delete obsolete gamestate … … 75 75 return true; 76 76 } 77 77 78 78 bool GamestateManager::processGamestates(){ 79 std::map< int, packet::Gamestate*>::iterator it;79 std::map<unsigned int, packet::Gamestate*>::iterator it; 80 80 // now push only the most recent gamestates we received (ignore obsolete ones) 81 81 for(it = gamestateQueue.begin(); it!=gamestateQueue.end(); it++){ 82 assert(processGamestate(it->second)); 82 bool b = processGamestate(it->second); 83 assert(b); 83 84 delete it->second; 84 85 } … … 87 88 return true; 88 89 } 89 90 90 91 91 92 bool GamestateManager::getSnapshot(){ 92 93 reference = new packet::Gamestate(); 93 reference->collectData(++id_);94 //COUT(4) << "inserting gamestate: " << reference << std::endl;95 //gamestateMap_.insert(std::pair<int, packet::Gamestate*>(id_, reference));96 // gamestateUsed[id_]=0; 97 return true; 98 } 99 94 if(!reference->collectData(++id_)){ //we have no data to send 95 delete reference; 96 reference=0; 97 } 98 return true; 99 } 100 100 101 /** 101 102 * this function is used to keep the memory usage low 102 103 * it tries to delete all the unused gamestates 103 * 104 * 104 * 105 * 105 106 */ 106 107 /* void GamestateManager::cleanup(){ … … 126 127 }*/ 127 128 128 packet::Gamestate *GamestateManager::popGameState( int clientID) {129 packet::Gamestate *GamestateManager::popGameState(unsigned int clientID) { 129 130 //why are we searching the same client's gamestate id as we searched in 130 131 //Server::sendGameState? 131 132 packet::Gamestate *gs; 132 int gID = ClientInformation::findClient(clientID)->getGamestateID(); 133 unsigned int gID = ClientInformation::findClient(clientID)->getGamestateID(); 134 if(!reference) 135 return 0; 133 136 gs = reference->doSelection(clientID); 134 137 // gs = new packet::Gamestate(*reference); … … 139 142 packet::Gamestate *client=NULL; 140 143 if(gID != GAMESTATEID_INITIAL){ 141 std::map<unsigned int, std::map< int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(clientID);144 std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(clientID); 142 145 if(clientMap!=gamestateMap_.end()){ 143 std::map< int, packet::Gamestate*>::iterator it = clientMap->second.find(gID);146 std::map<unsigned int, packet::Gamestate*>::iterator it = clientMap->second.find(gID); 144 147 if(it!=clientMap->second.end()) 145 148 client = it->second; … … 158 161 return gs; 159 162 } 160 161 162 bool GamestateManager::ack( int gamestateID,int clientID) {163 164 165 bool GamestateManager::ack(unsigned int gamestateID, unsigned int clientID) { 163 166 ClientInformation *temp = ClientInformation::findClient(clientID); 164 167 assert(temp); 165 int curid = temp->getGamestateID();166 168 unsigned int curid = temp->getGamestateID(); 169 167 170 if(gamestateID == 0){ 168 171 temp->setGamestateID(GAMESTATEID_INITIAL); 169 172 return true; 170 173 } 171 172 assert(curid <gamestateID);174 175 assert(curid==(unsigned int)GAMESTATEID_INITIAL || curid<gamestateID); 173 176 COUT(4) << "acking gamestate " << gamestateID << " for clientid: " << clientID << " curid: " << curid << std::endl; 174 std::map< int, packet::Gamestate*>::iterator it, tempit;177 std::map<unsigned int, packet::Gamestate*>::iterator it, tempit; 175 178 for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end() && it->first<gamestateID; it++){ 176 179 delete it->second; … … 184 187 void GamestateManager::removeClient(ClientInformation* client){ 185 188 assert(client); 186 std::map<unsigned int, std::map< int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(client->getID());189 std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(client->getID()); 187 190 // first delete all remained gamestates 188 std::map< int, packet::Gamestate*>::iterator it;191 std::map<unsigned int, packet::Gamestate*>::iterator it; 189 192 for(it=clientMap->second.begin(); it!=clientMap->second.end(); it++) 190 193 delete it->second; … … 192 195 gamestateMap_.erase(clientMap); 193 196 } 194 197 195 198 bool GamestateManager::processGamestate(packet::Gamestate *gs){ 196 199 if(gs->isCompressed()) -
code/trunk/src/network/GamestateManager.h
r1907 r2087 66 66 * @author Oliver Scheuss 67 67 */ 68 class GamestateManager: public GamestateHandler{68 class _NetworkExport GamestateManager: public GamestateHandler{ 69 69 public: 70 70 GamestateManager(); 71 71 ~GamestateManager(); 72 72 73 bool add(packet::Gamestate *gs, int clientID);73 bool add(packet::Gamestate *gs, unsigned int clientID); 74 74 bool processGamestates(); 75 75 bool update(); 76 packet::Gamestate *popGameState( int clientID);76 packet::Gamestate *popGameState(unsigned int clientID); 77 77 78 78 bool getSnapshot(); 79 79 80 bool ack( int gamestateID,int clientID);80 bool ack(unsigned int gamestateID, unsigned int clientID); 81 81 void removeClient(ClientInformation *client); 82 82 private: … … 84 84 bool processGamestate(packet::Gamestate *gs); 85 85 86 std::map<unsigned int, std::map< int, packet::Gamestate*> > gamestateMap_;86 std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> > gamestateMap_; 87 87 //std::map<int, packet::Gamestate*> gamestateMap; //map gsID to gamestate* 88 88 //std::map<int, int> gamestateUsed; // save the number of clients, that use the specific gamestate 89 std::map< int, packet::Gamestate*> gamestateQueue;89 std::map<unsigned int, packet::Gamestate*> gamestateQueue; 90 90 packet::Gamestate *reference; 91 int id_;91 unsigned int id_; 92 92 }; 93 93 -
code/trunk/src/network/Host.cc
r1907 r2087 32 32 #include "core/ConsoleCommand.h" 33 33 #include "packet/Packet.h" 34 #include "ChatListener.h" 34 35 35 36 namespace network { … … 38 39 39 40 Host *Host::instance_=0; 40 41 41 42 /** 42 43 * @brief Constructor: assures that only one reference will be created and sets the pointer … … 90 91 * @return playerID 91 92 */ 92 unsigned int Host::getPlayerID(){ 93 unsigned int Host::getPlayerID(){ 93 94 if(!instance_) 94 95 return 0; … … 96 97 } 97 98 98 bool Host::Chat( std::stringmessage){99 bool Host::Chat(const std::string& message){ 99 100 if(!instance_) 100 101 return false; … … 102 103 } 103 104 104 bool Host::incomingChat(std::string message, unsigned int playerID){ 105 bool Host::Broadcast(const std::string& message){ 106 if(!instance_) 107 return false; 108 return instance_->broadcast(message); 109 } 110 111 bool Host::incomingChat(const std::string& message, unsigned int playerID){ 112 for (orxonox::ObjectList<ChatListener>::iterator it = orxonox::ObjectList<ChatListener>::begin(); it != orxonox::ObjectList<ChatListener>::end(); ++it) 113 it->incomingChat(message, playerID); 114 105 115 return instance_->processChat(message, playerID); 106 116 } -
code/trunk/src/network/Host.h
r1907 r2087 44 44 * @author Oliver Scheuss 45 45 */ 46 class Host{46 class _NetworkExport Host{ 47 47 private: 48 48 //TODO add theese functions or adequate … … 50 50 //virtual bool sendChat(packet::Chat *chat)=0; 51 51 virtual bool queuePacket(ENetPacket *packet, int clientID)=0; 52 virtual bool chat(std::string message)=0; 53 virtual bool processChat(std::string message, unsigned int playerID)=0; 52 virtual bool chat(const std::string& message)=0; 53 virtual bool broadcast(const std::string& message)=0; 54 virtual bool processChat(const std::string& message, unsigned int playerID)=0; 54 55 virtual bool isServer_()=0; 55 56 … … 72 73 static void setClientID(unsigned int id){ instance_->clientID_ = id; } 73 74 static void setShipID(unsigned int id){ instance_->shipID_ = id; } 74 static bool isServer(){ return instance_->isServer_(); } 75 static bool Chat(std::string message); 76 static bool incomingChat(std::string message, unsigned int playerID); 75 static bool isServer(){ return instance_->isServer_(); } 76 static bool Chat(const std::string& message); 77 static bool Broadcast(const std::string& message); 78 static bool incomingChat(const std::string& message, unsigned int playerID); 77 79 private: 78 80 }; -
code/trunk/src/network/NetworkCallback.h
r1536 r2087 2 2 #define _NETWORK_CALLBACK__ 3 3 4 #include "NetworkPrereqs.h" 5 4 6 namespace network{ 5 class NetworkCallbackBase7 class _NetworkExport NetworkCallbackBase 6 8 { 7 9 public: … … 9 11 virtual ~NetworkCallbackBase() {} 10 12 }; 11 13 12 14 template <class T> 13 15 class NetworkCallback: public NetworkCallbackBase … … 18 20 virtual void call() 19 21 { (this->object_->*function_)(); } 20 22 21 23 private: 22 24 T* object_; 23 25 void (T::*function_) (void); 24 }; 26 }; 25 27 26 28 -
code/trunk/src/network/NetworkPrereqs.h
r1735 r2087 63 63 class Client; 64 64 class ClientConnection; 65 class ClientConnectionListener; 65 66 class ClientFrameListener; 66 67 class ClientInformation; -
code/trunk/src/network/PacketBuffer.h
r1505 r2087 49 49 namespace network 50 50 { 51 struct PacketEnvelope{51 struct _NetworkExport PacketEnvelope{ 52 52 int length; 53 53 int data; 54 54 }; 55 55 56 struct QueueItem{56 struct _NetworkExport QueueItem{ 57 57 ENetEvent *event; 58 58 //ENetAddress address; … … 60 60 }; 61 61 62 class PacketBuffer{62 class _NetworkExport PacketBuffer{ 63 63 public: 64 64 PacketBuffer(); -
code/trunk/src/network/Server.cc
r1907 r2087 46 46 47 47 #include "ConnectionManager.h" 48 #include "ClientConnectionListener.h" 48 49 #include "GamestateManager.h" 49 50 #include "ClientInformation.h" 50 51 #include "util/Sleep.h" 51 #include "objects/SpaceShip.h"52 52 #include "core/ConsoleCommand.h" 53 53 #include "core/CoreIncludes.h" … … 58 58 #include "packet/DeleteObjects.h" 59 59 #include <util/Convert.h> 60 #include "ChatListener.h" 60 61 61 62 namespace network 62 63 { 63 const int MAX_FAILURES = 20; 64 const int NETWORK_FREQUENCY = 30; 64 const unsigned int MAX_FAILURES = 20; 65 const unsigned int NETWORK_FREQUENCY = 25; 66 const float NETWORK_PERIOD = (float)1/NETWORK_FREQUENCY; 65 67 66 68 /** … … 85 87 * @param bindAddress Address to listen on 86 88 */ 87 Server::Server(int port, std::stringbindAddress) {89 Server::Server(int port, const std::string& bindAddress) { 88 90 timeSinceLastUpdate_=0; 89 91 connection = new ConnectionManager(port, bindAddress); … … 101 103 gamestates_ = new GamestateManager(); 102 104 } 103 105 104 106 /** 105 107 * @brief Destructor … … 128 130 } 129 131 130 bool Server::processChat( std::stringmessage, unsigned int playerID){132 bool Server::processChat(const std::string& message, unsigned int playerID){ 131 133 ClientInformation *temp = ClientInformation::getBegin(); 132 134 packet::Chat *chat; … … 138 140 temp = temp->next(); 139 141 } 140 COUT(1) << "Player " << playerID << ": " << message << std::endl;142 // COUT(1) << "Player " << playerID << ": " << message << std::endl; 141 143 return true; 142 144 } … … 152 154 //this steers our network frequency 153 155 timeSinceLastUpdate_+=time; 154 if(timeSinceLastUpdate_>= (1./NETWORK_FREQUENCY)){155 timeSinceLastUpdate_ =(float)((int)(timeSinceLastUpdate_*NETWORK_FREQUENCY))/timeSinceLastUpdate_;156 if(timeSinceLastUpdate_>=NETWORK_PERIOD){ 157 timeSinceLastUpdate_ -= static_cast<unsigned int>( timeSinceLastUpdate_ / NETWORK_PERIOD ) * NETWORK_PERIOD; 156 158 gamestates_->processGamestates(); 157 159 updateGamestate(); … … 162 164 return connection->addPacket(packet, clientID); 163 165 } 164 166 167 /** 168 * @brief: returns ping time to client in milliseconds 169 */ 170 unsigned int Server::getPing(unsigned int clientID){ 171 assert(ClientInformation::findClient(clientID)); 172 return ClientInformation::findClient(clientID)->getRTT(); 173 } 174 175 /** 176 * @brief: return packet loss ratio to client (scales from 0 to 1) 177 */ 178 double Server::getPacketLoss(unsigned int clientID){ 179 assert(ClientInformation::findClient(clientID)); 180 return ClientInformation::findClient(clientID)->getPacketLoss(); 181 } 182 165 183 /** 166 184 * processes all the packets waiting in the queue … … 239 257 if(gs==NULL){ 240 258 COUT(2) << "Server: could not generate gamestate (NULL from compress)" << std::endl; 259 temp = temp->next(); 241 260 continue; 242 261 } … … 281 300 282 301 bool Server::addClient(ENetEvent *event){ 302 static unsigned int newid=1; 303 304 COUT(2) << "Server: adding client" << std::endl; 283 305 ClientInformation *temp = ClientInformation::insertBack(new ClientInformation); 284 306 if(!temp){ … … 286 308 return false; 287 309 } 288 if(temp==ClientInformation::getBegin()) { //not good if you use anything else than insertBack289 temp->setID(1);310 /*if(temp==ClientInformation::getBegin()) { //not good if you use anything else than insertBack 311 newid=1; 290 312 } 291 313 else 292 temp->setID(temp->prev()->getID()+1); 314 newid=temp->prev()->getID()+1;*/ 315 temp->setID(newid); 293 316 temp->setPeer(event->peer); 317 318 // inform all the listeners 319 orxonox::ObjectList<ClientConnectionListener>::iterator listener = orxonox::ObjectList<ClientConnectionListener>::begin(); 320 while(listener){ 321 listener->clientConnected(newid); 322 listener++; 323 } 324 325 newid++; 326 294 327 COUT(3) << "Server: added client id: " << temp->getID() << std::endl; 295 328 return createClient(temp->getID()); 296 329 } 297 330 298 331 bool Server::createClient(int clientID){ … … 304 337 COUT(4) << "Con.Man: creating client id: " << temp->getID() << std::endl; 305 338 connection->syncClassid(temp->getID()); 306 COUT(5) << "creating spaceship for clientid: " << temp->getID() << std::endl;307 // TODO: this is only a hack, untill we have a possibility to define default player-join actions308 if(!createShip(temp))309 COUT(2) << "Con.Man. could not create ship for clientid: " << clientID << std::endl;310 else311 COUT(3) << "created spaceship" << std::endl;312 339 temp->setSynched(true); 313 340 COUT(3) << "sending welcome" << std::endl; … … 319 346 g->setClientID(temp->getID()); 320 347 b = g->collectData(0); 321 assert(b); 348 if(!b) 349 return false; //no data for the client 322 350 b = g->compressData(); 323 351 assert(b); … … 327 355 } 328 356 329 bool Server::createShip(ClientInformation *client){330 if(!client)331 return false;332 orxonox::Identifier* id = ClassByName("SpaceShip");333 if(!id){334 COUT(4) << "We could not create the SpaceShip for client: " << client->getID() << std::endl;335 return false;336 }337 orxonox::SpaceShip *no = dynamic_cast<orxonox::SpaceShip *>(id->fabricate());338 no->classID = id->getNetworkID();339 client->setShipID(no->getObjectID());340 no->setPosition(orxonox::Vector3(0,0,80));341 no->setScale(10);342 //no->setYawPitchRoll(orxonox::Degree(-90),orxonox::Degree(-90),orxonox::Degree(0));343 no->setMesh("assff.mesh");344 no->setMaxSpeed(500);345 no->setMaxSideAndBackSpeed(50);346 no->setMaxRotation(1.0);347 no->setTransAcc(200);348 no->setRotAcc(3.0);349 no->setTransDamp(75);350 no->setRotDamp(1.0);351 no->setCamera(std::string("cam_") + convertToString(client->getID()));352 no->create();353 354 return true;355 }356 357 357 bool Server::disconnectClient(ENetEvent *event){ 358 358 COUT(4) << "removing client from list" << std::endl; … … 360 360 361 361 //boost::recursive_mutex::scoped_lock lock(head_->mutex_); 362 orxonox::ObjectList<orxonox::SpaceShip>::iterator it = orxonox::ObjectList<orxonox::SpaceShip>::begin();363 362 ClientInformation *client = ClientInformation::findClient(&event->peer->address); 364 363 if(!client) 365 364 return false; 366 365 gamestates_->removeClient(client); 367 while(it){ 368 if(it->getObjectID()!=client->getShipID()){ 369 ++it; 370 continue; 371 } 372 orxonox::ObjectList<orxonox::SpaceShip>::iterator temp=it; 373 ++it; 374 delete *temp; 375 return ClientInformation::removeClient(event->peer); 376 } 377 return false; 366 367 // inform all the listeners 368 orxonox::ObjectList<ClientConnectionListener>::iterator listener = orxonox::ObjectList<ClientConnectionListener>::begin(); 369 while(listener){ 370 listener->clientDisconnected(client->getID()); 371 listener++; 372 } 373 374 return ClientInformation::removeClient(event->peer); 378 375 } 379 376 … … 387 384 gamestates_->removeClient(client); 388 385 } 389 390 bool Server::chat(std::string message){ 386 387 bool Server::chat(const std::string& message){ 388 return this->sendChat(message, Host::getPlayerID()); 389 } 390 391 bool Server::broadcast(const std::string& message){ 392 return this->sendChat(message, CLIENTID_UNKNOWN); 393 } 394 395 bool Server::sendChat(const std::string& message, unsigned int clientID){ 391 396 ClientInformation *temp = ClientInformation::getBegin(); 392 397 packet::Chat *chat; 393 398 while(temp){ 394 chat = new packet::Chat(message, Host::getPlayerID());399 chat = new packet::Chat(message, clientID); 395 400 chat->setClientID(temp->getID()); 396 401 if(!chat->send()) … … 398 403 temp = temp->next(); 399 404 } 400 COUT(1) << "Player " << Host::getPlayerID() << ": " << message << std::endl; 405 // COUT(1) << "Player " << Host::getPlayerID() << ": " << message << std::endl; 406 for (orxonox::ObjectList<ChatListener>::iterator it = orxonox::ObjectList<ChatListener>::begin(); it != orxonox::ObjectList<ChatListener>::end(); ++it) 407 it->incomingChat(message, clientID); 408 401 409 return true; 402 410 } -
code/trunk/src/network/Server.h
r1907 r2087 52 52 { 53 53 const int CLIENTID_SERVER = 0; 54 54 55 55 /** 56 56 * This class is the root class of the network module for a server. … … 61 61 Server(); 62 62 Server(int port); 63 Server(int port, std::stringbindAddress);63 Server(int port, const std::string& bindAddress); 64 64 Server(int port, const char *bindAddress); 65 65 ~Server(); 66 66 67 67 void open(); 68 68 void close(); 69 bool processChat( std::stringmessage, unsigned int playerID);69 bool processChat(const std::string& message, unsigned int playerID); 70 70 bool queuePacket(ENetPacket *packet, int clientID); 71 71 void tick(float time); 72 unsigned int getPing(unsigned int clientID); 73 double getPacketLoss(unsigned int clientID); 72 74 protected: 73 75 void processQueue(); … … 77 79 unsigned int shipID(){return 0;} 78 80 unsigned int playerID(){return 0;} 79 81 80 82 bool addClient(ENetEvent *event); 81 83 bool createClient(int clientID); 82 bool createShip(ClientInformation *client);83 84 bool disconnectClient(ENetEvent *event); 84 85 void disconnectClient(int clientID); … … 87 88 bool sendGameState(); 88 89 bool sendObjectDeletes(); 89 virtual bool chat(std::string message); 90 90 virtual bool chat(const std::string& message); 91 virtual bool broadcast(const std::string& message); 92 bool sendChat(const std::string& message, unsigned int clientID); 93 91 94 //void processChat( chat *data, int clientId); 92 95 ConnectionManager *connection; 93 96 GamestateManager *gamestates_; 94 97 95 98 96 99 float timeSinceLastUpdate_; 97 100 }; -
code/trunk/src/network/Synchronisable.cc
r1907 r2087 42 42 43 43 #include <cstring> 44 #include <string> 44 45 #include <iostream> 45 46 #include <assert.h> … … 51 52 namespace network 52 53 { 53 54 54 55 55 56 std::map<unsigned int, Synchronisable *> Synchronisable::objectMap_; … … 62 63 * Initializes all Variables and sets the right objectID 63 64 */ 64 Synchronisable::Synchronisable( ){65 Synchronisable::Synchronisable(orxonox::BaseObject* creator){ 65 66 RegisterRootObject(Synchronisable); 66 67 static uint32_t idCounter=0; … … 68 69 objectMode_=0x1; // by default do not send data to server 69 70 objectID=idCounter++; 71 classID = (unsigned int)-1; 70 72 syncList = new std::list<synchronisableVariable *>; 71 } 72 73 /** 74 * Destructor: 73 74 this->creatorID = OBJECTID_UNKNOWN; 75 76 searchcreatorID: 77 if (creator) 78 { 79 Synchronisable* synchronisable_creator = dynamic_cast<Synchronisable*>(creator); 80 if (synchronisable_creator && synchronisable_creator->objectMode_) 81 { 82 this->creatorID = synchronisable_creator->getObjectID(); 83 } 84 else if (creator != creator->getCreator()) 85 { 86 creator = creator->getCreator(); 87 goto searchcreatorID; 88 } 89 } 90 } 91 92 /** 93 * Destructor: 75 94 * Delete all callback objects and remove objectID from the objectMap_ 76 95 */ … … 80 99 for(std::list<synchronisableVariable *>::iterator it = syncList->begin(); it!=syncList->end(); it++) 81 100 delete (*it)->callback; 82 deletedObjects_.push(objectID); 101 if (this->objectMode_ != 0x0) 102 deletedObjects_.push(objectID); 83 103 // COUT(3) << "destruct synchronisable +++" << objectID << " | " << classID << std::endl; 84 104 // COUT(3) << " bump ---" << objectID << " | " << &objectMap_ << std::endl; … … 96 116 this->classID = this->getIdentifier()->getNetworkID(); 97 117 // COUT(4) << "creating synchronisable: setting classid from " << this->getIdentifier()->getName() << " to: " << classID << std::endl; 98 118 99 119 // COUT(3) << "construct synchronisable +++" << objectID << " | " << classID << std::endl; 100 120 // objectMap_[objectID]=this; … … 127 147 synchronisableHeader *header = (synchronisableHeader *)mem; 128 148 129 COUT(3) << "fabricating object with id: " << header->objectID << std::endl; 149 if(!header->dataAvailable) 150 { 151 mem += header->size; 152 return 0; 153 } 154 155 COUT(4) << "fabricating object with id: " << header->objectID << std::endl; 130 156 131 157 orxonox::Identifier* id = ClassByID(header->classID); 132 158 assert(id); 133 orxonox::BaseObject *bo = id->fabricate(); 159 orxonox::BaseObject* creator = 0; 160 if (header->creatorID != OBJECTID_UNKNOWN) 161 { 162 Synchronisable* synchronisable_creator = Synchronisable::getSynchronisable(header->creatorID); 163 if (!synchronisable_creator) 164 { 165 mem += header->size; //.TODO: this suckz.... remove size from header 166 return 0; 167 } 168 else 169 creator = dynamic_cast<orxonox::BaseObject*>(synchronisable_creator); 170 } 171 orxonox::BaseObject *bo = id->fabricate(creator); 172 assert(bo); 134 173 Synchronisable *no = dynamic_cast<Synchronisable *>(bo); 135 174 assert(no); 136 175 no->objectID=header->objectID; 176 no->creatorID=header->creatorID; //TODO: remove this 137 177 no->classID=header->classID; 138 COUT( 3) << "fabricate objectID: " << no->objectID << " classID: " << no->classID << std::endl;178 COUT(4) << "fabricate objectID: " << no->objectID << " classID: " << no->classID << std::endl; 139 179 // update data and create object/entity... 140 bool b = no->updateData(mem, mode );180 bool b = no->updateData(mem, mode, true); 141 181 assert(b); 142 b = no->create(); 143 assert(b); 182 if (b) 183 { 184 b = no->create(); 185 assert(b); 186 } 144 187 return no; 145 188 } 146 189 147 190 148 191 /** 149 192 * Finds and deletes the Synchronisable with the appropriate objectID … … 164 207 return true; 165 208 } 166 209 167 210 /** 168 211 * This function looks up the objectID in the objectMap_ and returns a pointer to the right Synchronisable … … 185 228 } 186 229 187 230 188 231 /** 189 232 * This function is used to register a variable to be synchronized … … 196 239 */ 197 240 void Synchronisable::registerVar(void *var, int size, variableType t, int mode, NetworkCallbackBase *cb){ 241 assert( mode==direction::toclient || mode==direction::toserver || mode==direction::serverMaster || mode==direction::clientMaster); 198 242 // create temporary synch.Var struct 199 243 synchronisableVariable *temp = new synchronisableVariable; … … 203 247 temp->type = t; 204 248 temp->callback = cb; 249 if( ( mode & direction::bidirectional ) ) 250 { 251 temp->varBuffer = new uint8_t[size]; 252 memcpy(temp->varBuffer, temp->var, size); //now fill the buffer for the first time 253 temp->varReference = 0; 254 } 205 255 COUT(5) << "Syncronisable::registering var with size: " << temp->size << " and type: " << temp->type << std::endl; 206 256 //std::cout << "push temp to syncList (at the bottom) " << datasize << std::endl; … … 228 278 * 0x2: client->server (not recommended) 229 279 * 0x3: bidirectional 230 * @return true: if ! isMyTickor if everything was successfully saved280 * @return true: if !doSync or if everything was successfully saved 231 281 */ 232 282 bool Synchronisable::getData(uint8_t*& mem, unsigned int id, int mode){ 233 283 //if this tick is we dont synchronise, then abort now 234 if(! isMyTick(id))284 if(!doSync(id)) 235 285 return true; 236 286 //std::cout << "inside getData" << std::endl; … … 240 290 if(classID==0) 241 291 COUT(3) << "classid 0 " << this->getIdentifier()->getName() << std::endl; 292 293 if (this->classID == (unsigned int)-1) 294 this->classID = this->getIdentifier()->getNetworkID(); 295 242 296 assert(this->classID==this->getIdentifier()->getNetworkID()); 243 297 // this->classID=this->getIdentifier()->getNetworkID(); // TODO: correct this … … 250 304 header->size = size; 251 305 header->objectID = this->objectID; 306 header->creatorID = this->creatorID; 252 307 header->classID = this->classID; 253 308 header->dataAvailable = true; … … 263 318 COUT(5) << "not getting data: " << std::endl; 264 319 continue; // this variable should only be received 320 } 321 // if the variable gets synchronised bidirectional, then add the reference to the bytestream 322 if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional ) 323 { 324 *(uint8_t*)mem = (*i)->varReference; 325 mem += sizeof( (*i)->varReference ); 326 tempsize += sizeof( (*i)->varReference ); 265 327 } 266 328 switch((*i)->type){ … … 271 333 break; 272 334 case STRING: 273 memcpy( (void *)(mem), (void *)&((*i)->size), sizeof( int) );274 mem+=sizeof( int);335 memcpy( (void *)(mem), (void *)&((*i)->size), sizeof(size_t) ); 336 mem+=sizeof(size_t); 275 337 const char *data = ( ( *(std::string *) (*i)->var).c_str()); 276 338 memcpy( mem, (void*)data, (*i)->size); 277 339 COUT(5) << "synchronisable: char: " << (const char *)(mem) << " data: " << data << " string: " << *(std::string *)((*i)->var) << std::endl; 278 340 mem+=(*i)->size; 279 tempsize+=(*i)->size + 4;341 tempsize+=(*i)->size + sizeof(size_t); 280 342 break; 281 343 } … … 292 354 * @return true/false 293 355 */ 294 bool Synchronisable::updateData(uint8_t*& mem, int mode ){356 bool Synchronisable::updateData(uint8_t*& mem, int mode, bool forceCallback){ 295 357 if(mode==0x0) 296 358 mode=state_; … … 305 367 synchronisableHeader *syncHeader = (synchronisableHeader *)mem; 306 368 assert(syncHeader->objectID==this->objectID); 369 // assert(syncHeader->creatorID==this->creatorID); 307 370 if(syncHeader->dataAvailable==false){ 308 371 mem+=syncHeader->size; … … 314 377 assert(this->objectID==syncHeader->objectID); 315 378 // assert(this->classID==syncHeader->classID); //TODO: fix this!!! maybe a problem with the identifier ? 316 379 317 380 COUT(5) << "Synchronisable: objectID " << syncHeader->objectID << ", classID " << syncHeader->classID << " size: " << syncHeader->size << " synchronising data" << std::endl; 318 381 for(i=syncList->begin(); i!=syncList->end() && mem <= data+syncHeader->size; i++){ … … 325 388 switch((*i)->type){ 326 389 case DATA: 390 if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional ) 391 { 392 if( ( mode == 0x1 && (*i)->mode == direction::serverMaster ) || \ 393 ( mode == 0x2 && (*i)->mode == direction::clientMaster ) ) // if true we are master on this variable 394 { 395 uint8_t refNr = *(uint8_t *)mem; 396 if( refNr != (*i)->varReference ) 397 { 398 mem += sizeof((*i)->varReference) + (*i)->size; // the reference for this variable is not recent, discard data 399 break; 400 } 401 } 402 else //we are slave for this variable 403 { 404 (*i)->varReference = *(uint8_t *)mem; //copy the reference value for this variable 405 } 406 mem += sizeof((*i)->varReference); 407 } 327 408 if((*i)->callback) // check whether this variable changed (but only if callback was set) 328 409 if(strncmp((char *)(*i)->var, (char *)mem, (*i)->size)!=0) … … 332 413 break; 333 414 case STRING: 334 (*i)->size = *(uint32_t *)mem; 415 if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional ) 416 { 417 if( ( mode == 0x1 && (*i)->mode == direction::serverMaster ) || \ 418 ( mode == 0x2 && (*i)->mode == direction::clientMaster ) ) // if true we are master for this variable 419 { 420 uint8_t refNr = *(uint8_t *)mem; 421 mem += sizeof( (*i)->varReference ); 422 if( refNr != (*i)->varReference ){ 423 mem += sizeof(size_t) + *(size_t *)mem; // the reference for this variable is not recent, discard data 424 break; 425 } 426 } 427 else //we are slave for this variable 428 { 429 (*i)->varReference = *(uint8_t *)mem; //copy the reference value for this variable 430 } 431 mem += sizeof( (*i)->varReference ); 432 } 433 (*i)->size = *(size_t *)mem; 335 434 COUT(5) << "string size: " << (*i)->size << std::endl; 336 mem +=sizeof(int);435 mem += sizeof(size_t); 337 436 if((*i)->callback) // check whether this string changed 338 437 if( *(std::string *)((*i)->var) != std::string((char *)mem) ) … … 344 443 } 345 444 // call the callback function, if defined 346 if( callback&& (*i)->callback)445 if((callback || forceCallback) && (*i)->callback) 347 446 (*i)->callback->call(); 348 447 } … … 357 456 */ 358 457 uint32_t Synchronisable::getSize(unsigned int id, int mode){ 359 if(! isMyTick(id))458 if(!doSync(id)) 360 459 return 0; 361 460 int tsize=sizeof(synchronisableHeader); … … 377 476 break; 378 477 } 478 if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional ) 479 { 480 tsize+=sizeof( (*i)->varReference ); 481 } 379 482 } 380 483 return tsize; … … 386 489 * @return true/false 387 490 */ 388 bool Synchronisable:: isMyTick(unsigned int id){389 return ( (objectMode_&state_)!=0 );491 bool Synchronisable::doSync(unsigned int id){ 492 return ( (objectMode_&state_)!=0 && (!syncList->empty() ) ); 390 493 } 391 494 … … 413 516 */ 414 517 void Synchronisable::setObjectMode(int mode){ 415 assert(mode==0x 1 || mode==0x2 || mode==0x3);518 assert(mode==0x0 || mode==0x1 || mode==0x2 || mode==0x3); 416 519 objectMode_=mode; 417 520 } -
code/trunk/src/network/Synchronisable.h
r1910 r2087 41 41 #include "util/Integers.h" 42 42 43 #define REGISTERDATA(varname) registerVar(&varname, sizeof(varname), network::DATA) 44 #define REGISTERDATA_WITHDIR(varname, mode) registerVar(&varname, sizeof(varname), network::DATA, mode) 45 #define REGISTERSTRING(stringname) registerVar(&stringname, stringname.length()+1, network::STRING) 46 #define REGISTERSTRING_WITHDIR(stringname, mode) registerVar(&stringname, stringname.length()+1, network::STRING, mode) 47 48 //TODO: this is only a very ugly hack ... 49 namespace orxonox{ 50 class SpaceShip; 51 } 43 #define REGISTERDATA(varname, ...) \ 44 registerVar((void*)&varname, sizeof(varname), network::DATA, __VA_ARGS__) 45 #define REGISTERSTRING(stringname, ...) \ 46 registerVar(&stringname, stringname.length()+1, network::STRING, __VA_ARGS__) 52 47 53 48 namespace network 54 49 { 50 static const unsigned int OBJECTID_UNKNOWN = (unsigned int)-1; 51 55 52 namespace direction{ 56 53 enum syncdirection{ 57 54 toclient=0x1, 58 55 toserver=0x2, 59 bidirectional=0x3 56 bidirectional=0x3, 57 serverMaster=0x3, 58 clientMaster=0x7 60 59 }; 61 60 } 62 61 63 62 namespace syncmode{ 64 63 enum mode{ … … 67 66 }; 68 67 } 69 68 70 69 enum variableType{ 71 70 DATA, … … 73 72 }; 74 73 75 struct synchronisableHeader{74 struct _NetworkExport synchronisableHeader{ 76 75 uint32_t size:31; 77 76 bool dataAvailable:1; 78 77 uint32_t objectID; 78 uint32_t creatorID; 79 79 uint32_t classID; 80 80 }; 81 81 82 typedef struct synchronisableVariable{82 struct _NetworkExport synchronisableVariable{ 83 83 unsigned int size; 84 84 int mode; // this determines in which direction the variable gets synchronised … … 86 86 variableType type; 87 87 NetworkCallbackBase *callback; 88 }SYNCVAR; 88 void *varBuffer; 89 uint8_t varReference; 90 }; 89 91 90 92 /** … … 98 100 friend class GamestateClient; 99 101 friend class Server; 100 friend class orxonox::SpaceShip;101 102 virtual ~Synchronisable(); 102 103 103 104 104 105 virtual bool create(); 105 106 static void setClient(bool b); 106 107 107 108 static Synchronisable *fabricate(uint8_t*& mem, int mode=0x0); 108 109 static bool deleteObject(unsigned int objectID); … … 110 111 static unsigned int getNumberOfDeletedObject(){ return deletedObjects_.size(); } 111 112 static unsigned int popDeletedObject(){ unsigned int i = deletedObjects_.front(); deletedObjects_.pop(); return i; } 112 113 113 114 inline unsigned int getObjectID(){return objectID;} 114 115 inline unsigned int getClassID(){return classID;} 115 116 protected: 116 Synchronisable( );117 Synchronisable(orxonox::BaseObject* creator); 117 118 void registerVar(void *var, int size, variableType t, int mode=1, NetworkCallbackBase *cb=0); 118 119 void setObjectMode(int mode); 119 120 void setObjectFrequency(unsigned int freq){ objectFrequency_ = freq; } 120 virtual void registerAllVariables()=0; 121 122 121 122 123 123 private: 124 124 bool getData(uint8_t*& men, unsigned int id, int mode=0x0); 125 125 uint32_t getSize(unsigned int id, int mode=0x0); 126 bool updateData(uint8_t*& mem, int mode=0x0 );126 bool updateData(uint8_t*& mem, int mode=0x0, bool forceCallback=false); 127 127 bool isMyData(uint8_t* mem); 128 128 bool doSelection(unsigned int id); 129 bool isMyTick(unsigned int id);130 129 bool doSync(unsigned int id); 130 131 131 unsigned int objectID; 132 unsigned int creatorID; 132 133 unsigned int classID; 133 134 134 135 std::list<synchronisableVariable *> *syncList; 135 136 static int state_; // detemines wheter we are server (default) or client -
code/trunk/src/network/packet/Acknowledgement.h
r1907 r2087 29 29 #define NETWORKACKNOLEDGEMENT_H 30 30 31 #include "../NetworkPrereqs.h" 31 32 #include "Packet.h" 32 33 … … 35 36 namespace packet { 36 37 /** 37 @author 38 @author 38 39 */ 39 class Acknowledgement : public Packet40 class _NetworkExport Acknowledgement : public Packet 40 41 { 41 42 public: … … 43 44 Acknowledgement( uint8_t* data, unsigned int clientID ); 44 45 ~Acknowledgement(); 45 46 46 47 inline unsigned int getSize() const; 47 48 bool process(); 48 49 49 50 unsigned int getAckID(); 50 51 private: -
code/trunk/src/network/packet/Chat.h
r1907 r2087 2 2 #ifndef NETWORKCHAT_H 3 3 #define NETWORKCHAT_H 4 5 #include "../NetworkPrereqs.h" 4 6 5 7 #include <string> … … 11 13 namespace packet { 12 14 /** 13 @author 15 @author 14 16 */ 15 class Chat : public Packet17 class _NetworkExport Chat : public Packet 16 18 { 17 19 public: … … 19 21 Chat( uint8_t* data, unsigned int clientID ); 20 22 ~Chat(); 21 23 22 24 inline unsigned int getSize() const; 23 25 bool process(); 24 26 25 27 unsigned int getMessageLength(){ return messageLength_; }; 26 28 unsigned char *getMessage(); -
code/trunk/src/network/packet/ClassID.h
r1907 r2087 29 29 #define NETWORKCLASSID_H 30 30 31 #include "../NetworkPrereqs.h" 32 31 33 #include <string> 32 34 … … 37 39 38 40 /** 39 @author 41 @author 40 42 */ 41 class ClassID : public Packet43 class _NetworkExport ClassID : public Packet 42 44 { 43 45 public: … … 45 47 ClassID( uint8_t* data, unsigned int clientID ); 46 48 ~ClassID(); 47 49 48 50 inline unsigned int getSize() const; 49 51 bool process(); 50 52 51 53 unsigned int getClassID(); 52 54 unsigned int getClassNameLength(){ return classNameLength_; } -
code/trunk/src/network/packet/DeleteObjects.h
r1907 r2087 29 29 #define NETWORKPACKETDELETEOBJECTS_H 30 30 31 #include "../NetworkPrereqs.h" 32 31 33 #include "Packet.h" 32 34 … … 35 37 namespace packet { 36 38 /** 37 @author 39 @author 38 40 */ 39 class DeleteObjects : public Packet41 class _NetworkExport DeleteObjects : public Packet 40 42 { 41 43 public: … … 43 45 DeleteObjects( uint8_t* data, unsigned int clientID ); 44 46 ~DeleteObjects(); 45 47 46 48 bool fetchIDs(); 47 49 48 50 inline unsigned int getSize() const; 49 51 bool process(); 50 52 51 53 private: 52 54 }; -
code/trunk/src/network/packet/Gamestate.cc
r1907 r2087 46 46 #define HEADER GAMESTATE_HEADER(data_) 47 47 48 48 49 49 #define PACKET_FLAG_GAMESTATE ENET_PACKET_FLAG_RELIABLE 50 50 51 51 Gamestate::Gamestate() 52 52 { … … 85 85 return false; 86 86 } 87 87 88 88 #ifndef NDEBUG 89 89 std::list<Synchronisable*> slist; … … 115 115 slist.push_back(*it); 116 116 #endif 117 117 118 118 //if(it->doSelection(id)) 119 119 dataMap_[mem-data_]=(*it); // save the mem location of the synchronisable data … … 157 157 if(!s) 158 158 { 159 s = Synchronisable::fabricate(mem, mode); 160 assert(s); 161 // if(!s) 162 // return false; 159 Synchronisable::fabricate(mem, mode); 163 160 } 164 161 else … … 257 254 HEADER->compressed = true; 258 255 assert(HEADER->compressed); 259 COUT( 3) << "gamestate compress datasize: " << HEADER->datasize << " compsize: " << HEADER->compsize << std::endl;256 COUT(4) << "gamestate compress datasize: " << HEADER->datasize << " compsize: " << HEADER->compsize << std::endl; 260 257 return true; 261 258 } … … 264 261 assert(HEADER); 265 262 assert(HEADER->compressed); 266 COUT( 3) << "GameStateClient: uncompressing gamestate. id: " << HEADER->id << ", baseid: " << HEADER->base_id << ", datasize: " << HEADER->datasize << ", compsize: " << HEADER->compsize << std::endl;263 COUT(4) << "GameStateClient: uncompressing gamestate. id: " << HEADER->id << ", baseid: " << HEADER->base_id << ", datasize: " << HEADER->datasize << ", compsize: " << HEADER->compsize << std::endl; 267 264 unsigned int datasize = HEADER->datasize; 268 265 unsigned int compsize = HEADER->compsize; 269 266 unsigned int bufsize; 270 assert(compsize<=datasize);267 // assert(compsize<=datasize); 271 268 bufsize = datasize; 272 269 assert(bufsize!=0); … … 289 286 //copy over the header 290 287 *GAMESTATE_HEADER(ndata) = *HEADER; 291 //delete old (compressed data) 292 delete[] data_; 288 289 if (this->bDataENetAllocated_){ 290 // Memory was allocated by ENet. --> We let it be since enet_packet_destroy will 291 // deallocated it anyway. So data and packet stay together. 292 this->bDataENetAllocated_ = false; 293 } 294 else{ 295 // We allocated the memory in the first place (unlikely). So we destroy the old data 296 // and overwrite it with the new decompressed data. 297 delete[] this->data_; 298 } 299 293 300 //set new pointers 294 301 data_ = ndata; … … 339 346 assert(data_); 340 347 std::map<unsigned int, Synchronisable *>::iterator it; 341 348 342 349 // allocate memory for new data 343 350 uint8_t *gdata = new uint8_t[HEADER->datasize+sizeof(GamestateHeader)]; … … 346 353 uint8_t *newdata = gdata + sizeof(GamestateHeader); 347 354 uint8_t *origdata = GAMESTATE_START(data_); 348 355 349 356 //copy the GamestateHeader 350 357 *(GamestateHeader*)gdata = *HEADER; 351 358 352 359 synchronisableHeader *oldobjectheader, *newobjectheader; 353 360 unsigned int objectOffset; 354 361 355 362 //copy in the zeros 356 363 for(it=dataMap_.begin(); it!=dataMap_.end(); it++){ … … 360 367 assert(it->second->objectID==oldobjectheader->objectID); 361 368 *newobjectheader = *oldobjectheader; 362 objectOffset=sizeof(uint8_t)+sizeof(bool); //skip the size and the availableDat evariables in the objectheader369 objectOffset=sizeof(uint8_t)+sizeof(bool); //skip the size and the availableData variables in the objectheader 363 370 if(it->second->doSelection(HEADER->id)){ 364 371 newobjectheader->dataAvailable=true; //TODO: probably not neccessary … … 390 397 assert(!HEADER->compressed); 391 398 assert(!HEADER->diffed); 392 399 393 400 //preparations 394 401 std::map<unsigned int, Synchronisable *>::iterator it; 395 402 uint8_t *origdata, *basedata, *destdata, *ndata; 396 403 unsigned int objectOffset, streamOffset=0; //data offset 397 unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize; 404 unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize; 398 405 synchronisableHeader *origheader; 399 406 synchronisableHeader *destheader; 400 407 401 408 origdata = GAMESTATE_START(this->data_); 402 409 basedata = GAMESTATE_START(base->data_); 403 410 ndata = new uint8_t[HEADER->datasize + sizeof(GamestateHeader)]; 404 411 destdata = ndata + sizeof(GamestateHeader); 405 412 406 413 // do the diff 407 414 for(it=dataMap_.begin(); it!=dataMap_.end(); it++){ … … 410 417 origheader = (synchronisableHeader *)(origdata+streamOffset); 411 418 destheader = (synchronisableHeader *)(destdata+streamOffset); 412 419 413 420 //copy and partially diff the object header 414 421 assert(sizeof(synchronisableHeader)==3*sizeof(unsigned int)+sizeof(bool)); … … 420 427 }else{ 421 428 *(uint32_t*)(destdata+sizeof(uint32_t)+sizeof(bool)) = 0; 422 *(uint32_t*)(destdata+2*sizeof(uint32_t)+sizeof(bool)) = 0; 429 *(uint32_t*)(destdata+2*sizeof(uint32_t)+sizeof(bool)) = 0; 423 430 } 424 431 objectOffset=sizeof(synchronisableHeader); 425 432 streamOffset+=sizeof(synchronisableHeader); 426 433 427 434 //now handle the object data or fill with zeros 428 435 while(objectOffset<origheader->size ){ 429 436 430 437 if(sendData && streamOffset<minsize) 431 438 *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor … … 434 441 else 435 442 *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered 436 443 437 444 objectOffset++; 438 445 streamOffset++; … … 442 449 basedata+=objectOffset; 443 450 } 444 451 445 452 //copy over the gamestate header and set the diffed flag 446 453 *(GamestateHeader *)ndata = *HEADER; //copy over the header … … 458 465 assert(!HEADER->compressed); 459 466 assert(HEADER->diffed); 460 467 461 468 //preparations 462 469 std::map<unsigned int, Synchronisable *>::iterator it; 463 470 uint8_t *origdata, *basedata, *destdata, *ndata; 464 471 unsigned int objectOffset, streamOffset=0; //data offset 465 unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize; 472 unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize; 466 473 synchronisableHeader *origheader; 467 474 synchronisableHeader *destheader; 468 475 469 476 origdata = GAMESTATE_START(this->data_); 470 477 basedata = GAMESTATE_START(base->data_); 471 478 ndata = new uint8_t[HEADER->datasize + sizeof(GamestateHeader)]; 472 479 destdata = ndata + sizeof(GamestateHeader); 473 480 474 481 // do the undiff 475 482 for(it=dataMap_.begin(); it!=dataMap_.end(); it++){ … … 478 485 destheader = (synchronisableHeader *)(destdata+streamOffset); 479 486 bool sendData; 480 487 481 488 //copy and partially diff the object header 482 489 assert(sizeof(synchronisableHeader)==3*sizeof(unsigned int)+sizeof(bool)); … … 489 496 }else{ 490 497 *(unsigned int*)(destdata+sizeof(unsigned int)+sizeof(bool)) = 0; 491 *(unsigned int*)(destdata+2*sizeof(unsigned int)+sizeof(bool)) = 0; 498 *(unsigned int*)(destdata+2*sizeof(unsigned int)+sizeof(bool)) = 0; 492 499 } 493 500 objectOffset=sizeof(synchronisableHeader); 494 501 streamOffset+=sizeof(synchronisableHeader); 495 502 496 503 //now handle the object data or fill with zeros 497 504 while(objectOffset<origheader->size ){ 498 505 499 506 if(sendData && streamOffset<minsize) 500 507 *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor … … 503 510 else 504 511 *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered 505 512 506 513 objectOffset++; 507 514 streamOffset++; … … 511 518 basedata+=objectOffset; 512 519 } 513 520 514 521 //copy over the gamestate header and set the diffed flag 515 522 *(GamestateHeader *)ndata = *HEADER; //copy over the header -
code/trunk/src/network/packet/Gamestate.h
r1907 r2087 27 27 */ 28 28 29 30 #ifndef NETWORK_PACKETGAMESTATE_H 31 #define NETWORK_PACKETGAMESTATE_H 32 33 #include "../NetworkPrereqs.h" 34 29 35 #include "Packet.h" 30 36 #include "network/Synchronisable.h" … … 34 40 #endif 35 41 36 37 #ifndef NETWORK_PACKETGAMESTATE_H38 #define NETWORK_PACKETGAMESTATE_H39 40 42 namespace network { 41 43 42 44 namespace packet { 43 45 44 struct GamestateHeader{46 struct _NetworkExport GamestateHeader{ 45 47 ENUM::Type packetType; 46 48 int32_t id; // id of the gamestate … … 59 61 @author Oliver Scheuss 60 62 */ 61 class Gamestate: public Packet{63 class _NetworkExport Gamestate: public Packet{ 62 64 public: 63 65 Gamestate(); -
code/trunk/src/network/packet/Packet.cc
r1907 r2087 49 49 50 50 namespace packet{ 51 51 52 52 #define PACKET_FLAG_DEFAULT ENET_PACKET_FLAG_NO_ALLOCATE 53 53 #define _PACKETID 0 54 54 55 55 std::map<ENetPacket *, Packet *> Packet::packetMap_; 56 56 57 57 Packet::Packet(){ 58 58 flags_ = PACKET_FLAG_DEFAULT; … … 61 61 data_=0; 62 62 enetPacket_=0; 63 bDataENetAllocated_ = false; 63 64 } 64 65 … … 73 74 data_=data; 74 75 enetPacket_=0; 76 bDataENetAllocated_ = false; 75 77 } 76 78 … … 86 88 }else 87 89 data_=0; 88 } 89 90 bDataENetAllocated_ = p.bDataENetAllocated_; 91 } 92 93 /** 94 @brief 95 Destroys a packet completely. 96 97 That also means destroying the ENetPacket if one exists. There 98 */ 90 99 Packet::~Packet(){ 91 if(enetPacket_){ 92 assert(enetPacket_->freeCallback==0); 100 // Deallocate data_ memory if necessary. 101 if (this->bDataENetAllocated_){ 102 // In this case ENet allocated data_ and will destroy it. 103 } 104 else if (this->data_) { 105 // This destructor was probably called as a consequence to ENet executing our callback. 106 // It simply serves us to be able to deallocate the packet content (data_) ourselves since 107 // we have created it in the first place. 108 delete[] this->data_; 109 } 110 111 // Destroy the ENetPacket if necessary. 112 // Note: For the case ENet used the callback to destroy the packet, we have already set 113 // enetPacket_ to NULL to avoid destroying it again. 114 if (this->enetPacket_){ 115 // enetPacket_->data gets destroyed too by ENet if it was allocated by it. 93 116 enet_packet_destroy(enetPacket_); 94 117 } 95 if(data_)96 delete[] data_;97 118 } 98 119 … … 107 128 return false; 108 129 } 130 // We deliver ENet the data address so that it doesn't memcpy everything again. 131 // --> We have to delete data_ ourselves! 109 132 enetPacket_ = enet_packet_create(getData(), getSize(), getFlags()); 110 133 enetPacket_->freeCallback = &Packet::deletePacket; 111 // enetPacket_->freeCallback = &blub; 134 // Add the packet to a global list so we can access it again once enet calls our 135 // deletePacket method. We can of course only give a one argument function to the ENet C library. 112 136 packetMap_[enetPacket_] = this; 113 137 } 114 #ifndef NDEBUG 138 #ifndef NDEBUG 115 139 switch( *(ENUM::Type *)(data_ + _PACKETID) ) 116 140 { … … 127 151 } 128 152 #endif 129 ENetPacket *temp = enetPacket_;130 enetPacket_ = 0; // otherwise we have a double free because enet already handles the deallocation of the packet131 network::Host::addPacket( temp, clientID_);153 // ENetPacket *temp = enetPacket_; 154 // enetPacket_ = 0; // otherwise we have a double free because enet already handles the deallocation of the packet 155 network::Host::addPacket( enetPacket_, clientID_); 132 156 return true; 133 157 } … … 135 159 Packet *Packet::createPacket(ENetPacket *packet, ENetPeer *peer){ 136 160 uint8_t *data = packet->data; 161 assert(ClientInformation::findClient(&peer->address)->getID() != (unsigned int)-2 || !Host::isServer()); 137 162 unsigned int clientID = ClientInformation::findClient(&peer->address)->getID(); 138 163 Packet *p; … … 169 194 break; 170 195 } 196 197 // Data was created by ENet 198 p->bDataENetAllocated_ = true; 199 171 200 return p; 172 201 } 173 202 174 void Packet::deletePacket(ENetPacket *packet){ 175 assert(packetMap_[packet]); 176 assert(packetMap_[packet]->enetPacket_==0); 177 delete packetMap_[packet]; 203 /** 204 @brief 205 ENet calls this method whenever it wants to destroy a packet that contains 206 data we allocated ourselves. 207 */ 208 void Packet::deletePacket(ENetPacket *enetPacket){ 209 // Get our Packet from a gloabal map with all Packets created in the send() method of Packet. 210 std::map<ENetPacket*, Packet*>::iterator it = packetMap_.find(enetPacket); 211 assert(it != packetMap_.end()); 212 // Make sure we don't delete it again in the destructor 213 it->second->enetPacket_ = 0; 214 delete it->second; 215 //packetMap_.erase(it); 216 COUT(4) << "PacketMap size: " << packetMap_.size() << std::endl; 178 217 } 179 218 -
code/trunk/src/network/packet/Packet.h
r1907 r2087 29 29 #define NETWORKPACKET_H 30 30 31 #include "../NetworkPrereqs.h" 32 31 33 #include <map> 32 34 #include <enet/enet.h> … … 37 39 38 40 namespace packet{ 39 41 40 42 namespace ENUM{ 41 43 enum Direction{ … … 53 55 }; 54 56 } 55 57 56 58 /** 57 59 @author Oliver Scheuss <scheusso [at] ee.ethz.ch> 58 60 */ 59 class Packet{61 class _NetworkExport Packet{ 60 62 public: 61 63 Packet(const Packet &p); … … 63 65 static Packet *createPacket(ENetPacket *packet, ENetPeer *peer); 64 66 static void deletePacket(ENetPacket *packet); 65 67 66 68 virtual unsigned char *getData(){ return data_; }; 67 69 virtual unsigned int getSize() const =0; … … 73 75 void setClientID( int id ) 74 76 { clientID_ = id; } 75 77 76 78 bool send(); 77 79 protected: … … 82 84 unsigned int clientID_; 83 85 ENUM::Direction packetDirection_; 86 /** Pointer to the data. Be careful when deleting it because it might 87 point to a location that was allocated by ENet. 88 See bDataENetAllocated_ */ 84 89 uint8_t *data_; 90 /** Tells whether data_ was allocated by ENet or ourselves. 91 data_ might no correlate with enetPacket_->data. */ 92 bool bDataENetAllocated_; 85 93 private: 86 94 static std::map<ENetPacket *, Packet *> packetMap_; -
code/trunk/src/network/packet/Welcome.h
r1907 r2087 29 29 #define NETWORKWELCOME_H 30 30 31 #include "../NetworkPrereqs.h" 32 31 33 #include "Packet.h" 32 34 … … 35 37 36 38 /** 37 @author 39 @author 38 40 */ 39 class Welcome : public Packet41 class _NetworkExport Welcome : public Packet 40 42 { 41 43 public: … … 43 45 Welcome( uint8_t* data, unsigned int clientID ); 44 46 virtual ~Welcome(); 45 47 46 48 uint8_t *getData(); 47 49 inline unsigned int getSize() const; 48 50 bool process(); 49 51 50 52 private: 51 53 };
Note: See TracChangeset
for help on using the changeset viewer.