Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/network/src/network/PacketDecoder.cc @ 1494

Last change on this file since 1494 was 1494, checked in by rgrieder, 16 years ago
  • set the svn:eol-style property to all files so, that where ever you check out, you'll get the right line endings (had to change every file with mixed endings to windows in order to set the property)
  • Property svn:eol-style set to native
File size: 10.4 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Dumeni Manatschal, (C) 2007
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/*
30* Class contains functions to determine and decode incomming packages
31* ->don't read this without the class PacketGenerator, since they belong together
32*
33* Autor: Dumeni Manatschal
34*
35*/
36
37#include "PacketTypes.h"
38#include "PacketManager.h"
39
40#include <iostream>
41
42#include "core/Debug.h"
43
44namespace network
45{
46
47  PacketDecoder::PacketDecoder(){}
48
49  PacketDecoder::~PacketDecoder(){}
50
51  //call this function out of an instance of PacketDecoder
52  //it will determine the type id and call the right decode function
53  bool PacketDecoder::elaborate( ENetPacket* packet, int clientId )
54  {
55    COUT(5) << "PacketDecoder: clientId: " << clientId << std::endl; //control cout, not important, just debugging info
56    int id = (int)*packet->data; //the first 4 bytes are always the enet packet id
57    COUT(5) << "PacketDecoder: packet id: " << id << std::endl;
58    //COUT(5) << "packet size inside packetdecoder: " << packet->dataLength << std::endl;
59
60    if ( packet == NULL ) {
61      COUT(4) << "PacketDecoder: no packets->packetbuffer queue is empty" << std::endl;
62      return false;
63    }
64    switch( id ) {
65    case ACK:
66      acknowledgement( packet, clientId );
67      return true;
68    case COMMAND:
69      return command( packet, clientId );
70    case CHAT:
71      chatMessage( packet, clientId );
72      return true;
73    case GAMESTATE:
74      gstate( packet, clientId );
75      return true;
76    case CLASSID:
77      clid(packet);
78      return true;
79    case WELCOME:
80      return decodeWelcome( packet, clientId );
81    case CONNECT:
82      return decodeConnectRequest( packet, clientId );
83    }
84    return false;
85  }
86
87  bool PacketDecoder::testAndRemoveCRC(ENetPacket *packet){
88    uint32_t submittetcrc;
89    int dataLength = packet->dataLength;
90    // get the submittet crc code
91    memcpy(&submittetcrc, &packet->data[dataLength-sizeof(uint32_t)], sizeof(uint32_t));
92    unsigned char *data = packet->data;
93    uint32_t crc32=calcCRC(data, packet->dataLength-sizeof(uint32_t));
94    // now append the crc to the packet data
95    if(crc32==submittetcrc){
96      dataLength-=sizeof(uint32_t);
97      enet_packet_resize(packet, dataLength);
98      return true;
99    }
100    COUT(3) << "gamestate crc: " << crc32 << std::endl;
101    COUT(3) << "submitted crc: " << submittetcrc << std::endl;
102    return false;
103  }
104
105  // ATTENTION: TODO watch, that arguments we pass over to the processFunction gets deleted in THE PROCESSXXX function
106
107  //following are the decode functions for the data of the packets
108
109  void PacketDecoder::acknowledgement( ENetPacket* packet, int clientId )
110  {
111    ack* a = new ack;
112    *a = *(ack*)(packet->data); //press pattern of ack on new data
113
114
115    COUT(4) << "PacketDecoder: got ack id: " << a->a << std::endl;
116    processAck( a, clientId ); //debug info
117    //clean memory
118    enet_packet_destroy( packet );
119  }
120
121  bool PacketDecoder::command( ENetPacket* packet, int clientId ){
122    int length = *(int*)((unsigned char *)packet->data+sizeof(int));
123    if(length<=0)
124      return false;
125    void *data = (void *)new unsigned char[length];
126    memcpy(data, (void *)(packet->data+2*sizeof(int)), length);
127    enet_packet_destroy( packet );
128    return true;
129  }
130
131  void PacketDecoder::chatMessage( ENetPacket* packet, int clientId )
132  {
133    chat* chatting = new chat;
134    if(packet->dataLength==4)
135      return;
136    chatting->id = (int)*packet->data; //first copy id into new struct
137    //since the chat message is a char*, allocate the memory needed
138    char* reserve = new char[packet->dataLength-4];
139    //copy the transmitted bytestream into the new generated char*,
140    //note the lenght of the message is represented as "packet->dataLength-sizeof( int )"
141    memcpy( &reserve[0], packet->data+sizeof(int), packet->dataLength-sizeof(int) );
142    //put pointer of chatting struct to the begining of the new generated char*
143    chatting->message = reserve;
144
145    //clean memory
146    enet_packet_destroy( packet );
147
148    processChat( chatting, clientId ); //debug info
149  }
150
151  void PacketDecoder::gstate( ENetPacket* packet, int clientID )
152  {
153    if(!testAndRemoveCRC(packet)){
154      COUT(3) << "crc test of gamestate failed - dropping packet" << std::endl;
155      return;
156    }
157    GameStateCompressed* currentState = NULL;
158    currentState = new GameStateCompressed;
159    if(currentState == NULL){
160      COUT(3) << "PacketDecoder: could not generate new GameStateCompressed" << std::endl;
161      return;
162    }
163    //copy the GameStateCompressed id into the struct, which is located at second place data+sizeof( int )
164    memcpy( (void*)&(currentState->id), (const void*)(packet->data+1*sizeof( int )), sizeof( int) );
165    COUT(5) << "PacketDecoder: received gs id: " << currentState->id << std::endl;
166    //copy the size of the GameStateCompressed compressed data into the new GameStateCompressed struct, located at 3th
167    //position of the data stream, data+2*sizeof( int )
168    memcpy( (void*)&(currentState->compsize), (const void*)(packet->data+2*sizeof( int )), sizeof( int) );
169    //size of uncompressed data
170    memcpy( (void*)&(currentState->normsize), (const void*)(packet->data+3*sizeof( int )), sizeof( int ) );
171    memcpy( (void*)&(currentState->base_id), (const void*)(packet->data+4*sizeof( int )), sizeof( int ) );
172    //since the packetgenerator was changed, due to a new parameter, change this function too
173    memcpy( (void*)&(currentState->diffed), (const void*)(packet->data+5*sizeof(int)), sizeof(bool));
174    memcpy( (void*)&(currentState->complete), (const void*)(packet->data+5*sizeof(int)+sizeof(bool)), sizeof(bool));
175    //since data is not allocated, because it's just a pointer, allocate it with size of gamestatedatastream
176    if(currentState->compsize==0)
177    {
178      COUT(2) << "PacketDecoder: compsize is 0" << std::endl;
179    }
180//     currentState->data = (unsigned char*)(malloc( currentState->compsize ));
181    if(currentState->compsize==0)
182      return;
183    currentState->data = new unsigned char[currentState->compsize];
184    if(currentState->data==NULL)
185    {
186      COUT(2) << "PacketDecoder: Gamestatepacket-decoder: memory leak" << std::endl;
187    }
188    //copy the GameStateCompressed data
189    memcpy( (void*)(currentState->data), (const void*)(packet->data+5*sizeof( int ) + 2*sizeof(bool)), currentState->compsize );
190
191    //clean memory
192    enet_packet_destroy( packet );
193    processGamestate(currentState, clientID);
194  }
195
196  void PacketDecoder::clid( ENetPacket *packet)
197  {
198    classid* cid = new classid;
199    cid->length = ((classid*)(packet->data))->length;
200    cid->id = ((classid *)(packet->data))->id;
201    cid->clid = ((classid *)(packet->data))->clid;
202    if(cid->length==0)
203      return;
204//     cid->message = (const char *)malloc(cid->length);
205    cid->message = new char[cid->length];
206    void *data  = (void *)cid->message;
207    memcpy(data, (const void*)(packet->data+3*sizeof(int)), cid->length);
208    COUT(4) << "PacketDecoder: classid: " << cid->clid << ", name: " << cid->message << std::endl;
209    enet_packet_destroy( packet );
210    processClassid(cid);
211  }
212
213
214  bool PacketDecoder::decodeWelcome( ENetPacket* packet, int clientID ){
215    welcome *w = new welcome;
216    w->allowed = ((welcome *)(packet->data))->allowed;
217    w->shipID = ((welcome *)(packet->data))->shipID;
218    w->clientID = ((welcome *)(packet->data))->clientID;
219    w->id = ((welcome *)(packet->data))->id;
220    enet_packet_destroy( packet );
221    return processWelcome(w);
222  }
223
224  bool PacketDecoder::decodeConnectRequest( ENetPacket *packet, int clientID ){
225    connectRequest *con = new connectRequest;
226    con->id = ((connectRequest *)(packet->data))->id;
227    enet_packet_destroy( packet );
228    return processConnectRequest(con, clientID );
229  }
230
231
232  // now the data processing functions:
233
234  void PacketDecoder::processChat( chat *data, int clientId)
235  {
236    printChat(data, clientId);
237    delete[] data->message;
238    delete data;
239  }
240
241  void PacketDecoder::processGamestate( GameStateCompressed *state, int clientID )
242  {
243    COUT(3) << "PacketDecoder-process: processing Gamestate" << std::endl;
244    //printGamestate( state );
245//     delete[] state->data;
246//     delete state;
247  }
248
249  void PacketDecoder::processClassid( classid *cid)
250  {
251    printClassid(cid);
252    delete cid;
253    return;
254  }
255
256  void PacketDecoder::processAck( ack *data, int clientID)
257  {
258    printAck(data);
259    delete data;
260    return;
261  }
262
263  bool PacketDecoder::processWelcome( welcome *w ){
264    delete w;
265    return true;
266  }
267
268  bool PacketDecoder::processConnectRequest( connectRequest *con, int clientID ){
269    COUT(3) << "packetdecoder: processing connectRequest" << std::endl;
270    delete con;
271    return true;
272  }
273
274  //these are some print functions for test stuff
275
276  void PacketDecoder::printAck( ack* data )
277  {
278    COUT(5) << "data id: " << data->id << std::endl;
279    COUT(5) << "data:    " << data->a << std::endl;
280  }
281
282
283  void PacketDecoder::printChat( chat* data, int clientId )
284  {
285    if(clientId!=CLIENTID_CLIENT)
286    {
287      COUT(5) << "client: " << clientId << std::endl;
288    }
289    COUT(5) << "data id: " << data->id << std::endl;
290    COUT(5) << "data:    " << data->message << std::endl;
291  }
292
293  void PacketDecoder::printGamestate( GameStateCompressed* data )
294  {
295    COUT(5) << "id of GameStateCompressed:   " << data->id << std::endl;
296    COUT(5) << "size of GameStateCompressed: " << data->compsize << std::endl;
297  }
298
299  void PacketDecoder::printClassid( classid *cid)
300  {
301    COUT(5) << "id of classid:    " << cid->id << std::endl;
302    COUT(5) << "size of classid:  " << cid->length << std::endl;
303    COUT(5) << "ID of classid:    " << cid->clid << std::endl;
304    COUT(5) << "data of classid:  " << cid->message << std::endl;
305  }
306
307}
Note: See TracBrowser for help on using the repository browser.