Changeset 777 for code/branches/FICN/src/network
- Timestamp:
- Dec 31, 2007, 7:40:23 PM (17 years ago)
- Location:
- code/branches/FICN/src/network
- Files:
-
- 1 added
- 29 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/FICN/src/network/Client.cc
r632 r777 1 1 /* 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 2 * ORXONOX - the hottest 3D action shooter ever to exist 3 * 4 * 5 * License notice: 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * Author: 22 * Oliver Scheuss, (C) 2007 23 * Co-authors: 24 * ... 25 * 26 */ 27 27 28 28 // … … 38 38 // 39 39 40 #include "core/CoreIncludes.h" 40 41 #include "Client.h" 41 42 42 namespace network {43 44 /** 45 46 47 43 namespace network 44 { 45 /** 46 * Constructor for the Client class 47 * initializes the address and the port to default localhost:NETWORK_PORT 48 */ 48 49 Client::Client(): client_connection(NETWORK_PORT,"127.0.0.1"){ 49 50 // set server address to localhost … … 52 53 53 54 /** 54 55 56 57 55 * Constructor for the Client class 56 * @param address the server address 57 * @param port port of the application on the server 58 */ 58 59 Client::Client(std::string address, int port) : client_connection(port, address){ 59 60 isConnected=false; … … 61 62 62 63 /** 63 64 65 66 64 * Constructor for the Client class 65 * @param address the server address 66 * @param port port of the application on the server 67 */ 67 68 Client::Client(const char *address, int port) : client_connection(port, address){ 68 69 isConnected=false; … … 70 71 71 72 /** 72 73 74 73 * Establish the Connection to the Server 74 * @return true/false 75 */ 75 76 bool Client::establishConnection(){ 76 77 isConnected=client_connection.createConnection(); … … 79 80 80 81 /** 81 82 83 82 * closes the Connection to the Server 83 * @return true/false 84 */ 84 85 bool Client::closeConnection(){ 85 86 isConnected=false; … … 88 89 89 90 /** 90 91 92 93 94 91 * submits a MouseAction to the server 92 * @param x x Coordinate 93 * @param y y Coordinate 94 * @return true/false 95 */ 95 96 bool Client::sendMouse(double x, double y){ 96 97 // generate packet and add it to the queue … … 98 99 return false; 99 100 if(!client_connection.addPacket(pck_gen.mousem(x, y))) 100 101 return false; 101 102 // send packets 102 103 return client_connection.sendPackets(); … … 104 105 105 106 /** 106 107 108 109 107 * submits a Keystrike to the server 108 * @param key_code code to submit 109 * @return true/false 110 */ 110 111 bool Client::sendKeyboard(char key_code){ 111 112 // generate packet and add it to queue … … 113 114 return false; 114 115 if(!client_connection.addPacket(pck_gen.keystrike(key_code))) 115 116 return false; 116 117 // send packets 117 118 return client_connection.sendPackets(); … … 119 120 120 121 /** 121 122 123 124 122 * submits a chat message to the server 123 * @param message message to send 124 * @return true/false 125 */ 125 126 bool Client::sendChat( std::string message ){ 126 127 // generate packet and add it to queue … … 134 135 135 136 /** 136 137 138 139 140 137 * Adds a MouseAction to the PacketQueue 138 * @param x x Coordinate 139 * @param y y Coordinate 140 * @return true/false 141 */ 141 142 bool Client::addMouse(double x, double y){ 142 143 // generate packet and add it to the queue … … 148 149 149 150 /** 150 151 152 153 151 * Adds a Keystrike to the PacketQueue 152 * @param key_code 153 * @return true/false 154 */ 154 155 bool Client::addKeyboard(char key_code){ 155 156 // generate packet and add it to queue … … 161 162 162 163 /** 163 164 164 * Sends out all the packets queued by addXXX 165 */ 165 166 bool Client::sendPackets(){ 166 167 if(!isConnected) … … 176 177 177 178 /** 178 179 179 * Performs a GameState update 180 */ 180 181 void Client::tick(float time){ 181 182 ENetPacket *packet; -
code/branches/FICN/src/network/Client.h
r774 r777 16 16 #include <string> 17 17 18 #include "NetworkPrereqs.h" 18 19 #include "ClientConnection.h" 19 20 #include "PacketManager.h" 20 21 #include "GameStateClient.h" 21 #include "core/CoreIncludes.h"22 22 //#include "NetworkFrameListener.h" 23 23 24 24 25 namespace network{ 25 namespace network 26 { 27 /** 28 network::Client *client; 29 * The network/Client class 30 * This class implements all necessary function for the network communication 31 * It is the root class of the network module 32 * 33 */ 34 class _NetworkExport Client : PacketDecoder{ 35 public: 36 Client(); 37 Client(std::string address, int port); 38 Client(const char *address, int port); 26 39 40 bool establishConnection(); 41 bool closeConnection(); 27 42 28 29 /** 30 network::Client *client; 31 * The network/Client class 32 * This class implements all necessary function for the network communication 33 * It is the root class of the network module 34 * 35 */ 36 class Client : PacketDecoder{ 37 public: 38 Client(); 39 Client(std::string address, int port); 40 Client(const char *address, int port); 43 bool sendMouse(double x, double y); 44 bool sendKeyboard(char key_code); 45 bool sendChat( std::string message ); 41 46 42 bool establishConnection();43 bool closeConnection();47 bool addMouse(double x, double y); 48 bool addKeyboard(char key_code); 44 49 45 bool sendMouse(double x, double y); 46 bool sendKeyboard(char key_code); 47 bool sendChat( std::string message ); 50 bool sendPackets(); 48 51 49 bool addMouse(double x, double y); 50 bool addKeyboard(char key_code); 51 52 bool sendPackets(); 53 54 void tick(float time); 52 void tick(float time); 55 53 56 54 private: 57 ClientConnection client_connection;58 PacketGenerator pck_gen;59 GameStateClient gamestate;60 bool isConnected;61 62 // implement data processing functions of PacketDecoder63 void processGamestate( GameStateCompressed *data);64 void processClassid(classid *clid);65 void processChat( chat *data);66 };55 ClientConnection client_connection; 56 PacketGenerator pck_gen; 57 GameStateClient gamestate; 58 bool isConnected; 59 60 // implement data processing functions of PacketDecoder 61 void processGamestate( GameStateCompressed *data); 62 void processClassid(classid *clid); 63 void processChat( chat *data); 64 }; 67 65 68 66 -
code/branches/FICN/src/network/ClientConnection.cc
r742 r777 1 1 /* 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 2 * ORXONOX - the hottest 3D action shooter ever to exist 3 * 4 * 5 * License notice: 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * Author: 22 * Oliver Scheuss, (C) 2007 23 * Co-authors: 24 * ... 25 * 26 */ 27 27 28 28 // … … 37 37 // 38 38 39 #include <iostream> 40 // boost.thread library for multithreading support 41 #include <boost/thread/thread.hpp> 42 #include <boost/bind.hpp> 43 44 #include "util/Sleep.h" 39 45 #include "ClientConnection.h" 40 46 41 #include "util/Sleep.h" 42 43 namespace network{ 44 47 namespace network 48 { 45 49 static boost::thread_group network_threads; 46 50 47 ClientConnection::ClientConnection(int port, std::string address) {51 ClientConnection::ClientConnection(int port, std::string address) { 48 52 quit=false; 49 53 server=NULL; … … 53 57 } 54 58 55 ClientConnection::ClientConnection(int port, const char *address) {59 ClientConnection::ClientConnection(int port, const char *address) { 56 60 quit=false; 57 61 server=NULL; … … 61 65 } 62 66 63 bool ClientConnection::waitEstablished(int milisec) {67 bool ClientConnection::waitEstablished(int milisec) { 64 68 for(int i=0; i<=milisec && !established; i++) 65 69 usleep(1000); … … 69 73 70 74 71 ENetPacket *ClientConnection::getPacket(ENetAddress &address) {75 ENetPacket *ClientConnection::getPacket(ENetAddress &address) { 72 76 if(!buffer.isEmpty()) { 73 77 //std::cout << "###BUFFER IS NOT EMPTY###" << std::endl; … … 75 79 } 76 80 else{ 77 78 } 79 } 80 81 ENetPacket *ClientConnection::getPacket() {81 return NULL; 82 } 83 } 84 85 ENetPacket *ClientConnection::getPacket() { 82 86 ENetAddress address; 83 87 return getPacket(address); 84 88 } 85 89 86 bool ClientConnection::queueEmpty() {90 bool ClientConnection::queueEmpty() { 87 91 return buffer.isEmpty(); 88 92 } 89 93 90 bool ClientConnection::createConnection() {94 bool ClientConnection::createConnection() { 91 95 network_threads.create_thread(boost::bind(boost::mem_fn(&ClientConnection::receiverThread), this)); 92 96 // wait 10 seconds for the connection to be established … … 94 98 } 95 99 96 bool ClientConnection::closeConnection() {100 bool ClientConnection::closeConnection() { 97 101 quit=true; 98 102 network_threads.join_all(); … … 102 106 103 107 104 bool ClientConnection::addPacket(ENetPacket *packet) {108 bool ClientConnection::addPacket(ENetPacket *packet) { 105 109 if(server==NULL) 106 110 return false; … … 110 114 } 111 115 112 bool ClientConnection::sendPackets(ENetEvent *event) {116 bool ClientConnection::sendPackets(ENetEvent *event) { 113 117 if(server==NULL) 114 118 return false; … … 119 123 } 120 124 121 bool ClientConnection::sendPackets() {125 bool ClientConnection::sendPackets() { 122 126 ENetEvent event; 123 127 if(server==NULL) … … 129 133 } 130 134 131 void ClientConnection::receiverThread() {135 void ClientConnection::receiverThread() { 132 136 // what about some error-handling here ? 133 137 enet_initialize(); … … 170 174 171 175 if(!disconnectConnection()) 172 // if disconnecting failed destroy conn.176 // if disconnecting failed destroy conn. 173 177 enet_peer_reset(server); 174 178 return; 175 179 } 176 180 177 bool ClientConnection::disconnectConnection() {181 bool ClientConnection::disconnectConnection() { 178 182 ENetEvent event; 179 183 enet_peer_disconnect(server, 0); … … 181 185 switch (event.type) 182 186 { 183 184 185 186 187 188 189 187 case ENET_EVENT_TYPE_NONE: 188 case ENET_EVENT_TYPE_CONNECT: 189 case ENET_EVENT_TYPE_RECEIVE: 190 enet_packet_destroy(event.packet); 191 break; 192 case ENET_EVENT_TYPE_DISCONNECT: 193 return true; 190 194 } 191 195 } … … 194 198 } 195 199 196 bool ClientConnection::establishConnection() {200 bool ClientConnection::establishConnection() { 197 201 ENetEvent event; 198 202 // connect to peer … … 210 214 } 211 215 212 bool ClientConnection::processData(ENetEvent *event) {216 bool ClientConnection::processData(ENetEvent *event) { 213 217 //std::cout << "got packet, pushing to queue" << std::endl; 214 218 // just add packet to the buffer … … 217 221 } 218 222 219 220 223 } -
code/branches/FICN/src/network/ClientConnection.h
r673 r777 13 13 #define _ClientConnection_H__ 14 14 15 #include <iostream>16 15 #include <string> 17 // enet library for networking support18 16 #include <enet/enet.h> 19 // boost.thread library for multithreading support 20 #include <boost/thread/thread.hpp> 21 #include <boost/bind.hpp> 22 // headerfile 23 #include "ClientConnection.h" 17 18 #include "NetworkPrereqs.h" 24 19 #include "PacketBuffer.h" 25 20 26 namespace network{ 27 // 21 namespace network 22 { 23 28 24 #define NETWORK_PORT 55556 29 25 #define NETWORK_CLIENT_MAX_CONNECTIONS 5 … … 34 30 35 31 class ClientConnection{ 36 32 public: 37 33 ClientConnection(int port, std::string address); 38 34 ClientConnection(int port, const char* address); … … 51 47 bool sendPackets(ENetEvent *event); 52 48 bool waitEstablished(int milisec); 53 49 private: 54 50 bool processData(ENetEvent *event); 55 51 // implementation of the listener -
code/branches/FICN/src/network/ClientInformation.cc
r636 r777 1 1 /* 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 2 * ORXONOX - the hottest 3D action shooter ever to exist 3 * 4 * 5 * License notice: 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * Author: 22 * ... 23 * Co-authors: 24 * ... 25 * 26 */ 27 27 28 28 // … … 37 37 // 38 38 // 39 40 #include <iostream> //debug 41 39 42 #include "ClientInformation.h" 40 43 41 namespace network { 42 43 ClientInformation::ClientInformation() 44 namespace network 44 45 { 45 gamestateID_=GAMESTATEID_INITIAL; 46 preve=0; 47 nexte=0; 48 this->head=false; 49 synched_=false; 46 ClientInformation::ClientInformation() { 47 gamestateID_=GAMESTATEID_INITIAL; 48 preve=0; 49 nexte=0; 50 this->head=false; 51 synched_=false; 52 } 53 54 ClientInformation::ClientInformation(bool head) { 55 gamestateID_=GAMESTATEID_INITIAL; 56 preve=0; 57 nexte=0; 58 this->head=head; 59 synched_=false; 60 } 61 62 // ClientInformation::ClientInformation(ClientInformation *prev) { 63 // if(prev->next()!=0){ 64 // this->nexte=prev->next(); 65 // this->nexte->setPrev(this); 66 // } 67 // else 68 // this->nexte = 0; 69 // prev->setNext(this); 70 // this->preve = pref; 71 // } 72 // 73 // ClientInformation::ClientInformation(ClientInformation *prev, ClientInformation *next){ 74 // this->nexte = next; 75 // this->preve = prev; 76 // this->preve->setNext(this); 77 // this->nexte->setPrev(this); 78 // } 79 80 ClientInformation::~ClientInformation() { 81 if(preve!=0) 82 preve->setNext(this->nexte); 83 if(nexte!=0) 84 nexte->setPrev(this->preve); 85 } 86 87 ClientInformation *ClientInformation::next() { 88 if(this!=0) 89 return this->nexte; 90 else 91 return 0; 92 } 93 ClientInformation *ClientInformation::prev() { 94 if(this!=0) 95 return this->preve; 96 else 97 return 0; 98 } 99 100 bool ClientInformation::setPrev(ClientInformation *prev) { 101 if(!head) 102 this->preve = prev; 103 else 104 return false; 105 return true; 106 } 107 108 bool ClientInformation::setNext(ClientInformation *next) { 109 this->nexte = next; 110 return true; 111 } 112 113 ClientInformation *ClientInformation::insertAfter(ClientInformation *ins) { 114 this->nexte->setPrev(ins); 115 ins->setNext(this->nexte); 116 ins->setPrev(this); 117 this->nexte = ins; 118 return ins; 119 } 120 121 ClientInformation *ClientInformation::insertBefore(ClientInformation *ins){ 122 this->prev()->setNext(ins); 123 ins->setPrev(this->preve); 124 this->preve=ins; 125 ins->setNext(this); 126 return ins; 127 } 128 129 void ClientInformation::setID(int clientID){ 130 clientID_ = clientID; 131 } 132 133 void ClientInformation::setPeer(ENetPeer *peer){ 134 peer_ = peer; 135 } 136 137 void ClientInformation::setGamestateID(int id){ 138 gamestateID_=id; 139 } 140 141 int ClientInformation::getID() { 142 return clientID_; 143 } 144 145 ENetPeer *ClientInformation::getPeer() { 146 return peer_; 147 } 148 149 int ClientInformation::getGamestateID() { 150 return gamestateID_; 151 } 152 153 ClientInformation *ClientInformation::insertBack(ClientInformation *ins) { 154 ClientInformation *temp = this; 155 while(temp->next()!=0){ 156 temp = temp->next(); 157 } 158 temp->setNext(ins); 159 ins->setPrev(temp); 160 return ins; 161 } 162 163 bool ClientInformation::removeClient(int clientID) { 164 ClientInformation *temp = this; 165 while(temp!=0 && temp->getID()!=clientID) 166 temp = temp->next(); 167 if(temp==0) 168 return false; 169 delete temp; 170 return true; 171 } 172 173 bool ClientInformation::removeClient(ENetPeer *peer) { 174 ClientInformation *temp = this; 175 while(temp!=0){ 176 if(!temp->head) 177 if(temp->getPeer()->address.host==peer->address.host && temp->getPeer()->address.port==peer->address.port) 178 break; 179 temp = temp->next(); 180 } 181 if(temp==0) 182 return false; 183 delete temp; 184 return true; 185 } 186 187 /** 188 * This function goes forward through the list and looks for an element with clientID 189 * This function should only be applied to the head of the list 190 * @param clientID id to look for 191 * @return pointer to the element in the list or 0 if the search was unsuccessfull 192 */ 193 ClientInformation *ClientInformation::findClient(int clientID, bool look_backwards) { 194 ClientInformation *temp = this; 195 if (temp->head) 196 temp=temp->next(); 197 while(temp!=0 && temp->getID()!=clientID){ 198 temp = temp->next(); 199 } 200 // returns 0 if nothing has been found 201 return temp; 202 } 203 204 /** 205 * This function goes forward through the list and looks for an element with clientID 206 * This function should only be applied to the head of the list 207 * @param peer peer to look for 208 * @return pointer to the element in the list 209 */ 210 ClientInformation *ClientInformation::findClient(ENetAddress *address, bool look_backwards) { 211 ClientInformation *temp = this; 212 while(temp!=0){ 213 if(temp->head){ 214 temp = temp->next(); 215 continue; 216 } 217 if(temp->getPeer()->address.host==address->host && temp->getPeer()->address.port == address->port) 218 break; 219 temp = temp->next(); 220 } 221 // returns 0 if nothing has been found 222 return temp; 223 } 224 225 void ClientInformation::setSynched(bool s) { 226 synched_=s; 227 } 228 229 bool ClientInformation::getSynched() { 230 return synched_; 231 } 232 50 233 } 51 52 ClientInformation::ClientInformation(bool head)53 {54 gamestateID_=GAMESTATEID_INITIAL;55 preve=0;56 nexte=0;57 this->head=head;58 synched_=false;59 }60 //61 62 // ClientInformation::ClientInformation(ClientInformation *prev){63 // if(prev->next()!=0){64 // this->nexte=prev->next();65 // this->nexte->setPrev(this);66 // }67 // else68 // this->nexte = 0;69 // prev->setNext(this);70 // this->preve = pref;71 // }72 //73 // ClientInformation::ClientInformation(ClientInformation *prev, ClientInformation *next){74 // this->nexte = next;75 // this->preve = prev;76 // this->preve->setNext(this);77 // this->nexte->setPrev(this);78 // }79 80 ClientInformation::~ClientInformation()81 {82 if(preve!=0)83 preve->setNext(this->nexte);84 if(nexte!=0)85 nexte->setPrev(this->preve);86 }87 88 ClientInformation *ClientInformation::next(){89 if(this!=0)90 return this->nexte;91 else92 return 0;93 }94 ClientInformation *ClientInformation::prev(){95 if(this!=0)96 return this->preve;97 else98 return 0;99 }100 101 bool ClientInformation::setPrev(ClientInformation *prev){102 if(!head)103 this->preve = prev;104 else105 return false;106 return true;107 }108 109 bool ClientInformation::setNext(ClientInformation *next){110 this->nexte = next;111 return true;112 }113 114 ClientInformation *ClientInformation::insertAfter(ClientInformation *ins){115 this->nexte->setPrev(ins);116 ins->setNext(this->nexte);117 ins->setPrev(this);118 this->nexte = ins;119 return ins;120 }121 122 ClientInformation *ClientInformation::insertBefore(ClientInformation *ins){123 this->prev()->setNext(ins);124 ins->setPrev(this->preve);125 this->preve=ins;126 ins->setNext(this);127 return ins;128 }129 130 void ClientInformation::setID(int clientID){131 clientID_ = clientID;132 }133 void ClientInformation::setPeer(ENetPeer *peer){134 peer_ = peer;135 }136 137 void ClientInformation::setGamestateID(int id){138 gamestateID_=id;139 }140 141 int ClientInformation::getID(){142 return clientID_;143 }144 ENetPeer *ClientInformation::getPeer(){145 return peer_;146 }147 148 int ClientInformation::getGamestateID(){149 return gamestateID_;150 }151 152 ClientInformation *ClientInformation::insertBack(ClientInformation *ins){153 ClientInformation *temp = this;154 while(temp->next()!=0){155 temp = temp->next();156 }157 temp->setNext(ins);158 ins->setPrev(temp);159 return ins;160 }161 162 bool ClientInformation::removeClient(int clientID){163 ClientInformation *temp = this;164 while(temp!=0 && temp->getID()!=clientID)165 temp = temp->next();166 if(temp==0)167 return false;168 delete temp;169 return true;170 }171 172 bool ClientInformation::removeClient(ENetPeer *peer){173 ClientInformation *temp = this;174 while(temp!=0){175 if(!temp->head)176 if(temp->getPeer()->address.host==peer->address.host && temp->getPeer()->address.port==peer->address.port)177 break;178 temp = temp->next();179 }180 if(temp==0)181 return false;182 delete temp;183 return true;184 }185 186 /**187 * This function goes forward through the list and looks for an element with clientID188 * This function should only be applied to the head of the list189 * @param clientID id to look for190 * @return pointer to the element in the list or 0 if the search was unsuccessfull191 */192 ClientInformation *ClientInformation::findClient(int clientID, bool look_backwards){193 ClientInformation *temp = this;194 if (temp->head)195 temp=temp->next();196 while(temp!=0 && temp->getID()!=clientID){197 temp = temp->next();198 }199 // returns 0 if nothing has been found200 return temp;201 }202 203 /**204 * This function goes forward through the list and looks for an element with clientID205 * This function should only be applied to the head of the list206 * @param peer peer to look for207 * @return pointer to the element in the list208 */209 ClientInformation *ClientInformation::findClient(ENetAddress *address, bool look_backwards){210 ClientInformation *temp = this;211 while(temp!=0){212 if(temp->head){213 temp = temp->next();214 continue;215 }216 if(temp->getPeer()->address.host==address->host && temp->getPeer()->address.port == address->port)217 break;218 temp = temp->next();219 }220 // returns 0 if nothing has been found221 return temp;222 }223 224 void ClientInformation::setSynched(bool s){225 synched_=s;226 }227 bool ClientInformation::getSynched(){228 return synched_;229 }230 231 } -
code/branches/FICN/src/network/ClientInformation.h
r673 r777 14 14 15 15 #include <enet/enet.h> 16 #include <iostream> //debug 16 17 #include "NetworkPrereqs.h" 17 18 18 19 #define GAMESTATEID_INITIAL -1 19 20 20 namespace network { 21 namespace network 22 { 23 /** 24 * This class implements a list for client informations 25 * @author Oliver Scheuss 26 */ 27 class ClientInformation{ 28 public: 29 ClientInformation(); 30 ClientInformation(bool head); 31 // ClientInformation(ClientInformation *prev, ClientInformation *next); 32 // ClientInformation(ClientInformation *prev); 33 ~ClientInformation(); 34 ClientInformation *next(); 35 ClientInformation *prev(); 36 bool setNext(ClientInformation *next); 37 bool setPrev(ClientInformation *prev); 38 ClientInformation *insertAfter(ClientInformation *ins); 39 ClientInformation *insertBefore(ClientInformation *ins); 40 ClientInformation *insertBack(ClientInformation *ins); 41 void setID(int clientID); 42 void setPeer(ENetPeer *peer); 43 void setGamestateID(int id); 44 int getID(); 45 ENetPeer *getPeer(); 46 int getGamestateID(); 47 bool removeClient(int clientID); 48 bool removeClient(ENetPeer *peer); 49 ClientInformation *findClient(int clientID, bool look_backwards=false); 50 ClientInformation *findClient(ENetAddress *address, bool look_backwards=false); 21 51 22 /** 23 * This class implements a list for client informations 24 * @author Oliver Scheuss 25 */ 26 class ClientInformation{ 27 public: 28 ClientInformation(); 29 ClientInformation(bool head); 30 // ClientInformation(ClientInformation *prev, ClientInformation *next); 31 // ClientInformation(ClientInformation *prev); 32 ~ClientInformation(); 33 ClientInformation *next(); 34 ClientInformation *prev(); 35 bool setNext(ClientInformation *next); 36 bool setPrev(ClientInformation *prev); 37 ClientInformation *insertAfter(ClientInformation *ins); 38 ClientInformation *insertBefore(ClientInformation *ins); 39 ClientInformation *insertBack(ClientInformation *ins); 40 void setID(int clientID); 41 void setPeer(ENetPeer *peer); 42 void setGamestateID(int id); 43 int getID(); 44 ENetPeer *getPeer(); 45 int getGamestateID(); 46 bool removeClient(int clientID); 47 bool removeClient(ENetPeer *peer); 48 ClientInformation *findClient(int clientID, bool look_backwards=false); 49 ClientInformation *findClient(ENetAddress *address, bool look_backwards=false); 50 51 void setSynched(bool s); 52 bool getSynched(); 53 54 bool head; 55 56 private: 57 ClientInformation *preve; 58 ClientInformation *nexte; 59 //actual information: 60 ENetPeer *peer_; 61 int clientID_; 62 int gamestateID_; 63 bool synched_; 64 }; 52 void setSynched(bool s); 53 bool getSynched(); 54 55 bool head; 56 57 private: 58 ClientInformation *preve; 59 ClientInformation *nexte; 60 //actual information: 61 ENetPeer *peer_; 62 int clientID_; 63 int gamestateID_; 64 bool synched_; 65 }; 65 66 66 67 } -
code/branches/FICN/src/network/ConnectionManager.cc
r681 r777 1 1 /* 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 2 * ORXONOX - the hottest 3D action shooter ever to exist 3 * 4 * 5 * License notice: 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * Author: 22 * Oliver Scheuss, (C) 2007 23 * Co-authors: 24 * ... 25 * 26 */ 27 27 28 28 // … … 37 37 // 38 38 39 #include <iostream> 40 // boost.thread library for multithreading support 41 #include <boost/thread/thread.hpp> 42 #include <boost/bind.hpp> 43 44 #include "core/CoreIncludes.h" 45 #include "ClientInformation.h" 39 46 #include "ConnectionManager.h" 40 47 41 namespace std{ 42 bool operator< (ENetAddress a, ENetAddress b){ 48 namespace std 49 { 50 bool operator< (ENetAddress a, ENetAddress b) { 43 51 if(a.host <= b.host) 44 52 return true; … … 48 56 } 49 57 50 namespace network {51 58 namespace network 59 { 52 60 boost::thread_group network_threads; 53 61 54 ConnectionManager::ConnectionManager(ClientInformation *head) {62 ConnectionManager::ConnectionManager(ClientInformation *head) { 55 63 quit=false; 56 64 bindAddress.host = ENET_HOST_ANY; … … 59 67 } 60 68 61 ConnectionManager::ConnectionManager(int port, std::string address, ClientInformation *head) {69 ConnectionManager::ConnectionManager(int port, std::string address, ClientInformation *head) { 62 70 quit=false; 63 71 enet_address_set_host (& bindAddress, address.c_str()); … … 66 74 } 67 75 68 ConnectionManager::ConnectionManager(int port, const char *address, ClientInformation *head) {76 ConnectionManager::ConnectionManager(int port, const char *address, ClientInformation *head) { 69 77 quit=false; 70 78 enet_address_set_host (& bindAddress, address); … … 73 81 } 74 82 75 ENetPacket *ConnectionManager::getPacket(ENetAddress &address) {83 ENetPacket *ConnectionManager::getPacket(ENetAddress &address) { 76 84 if(!buffer.isEmpty()) 77 85 return buffer.pop(address); 78 86 else 79 80 } 81 82 ENetPacket *ConnectionManager::getPacket(int &clientID) {87 return NULL; 88 } 89 90 ENetPacket *ConnectionManager::getPacket(int &clientID) { 83 91 ENetAddress address; 84 92 ENetPacket *packet=getPacket(address); … … 88 96 } 89 97 90 bool ConnectionManager::queueEmpty() {98 bool ConnectionManager::queueEmpty() { 91 99 return buffer.isEmpty(); 92 100 } 93 101 94 void ConnectionManager::createListener() {102 void ConnectionManager::createListener() { 95 103 network_threads.create_thread(boost::bind(boost::mem_fn(&ConnectionManager::receiverThread), this)); 96 // boost::thread thr(boost::bind(boost::mem_fn(&ConnectionManager::receiverThread), this));104 // boost::thread thr(boost::bind(boost::mem_fn(&ConnectionManager::receiverThread), this)); 97 105 return; 98 106 } 99 107 100 bool ConnectionManager::quitListener() {108 bool ConnectionManager::quitListener() { 101 109 quit=true; 102 110 network_threads.join_all(); … … 104 112 } 105 113 106 bool ConnectionManager::addPacket(ENetPacket *packet, ENetPeer *peer) {114 bool ConnectionManager::addPacket(ENetPacket *packet, ENetPeer *peer) { 107 115 if(enet_peer_send(peer, head_->findClient(&(peer->address))->getID() , packet)!=0) 108 116 return false; … … 110 118 } 111 119 112 bool ConnectionManager::addPacket(ENetPacket *packet, int clientID) {120 bool ConnectionManager::addPacket(ENetPacket *packet, int clientID) { 113 121 if(enet_peer_send(head_->findClient(clientID)->getPeer(), clientID, packet)!=0) 114 122 return false; … … 116 124 } 117 125 118 bool ConnectionManager::addPacketAll(ENetPacket *packet) {126 bool ConnectionManager::addPacketAll(ENetPacket *packet) { 119 127 for(ClientInformation *i=head_->next(); i!=0; i=i->next()){ 120 128 if(enet_peer_send(i->getPeer(), i->getID(), packet)!=0) 121 122 } 123 return true; 124 } 125 126 bool ConnectionManager::sendPackets(ENetEvent *event) {129 return false; 130 } 131 return true; 132 } 133 134 bool ConnectionManager::sendPackets(ENetEvent *event) { 127 135 if(server==NULL) 128 136 return false; … … 133 141 } 134 142 135 bool ConnectionManager::sendPackets() {143 bool ConnectionManager::sendPackets() { 136 144 ENetEvent event; 137 145 if(server==NULL) … … 143 151 } 144 152 145 void ConnectionManager::receiverThread() {153 void ConnectionManager::receiverThread() { 146 154 // what about some error-handling here ? 147 155 enet_initialize(); … … 164 172 // log handling ================ 165 173 case ENET_EVENT_TYPE_CONNECT: 166 addClient(&event);167 break;168 case ENET_EVENT_TYPE_RECEIVE:169 //std::cout << "received data" << std::endl;170 processData(&event);171 break;172 case ENET_EVENT_TYPE_DISCONNECT:173 // add some error/log handling here174 clientDisconnect(event.peer);175 break;176 case ENET_EVENT_TYPE_NONE:177 break;174 addClient(&event); 175 break; 176 case ENET_EVENT_TYPE_RECEIVE: 177 //std::cout << "received data" << std::endl; 178 processData(&event); 179 break; 180 case ENET_EVENT_TYPE_DISCONNECT: 181 // add some error/log handling here 182 clientDisconnect(event.peer); 183 break; 184 case ENET_EVENT_TYPE_NONE: 185 break; 178 186 } 179 187 } … … 183 191 } 184 192 185 void ConnectionManager::disconnectClients() {193 void ConnectionManager::disconnectClients() { 186 194 ENetEvent event; 187 195 ClientInformation *temp = head_->next(); … … 194 202 switch (event.type) 195 203 { 196 197 198 199 200 201 202 203 204 205 204 case ENET_EVENT_TYPE_NONE: 205 case ENET_EVENT_TYPE_CONNECT: 206 case ENET_EVENT_TYPE_RECEIVE: 207 enet_packet_destroy(event.packet); 208 break; 209 case ENET_EVENT_TYPE_DISCONNECT: 210 std::cout << "disconnecting client" << std::endl; 211 delete head_->findClient(&(event.peer->address)); 212 temp = temp->next(); 213 break; 206 214 } 207 215 } … … 209 217 } 210 218 211 bool ConnectionManager::processData(ENetEvent *event) {219 bool ConnectionManager::processData(ENetEvent *event) { 212 220 // just add packet to the buffer 213 221 // this can be extended with some preprocessing … … 215 223 } 216 224 217 // bool ConnectionManager::clientDisconnect(ENetPeer *peer){ 218 // return clientDisconnect(*peer); 219 // } 220 221 222 223 bool ConnectionManager::clientDisconnect(ENetPeer *peer){ 225 //bool ConnectionManager::clientDisconnect(ENetPeer *peer) { 226 // return clientDisconnect(*peer); 227 //} 228 229 bool ConnectionManager::clientDisconnect(ENetPeer *peer) { 224 230 return head_->removeClient(peer); 225 231 } 226 232 227 bool ConnectionManager::addClient(ENetEvent *event) {233 bool ConnectionManager::addClient(ENetEvent *event) { 228 234 ClientInformation *temp = head_->insertBack(new ClientInformation); 229 235 if(temp->prev()->head) … … 238 244 } 239 245 240 int ConnectionManager::getClientID(ENetPeer peer) {246 int ConnectionManager::getClientID(ENetPeer peer) { 241 247 return getClientID(peer.address); 242 248 } 243 249 244 int ConnectionManager::getClientID(ENetAddress address) {250 int ConnectionManager::getClientID(ENetAddress address) { 245 251 return head_->findClient(&address)->getID(); 246 252 } 247 253 248 ENetPeer *ConnectionManager::getClientPeer(int clientID) {254 ENetPeer *ConnectionManager::getClientPeer(int clientID) { 249 255 return head_->findClient(clientID)->getPeer(); 250 256 } 251 257 252 void ConnectionManager::syncClassid(int clientID) {258 void ConnectionManager::syncClassid(int clientID) { 253 259 int i=0; 254 260 std::string classname; -
code/branches/FICN/src/network/ConnectionManager.h
r774 r777 13 13 #define _ConnectionManager_H__ 14 14 15 #include <iostream>16 15 #include <string> 17 16 // enet library for networking support 18 17 #include <enet/enet.h> 19 // boost.thread library for multithreading support 20 #include <boost/thread/thread.hpp> 21 #include <boost/bind.hpp> 22 // headerfiles 23 #include "ClientInformation.h" 18 19 #include "NetworkPrereqs.h" 24 20 #include "PacketBuffer.h" 25 21 #include "PacketManager.h" 26 #include "core/CoreIncludes.h"27 22 28 namespace std{ 23 namespace std 24 { 29 25 bool operator<(ENetAddress a, ENetAddress b); 30 26 } 31 27 32 namespace network {33 // 28 namespace network 29 { 34 30 #define NETWORK_PORT 55556 35 31 #define NETWORK_MAX_CONNECTIONS 50 … … 42 38 ClientList *next; 43 39 }; 44 40 45 41 class ConnectionManager{ 46 42 public: 47 43 ConnectionManager(ClientInformation *head); 48 44 ConnectionManager(int port, const char *address, ClientInformation *head); … … 71 67 PacketBuffer buffer; 72 68 PacketGenerator packet_gen; 73 69 74 70 ENetHost *server; 75 71 ENetAddress bindAddress; 76 72 77 73 bool quit; // quit-variable (communication with threads) 78 74 ClientInformation *head_; -
code/branches/FICN/src/network/GameStateClient.cc
r636 r777 1 1 /* 2 * ORXONOX - the hottest 3D action shooter ever to exist 3 * 4 * 5 * License notice: 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * Author: 22 * ... 23 * Co-authors: 24 * ... 25 * 26 */ 2 * ORXONOX - the hottest 3D action shooter ever to exist 3 * 4 * 5 * License notice: 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * Author: 22 * ... 23 * Co-authors: 24 * ... 25 * 26 */ 27 #include <zlib.h> 27 28 29 #include "core/CoreIncludes.h" 30 #include "Synchronisable.h" 28 31 #include "GameStateClient.h" 29 32 30 namespace network { 31 32 GameStateClient::GameStateClient() 33 namespace network 33 34 { 34 } 35 36 37 GameStateClient::~GameStateClient() 38 { 39 } 40 41 bool GameStateClient::pushGameState(GameStateCompressed *compstate){ 42 if(compstate->diffed) 43 return loadSnapshot(decode(reference, *compstate)); 44 else 45 return loadSnapshot(decode(*compstate)); 46 } 47 48 49 /** 50 * This function removes a Synchronisable out of the universe 51 * @param it iterator of the list pointing to the object 52 * @return iterator pointing to the next object in the list 53 */ 54 void GameStateClient::removeObject(orxonox::Iterator<Synchronisable> &it){ 55 orxonox::Iterator<Synchronisable> temp=it; 56 ++it; 57 delete *temp; 58 } 59 60 /** 61 * This function loads a Snapshort of the gamestate into the universe 62 * @param state a GameState struct containing the size of the gamestate and a pointer linking to a flat list (returned by getSnapshot) 63 */ 64 bool GameStateClient::loadSnapshot(GameState state) 65 { 66 unsigned char *data=state.data; 67 std::cout << "loadSnapshot: loading gs: " << state.id << std::endl; 68 // get the start of the Synchronisable list 69 orxonox::Iterator<Synchronisable> it=orxonox::ObjectList<Synchronisable>::start(); 70 syncData sync; 71 // loop as long as we have some data ;) 72 while(data < state.data+state.size){ 73 // prepare the syncData struct 74 sync.length = (int)*data; 75 data+=sizeof(int); 76 sync.objectID = (int)*data; 77 data+=sizeof(int); 78 sync.classID = (int)*data; 79 data+=sizeof(int); 80 sync.data = data; 81 data+=sync.length; 82 83 if(it->objectID!=sync.objectID){ 84 // bad luck ;) 85 // delete the synchronisable (obviously seems to be deleted on the server) 86 while(it != 0 && it->objectID!=sync.objectID){ 87 removeObject(it); 88 } 89 if(it==0){ 90 std::cout << "classid: " << sync.classID << ", name: " << ID(sync.classID)->getName() << std::endl; 91 orxonox::BaseObject *no = ID(sync.classID)->fabricate(); 92 ((Synchronisable *)no)->objectID=sync.objectID; 93 ((Synchronisable *)no)->classID=sync.classID; 94 it=orxonox::ObjectList<Synchronisable>::end(); 95 // update data and create object/entity... 96 if( !(((Synchronisable *)no)->updateData(sync)) && !(((Synchronisable *)no)->create()) ) 97 COUT(0) << "We couldn't create/update the object: " << sync.objectID << std::endl; 98 ++it; 99 } 100 } else { 101 // we have our object 102 if(! it->updateData(sync)) 103 std::cout << "We couldn't update objectID: " \ 104 << sync.objectID << "; classID: " << sync.classID << std::endl; 105 } 106 ++it; 35 GameStateClient::GameStateClient() { 107 36 } 108 37 109 return true;110 }38 GameStateClient::~GameStateClient() { 39 } 111 40 112 GameState GameStateClient::diff(GameState a, GameState b){ 113 unsigned char *ap = a.data, *bp = b.data; 114 int of=0; // pointers offset 115 int dest_length=0; 116 if(a.size>=b.size) 117 dest_length=a.size; 118 else 119 dest_length=b.size; 120 unsigned char *dp = (unsigned char *)malloc(dest_length*sizeof(unsigned char)); 121 while(of<a.size && of<b.size){ 122 *(dp+of)=*(ap+of)^*(bp+of); // do the xor 123 ++of; 41 bool GameStateClient::pushGameState(GameStateCompressed *compstate) { 42 if(compstate->diffed) 43 return loadSnapshot(decode(reference, *compstate)); 44 else 45 return loadSnapshot(decode(*compstate)); 124 46 } 125 if(a.size!=b.size){ // do we have to fill up ? 126 unsigned char n=0; 127 if(a.size<b.size){ 128 while(of<dest_length){ 129 *(dp+of)=n^*(bp+of); 130 of++; 47 48 /** 49 * This function removes a Synchronisable out of the universe 50 * @param it iterator of the list pointing to the object 51 * @return iterator pointing to the next object in the list 52 */ 53 void GameStateClient::removeObject(orxonox::Iterator<Synchronisable> &it) { 54 orxonox::Iterator<Synchronisable> temp=it; 55 ++it; 56 delete *temp; 57 } 58 59 /** 60 * This function loads a Snapshort of the gamestate into the universe 61 * @param state a GameState struct containing the size of the gamestate and a pointer linking to a flat list (returned by getSnapshot) 62 */ 63 bool GameStateClient::loadSnapshot(GameState state) { 64 unsigned char *data=state.data; 65 std::cout << "loadSnapshot: loading gs: " << state.id << std::endl; 66 // get the start of the Synchronisable list 67 orxonox::Iterator<Synchronisable> it=orxonox::ObjectList<Synchronisable>::start(); 68 syncData sync; 69 // loop as long as we have some data ;) 70 while(data < state.data+state.size){ 71 // prepare the syncData struct 72 sync.length = (int)*data; 73 data+=sizeof(int); 74 sync.objectID = (int)*data; 75 data+=sizeof(int); 76 sync.classID = (int)*data; 77 data+=sizeof(int); 78 sync.data = data; 79 data+=sync.length; 80 81 if(it->objectID!=sync.objectID){ 82 // bad luck ;) 83 // delete the synchronisable (obviously seems to be deleted on the server) 84 while(it != 0 && it->objectID!=sync.objectID){ 85 removeObject(it); 86 } 87 if(it==0){ 88 std::cout << "classid: " << sync.classID << ", name: " << ID(sync.classID)->getName() << std::endl; 89 Synchronisable *no = (Synchronisable*)(ID(sync.classID)->fabricate()); 90 no->objectID=sync.objectID; 91 no->classID=sync.classID; 92 it=orxonox::ObjectList<Synchronisable>::end(); 93 // update data and create object/entity... 94 if( !no->updateData(sync) && !no->create() ) 95 COUT(0) << "We couldn't create/update the object: " << sync.objectID << std::endl; 96 ++it; 97 } 98 } else { 99 // we have our object 100 if(! it->updateData(sync)) 101 std::cout << "We couldn't update objectID: " \ 102 << sync.objectID << "; classID: " << sync.classID << std::endl; 131 103 } 132 } else{ 133 while(of<dest_length){ 134 *(dp+of)=*(ap+of)^n; 135 of++; 104 ++it; 105 } 106 107 return true; 108 } 109 110 GameState GameStateClient::diff(GameState a, GameState b) { 111 unsigned char *ap = a.data, *bp = b.data; 112 int of=0; // pointers offset 113 int dest_length=0; 114 if(a.size>=b.size) 115 dest_length=a.size; 116 else 117 dest_length=b.size; 118 unsigned char *dp = (unsigned char *)malloc(dest_length*sizeof(unsigned char)); 119 while(of<a.size && of<b.size){ 120 *(dp+of)=*(ap+of)^*(bp+of); // do the xor 121 ++of; 122 } 123 if(a.size!=b.size){ // do we have to fill up ? 124 unsigned char n=0; 125 if(a.size<b.size){ 126 while(of<dest_length){ 127 *(dp+of)=n^*(bp+of); 128 of++; 129 } 130 } else{ 131 while(of<dest_length){ 132 *(dp+of)=*(ap+of)^n; 133 of++; 134 } 136 135 } 137 136 } 138 } 139 // should be finished now 140 GameState r = {b.id, dest_length, dp}; 141 return r; 142 } 143 144 145 GameState GameStateClient::decompress(GameStateCompressed a){ 146 int normsize = a.normsize; 147 int compsize = a.compsize; 148 int bufsize; 149 if(normsize < compsize) 150 bufsize = compsize; 151 else 152 bufsize = normsize; 153 unsigned char* dest = (unsigned char*)malloc( bufsize ); 154 int retval; 155 uLongf length=normsize; 156 //std::cout << "gamestateclient" << std::endl; 157 //std::cout << "normsize " << a.normsize << " compsize " << a.compsize << " " << bufsize << std::endl; 158 retval = uncompress( dest, &length, a.data, (uLong)compsize ); 159 //std::cout << "length " << length << std::endl; 160 switch ( retval ) { 161 case Z_OK: std::cout << "successfully decompressed" << std::endl; break; 162 case Z_MEM_ERROR: std::cout << "not enough memory available" << std::endl; break; 163 case Z_BUF_ERROR: std::cout << "not enough memory available in the buffer" << std::endl; break; 164 case Z_DATA_ERROR: std::cout << "data corrupted" << std::endl; break; 137 // should be finished now 138 GameState r = {b.id, dest_length, dp}; 139 return r; 165 140 } 166 141 167 GameState gamestate; 168 gamestate.id = a.id; 169 gamestate.size = normsize; 170 gamestate.data = dest; 171 gamestate.diffed = a.diffed; 172 173 return gamestate; 174 } 142 GameState GameStateClient::decompress(GameStateCompressed a) { 143 int normsize = a.normsize; 144 int compsize = a.compsize; 145 int bufsize; 146 if(normsize < compsize) 147 bufsize = compsize; 148 else 149 bufsize = normsize; 150 unsigned char* dest = (unsigned char*)malloc( bufsize ); 151 int retval; 152 uLongf length=normsize; 153 //std::cout << "gamestateclient" << std::endl; 154 //std::cout << "normsize " << a.normsize << " compsize " << a.compsize << " " << bufsize << std::endl; 155 retval = uncompress( dest, &length, a.data, (uLong)compsize ); 156 //std::cout << "length " << length << std::endl; 157 switch ( retval ) { 158 case Z_OK: std::cout << "successfully decompressed" << std::endl; break; 159 case Z_MEM_ERROR: std::cout << "not enough memory available" << std::endl; break; 160 case Z_BUF_ERROR: std::cout << "not enough memory available in the buffer" << std::endl; break; 161 case Z_DATA_ERROR: std::cout << "data corrupted" << std::endl; break; 162 } 175 163 164 GameState gamestate; 165 gamestate.id = a.id; 166 gamestate.size = normsize; 167 gamestate.data = dest; 168 gamestate.diffed = a.diffed; 176 169 177 GameState GameStateClient::decode(GameState a, GameStateCompressed x){ 178 GameState t = decompress(x); 179 return diff(a, t); 180 } 170 return gamestate; 171 } 181 172 182 GameState GameStateClient::decode(GameStateCompressed x){183 GameState t = decompress(x);184 return t;185 }173 GameState GameStateClient::decode(GameState a, GameStateCompressed x) { 174 GameState t = decompress(x); 175 return diff(a, t); 176 } 186 177 187 178 GameState GameStateClient::decode(GameStateCompressed x) { 179 GameState t = decompress(x); 180 return t; 181 } 188 182 189 183 } -
code/branches/FICN/src/network/GameStateClient.h
r774 r777 13 13 #define _GameStateClient_H__ 14 14 15 #include "zlib.h" 16 #include "Synchronisable.h" 17 #include "core/CoreIncludes.h" 18 #include "core/BaseObject.h" 15 #include "NetworkPrereqs.h" 19 16 #include "GameStateManager.h" 20 17 21 namespace network { 18 namespace network 19 { 20 class GameStateClient 21 { 22 public: 23 GameStateClient(); 24 ~GameStateClient(); 25 bool pushGameState(GameStateCompressed *compstate); 26 private: 27 bool loadSnapshot(GameState state); 28 GameState diff(GameState a, GameState b); 29 GameState decompress(GameStateCompressed a); 30 GameState decode(GameState a, GameStateCompressed x); 31 GameState decode(GameStateCompressed x); 32 void removeObject(orxonox::Iterator<Synchronisable> &it); 22 33 23 class GameStateClient{ 24 public: 25 GameStateClient(); 26 ~GameStateClient(); 27 bool pushGameState(GameStateCompressed *compstate); 28 private: 29 bool loadSnapshot(GameState state); 30 GameState diff(GameState a, GameState b); 31 GameState decompress(GameStateCompressed a); 32 GameState decode(GameState a, GameStateCompressed x); 33 GameState decode(GameStateCompressed x); 34 void removeObject(orxonox::Iterator<Synchronisable> &it); 35 36 GameState reference; 37 }; 34 GameState reference; 35 }; 38 36 39 37 } -
code/branches/FICN/src/network/GameStateManager.cc
r656 r777 1 1 /* 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 2 * ORXONOX - the hottest 3D action shooter ever to exist 3 * 4 * 5 * License notice: 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * Author: 22 * Oliver Scheuss, (C) 2007 23 * Co-authors: 24 * ... 25 * 26 */ 27 27 28 28 // … … 37 37 // 38 38 // 39 40 #include <utility> 41 #include <iostream> 42 #include <zlib.h> 43 44 #include "core/CoreIncludes.h" 45 #include "ClientInformation.h" 46 #include "Synchronisable.h" 39 47 #include "GameStateManager.h" 40 48 41 namespace network { 42 43 GameStateManager::GameStateManager(ClientInformation *head) 49 namespace network 44 50 { 45 id=0; 46 head_=head; 51 GameStateManager::GameStateManager(ClientInformation *head) { 52 id=0; 53 head_=head; 54 } 55 56 GameStateManager::~GameStateManager() { 57 } 58 59 void GameStateManager::update(){ 60 reference = getSnapshot(id); 61 gameStateMap.insert(std::pair<int, GameState*>(id, reference)); 62 gameStateUsed[id]=0; 63 ++id; 64 return; 65 } 66 67 GameStateCompressed GameStateManager::popGameState(int clientID) { 68 int gID = head_->findClient(clientID)->getGamestateID(); 69 std::cout << "popgamestate: sending gstate id: " << id << "diffed from: " << gID << std::endl; 70 if(gID!=GAMESTATEID_INITIAL){ 71 GameState *client = gameStateMap[gID]; 72 GameState *server = reference; 73 //head_->findClient(clientID)->setGamestateID(id); 74 return encode(client, server); 75 } else { 76 GameState *server = reference; 77 //head_->findClient(clientID)->setGamestateID(id); 78 return encode(server); 79 // return an undiffed gamestate and set appropriate flags 80 } 81 } 82 83 /** 84 * This function goes through the whole list of synchronisables and 85 * saves all the synchronisables to a flat "list". 86 * @return struct of type gamestate containing the size of the whole gamestate and a pointer linking to the flat list 87 */ 88 GameState *GameStateManager::getSnapshot(int id) 89 { 90 //the size of the gamestate 91 int totalsize=0; 92 int memsize=1000; 93 //the size of one specific synchronisable 94 int tempsize=0; 95 // get the start of the Synchronisable list 96 orxonox::Iterator<Synchronisable> it; 97 // struct for return value of Synchronisable::getData() 98 syncData sync; 99 100 GameState *retval=new GameState; //return value 101 retval->id=id++; 102 std::cout << "producing gamestate with id: " << retval->id << std::endl; 103 // reserve a little memory and increase it later on 104 //COUT(2) << "mallocing" << std::endl; 105 retval->data = (unsigned char*)malloc(memsize); 106 //COUT(2) << "malloced" << std::endl; 107 108 // offset of memory functions 109 int offset=0; 110 // go through all Synchronisables 111 for(it = orxonox::ObjectList<Synchronisable>::start(); it != 0; ++it){ 112 //std::cout << "gamestatemanager: in for loop" << std::endl; 113 //get size of the synchronisable 114 tempsize=it->getSize(); 115 //std::cout << "size of temp gamestate: " << tempsize << std::endl; 116 //COUT(2) << "size of synchronisable: " << tempsize << std::endl; 117 // add place for data and 3 ints (length,classid,objectid) 118 totalsize+=tempsize+3*sizeof(int); 119 //std::cout << "totalsize: " << totalsize << std::endl; 120 // allocate additional space 121 if(totalsize+tempsize>memsize){ 122 if(tempsize<1000){ 123 retval->data = (unsigned char *)realloc((void *)retval->data, totalsize+1000); 124 memsize+=1000; 125 } else { 126 retval->data = (unsigned char *)realloc((void *)retval->data, totalsize+1000); 127 memsize+=tempsize+1000; 128 } 129 } 130 131 // run Synchronisable::getData with offset and additional place for 3 ints in between (for ids and length) 132 sync=it->getData((retval->data)+offset+3*sizeof(int)); 133 *(retval->data+offset)=sync.length; 134 *(retval->data+offset+sizeof(int))=sync.objectID; 135 *(retval->data+offset+2*sizeof(int))=sync.classID; 136 // increase data pointer 137 offset+=tempsize+3*sizeof(int); 138 } 139 retval->size=totalsize; 140 return retval; 141 } 142 143 GameStateCompressed GameStateManager::encode(GameState *a, GameState *b) { 144 //GameState r = diff(a,b); 145 //r.diffed = true; 146 GameState r = *b; 147 r.diffed = false; 148 return compress_(&r); 149 } 150 151 GameStateCompressed GameStateManager::encode(GameState *a) { 152 a->diffed=false; 153 return compress_(a); 154 } 155 156 GameState GameStateManager::diff(GameState *a, GameState *b) { 157 unsigned char *ap = a->data, *bp = b->data; 158 int of=0; // pointers offset 159 int dest_length=0; 160 if(a->size>=b->size) 161 dest_length=a->size; 162 else 163 dest_length=b->size; 164 unsigned char *dp = (unsigned char *)malloc(dest_length*sizeof(unsigned char)); 165 while(of<a->size && of<b->size){ 166 *(dp+of)=*(ap+of)^*(bp+of); // do the xor 167 ++of; 168 } 169 if(a->size!=b->size){ // do we have to fill up ? 170 unsigned char n=0; 171 if(a->size<b->size){ 172 while(of<dest_length){ 173 *(dp+of)=n^*(bp+of); 174 of++; 175 } 176 } else{ 177 while(of<dest_length){ 178 *(dp+of)=*(ap+of)^n; 179 of++; 180 } 181 } 182 } 183 // should be finished now 184 GameState r = {b->id, dest_length, dp}; 185 return r; 186 } 187 188 GameStateCompressed GameStateManager::compress_(GameState *a) { 189 //COUT(2) << "compressing gamestate" << std::endl; 190 int size = a->size; 191 uLongf buffer = (uLongf)((a->size + 12)*1.01)+1; 192 unsigned char* dest = (unsigned char*)malloc( buffer ); 193 int retval; 194 //std::cout << "before ziped " << buffer << std::endl; 195 retval = compress( dest, &buffer, a->data, (uLong)size ); 196 //std::cout << "after ziped " << buffer << std::endl; 197 198 switch ( retval ) { 199 case Z_OK: std::cout << "successfully compressed" << std::endl; break; 200 case Z_MEM_ERROR: std::cout << "not enough memory available" << std::endl; break; 201 case Z_BUF_ERROR: std::cout << "not enough memory available in the buffer" << std::endl; break; 202 case Z_DATA_ERROR: std::cout << "decompress: data corrupted" << std::endl; break; 203 } 204 205 GameStateCompressed compressedGamestate; 206 compressedGamestate.compsize = buffer; 207 //std::cout << "compressedGamestate.compsize = buffer; " << buffer << std::endl; 208 compressedGamestate.normsize = size; 209 //std::cout << "compressedGamestate.normsize = size; " << size << std::endl; 210 compressedGamestate.id = a->id; 211 compressedGamestate.data = dest; 212 compressedGamestate.diffed = a->diffed; 213 214 return compressedGamestate; 215 } 216 217 void GameStateManager::ackGameState(int clientID, int gamestateID) { 218 ClientInformation *temp = head_->findClient(clientID); 219 int curid = temp->getID(); 220 // decrease usage of gamestate and save it 221 deleteUnusedGameState(curid); 222 //increase gamestateused 223 ++gameStateUsed.find(gamestateID)->second; 224 temp->setGamestateID(gamestateID); 225 /* 226 GameState *old = clientGameState[clientID]; 227 deleteUnusedGameState(old); 228 clientGameState[clientID]=idGameState[gamestateID];*/ 229 } 230 231 bool GameStateManager::deleteUnusedGameState(int gamestateID) { 232 int used = --(gameStateUsed.find(gamestateID)->second); 233 if(id-gamestateID>KEEP_GAMESTATES && used==0){ 234 // delete gamestate 235 delete gameStateMap.find(gamestateID)->second; 236 gameStateMap.erase(gamestateID); 237 return true; 238 } 239 return false; 240 } 241 47 242 } 48 49 GameStateManager::~GameStateManager()50 {51 }52 53 void GameStateManager::update(){54 reference = getSnapshot(id);55 gameStateMap.insert(std::pair<int, GameState*>(id, reference));56 gameStateUsed[id]=0;57 ++id;58 return;59 }60 61 GameStateCompressed GameStateManager::popGameState(int clientID){62 int gID = head_->findClient(clientID)->getGamestateID();63 std::cout << "popgamestate: sending gstate id: " << id << "diffed from: " << gID << std::endl;64 if(gID!=GAMESTATEID_INITIAL){65 GameState *client = gameStateMap[gID];66 GameState *server = reference;67 //head_->findClient(clientID)->setGamestateID(id);68 return encode(client, server);69 } else {70 GameState *server = reference;71 //head_->findClient(clientID)->setGamestateID(id);72 return encode(server);73 // return an undiffed gamestate and set appropriate flags74 }75 }76 77 78 79 /**80 * This function goes through the whole list of synchronisables and81 * saves all the synchronisables to a flat "list".82 * @return struct of type gamestate containing the size of the whole gamestate and a pointer linking to the flat list83 */84 GameState *GameStateManager::getSnapshot(int id)85 {86 //the size of the gamestate87 int totalsize=0;88 int memsize=1000;89 //the size of one specific synchronisable90 int tempsize=0;91 // get the start of the Synchronisable list92 orxonox::Iterator<Synchronisable> it;93 // struct for return value of Synchronisable::getData()94 syncData sync;95 96 GameState *retval=new GameState; //return value97 retval->id=id++;98 std::cout << "producing gamestate with id: " << retval->id << std::endl;99 // reserve a little memory and increase it later on100 //COUT(2) << "mallocing" << std::endl;101 retval->data = (unsigned char*)malloc(memsize);102 //COUT(2) << "malloced" << std::endl;103 104 // offset of memory functions105 int offset=0;106 // go through all Synchronisables107 for(it = orxonox::ObjectList<Synchronisable>::start(); it != 0; ++it){108 //std::cout << "gamestatemanager: in for loop" << std::endl;109 //get size of the synchronisable110 tempsize=it->getSize();111 //std::cout << "size of temp gamestate: " << tempsize << std::endl;112 //COUT(2) << "size of synchronisable: " << tempsize << std::endl;113 // add place for data and 3 ints (length,classid,objectid)114 totalsize+=tempsize+3*sizeof(int);115 //std::cout << "totalsize: " << totalsize << std::endl;116 // allocate additional space117 if(totalsize+tempsize>memsize){118 if(tempsize<1000){119 retval->data = (unsigned char *)realloc((void *)retval->data, totalsize+1000);120 memsize+=1000;121 } else {122 retval->data = (unsigned char *)realloc((void *)retval->data, totalsize+1000);123 memsize+=tempsize+1000;124 }125 }126 127 // run Synchronisable::getData with offset and additional place for 3 ints in between (for ids and length)128 sync=it->getData((retval->data)+offset+3*sizeof(int));129 *(retval->data+offset)=sync.length;130 *(retval->data+offset+sizeof(int))=sync.objectID;131 *(retval->data+offset+2*sizeof(int))=sync.classID;132 // increase data pointer133 offset+=tempsize+3*sizeof(int);134 }135 retval->size=totalsize;136 return retval;137 }138 139 140 141 GameStateCompressed GameStateManager::encode(GameState *a, GameState *b){142 //GameState r = diff(a,b);143 //r.diffed = true;144 GameState r = *b;145 r.diffed = false;146 return compress_(&r);147 }148 149 GameStateCompressed GameStateManager::encode(GameState *a){150 a->diffed=false;151 return compress_(a);152 }153 154 GameState GameStateManager::diff(GameState *a, GameState *b){155 unsigned char *ap = a->data, *bp = b->data;156 int of=0; // pointers offset157 int dest_length=0;158 if(a->size>=b->size)159 dest_length=a->size;160 else161 dest_length=b->size;162 unsigned char *dp = (unsigned char *)malloc(dest_length*sizeof(unsigned char));163 while(of<a->size && of<b->size){164 *(dp+of)=*(ap+of)^*(bp+of); // do the xor165 ++of;166 }167 if(a->size!=b->size){ // do we have to fill up ?168 unsigned char n=0;169 if(a->size<b->size){170 while(of<dest_length){171 *(dp+of)=n^*(bp+of);172 of++;173 }174 } else{175 while(of<dest_length){176 *(dp+of)=*(ap+of)^n;177 of++;178 }179 }180 }181 // should be finished now182 GameState r = {b->id, dest_length, dp};183 return r;184 }185 186 GameStateCompressed GameStateManager::compress_(GameState *a) {187 //COUT(2) << "compressing gamestate" << std::endl;188 int size = a->size;189 uLongf buffer = (uLongf)((a->size + 12)*1.01)+1;190 unsigned char* dest = (unsigned char*)malloc( buffer );191 int retval;192 //std::cout << "before ziped " << buffer << std::endl;193 retval = compress( dest, &buffer, a->data, (uLong)size );194 //std::cout << "after ziped " << buffer << std::endl;195 196 switch ( retval ) {197 case Z_OK: std::cout << "successfully compressed" << std::endl; break;198 case Z_MEM_ERROR: std::cout << "not enough memory available" << std::endl; break;199 case Z_BUF_ERROR: std::cout << "not enough memory available in the buffer" << std::endl; break;200 case Z_DATA_ERROR: std::cout << "decompress: data corrupted" << std::endl; break;201 }202 203 GameStateCompressed compressedGamestate;204 compressedGamestate.compsize = buffer;205 //std::cout << "compressedGamestate.compsize = buffer; " << buffer << std::endl;206 compressedGamestate.normsize = size;207 //std::cout << "compressedGamestate.normsize = size; " << size << std::endl;208 compressedGamestate.id = a->id;209 compressedGamestate.data = dest;210 compressedGamestate.diffed = a->diffed;211 212 return compressedGamestate;213 }214 215 void GameStateManager::ackGameState(int clientID, int gamestateID){216 ClientInformation *temp = head_->findClient(clientID);217 int curid = temp->getID();218 // decrease usage of gamestate and save it219 deleteUnusedGameState(curid);220 //increase gamestateused221 ++gameStateUsed.find(gamestateID)->second;222 temp->setGamestateID(gamestateID);223 /*224 GameState *old = clientGameState[clientID];225 deleteUnusedGameState(old);226 clientGameState[clientID]=idGameState[gamestateID];*/227 }228 229 bool GameStateManager::deleteUnusedGameState(int gamestateID){230 int used = --(gameStateUsed.find(gamestateID)->second);231 if(id-gamestateID>KEEP_GAMESTATES && used==0){232 // delete gamestate233 delete gameStateMap.find(gamestateID)->second;234 gameStateMap.erase(gamestateID);235 return true;236 }237 return false;238 }239 240 }241 242 -
code/branches/FICN/src/network/GameStateManager.h
r774 r777 15 15 #include <map> 16 16 17 #include "zlib.h" 18 19 #include "ClientInformation.h" 20 #include "Synchronisable.h" 21 #include "core/CoreIncludes.h" 22 #include "core/Iterator.h" 17 #include "NetworkPrereqs.h" 23 18 #include "PacketTypes.h" 24 19 25 namespace network { 20 namespace network 21 { 26 22 27 23 #define KEEP_GAMESTATES 20 28 24 29 /**30 * This Class implements a manager for gamestates:31 * - creating snapshots of gamestates32 * - writing gamestates to universe33 * - diffing gamestates ?34 *35 * EN/DECODATION:36 * a: last Gamestate a client has received37 * b: new Gamestate38 * x: diffed and compressed gamestate39 * x=(a^b)40 * b=(a^x)41 * diff(a,diff(a,x))=x (hope this is correct)42 * @author Oliver Scheuss43 */44 class GameStateManager{45 public:46 GameStateManager(ClientInformation *head);47 ~GameStateManager();48 void update();49 GameStateCompressed popGameState(int clientID);50 void ackGameState(int clientID, int gamestateID);51 int id;52 private:53 GameState *getSnapshot(int id);54 GameStateCompressed encode(GameState *a, GameState *b);55 GameStateCompressed encode(GameState *a);56 GameState diff(GameState *a, GameState *b);57 GameStateCompressed compress_(GameState *a);58 bool deleteUnusedGameState(int gamestateID);59 60 std::map<int, GameState*> gameStateMap; //map gsID to gamestate*61 std::map<int, int> gameStateUsed; // save the number of clients, that use the specific gamestate62 GameState *reference;63 ClientInformation *head_;64 };25 /** 26 * This Class implements a manager for gamestates: 27 * - creating snapshots of gamestates 28 * - writing gamestates to universe 29 * - diffing gamestates ? 30 * 31 * EN/DECODATION: 32 * a: last Gamestate a client has received 33 * b: new Gamestate 34 * x: diffed and compressed gamestate 35 * x=(a^b) 36 * b=(a^x) 37 * diff(a,diff(a,x))=x (hope this is correct) 38 * @author Oliver Scheuss 39 */ 40 class GameStateManager{ 41 public: 42 GameStateManager(ClientInformation *head); 43 ~GameStateManager(); 44 void update(); 45 GameStateCompressed popGameState(int clientID); 46 void ackGameState(int clientID, int gamestateID); 47 int id; 48 private: 49 GameState *getSnapshot(int id); 50 GameStateCompressed encode(GameState *a, GameState *b); 51 GameStateCompressed encode(GameState *a); 52 GameState diff(GameState *a, GameState *b); 53 GameStateCompressed compress_(GameState *a); 54 bool deleteUnusedGameState(int gamestateID); 55 56 std::map<int, GameState*> gameStateMap; //map gsID to gamestate* 57 std::map<int, int> gameStateUsed; // save the number of clients, that use the specific gamestate 58 GameState *reference; 59 ClientInformation *head_; 60 }; 65 61 66 62 } -
code/branches/FICN/src/network/NetworkFrameListener.h
r708 r777 16 16 #include <OgreFrameListener.h> 17 17 18 #include "NetworkPrereqs.h" 18 19 #include "Server.h" 19 20 #include "Client.h" 20 //#include <iostream> 21 // #include "orxonox/Orxonox.cc" 21 22 22 network::Server *server_g; 23 23 network::Client *client_g; 24 24 25 namespace network{ 25 namespace network 26 { 27 class ServerFrameListener : public Ogre::FrameListener{ 28 private: 29 bool frameStarted(const Ogre::FrameEvent &evt){ 30 server_g->tick(evt.timeSinceLastFrame); 31 return FrameListener::frameStarted(evt); 32 } 33 }; 26 34 27 28 class ServerFrameListener : public Ogre::FrameListener{ 29 private: 30 bool frameStarted(const Ogre::FrameEvent &evt){ 31 server_g->tick(evt.timeSinceLastFrame); 32 return FrameListener::frameStarted(evt); 33 } 34 }; 35 36 class ClientFrameListener : public Ogre::FrameListener{ 37 private: 38 bool frameStarted(const Ogre::FrameEvent &evt){ 39 //std::cout << "framelistener" << std::endl; 40 client_g->tick(evt.timeSinceLastFrame); 41 return FrameListener::frameStarted(evt); 42 } 43 }; 35 class ClientFrameListener : public Ogre::FrameListener{ 36 private: 37 bool frameStarted(const Ogre::FrameEvent &evt){ 38 //std::cout << "framelistener" << std::endl; 39 client_g->tick(evt.timeSinceLastFrame); 40 return FrameListener::frameStarted(evt); 41 } 42 }; 44 43 45 44 -
code/branches/FICN/src/network/PacketBuffer.cc
r632 r777 1 1 /* 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 2 * ORXONOX - the hottest 3D action shooter ever to exist 3 * 4 * 5 * License notice: 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * Author: 22 * Oliver Scheuss, (C) 2007 23 * Co-authors: 24 * ... 25 * 26 */ 27 27 28 28 // C++ PacketBuffer … … 30 30 // Author Oliver Scheuss 31 31 32 #ifndef NETWORK_PACKETBUFFER_CC 33 #define NETWORK_PACKETBUFFER_CC 32 #include <iostream> 33 #include <queue> 34 #include <string> 35 #include <boost/bind.hpp> 36 #include <boost/thread/mutex.hpp> 34 37 35 #include <iostream>36 38 #include "PacketBuffer.h" 37 39 38 namespace network{ 40 namespace network 41 { 42 boost::mutex networkPacketBufferMutex; 39 43 40 boost::mutex networkPacketBufferMutex; 41 42 PacketBuffer::PacketBuffer(){ 43 closed=false; 44 first=NULL; 45 last=NULL; 46 } 47 //this is needed in order to make the packetbuffer threadsafe 44 PacketBuffer::PacketBuffer() { 45 closed=false; 46 first=NULL; 47 last=NULL; 48 } 49 //this is needed in order to make the packetbuffer threadsafe 48 50 49 51 50 bool PacketBuffer::push(ENetEvent *ev){51 boost::mutex::scoped_lock lock(networkPacketBufferMutex);52 //std::cout << "event size inside packetbuffer " << ev->packet->dataLength << std::endl;53 // if(closed)54 // return false;55 // first element?56 if(first==NULL){57 first=new QueueItem;58 last=first;59 last->next=NULL;60 // change this!!!!!!!61 last->packet = ev->packet;62 last->address = ev->peer->address;52 bool PacketBuffer::push(ENetEvent *ev) { 53 boost::mutex::scoped_lock lock(networkPacketBufferMutex); 54 //std::cout << "event size inside packetbuffer " << ev->packet->dataLength << std::endl; 55 // if(closed) 56 // return false; 57 // first element? 58 if(first==NULL){ 59 first=new QueueItem; 60 last=first; 61 last->next=NULL; 62 // change this!!!!!!! 63 last->packet = ev->packet; 64 last->address = ev->peer->address; 63 65 } else { 64 //insert a new element at the bottom 65 last->next = new QueueItem; 66 last=last->next; 67 // initialize last->next 68 last->next=NULL; 69 // save the packet to the new element 70 last->packet = ev->packet; 71 last->address = ev->peer->address; 72 } 73 return true; 74 } 75 76 ENetPacket *PacketBuffer::pop(){ 77 boost::mutex::scoped_lock lock(networkPacketBufferMutex); 78 //std::cout << "packetbuffer pop" << std::endl; 79 if(first!=NULL /*&& !closed*/){ 80 QueueItem *temp = first; 81 // get packet 82 ENetPacket *pck=first->packet; 83 // remove first element 84 first = first->next; 85 delete temp; 86 //std::cout << "pop size of packet " << pck->dataLength << std::endl; 87 return pck; 88 } else{ 89 //std::cout << "nothing to return" << std::endl; 90 return NULL; 91 } 92 } 93 94 ENetPacket *PacketBuffer::pop(ENetAddress &address){ 95 boost::mutex::scoped_lock lock(networkPacketBufferMutex); 96 //std::cout << "packetbuffer pop(address)" << std::endl; 97 if(first!=NULL /*&& !closed*/){ 98 QueueItem *temp = first; 99 // get packet 100 ENetPacket *pck=first->packet; 101 address = first->address; 102 // remove first element 103 first = first->next; 104 delete temp; 105 //std::cout << "pop(address) size of packet " << pck->dataLength << std::endl; 106 return pck; 107 } else{ 108 return NULL; 109 } 110 } 111 112 bool PacketBuffer::isEmpty(){ 113 return (first==NULL); 114 } 115 116 void PacketBuffer::print(){ 117 QueueItem *temp=first; 118 while(temp!=NULL){ 119 // std::cout << temp->packet->data << std::endl; 120 temp=temp->next; 66 //insert a new element at the bottom 67 last->next = new QueueItem; 68 last=last->next; 69 // initialize last->next 70 last->next=NULL; 71 // save the packet to the new element 72 last->packet = ev->packet; 73 last->address = ev->peer->address; 74 } 75 return true; 121 76 } 122 77 123 } 78 ENetPacket *PacketBuffer::pop() { 79 boost::mutex::scoped_lock lock(networkPacketBufferMutex); 80 //std::cout << "packetbuffer pop" << std::endl; 81 if(first!=NULL /*&& !closed*/){ 82 QueueItem *temp = first; 83 // get packet 84 ENetPacket *pck=first->packet; 85 // remove first element 86 first = first->next; 87 delete temp; 88 //std::cout << "pop size of packet " << pck->dataLength << std::endl; 89 return pck; 90 } else{ 91 //std::cout << "nothing to return" << std::endl; 92 return NULL; 93 } 94 } 124 95 125 bool PacketBuffer::isClosed(){ 126 return closed; 127 } 96 ENetPacket *PacketBuffer::pop(ENetAddress &address) { 97 boost::mutex::scoped_lock lock(networkPacketBufferMutex); 98 //std::cout << "packetbuffer pop(address)" << std::endl; 99 if(first!=NULL /*&& !closed*/){ 100 QueueItem *temp = first; 101 // get packet 102 ENetPacket *pck=first->packet; 103 address = first->address; 104 // remove first element 105 first = first->next; 106 delete temp; 107 //std::cout << "pop(address) size of packet " << pck->dataLength << std::endl; 108 return pck; 109 } else{ 110 return NULL; 111 } 112 } 128 113 129 void PacketBuffer::setClosed(bool value){ 130 closed=value; 131 return; 132 } 114 bool PacketBuffer::isEmpty() { 115 return (first==NULL); 116 } 133 117 134 }// namespace network 118 void PacketBuffer::print() { 119 QueueItem *temp=first; 120 while(temp!=NULL){ 121 // std::cout << temp->packet->data << std::endl; 122 temp=temp->next; 123 } 135 124 136 #endif 125 } 126 127 bool PacketBuffer::isClosed() { 128 return closed; 129 } 130 131 void PacketBuffer::setClosed(bool value){ 132 closed=value; 133 return; 134 } 135 136 } // namespace network -
code/branches/FICN/src/network/PacketBuffer.h
r673 r777 14 14 #define _PacketBuffer_H__ 15 15 16 #include <queue>17 #include <string>18 16 #include <enet/enet.h> 19 #include <boost/bind.hpp>20 #include <boost/thread/mutex.hpp>21 17 18 #include "NetworkPrereqs.h" 22 19 23 namespace network{ 20 namespace network 21 { 22 struct PacketEnvelope{ 23 int length; 24 int data; 25 }; 24 26 27 struct QueueItem{ 28 ENetPacket *packet; 29 ENetAddress address; 30 QueueItem *next; 31 }; 25 32 26 struct PacketEnvelope{ 27 int length; 28 int data; 29 }; 33 class PacketBuffer{ 34 public: 35 PacketBuffer(); 36 bool isEmpty(); 37 bool isClosed(); 38 void setClosed(bool value); 39 void print(); 40 // pops a packet from the queue 41 ENetPacket *pop(); 42 ENetPacket *pop(ENetAddress &address); 43 // pushs a packet to the queue 44 bool push(ENetEvent *ev); 30 45 31 struct QueueItem{ 32 ENetPacket *packet; 33 ENetAddress address; 34 QueueItem *next; 35 }; 46 private: 47 QueueItem *first; 48 QueueItem *last; 49 bool closed; 36 50 37 class PacketBuffer{ 38 public: 39 PacketBuffer(); 40 bool isEmpty(); 41 bool isClosed(); 42 void setClosed(bool value); 43 void print(); 44 // pops a packet from the queue 45 ENetPacket *pop(); 46 ENetPacket *pop(ENetAddress &address); 47 // pushs a packet to the queue 48 bool push(ENetEvent *ev); 49 50 private: 51 QueueItem *first; 52 QueueItem *last; 53 bool closed; 54 55 }; 51 }; 56 52 57 53 } //namespace -
code/branches/FICN/src/network/PacketBufferTestExt.cc
r514 r777 1 1 /* 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 2 * ORXONOX - the hottest 3D action shooter ever to exist 3 * 4 * 5 * License notice: 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * Author: 22 * ... 23 * Co-authors: 24 * ... 25 * 26 */ 27 27 28 28 #include <string> … … 30 30 #include <enet/enet.h> 31 31 #include <boost/thread/thread.hpp> 32 33 #include "util/Sleep.h" 32 34 #include "PacketBuffer.h" 33 35 #include "PacketBuffer.cc" 34 36 35 #ifdef WIN3236 #include <windows.h>37 #define usleep(x) Sleep((x)/1000)38 #else39 #include <unistd.h>40 #endif41 42 37 using namespace network; 43 44 38 45 39 void write(PacketBuffer *test){ … … 51 45 std::string temp = "packet "; 52 46 packet = enet_packet_create("packet", strlen("packet ")+1, 53 ENET_PACKET_FLAG_RELIABLE);47 ENET_PACKET_FLAG_RELIABLE); 54 48 std::cout << i << ": pushing " << packet->data << std::endl; 55 49 event.packet=packet; -
code/branches/FICN/src/network/PacketDecoder.cc
r636 r777 1 1 /* 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 2 * ORXONOX - the hottest 3D action shooter ever to exist 3 * 4 * 5 * License notice: 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * Author: 22 * Dumeni Manatschal, (C) 2007 23 * Co-authors: 24 * ... 25 * 26 */ 27 27 28 28 /* 29 30 31 32 33 29 * Class contains functions to determine and decode incomming packages 30 * ->don't read this without the class PacketGenerator, since they belong together 31 * 32 * Autor: Dumeni Manatschal 33 * 34 34 */ 35 35 36 #include <enet/enet.h> 36 #include <iostream> 37 38 #include "PacketTypes.h" 37 39 #include "PacketManager.h" 38 #include <iostream> 39 40 using namespace std; 41 using namespace network; 42 43 PacketDecoder::PacketDecoder(){} 44 45 PacketDecoder::~PacketDecoder(){} 46 47 //call this function out of an instance of PacketDecoder 48 //it will determine the type id and call the right decode function 49 bool PacketDecoder::elaborate( ENetPacket* packet, int clientId ) 40 41 namespace network 50 42 { 51 int client = clientId; 52 cout << "clientId: " << client << endl; //control cout, not important, just debugging info 53 int id = (int)*packet->data; //the first 4 bytes are always the enet packet id 54 std::cout << "packet id: " << id << std::endl; 55 std::cout << "packet size inside packetdecoder: " << packet->dataLength << std::endl; 56 switch( id ) { 57 case ACK: 58 acknowledgement( packet, clientId ); 59 return true; 60 break; 61 case MOUSE: 62 mousem( packet, clientId ); 63 return true; 64 break; 65 case KEYBOARD: 66 keystrike( packet, clientId ); 67 return true; 68 break; 69 case CHAT: 70 chatMessage( packet, clientId ); 71 return true; 72 break; 73 case GAMESTATE: 74 gstate( packet ); 75 return true; 76 break; 77 case CLASSID: 78 clid(packet); 79 return true; 80 break; 81 } 82 return false; 43 using namespace std; 44 45 PacketDecoder::PacketDecoder(){} 46 47 PacketDecoder::~PacketDecoder(){} 48 49 //call this function out of an instance of PacketDecoder 50 //it will determine the type id and call the right decode function 51 bool PacketDecoder::elaborate( ENetPacket* packet, int clientId ) 52 { 53 int client = clientId; 54 cout << "clientId: " << client << endl; //control cout, not important, just debugging info 55 int id = (int)*packet->data; //the first 4 bytes are always the enet packet id 56 std::cout << "packet id: " << id << std::endl; 57 std::cout << "packet size inside packetdecoder: " << packet->dataLength << std::endl; 58 switch( id ) { 59 case ACK: 60 acknowledgement( packet, clientId ); 61 return true; 62 break; 63 case MOUSE: 64 mousem( packet, clientId ); 65 return true; 66 break; 67 case KEYBOARD: 68 keystrike( packet, clientId ); 69 return true; 70 break; 71 case CHAT: 72 chatMessage( packet, clientId ); 73 return true; 74 break; 75 case GAMESTATE: 76 gstate( packet ); 77 return true; 78 break; 79 case CLASSID: 80 clid(packet); 81 return true; 82 break; 83 } 84 return false; 85 } 86 87 //following are the decode functions for the data of the packets 88 89 void PacketDecoder::acknowledgement( ENetPacket* packet, int clientId ) 90 { 91 ack* a = new ack; 92 *a = *(ack*)packet->data; //press pattern of ack on new data 93 94 95 std::cout << "got ack id: " << a->id << std::endl; 96 processAck( a, clientId ); //debug info 97 98 //clean memory 99 enet_packet_destroy( packet ); 100 } 101 102 void PacketDecoder::mousem( ENetPacket* packet, int clientId ) 103 { 104 mouse* mouseMove = new mouse; 105 //copy data of packet->data to new struct 106 *mouseMove = *(mouse*)packet->data; 107 108 //clean memory 109 enet_packet_destroy( packet ); 110 111 printMouse( mouseMove ); //debug info 112 } 113 114 void PacketDecoder::keystrike( ENetPacket* packet, int clientId ) 115 { 116 keyboard* key = new keyboard; 117 *key = *(keyboard*)packet->data; //see above 118 119 //clean memory 120 enet_packet_destroy( packet ); 121 122 printKey( key ); //debug info 123 124 } 125 126 void PacketDecoder::chatMessage( ENetPacket* packet, int clientId ) 127 { 128 chat* chatting = new chat; 129 chatting->id = (int)*packet->data; //first copy id into new struct 130 //since the chat message is a char*, allocate the memory needed 131 char* reserve = new char[packet->dataLength-4]; 132 //copy the transmitted bytestream into the new generated char*, 133 //note the lenght of the message is represented as "packet->dataLength-sizeof( int )" 134 memcpy( &reserve[0], packet->data+sizeof(int), packet->dataLength-sizeof(int) ); 135 //put pointer of chatting struct to the begining of the new generated char* 136 chatting->message = reserve; 137 138 //clean memory 139 enet_packet_destroy( packet ); 140 141 processChat( chatting, clientId ); //debug info 142 } 143 144 void PacketDecoder::gstate( ENetPacket* packet ) 145 { 146 GameStateCompressed* currentState = new GameStateCompressed; 147 //since it's not alowed to use void* for pointer arithmetic 148 unsigned char* data = (unsigned char*)packet->data; 149 //copy the GameStateCompressed id into the struct, which is located at second place data+sizeof( int ) 150 //memcpy( (void*)&(currentState->id), (const void*)(data+sizeof( int )), sizeof( int ) ); 151 currentState->id = (int)*(data+sizeof(int)); 152 std::cout << "id: " << currentState->id << std::endl; 153 //copy the size of the GameStateCompressed compressed data into the new GameStateCompressed struct, located at 3th 154 //position of the data stream, data+2*sizeof( int ) 155 memcpy( (void*)&(currentState->compsize), (const void*)(data+2*sizeof( int )), sizeof( int) ); 156 //currentState->compsize = (int)*(data+2*sizeof(int)); 157 std::cout << "compsize: " << currentState->compsize << std::endl; 158 //size of uncompressed data 159 memcpy( (void*)&(currentState->normsize), (const void*)(data+3*sizeof( int )), sizeof( int ) ); 160 //currentState->normsize = (int)*(data+3*sizeof(int)); 161 std::cout << "normsize. " << currentState->normsize << std::endl; 162 //since the packetgenerator was changed, due to a new parameter, change this function too 163 memcpy( (void*)&(currentState->diffed), (const void*)(data+4*sizeof(int)), sizeof(bool)); 164 //currentState->diffed = (bool)*(data+4*sizeof(int)); 165 std::cout << "diffed: " << currentState->diffed << std::endl; 166 //since data is not allocated, because it's just a pointer, allocate it with size of gamestatedatastream 167 currentState->data = (unsigned char*)(malloc( currentState->compsize )); 168 if(currentState->data==NULL) 169 std::cout << "memory leak" << std::endl; 170 //copy the GameStateCompressed data 171 //std::cout << "packet size (enet): " << packet->dataLength << std::endl; 172 //std::cout << "totallen: " << 4*sizeof(int)+sizeof(bool)+currentState->compsize << std::endl; 173 memcpy( (void*)(currentState->data), (const void*)(data+4*sizeof( int ) + sizeof(bool)), currentState->compsize ); 174 175 //clean memory 176 enet_packet_destroy( packet ); 177 //run processGameStateCompressed 178 //TODO: not yet implemented! 179 processGamestate(currentState); 180 } 181 182 void PacketDecoder::clid( ENetPacket *packet) 183 { 184 classid* cid = new classid; 185 cid->length = ((classid*)(packet->data))->length; 186 cid->id = ((classid *)(packet->data))->id; 187 cid->clid = ((classid *)(packet->data))->clid; 188 cid->message = (const char *)malloc(cid->length); 189 void *data = (void *)cid->message; 190 memcpy(data, (const void*)(packet->data+3*sizeof(int)), cid->length); 191 std::cout << "classid: " << cid->clid << ", name: " << cid->message << std::endl; 192 enet_packet_destroy( packet ); 193 processClassid(cid); 194 } 195 196 197 // now the data processing functions: 198 199 void PacketDecoder::processChat( chat *data, int clientId) 200 { 201 printChat(data, clientId); 202 } 203 204 void PacketDecoder::processGamestate( GameStateCompressed *state ) 205 { 206 } 207 208 void PacketDecoder::processClassid( classid *cid) 209 { 210 printClassid(cid); 211 return; 212 } 213 214 void PacketDecoder::processAck( ack *data, int clientID) 215 { 216 printAck(data); 217 return; 218 } 219 220 221 //these are some print functions for test stuff 222 223 void PacketDecoder::printAck( ack* data ) 224 { 225 cout << "data id: " << data->id << endl; 226 cout << "data: " << data->a << endl; 227 } 228 229 void PacketDecoder::printMouse( mouse* data ) 230 { 231 cout << "data id: " << data->id << endl; 232 cout << "data: " << data->x << " " << data->y << endl; 233 } 234 235 void PacketDecoder::printKey( keyboard* data ) 236 { 237 cout << "data id: " << data->id << endl; 238 cout << "data: " << (char)data->press << endl; 239 } 240 241 void PacketDecoder::printChat( chat* data, int clientId ) 242 { 243 if(clientId!=CLIENTID_CLIENT) 244 cout << "client: " << clientId << endl; 245 cout << "data id: " << data->id << endl; 246 cout << "data: " << data->message << endl; 247 } 248 249 void PacketDecoder::printGamestate( GameStateCompressed* data ) 250 { 251 cout << "id of GameStateCompressed: " << data->id << endl; 252 cout << "size of GameStateCompressed: " << data->compsize << endl; 253 } 254 255 void PacketDecoder::printClassid( classid *cid) 256 { 257 cout << "id of classid: " << cid->id << endl; 258 cout << "size of classid: " << cid->length << endl; 259 cout << "ID of classid: " << cid->clid <<endl; 260 cout << "data of classid: " << cid->message <<endl; 261 } 262 83 263 } 84 85 //following are the decode functions for the data of the packets86 87 void PacketDecoder::acknowledgement( ENetPacket* packet, int clientId )88 {89 ack* a = new ack;90 *a = *(ack*)packet->data; //press pattern of ack on new data91 92 93 std::cout << "got ack id: " << a->id << std::endl;94 processAck( a, clientId ); //debug info95 96 //clean memory97 enet_packet_destroy( packet );98 }99 100 void PacketDecoder::mousem( ENetPacket* packet, int clientId )101 {102 mouse* mouseMove = new mouse;103 //copy data of packet->data to new struct104 *mouseMove = *(mouse*)packet->data;105 106 //clean memory107 enet_packet_destroy( packet );108 109 printMouse( mouseMove ); //debug info110 }111 112 void PacketDecoder::keystrike( ENetPacket* packet, int clientId )113 {114 keyboard* key = new keyboard;115 *key = *(keyboard*)packet->data; //see above116 117 //clean memory118 enet_packet_destroy( packet );119 120 printKey( key ); //debug info121 122 }123 124 void PacketDecoder::chatMessage( ENetPacket* packet, int clientId )125 {126 chat* chatting = new chat;127 chatting->id = (int)*packet->data; //first copy id into new struct128 //since the chat message is a char*, allocate the memory needed129 char* reserve = new char[packet->dataLength-4];130 //copy the transmitted bytestream into the new generated char*,131 //note the lenght of the message is represented as "packet->dataLength-sizeof( int )"132 memcpy( &reserve[0], packet->data+sizeof(int), packet->dataLength-sizeof(int) );133 //put pointer of chatting struct to the begining of the new generated char*134 chatting->message = reserve;135 136 //clean memory137 enet_packet_destroy( packet );138 139 processChat( chatting, clientId ); //debug info140 141 }142 143 void PacketDecoder::gstate( ENetPacket* packet )144 {145 GameStateCompressed* currentState = new GameStateCompressed;146 //since it's not alowed to use void* for pointer arithmetic147 unsigned char* data = (unsigned char*)packet->data;148 //copy the GameStateCompressed id into the struct, which is located at second place data+sizeof( int )149 //memcpy( (void*)&(currentState->id), (const void*)(data+sizeof( int )), sizeof( int ) );150 currentState->id = (int)*(data+sizeof(int));151 std::cout << "id: " << currentState->id << std::endl;152 //copy the size of the GameStateCompressed compressed data into the new GameStateCompressed struct, located at 3th153 //position of the data stream, data+2*sizeof( int )154 memcpy( (void*)&(currentState->compsize), (const void*)(data+2*sizeof( int )), sizeof( int) );155 //currentState->compsize = (int)*(data+2*sizeof(int));156 std::cout << "compsize: " << currentState->compsize << std::endl;157 //size of uncompressed data158 memcpy( (void*)&(currentState->normsize), (const void*)(data+3*sizeof( int )), sizeof( int ) );159 //currentState->normsize = (int)*(data+3*sizeof(int));160 std::cout << "normsize. " << currentState->normsize << std::endl;161 //since the packetgenerator was changed, due to a new parameter, change this function too162 memcpy( (void*)&(currentState->diffed), (const void*)(data+4*sizeof(int)), sizeof(bool));163 //currentState->diffed = (bool)*(data+4*sizeof(int));164 std::cout << "diffed: " << currentState->diffed << std::endl;165 //since data is not allocated, because it's just a pointer, allocate it with size of gamestatedatastream166 currentState->data = (unsigned char*)(malloc( currentState->compsize ));167 if(currentState->data==NULL)168 std::cout << "memory leak" << std::endl;169 //copy the GameStateCompressed data170 //std::cout << "packet size (enet): " << packet->dataLength << std::endl;171 //std::cout << "totallen: " << 4*sizeof(int)+sizeof(bool)+currentState->compsize << std::endl;172 memcpy( (void*)(currentState->data), (const void*)(data+4*sizeof( int ) + sizeof(bool)), currentState->compsize );173 174 //clean memory175 enet_packet_destroy( packet );176 //run processGameStateCompressed177 //TODO: not yet implemented!178 processGamestate(currentState);179 }180 181 void PacketDecoder::clid( ENetPacket *packet)182 {183 classid* cid = new classid;184 cid->length = ((classid*)(packet->data))->length;185 cid->id = ((classid *)(packet->data))->id;186 cid->clid = ((classid *)(packet->data))->clid;187 cid->message = (const char *)malloc(cid->length);188 void *data = (void *)cid->message;189 memcpy(data, (const void*)(packet->data+3*sizeof(int)), cid->length);190 std::cout << "classid: " << cid->clid << ", name: " << cid->message << std::endl;191 enet_packet_destroy( packet );192 processClassid(cid);193 }194 195 196 // now the data processing functions:197 198 void PacketDecoder::processChat( chat *data, int clientId){199 printChat(data, clientId);200 }201 202 void PacketDecoder::processGamestate( GameStateCompressed *state ){203 204 }205 206 void PacketDecoder::processClassid( classid *cid){207 printClassid(cid);208 return;209 }210 211 void PacketDecoder::processAck( ack *data, int clientID){212 printAck(data);213 return;214 }215 216 217 //these are some print functions for test stuff218 219 void PacketDecoder::printAck( ack* data )220 {221 cout << "data id: " << data->id << endl;222 cout << "data: " << data->a << endl;223 }224 225 void PacketDecoder::printMouse( mouse* data )226 {227 cout << "data id: " << data->id << endl;228 cout << "data: " << data->x << " " << data->y << endl;229 }230 231 void PacketDecoder::printKey( keyboard* data )232 {233 cout << "data id: " << data->id << endl;234 cout << "data: " << (char)data->press << endl;235 }236 237 void PacketDecoder::printChat( chat* data, int clientId )238 {239 if(clientId!=CLIENTID_CLIENT)240 cout << "client: " << clientId << endl;241 cout << "data id: " << data->id << endl;242 cout << "data: " << data->message << endl;243 }244 245 void PacketDecoder::printGamestate( GameStateCompressed* data )246 {247 cout << "id of GameStateCompressed: " << data->id << endl;248 cout << "size of GameStateCompressed: " << data->compsize << endl;249 }250 251 void PacketDecoder::printClassid( classid *cid)252 {253 cout << "id of classid: " << cid->id << endl;254 cout << "size of classid: " << cid->length << endl;255 cout << "ID of classid: " << cid->clid <<endl;256 cout << "data of classid: " << cid->message <<endl;257 } -
code/branches/FICN/src/network/PacketGenerator.cc
r636 r777 1 1 /* 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 2 * ORXONOX - the hottest 3D action shooter ever to exist 3 * 4 * 5 * License notice: 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * Author: 22 * Dumeni Manatschal, (C) 2007 23 * Co-authors: 24 * ... 25 * 26 */ 27 27 28 28 /* 29 *Class generates packets that can be send by enet30 31 32 33 29 * Class generates packets that can be send by enet 30 * ->don't read this without the class PacketDecoder, since they belong together 31 * 32 * Autor: Dumeni Manatschal 33 * 34 34 */ 35 35 36 #include "PacketManager.h"37 #include <enet/enet.h>38 36 #include <iostream> 39 37 #include <list> … … 41 39 #include <cstring> 42 40 43 using namespace network; 41 #include "PacketTypes.h" 42 #include "PacketManager.h" 44 43 45 PacketGenerator::PacketGenerator() {} 44 namespace network 45 { 46 PacketGenerator::PacketGenerator() { } 46 47 47 //following functions create a packet in form of bytestream48 //following functions create a packet in form of bytestream 48 49 49 ENetPacket* PacketGenerator::acknowledgement( int state, int reliable )50 {50 ENetPacket* PacketGenerator::acknowledgement( int state, int reliable ) 51 { 51 52 std::cout << "generating new acknowledgement, id: " << state << std::endl; 52 53 54 53 ack* ackreq = new ack; 54 ackreq->id = ACK; 55 ackreq->a = state; 55 56 56 57 ENetPacket *packet = enet_packet_create( ackreq , sizeof( *ackreq ), reliable ); 57 58 58 return packet; 59 return packet; 60 } 61 62 /*### mouseupdates */ 63 ENetPacket* PacketGenerator::mousem( double x, double y, int reliable ) 64 { 65 std::cout << "generating new mouse" << std::endl; 66 mouse* mousemove = new mouse; 67 mousemove->id = MOUSE; 68 mousemove->x = x; 69 mousemove->y = y; 70 71 ENetPacket *packet = enet_packet_create( mousemove , sizeof( *mousemove ), reliable ); 72 73 return packet; 74 } 75 76 /*### keystrikes updates */ 77 ENetPacket* PacketGenerator::keystrike( char press, int reliable ) 78 { 79 std::cout << "generating new keyboard" << std::endl; 80 keyboard* key = new keyboard; 81 key->id = KEYBOARD; 82 key->press = press; 83 84 ENetPacket *packet = enet_packet_create( key , sizeof( *key ), reliable ); 85 86 return packet; 87 } 88 89 /*### chat messages packet */ 90 ENetPacket* PacketGenerator::chatMessage( const char* message, int reliable ) 91 { 92 int* trans = new int[sizeof(int) + strlen(message) + 1]; 93 *trans = CHAT; 94 //be carefull here, don't forget to allocate the space before using it ;-) 95 memcpy( &trans[1], (const void*)message, strlen( message ) + 1); 96 ENetPacket *packet = enet_packet_create( trans , sizeof( int ) + strlen( message ) + 1, reliable ); 97 98 return packet; 99 } 100 101 /*### gamestate packet */ 102 ENetPacket* PacketGenerator::gstate( GameStateCompressed* states, int reliable ) 103 { 104 //std::cout << "packetgenerator" << std::endl; 105 //std::cout << "states->normsize " << states->normsize << std::endl; 106 //std::cout << "states->compsize " << states->compsize << std::endl; 107 int gid = GAMESTATE; //first assign the correct enet id 108 int totalLen = 4*sizeof( int ) + sizeof(bool) + states->compsize; //calculate the total size of the datastream memory 109 //std::cout << "totalLen " << totalLen << std::endl; 110 unsigned char *data = (unsigned char*)malloc( totalLen ); //allocate the memory for datastream 111 memcpy( (void*)(data), (const void*)&gid, sizeof( int ) ); //this is the enet id 112 memcpy( (void*)(data+sizeof(int)), (const void*)&(states->id), sizeof(int) ); //the GameStateCompressed id 113 memcpy( (void*)(data+2*sizeof(int)), (const void*)&(states->compsize), sizeof(int)); 114 memcpy( (void*)(data+3*sizeof(int)), (const void*)&(states->normsize), sizeof(int)); 115 memcpy( (void*)(data+4*sizeof(int)), (const void*)&(states->diffed), sizeof(bool)); 116 /*(int)*(data) = gid; 117 (int)*(data+sizeof(int)) = states->id; 118 //this is the compressed size of the GameStateCompressed data, place at 3th position of the enet datastream 119 (int)*(data+2*sizeof(int)) = states->compsize; 120 //this is the uncompressed size of GameStateCompressed data 121 (int)*(data+3*sizeof(int)) = states->normsize; 122 //since there is a new parameter inside GameStateCompressed, change this function to create packet 123 (bool)*(data+4*sizeof(int)) = states->diffed;*/ 124 //place the GameStateCompressed data at the end of the enet datastream 125 memcpy( (void*)(data+4*sizeof( int ) + sizeof(bool)), (const void*)states->data, states->compsize ); 126 //create an enet packet with the generated bytestream 127 ENetPacket *packet = enet_packet_create( data , totalLen, reliable ); 128 //delete data; 129 return packet; 130 } 131 132 ENetPacket* PacketGenerator::clid( int classid, std::string classname, int reliable ) 133 { 134 unsigned char* data = (unsigned char *)malloc(3*sizeof(int)+classname.length()+1); 135 std::cout << "classid: " << classid << ", name: " << classname << std::endl; 136 *(int *)data = CLASSID; 137 *((int *)data+1) = classname.length()+1; 138 *((int *)data+2) = classid; 139 memcpy( (void *)(data+3*sizeof(int)), classname.c_str(), classname.length()+1); 140 ENetPacket *packet = enet_packet_create( data , 3*sizeof(int)+classname.length()+1, reliable ); 141 return packet; 142 } 143 59 144 } 60 /*### mouseupdates */61 ENetPacket* PacketGenerator::mousem( double x, double y, int reliable )62 {63 std::cout << "generating new mouse" << std::endl;64 mouse* mousemove = new mouse;65 mousemove->id = MOUSE;66 mousemove->x = x;67 mousemove->y = y;68 69 ENetPacket *packet = enet_packet_create( mousemove , sizeof( *mousemove ), reliable );70 71 return packet;72 }73 /*### keystrikes updates */74 ENetPacket* PacketGenerator::keystrike( char press, int reliable )75 {76 std::cout << "generating new keyboard" << std::endl;77 keyboard* key = new keyboard;78 key->id = KEYBOARD;79 key->press = press;80 81 ENetPacket *packet = enet_packet_create( key , sizeof( *key ), reliable );82 83 return packet;84 }85 /*### chat messages packet */86 ENetPacket* PacketGenerator::chatMessage( const char* message, int reliable )87 {88 int* trans = new int[sizeof(int) + strlen(message) + 1];89 *trans = CHAT;90 //be carefull here, don't forget to allocate the space before using it ;-)91 memcpy( &trans[1], (const void*)message, strlen( message ) + 1);92 ENetPacket *packet = enet_packet_create( trans , sizeof( int ) + strlen( message ) + 1, reliable );93 94 return packet;95 }96 97 /*### gamestate packet */98 ENetPacket* PacketGenerator::gstate( GameStateCompressed* states, int reliable )99 {100 //std::cout << "packetgenerator" << std::endl;101 //std::cout << "states->normsize " << states->normsize << std::endl;102 //std::cout << "states->compsize " << states->compsize << std::endl;103 int gid = GAMESTATE; //first assign the correct enet id104 int totalLen = 4*sizeof( int ) + sizeof(bool) + states->compsize; //calculate the total size of the datastream memory105 //std::cout << "totalLen " << totalLen << std::endl;106 unsigned char *data = (unsigned char*)malloc( totalLen ); //allocate the memory for datastream107 memcpy( (void*)(data), (const void*)&gid, sizeof( int ) ); //this is the enet id108 memcpy( (void*)(data+sizeof(int)), (const void*)&(states->id), sizeof(int) ); //the GameStateCompressed id109 memcpy( (void*)(data+2*sizeof(int)), (const void*)&(states->compsize), sizeof(int));110 memcpy( (void*)(data+3*sizeof(int)), (const void*)&(states->normsize), sizeof(int));111 memcpy( (void*)(data+4*sizeof(int)), (const void*)&(states->diffed), sizeof(bool));112 /*(int)*(data) = gid;113 (int)*(data+sizeof(int)) = states->id;114 //this is the compressed size of the GameStateCompressed data, place at 3th position of the enet datastream115 (int)*(data+2*sizeof(int)) = states->compsize;116 //this is the uncompressed size of GameStateCompressed data117 (int)*(data+3*sizeof(int)) = states->normsize;118 //since there is a new parameter inside GameStateCompressed, change this function to create packet119 (bool)*(data+4*sizeof(int)) = states->diffed;*/120 //place the GameStateCompressed data at the end of the enet datastream121 memcpy( (void*)(data+4*sizeof( int ) + sizeof(bool)), (const void*)states->data, states->compsize );122 //create an enet packet with the generated bytestream123 ENetPacket *packet = enet_packet_create( data , totalLen, reliable );124 //delete data;125 return packet;126 }127 128 ENetPacket* PacketGenerator::clid( int classid, std::string classname, int reliable ){129 unsigned char* data = (unsigned char *)malloc(3*sizeof(int)+classname.length()+1);130 std::cout << "classid: " << classid << ", name: " << classname << std::endl;131 *(int *)data = CLASSID;132 *((int *)data+1) = classname.length()+1;133 *((int *)data+2) = classid;134 memcpy( (void *)(data+3*sizeof(int)), classname.c_str(), classname.length()+1);135 ENetPacket *packet = enet_packet_create( data , 3*sizeof(int)+classname.length()+1, reliable );136 return packet;137 }138 139 -
code/branches/FICN/src/network/PacketManager.h
r673 r777 4 4 #include <string> 5 5 #include <enet/enet.h> 6 #include "PacketTypes.h" 6 7 #include "NetworkPrereqs.h" 7 8 8 9 #define CLIENTID_CLIENT -1 9 10 10 //enum netowk generaly used to set the type ID of a packet 11 namespace network{ 12 13 11 //enum netowk generally used to set the type ID of a packet 12 namespace network 13 { 14 /* 15 * class to generate packets 16 * 17 * @autor: Dumeni Manatschal 18 * 19 */ 20 class PacketGenerator 21 { 22 public: 23 PacketGenerator(); 24 //call one of this functions out of an instance of PacketGenerator to create a packet 25 ENetPacket* acknowledgement( int state, int reliable = ENET_PACKET_FLAG_RELIABLE ); 26 ENetPacket* mousem( double x, double y, int reliable = ENET_PACKET_FLAG_RELIABLE ); 27 ENetPacket* keystrike( char press, int reliable = ENET_PACKET_FLAG_RELIABLE ); 28 ENetPacket* chatMessage( const char* message, int reliable = ENET_PACKET_FLAG_RELIABLE ); 29 ENetPacket* gstate( GameStateCompressed *states, int reliable = ENET_PACKET_FLAG_RELIABLE ); 30 ENetPacket* clid( int classid, std::string classname, int reliable = ENET_PACKET_FLAG_RELIABLE ); 31 private: 32 }; 33 34 /* 35 * class used to decode incoming packets 36 * 37 * @autor: Dumeni Manatschal 38 * 39 */ 40 class _NetworkExport PacketDecoder 41 { 42 public: 43 PacketDecoder(); 44 virtual ~PacketDecoder(); 45 //call this function to decode, it calls the right decoding function below 46 bool elaborate( ENetPacket* packet, int clientId ); 47 protected: 48 49 virtual void processChat( chat *data, int clientId); 50 51 52 private: 14 53 15 54 16 55 17 /* 18 * class to generate packets 19 * 20 * @autor: Dumeni Manatschal 21 * 22 */ 23 class PacketGenerator 24 { 25 public: 26 PacketGenerator(); 27 //call one of this functions out of an instance of PacketGenerator to create a packet 28 ENetPacket* acknowledgement( int state, int reliable = ENET_PACKET_FLAG_RELIABLE ); 29 ENetPacket* mousem( double x, double y, int reliable = ENET_PACKET_FLAG_RELIABLE ); 30 ENetPacket* keystrike( char press, int reliable = ENET_PACKET_FLAG_RELIABLE ); 31 ENetPacket* chatMessage( const char* message, int reliable = ENET_PACKET_FLAG_RELIABLE ); 32 ENetPacket* gstate( GameStateCompressed *states, int reliable = ENET_PACKET_FLAG_RELIABLE ); 33 ENetPacket* clid( int classid, std::string classname, int reliable = ENET_PACKET_FLAG_RELIABLE ); 34 private: 35 }; 56 void acknowledgement( ENetPacket* packet, int clientId = CLIENTID_CLIENT ); 57 void mousem( ENetPacket* packet, int clientId = CLIENTID_CLIENT ); 58 void keystrike( ENetPacket* packet, int clientId = CLIENTID_CLIENT ); 59 void chatMessage( ENetPacket* packet, int clientId = CLIENTID_CLIENT); 60 void gstate( ENetPacket* packet ); 61 void clid( ENetPacket *packet); 36 62 37 /* 38 * class used to decode incoming packets 39 * 40 * @autor: Dumeni Manatschal 41 * 42 */ 43 class PacketDecoder 44 { 45 public: 46 PacketDecoder(); 47 virtual ~PacketDecoder(); 48 //call this function to decode, it calls the right decoding function below 49 bool elaborate( ENetPacket* packet, int clientId ); 50 protected: 51 52 virtual void processChat( chat *data, int clientId); 53 54 55 private: 56 57 58 59 void acknowledgement( ENetPacket* packet, int clientId = CLIENTID_CLIENT ); 60 void mousem( ENetPacket* packet, int clientId = CLIENTID_CLIENT ); 61 void keystrike( ENetPacket* packet, int clientId = CLIENTID_CLIENT ); 62 void chatMessage( ENetPacket* packet, int clientId = CLIENTID_CLIENT); 63 void gstate( ENetPacket* packet ); 64 void clid( ENetPacket *packet); 65 66 //process data 67 //two functions are note yet implemented! 68 virtual void processGamestate(GameStateCompressed *state); 69 virtual void processAck( ack *data, int clientID); 70 void processClassid( classid *cid); 71 //virtual void processAck( ack *data); 72 73 //print functions 74 void printAck( ack* data ); 75 void printMouse( mouse* data ); 76 void printKey( keyboard* data ); 77 void printChat( chat* data, int clientId ); 78 void printGamestate( GameStateCompressed *data ); 79 void printClassid( classid *cid); 80 }; 63 //process data 64 //two functions are note yet implemented! 65 virtual void processGamestate(GameStateCompressed *state); 66 virtual void processAck( ack *data, int clientID); 67 void processClassid( classid *cid); 68 //virtual void processAck( ack *data); 69 70 //print functions 71 void printAck( ack* data ); 72 void printMouse( mouse* data ); 73 void printKey( keyboard* data ); 74 void printChat( chat* data, int clientId ); 75 void printGamestate( GameStateCompressed *data ); 76 void printClassid( classid *cid); 77 }; 81 78 } 82 79 -
code/branches/FICN/src/network/PacketTypes.h
r673 r777 14 14 #define _PacketTypes_H__ 15 15 16 namespace network{ 17 enum packet_id { 18 ACK, 19 MOUSE, 20 KEYBOARD, 21 CHAT, 22 GAMESTATE , 23 CLASSID 24 }; 16 #include "NetworkPrereqs.h" 17 18 namespace network 19 { 20 enum packet_id { 21 ACK, 22 MOUSE, 23 KEYBOARD, 24 CHAT, 25 GAMESTATE , 26 CLASSID 27 }; 25 28 26 29 27 30 /** 28 29 30 31 31 * This struct defines a gamestate: 32 * size: total size of the data in *data 33 * data: pointer to the data allocated in the memory 34 */ 32 35 struct GameState{ 33 36 int id; … … 39 42 40 43 /** 41 42 43 44 45 44 * this struct defines a gamestate: 45 * compsize is the size of the compressed data 46 * normsize is the size of the uncompressed data 47 * data are the gamestates 48 */ 46 49 struct GameStateCompressed{ 47 50 int id; … … 76 79 char press; 77 80 }; 78 79 81 //only in this class, not PacketGenerator, used as pattern to put incoming 82 //bytes inside 80 83 struct chat { 81 84 int id; -
code/branches/FICN/src/network/Server.cc
r660 r777 11 11 // 12 12 13 #include <iostream> 13 14 15 #include "ConnectionManager.h" 16 #include "PacketTypes.h" 17 #include "GameStateManager.h" 18 #include "ClientInformation.h" 19 //#include "NetworkFrameListener.h" 14 20 #include "Server.h" 15 21 16 namespace network{17 22 23 namespace network 24 { 18 25 /** 19 20 21 22 Server::Server() {26 * Constructor for default values (bindaddress is set to ENET_HOST_ANY 27 * 28 */ 29 Server::Server() { 23 30 packet_gen = PacketGenerator(); 24 31 clients = new ClientInformation(true); … … 28 35 29 36 /** 30 31 32 33 34 Server::Server(int port, std::string bindAddress) {37 * Constructor 38 * @param port Port to listen on 39 * @param bindAddress Address to listen on 40 */ 41 Server::Server(int port, std::string bindAddress) { 35 42 packet_gen = PacketGenerator(); 36 43 clients = new ClientInformation(); … … 40 47 41 48 /** 42 43 44 45 46 Server::Server(int port, const char *bindAddress) {49 * Constructor 50 * @param port Port to listen on 51 * @param bindAddress Address to listen on 52 */ 53 Server::Server(int port, const char *bindAddress) { 47 54 packet_gen = PacketGenerator(); 48 55 clients = new ClientInformation(); … … 52 59 53 60 /** 54 55 56 void Server::open() {61 * This function opens the server by creating the listener thread 62 */ 63 void Server::open() { 57 64 connection->createListener(); 58 65 return; … … 60 67 61 68 /** 62 63 64 void Server::close() {69 * This function closes the server 70 */ 71 void Server::close() { 65 72 connection->quitListener(); 66 73 return; … … 68 75 69 76 /** 70 71 72 73 74 bool Server::sendMSG(std::string msg) {77 * This function sends out a message to all clients 78 * @param msg message 79 * @return true/false 80 */ 81 bool Server::sendMSG(std::string msg) { 75 82 ENetPacket *packet = packet_gen.chatMessage(msg.c_str()); 76 83 //std::cout <<"adding packets" << std::endl; … … 79 86 return connection->sendPackets(); 80 87 } 88 81 89 /** 82 83 84 85 86 bool Server::sendMSG(const char *msg) {90 * This function sends out a message to all clients 91 * @param msg message 92 * @return true/false 93 */ 94 bool Server::sendMSG(const char *msg) { 87 95 ENetPacket *packet = packet_gen.chatMessage(msg); 88 96 std::cout <<"adding Packets" << std::endl; … … 90 98 //std::cout <<"added packets" << std::endl; 91 99 if (connection->sendPackets()){ 92 93 100 std::cout << "Sucessfully" << std::endl; 101 return true; 94 102 } 95 103 return false; … … 97 105 98 106 /** 99 100 101 102 103 void Server::tick(float time) {107 * Run this function once every tick 108 * calls processQueue and updateGamestate 109 * @param time time since last tick 110 */ 111 void Server::tick(float time) { 104 112 processQueue(); 105 113 updateGamestate(); … … 108 116 109 117 /** 110 111 112 void Server::processQueue() {118 * processes all the packets waiting in the queue 119 */ 120 void Server::processQueue() { 113 121 ENetPacket *packet; 114 122 int clientID=-1; … … 121 129 122 130 /** 123 124 125 void Server::updateGamestate() {131 * takes a new snapshot of the gamestate and sends it to the clients 132 */ 133 void Server::updateGamestate() { 126 134 gamestates->update(); 127 135 //std::cout << "updated gamestate, sending it" << std::endl; … … 131 139 132 140 /** 133 134 135 bool Server::sendGameState() {141 * sends the gamestate 142 */ 143 bool Server::sendGameState() { 136 144 std::cout << "starting gamestate" << std::endl; 137 145 ClientInformation *temp = clients; … … 160 168 if(added) 161 169 return connection->sendPackets(); 162 else return false;163 //return true;170 else 171 return false; 164 172 } 165 173 166 void Server::processAck( ack *data, int clientID) {174 void Server::processAck( ack *data, int clientID) { 167 175 clients->findClient(clientID)->setGamestateID(data->a); 168 176 } -
code/branches/FICN/src/network/Server.h
r673 r777 16 16 #include <string> 17 17 18 #include "ConnectionManager.h"19 18 #include "PacketManager.h" 20 #include "PacketTypes.h" 21 #include "GameStateManager.h" 22 #include "ClientInformation.h" 23 //#include "enet/enet.h" 24 //#include "NetworkFrameListener.h" 19 #include "NetworkPrereqs.h" 25 20 26 27 namespace network{ 28 29 21 namespace network 22 { 30 23 /** 31 32 33 34 class Server : public PacketDecoder{35 24 * This class is the root class of the network module for a server. 25 * It implements all functions necessary for a Server 26 */ 27 class _NetworkExport Server : public PacketDecoder{ 28 public: 36 29 Server(); 37 30 Server(int port, std::string bindAddress); … … 42 35 bool sendMSG(const char *msg); 43 36 void tick(float time); 44 37 protected: 45 38 void processQueue(); 46 39 void updateGamestate(); 47 40 private: 48 41 bool sendGameState(); 49 42 void processAck( ack *data, int clientID); … … 51 44 GameStateManager *gamestates; 52 45 PacketGenerator packet_gen; 53 46 54 47 ClientInformation *clients; 55 48 }; 56 49 57 50 58 51 -
code/branches/FICN/src/network/Synchronisable.cc
r774 r777 10 10 // 11 11 12 #include <string> 13 #include <iostream> 14 12 15 #include "Synchronisable.h" 13 #include "core/CoreIncludes.h"14 16 17 namespace network 18 { 19 /** 20 * Constructor: 21 * calls registarAllVariables, that has to be implemented by the inheriting classID 22 */ 23 Synchronisable::Synchronisable(){ 24 RegisterRootObject(Synchronisable); 25 static int idCounter=0; 26 datasize=0; 27 objectID=idCounter++; 28 //registerAllVariables(); 29 } 15 30 16 namespace network { 31 Synchronisable::~Synchronisable(){ 32 } 17 33 18 /** 19 * Constructor: 20 * calls registarAllVariables, that has to be implemented by the inheriting classID 21 */ 22 Synchronisable::Synchronisable() 23 { 24 RegisterRootObject(Synchronisable); 25 static int idCounter=0; 26 datasize=0; 27 objectID=idCounter++; 28 //registerAllVariables(); 29 } 34 /** 35 * This function is used to register a variable to be synchronized 36 * also counts the total datasize needed to save the variables 37 * @param var pointer to the variable 38 * @param size size of the datatype the variable consists of 39 */ 40 void Synchronisable::registerVar(const void *var, int size, variableType t){ 41 // create temporary synch.Var struct 42 synchronisableVariable temp={size, var, t}; 43 // increase datasize 44 datasize+=sizeof(int)+size; 45 // push temp to syncList (at the bottom) 46 syncList.push_back(temp); 47 } 30 48 31 32 Synchronisable::~Synchronisable() 33 { 34 35 } 36 37 /** 38 * This function is used to register a variable to be synchronized 39 * also counts the total datasize needed to save the variables 40 * @param var pointer to the variable 41 * @param size size of the datatype the variable consists of 42 */ 43 void Synchronisable::registerVar(const void *var, int size, variableType t){ 44 // create temporary synch.Var struct 45 synchronisableVariable temp={size, var, t}; 46 // increase datasize 47 datasize+=sizeof(int)+size; 48 // push temp to syncList (at the bottom) 49 syncList.push_back(temp); 50 } 51 52 /** 53 * note: only use this function for debug use, because it's inefficient (in order to produce a gamestate, you have to copy the whole data again to another memory location after this process) 54 * This function takes all SynchronisableVariables out of the Synchronisable and saves it into a syncData struct 55 * structure of the bitstream: 56 * (var1_size,var1,var2_size,var2,...) 57 * varx_size: size = sizeof(int) 58 * varx: size = varx_size 59 * @return data containing all variables and their sizes 60 */ 61 // syncData Synchronisable::getData(){ 62 // std::list<synchronisableVariable>::iterator i; 63 // int totalsize=0; 64 // //figure out size of data to be allocated 65 // for(i=syncList.begin(); i!=syncList.end(); i++){ 66 // // increase size (size of variable and size of size of variable ;) 67 // if(i->type == STRING) 68 // totalsize+=sizeof(int)+((std::string *)i->var)->length()+1; 69 // else 70 // totalsize+=sizeof(int)+i->size; 71 // } 72 // syncData retVal; 73 // retVal.objectID=this->objectID; 74 // retVal.classID=this->classID; 75 // retVal.length=totalsize; 76 // // allocate memory 77 // retVal.data = (unsigned char *)malloc(totalsize); 78 // // copy to location 79 // //CHANGED: REMOVED DECLARATION int n=0 FROM LOOP 80 // int n=0; 81 // for(i=syncList.begin(); n<totalsize && i!=syncList.end(); i++){ 82 // std::memcpy(retVal.data+n, (const void*)(i->size), sizeof(int)); 83 // n+=sizeof(int); 84 // switch(i->type){ 85 // case STRING: 86 // std::memcpy(retVal.data+n, (const void *)(((std::string *)i->var)->c_str()), ((std::string *)i->var)->length()+1); 87 // n+=((std::string *)i->var)->length()+1; 88 // break; 89 // case DATA: 90 // std::memcpy(retVal.data+n, ((const void*)i->var), i->size); 91 // n+=i->size; 92 // break; 93 // } 94 // } 95 // return retVal; 96 // } 97 /** 98 * This function takes all SynchronisableVariables out of the Synchronisable and saves it into a syncData struct 99 * Difference to the above function: 100 * takes a pointer to already allocated memory (must have at least getSize bytes length) 101 * structure of the bitstream: 102 * (var1_size,var1,var2_size,var2,...) 103 * varx_size: size = sizeof(int) 104 * varx: size = varx_size 105 * @return data containing all variables and their sizes 106 */ 107 syncData Synchronisable::getData(unsigned char *mem){ 108 std::list<synchronisableVariable>::iterator i; 109 syncData retVal; 110 retVal.objectID=this->objectID; 111 retVal.classID=this->classID; 112 retVal.length=getSize(); 113 retVal.data=mem; 114 // copy to location 115 int n=0; 116 for(i=syncList.begin(); n<datasize && i!=syncList.end(); ++i){ 117 //COUT(2) << "size of variable: " << i->size << std::endl; 118 //(std::memcpy(retVal.data+n, (const void*)(&(i->size)), sizeof(int)); 119 memcpy( (void *)(retVal.data+n), (const void*)&(i->size), sizeof(int) ); 120 n+=sizeof(int); 121 switch(i->type){ 49 /** 50 * note: only use this function for debug use, because it's inefficient (in order to produce a gamestate, you have to copy the whole data again to another memory location after this process) 51 * This function takes all SynchronisableVariables out of the Synchronisable and saves it into a syncData struct 52 * structure of the bitstream: 53 * (var1_size,var1,var2_size,var2,...) 54 * varx_size: size = sizeof(int) 55 * varx: size = varx_size 56 * @return data containing all variables and their sizes 57 */ 58 // syncData Synchronisable::getData(){ 59 // std::list<synchronisableVariable>::iterator i; 60 // int totalsize=0; 61 // //figure out size of data to be allocated 62 // for(i=syncList.begin(); i!=syncList.end(); i++){ 63 // // increase size (size of variable and size of size of variable ;) 64 // if(i->type == STRING) 65 // totalsize+=sizeof(int)+((std::string *)i->var)->length()+1; 66 // else 67 // totalsize+=sizeof(int)+i->size; 68 // } 69 // syncData retVal; 70 // retVal.objectID=this->objectID; 71 // retVal.classID=this->classID; 72 // retVal.length=totalsize; 73 // // allocate memory 74 // retVal.data = (unsigned char *)malloc(totalsize); 75 // // copy to location 76 // //CHANGED: REMOVED DECLARATION int n=0 FROM LOOP 77 // int n=0; 78 // for(i=syncList.begin(); n<totalsize && i!=syncList.end(); i++){ 79 // std::memcpy(retVal.data+n, (const void*)(i->size), sizeof(int)); 80 // n+=sizeof(int); 81 // switch(i->type){ 82 // case STRING: 83 // std::memcpy(retVal.data+n, (const void *)(((std::string *)i->var)->c_str()), ((std::string *)i->var)->length()+1); 84 // n+=((std::string *)i->var)->length()+1; 85 // break; 86 // case DATA: 87 // std::memcpy(retVal.data+n, ((const void*)i->var), i->size); 88 // n+=i->size; 89 // break; 90 // } 91 // } 92 // return retVal; 93 // } 94 /** 95 * This function takes all SynchronisableVariables out of the Synchronisable and saves it into a syncData struct 96 * Difference to the above function: 97 * takes a pointer to already allocated memory (must have at least getSize bytes length) 98 * structure of the bitstream: 99 * (var1_size,var1,var2_size,var2,...) 100 * varx_size: size = sizeof(int) 101 * varx: size = varx_size 102 * @return data containing all variables and their sizes 103 */ 104 syncData Synchronisable::getData(unsigned char *mem){ 105 std::list<synchronisableVariable>::iterator i; 106 syncData retVal; 107 retVal.objectID=this->objectID; 108 retVal.classID=this->classID; 109 retVal.length=getSize(); 110 retVal.data=mem; 111 // copy to location 112 int n=0; 113 for(i=syncList.begin(); n<datasize && i!=syncList.end(); ++i){ 114 //COUT(2) << "size of variable: " << i->size << std::endl; 115 //(std::memcpy(retVal.data+n, (const void*)(&(i->size)), sizeof(int)); 116 memcpy( (void *)(retVal.data+n), (const void*)&(i->size), sizeof(int) ); 117 n+=sizeof(int); 118 switch(i->type){ 122 119 case DATA: 123 120 std::memcpy( (void *)(retVal.data+n), (const void*)(i->var), i->size); … … 128 125 n+=((std::string *) i->var)->length()+1; 129 126 break; 127 } 130 128 } 129 return retVal; 131 130 } 132 return retVal;133 }134 131 135 /**136 * This function takes a syncData struct and takes it to update the variables137 * @param vars data of the variables138 * @return true/false139 */140 bool Synchronisable::updateData(syncData vars){141 unsigned char *data=vars.data;142 std::list<synchronisableVariable>::iterator i;143 for(i=syncList.begin(); i!=syncList.end(); i++){144 if((int)*data==i->size || i->type==STRING){145 switch(i->type){132 /** 133 * This function takes a syncData struct and takes it to update the variables 134 * @param vars data of the variables 135 * @return true/false 136 */ 137 bool Synchronisable::updateData(syncData vars){ 138 unsigned char *data=vars.data; 139 std::list<synchronisableVariable>::iterator i; 140 for(i=syncList.begin(); i!=syncList.end(); i++){ 141 if((int)*data==i->size || i->type==STRING){ 142 switch(i->type){ 146 143 case DATA: 147 144 data+=sizeof(int); … … 155 152 data += i->size; 156 153 break; 157 } 158 } else 159 return false; //there was some problem with registerVar 154 } 155 } else 156 return false; //there was some problem with registerVar 157 } 158 return true; 160 159 } 161 return true;162 }163 160 164 /**165 * This function returns the total amount of bytes needed by getData to save the whole content of the variables166 * @return amount of bytes167 */168 int Synchronisable::getSize(){169 int tsize=0;170 std::list<synchronisableVariable>::iterator i;171 for(i=syncList.begin(); i!=syncList.end(); i++){172 switch(i->type){161 /** 162 * This function returns the total amount of bytes needed by getData to save the whole content of the variables 163 * @return amount of bytes 164 */ 165 int Synchronisable::getSize(){ 166 int tsize=0; 167 std::list<synchronisableVariable>::iterator i; 168 for(i=syncList.begin(); i!=syncList.end(); i++){ 169 switch(i->type){ 173 170 case DATA: 174 171 tsize+=sizeof(int); … … 179 176 tsize+=((std::string *)i->var)->length()+1; 180 177 break; 178 } 181 179 } 180 return tsize; 182 181 } 183 return tsize;184 }185 182 186 183 } -
code/branches/FICN/src/network/Synchronisable.h
r774 r777 14 14 15 15 #include <list> 16 #include <iostream>17 #include <string>18 16 17 #include "NetworkPrereqs.h" 19 18 #include "core/CoreIncludes.h" 20 #include "core/OrxonoxClass.h"21 19 22 namespace network { 20 namespace network 21 { 22 enum variableType{ 23 DATA, 24 STRING, 25 }; 23 26 24 enum variableType{ 25 DATA, 26 STRING, 27 }; 28 29 struct syncData{ 30 int length; 31 int objectID; 32 int classID; 33 unsigned char *data; 34 }; 27 struct syncData{ 28 int length; 29 int objectID; 30 int classID; 31 unsigned char *data; 32 }; 35 33 36 typedef struct synchronisableVariable{37 int size;38 const void *var;39 variableType type;40 }SYNCVAR;34 typedef struct synchronisableVariable{ 35 int size; 36 const void *var; 37 variableType type; 38 }SYNCVAR; 41 39 42 43 /**44 * This class is the base class of all the Objects in the universe that need to be synchronised over the network45 * Every class, that inherits from this class has to link the DATA THAT NEEDS TO BE SYNCHRONISED into the linked list. Additionally it also has to provide a Constructor, that takes exactly the variables in this linked list.46 * @author Oliver Scheuss47 */48 class Synchronisable : virtual public orxonox::OrxonoxClass{49 public:50 40 51 virtual ~Synchronisable(); 52 int objectID; 53 int classID; 54 55 void registerVar(const void *var, int size, variableType t); 56 // syncData getData(); 57 syncData getData(unsigned char *mem); 58 int getSize(); 59 bool updateData(syncData vars); 60 void registerAllVariables(); 61 virtual bool create()=0; 62 protected: 63 Synchronisable(); 64 private: 65 /* bool removeObject(Iterator<Synchronisable> it);*/ 66 67 std::list<SYNCVAR> syncList; 68 int datasize; 69 }; 41 /** 42 * This class is the base class of all the Objects in the universe that need to be synchronised over the network 43 * Every class, that inherits from this class has to link the DATA THAT NEEDS TO BE SYNCHRONISED into the linked list. Additionally it also has to provide a Constructor, that takes exactly the variables in this linked list. 44 * @author Oliver Scheuss 45 */ 46 class _NetworkExport Synchronisable : virtual public orxonox::OrxonoxClass{ 47 public: 48 49 virtual ~Synchronisable(); 50 int objectID; 51 int classID; 52 53 void registerVar(const void *var, int size, variableType t); 54 // syncData getData(); 55 syncData getData(unsigned char *mem); 56 int getSize(); 57 bool updateData(syncData vars); 58 void registerAllVariables(); 59 virtual bool create()=0; 60 protected: 61 Synchronisable(); 62 private: 63 /* bool removeObject(Iterator<Synchronisable> it);*/ 64 65 std::list<SYNCVAR> syncList; 66 int datasize; 67 }; 68 ExportAbstractClass(Synchronisable, Network); 70 69 71 70 } -
code/branches/FICN/src/network/dummyclient.cc
r514 r777 1 1 /* 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 2 * ORXONOX - the hottest 3D action shooter ever to exist 3 * 4 * 5 * License notice: 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * Author: 22 * Oliver Scheuss, (C) 2007 23 * Co-authors: 24 * ... 25 * 26 */ 27 27 28 28 //o … … 34 34 #include <string> 35 35 #include <enet/enet.h> 36 37 #include "util/Sleep.h" 36 38 #include "PacketManager.h" 37 38 #ifdef WIN3239 #include <windows.h>40 #define usleep(x) Sleep((x)/1000)41 #else42 #include <unistd.h>43 #endif44 45 39 46 40 using namespace std; … … 66 60 address.port = 55556; 67 61 68 62 // create client object 69 63 client = enet_host_create(NULL, 2, 0, 0); 70 64 … … 73 67 exit(EXIT_FAILURE); 74 68 } 75 69 // connect peer 76 70 peer = enet_host_connect(client, &address, 2); 77 71 if(peer==NULL){ … … 79 73 exit(EXIT_FAILURE); 80 74 } 81 75 // wait 5 seconds for the connection attempt to succeed 82 76 if(enet_host_service(client, &event, 5000) > 0 && event.type == ENET_EVENT_TYPE_CONNECT){ 83 77 cout << "Connection to " << str << " succeeded." << endl; … … 91 85 92 86 for(int i=0; i<10; i++){ 93 87 // weihnachtsmann bringt packete 94 88 //ENetPacket *packet = enet_packet_create ("packet1234", strlen("packet1234") + 1, ENET_PACKET_FLAG_RELIABLE); 95 96 89 // extend the packet and append the string foo to it 90 // send packet to peer on channel id 0 97 91 enet_peer_send(peer, 1, pck.chatMessage("test2")); 98 92 // keep the timeout very small for low delay 99 93 if(enet_host_service(client, &event, 1)==0){ 100 94 cout << "successfully sent: " << event.type << endl; … … 105 99 } 106 100 107 108 // enet_peer_disconnect (peer);101 // now disconnect 102 // enet_peer_disconnect (peer); 109 103 enet_peer_disconnect (peer, 0); 110 104 // 3 seconds timeout 111 105 while(enet_host_service(client, &event, 3000) > 0){ 112 106 switch (event.type) 113 107 { 114 115 116 117 118 119 108 case ENET_EVENT_TYPE_RECEIVE: 109 enet_packet_destroy(event.packet); 110 break; 111 case ENET_EVENT_TYPE_DISCONNECT: 112 puts("Disconnection succeeded."); 113 return 0; 120 114 } 121 115 } 122 116 // if disconnect failed 123 117 enet_peer_reset(peer); 124 118 -
code/branches/FICN/src/network/dummyclient2.cc
r660 r777 1 1 /* 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 2 * ORXONOX - the hottest 3D action shooter ever to exist 3 * 4 * 5 * License notice: 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * Author: 22 * Oliver Scheuss, (C) 2007 23 * Co-authors: 24 * ... 25 * 26 */ 27 27 28 28 // … … 34 34 #include <string> 35 35 #include <enet/enet.h> 36 37 #include "util/Sleep.h" 36 38 #include "PacketManager.h" 37 39 #include "ClientConnection.h" 38 39 #ifdef WIN3240 #include <windows.h>41 #define usleep(x) Sleep((x)/1000)42 #else43 #include <unistd.h>44 #endif45 40 46 41 using namespace network; … … 71 66 72 67 for(int i=0; i<10; i++){ 73 74 75 68 // weihnachtsmann bringt packete 69 // extend the packet and append the string foo to it 70 // send packet to peer on channel id 0 76 71 client.addPacket(pck.chatMessage("test")); 77 72 // keep the timeout very small for low delay 78 73 if(client.sendPackets(&event)){ 79 74 std::cout << "successfully sent: " << event.type << std::endl; … … 81 76 std::cout << "failed sending" << std::endl; 82 77 } 83 // usleep(1000000);78 // usleep(1000000); 84 79 } 85 80 usleep(1000000); 86 81 // now disconnect 87 82 if(client.closeConnection()) 88 83 std::cout << "Connection successfully closed" << std::endl; … … 90 85 std::cout << "Connection closing failed" << std::endl; 91 86 92 87 // 3 seconds timeout 93 88 return 0; 94 89 } -
code/branches/FICN/src/network/dummyclient3.cc
r632 r777 1 1 #include <iostream> 2 2 #include <string> 3 4 #include "util/Sleep.h" 3 5 #include "PacketManager.h" 4 6 #include "Client.h" 5 6 #ifdef WIN327 #include <windows.h>8 #define usleep(x) Sleep((x)/1000)9 #else10 #include <unistd.h>11 #endif12 7 13 8 using namespace network; … … 26 21 Client client( str, PORT ); 27 22 if ( client.establishConnection() ) 28 23 std::cout << "connection established" << std::endl; 29 24 else std::cout << "problems establishing connection" << std::endl; 30 25 char message[10000]; 31 26 char signs[] = "abcdefghijklmnopqrstuvwxy"; 32 27 while (true) { 33 34 35 36 37 38 39 40 41 42 43 28 client.tick(0); 29 30 std::cout << "your message2: "; 31 for ( int i=0; i<9999; i++ ) { 32 message[i] = signs[0]; 33 } 34 message[9999] = 'z'; 35 std::string str( message ); 36 client.sendChat( str ); 37 std::cout << str << std::endl; 38 std::cin.get(); std::cin.get(); 44 39 } 45 40 … … 49 44 50 45 void listener(){ 51 46 52 47 const int PORT = 55556; 53 48 std::cout << "Enter address of the server xxx.xxx.xxx.xxx (enter for localhost)" << std::endl; … … 60 55 Client client( str, PORT ); 61 56 if ( client.establishConnection() ) 62 57 std::cout << "connection established" << std::endl; 63 58 else std::cout << "problems establishing connection" << std::endl; 64 59 65 60 while (true) { 66 67 61 client.tick(0); 62 usleep(100); 68 63 } 69 64 -
code/branches/FICN/src/network/dummyserver.cc
r514 r777 1 1 /* 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 2 * ORXONOX - the hottest 3D action shooter ever to exist 3 * 4 * 5 * License notice: 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * Author: 22 * Oliver Scheuss, (C) 2007 23 * Co-authors: 24 * ... 25 * 26 */ 27 27 28 28 // … … 31 31 // Author: Oliver Scheuss 32 32 33 34 33 #include <iostream> 35 34 #include <enet/enet.h> 35 36 #include "util/Sleep.h" 36 37 #include "ConnectionManager.h" 37 38 #include "PacketManager.h" 38 39 #include "ClientInformation.h" 39 40 #ifdef WIN3241 #include <windows.h>42 #define usleep(x) Sleep((x)/1000)43 #else44 #include <unistd.h>45 #endif46 47 40 48 41 using namespace network; … … 59 52 while(!quit){ 60 53 if(server.queueEmpty()) 61 // Warning: usleep(100) is Sleep(100/1000) = Sleep(0), which is nothing!54 // Warning: usleep(100) is Sleep(100/1000) = Sleep(0), which is nothing! 62 55 usleep(1); 63 56 else{ -
code/branches/FICN/src/network/dummyserver3.cc
r533 r777 1 1 #include <iostream> 2 3 #include "util/Sleep.h" 2 4 #include "PacketManager.h" 3 5 //#include "PacketTypes.h" 4 6 #include "Server.h" 5 7 6 #ifdef WIN32 7 #include <windows.h> 8 #define usleep(x) Sleep((x)/1000) 9 #else 10 #include <unistd.h> 11 #endif 8 namespace network 9 { 12 10 13 namespace network{ 14 15 class dummyserver3 : public Server{ 11 class dummyserver3 : public Server 12 { 16 13 public: 17 dummyserver3();18 ~dummyserver3();19 void loop();14 dummyserver3(); 15 ~dummyserver3(); 16 void loop(); 20 17 private: 21 void tick(); 22 void processChat( chat *data, int clientId); 23 24 25 26 }; 18 void tick(); 19 void processChat( chat *data, int clientId); 27 20 28 dummyserver3::dummyserver3(){29 }30 dummyserver3::~dummyserver3(){31 }32 21 33 void dummyserver3::loop(){ 34 open(); 35 while(true){ 36 tick(); 37 usleep(100); 22 }; 23 24 dummyserver3::dummyserver3(){ 38 25 } 39 } 26 dummyserver3::~dummyserver3(){ 27 } 40 28 41 void dummyserver3::processChat( chat *data, int clientId){ 42 std::cout << "Client " << clientId << " sent: " << data->message << std::endl; 43 sendMSG(data->message); 44 } 29 void dummyserver3::loop(){ 30 open(); 31 while(true){ 32 tick(); 33 usleep(100); 34 } 35 } 45 36 46 void dummyserver3::tick(){ 47 processQueue(); 48 } 37 void dummyserver3::processChat( chat *data, int clientId){ 38 std::cout << "Client " << clientId << " sent: " << data->message << std::endl; 39 sendMSG(data->message); 40 } 49 41 42 void dummyserver3::tick(){ 43 processQueue(); 44 } 50 45 51 46 }
Note: See TracChangeset
for help on using the changeset viewer.