Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/merge/src/network/PacketDecoder.cc @ 1336

Last change on this file since 1336 was 1336, checked in by scheusso, 16 years ago

added crc checksum testing for submitted gamestates (can also be used for other packet types)

File size: 11.7 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 MOUSE:
71      mousem( packet, clientId );
72      return true;
73    case KEYBOARD:
74      keystrike( packet, clientId );
75      return true;
76    case CHAT:
77      chatMessage( packet, clientId );
78      return true;
79    case GAMESTATE:
80      gstate( packet, clientId );
81      return true;
82    case CLASSID:
83      clid(packet);
84      return true;
85    case WELCOME:
86      return decodeWelcome( packet, clientId );
87    case CONNECT:
88      return decodeConnectRequest( packet, clientId );
89    }
90    return false;
91  }
92 
93  bool PacketDecoder::testAndRemoveCRC(ENetPacket *packet){
94    uint32_t submittetcrc;
95    int dataLength = packet->dataLength;
96    // get the submittet crc code
97    memcpy(&submittetcrc, &packet->data[dataLength-sizeof(uint32_t)], sizeof(uint32_t));
98    unsigned char *data = packet->data;
99    uint32_t crc32=calcCRC(data, packet->dataLength-sizeof(uint32_t));
100    // now append the crc to the packet data
101    if(crc32==submittetcrc){
102      dataLength-=sizeof(uint32_t);
103      enet_packet_resize(packet, dataLength);
104      return true;
105    }
106    COUT(3) << "gamestate crc: " << crc32 << std::endl;
107    COUT(3) << "submitted crc: " << submittetcrc << std::endl;
108    return false;
109  }
110 
111  // ATTENTION: TODO watch, that arguments we pass over to the processFunction gets deleted in THE PROCESSXXX function
112
113  //following are the decode functions for the data of the packets
114
115  void PacketDecoder::acknowledgement( ENetPacket* packet, int clientId )
116  {
117    ack* a = new ack;
118    *a = *(ack*)(packet->data); //press pattern of ack on new data
119
120
121    COUT(4) << "PacketDecoder: got ack id: " << a->a << std::endl;
122    processAck( a, clientId ); //debug info
123    //clean memory
124    enet_packet_destroy( packet );
125  }
126 
127  bool PacketDecoder::command( ENetPacket* packet, int clientId ){
128    int length = *(int*)((unsigned char *)packet->data+sizeof(int));
129    void *data = (void *)new unsigned char[length];
130    memcpy(data, (void *)(packet->data+2*sizeof(int)), length);
131    enet_packet_destroy( packet );
132    return true;
133  }
134
135  void PacketDecoder::mousem( ENetPacket* packet, int clientId )
136  {
137    mouse* mouseMove = new mouse;
138    //copy data of packet->data to new struct
139    *mouseMove = *(mouse*)packet->data;
140
141    //clean memory
142    enet_packet_destroy( packet );
143    printMouse( mouseMove ); //debug info
144  }
145
146  void PacketDecoder::keystrike( ENetPacket* packet, int clientId )
147  {
148    keyboard* key = new keyboard;
149    *key = *(keyboard*)packet->data; //see above
150
151    //clean memory
152    enet_packet_destroy( packet );
153    printKey( key ); //debug info
154
155  }
156
157  void PacketDecoder::chatMessage( ENetPacket* packet, int clientId )
158  {
159    chat* chatting = new chat;
160    chatting->id = (int)*packet->data; //first copy id into new struct
161    //since the chat message is a char*, allocate the memory needed
162    char* reserve = new char[packet->dataLength-4];
163    //copy the transmitted bytestream into the new generated char*,
164    //note the lenght of the message is represented as "packet->dataLength-sizeof( int )"
165    memcpy( &reserve[0], packet->data+sizeof(int), packet->dataLength-sizeof(int) );
166    //put pointer of chatting struct to the begining of the new generated char*
167    chatting->message = reserve;
168
169    //clean memory
170    enet_packet_destroy( packet );
171
172    processChat( chatting, clientId ); //debug info
173  }
174
175  void PacketDecoder::gstate( ENetPacket* packet, int clientID )
176  {
177    if(!testAndRemoveCRC(packet)){
178      COUT(3) << "crc test of gamestate failed - dropping packet" << std::endl;
179      return;
180    }
181    GameStateCompressed* currentState = NULL;
182    currentState = new GameStateCompressed;
183    if(currentState == NULL){
184      COUT(3) << "PacketDecoder: could not generate new GameStateCompressed" << std::endl;
185      return;
186    }
187    //since it's not alowed to use void* for pointer arithmetic
188    //FIXME: variable never used
189    unsigned char* data = (unsigned char *)(packet->data);
190    //copy the GameStateCompressed id into the struct, which is located at second place data+sizeof( int )
191    memcpy( (void*)&(currentState->id), (const void*)(packet->data+1*sizeof( int )), sizeof( int) );
192    COUT(5) << "PacketDecoder: received gs id: " << currentState->id << std::endl;
193    //copy the size of the GameStateCompressed compressed data into the new GameStateCompressed struct, located at 3th
194    //position of the data stream, data+2*sizeof( int )
195    memcpy( (void*)&(currentState->compsize), (const void*)(packet->data+2*sizeof( int )), sizeof( int) );
196    //size of uncompressed data
197    memcpy( (void*)&(currentState->normsize), (const void*)(packet->data+3*sizeof( int )), sizeof( int ) );
198    memcpy( (void*)&(currentState->base_id), (const void*)(packet->data+4*sizeof( int )), sizeof( int ) );
199    //since the packetgenerator was changed, due to a new parameter, change this function too
200    memcpy( (void*)&(currentState->diffed), (const void*)(packet->data+5*sizeof(int)), sizeof(bool));
201    memcpy( (void*)&(currentState->complete), (const void*)(packet->data+5*sizeof(int)+sizeof(bool)), sizeof(bool));
202    //since data is not allocated, because it's just a pointer, allocate it with size of gamestatedatastream
203    if(currentState->compsize==0)
204      COUT(2) << "PacketDecoder: compsize is 0" << std::endl;
205//     currentState->data = (unsigned char*)(malloc( currentState->compsize ));
206    currentState->data = new unsigned char[currentState->compsize];
207    if(currentState->data==NULL)
208      COUT(2) << "PacketDecoder: Gamestatepacket-decoder: memory leak" << std::endl;
209    //copy the GameStateCompressed data
210    memcpy( (void*)(currentState->data), (const void*)(packet->data+5*sizeof( int ) + 2*sizeof(bool)), currentState->compsize );
211
212    //clean memory
213    enet_packet_destroy( packet );
214    processGamestate(currentState, clientID);
215  }
216
217  void PacketDecoder::clid( ENetPacket *packet)
218  {
219    classid* cid = new classid;
220    cid->length = ((classid*)(packet->data))->length;
221    cid->id = ((classid *)(packet->data))->id;
222    cid->clid = ((classid *)(packet->data))->clid;
223//     cid->message = (const char *)malloc(cid->length);
224    cid->message = new char[cid->length];
225    void *data  = (void *)cid->message;
226    memcpy(data, (const void*)(packet->data+3*sizeof(int)), cid->length);
227    COUT(4) << "PacketDecoder: classid: " << cid->clid << ", name: " << cid->message << std::endl;
228    enet_packet_destroy( packet );
229    processClassid(cid);
230  }
231 
232 
233  bool PacketDecoder::decodeWelcome( ENetPacket* packet, int clientID ){
234    welcome *w = new welcome;
235    w->allowed = ((welcome *)(packet->data))->allowed;
236    w->shipID = ((welcome *)(packet->data))->shipID;
237    w->clientID = ((welcome *)(packet->data))->clientID;
238    w->id = ((welcome *)(packet->data))->id;
239    enet_packet_destroy( packet );
240    return processWelcome(w);
241  }
242 
243  bool PacketDecoder::decodeConnectRequest( ENetPacket *packet, int clientID ){
244    connectRequest *con = new connectRequest;
245    con->id = ((connectRequest *)(packet->data))->id;
246    enet_packet_destroy( packet );
247    return processConnectRequest(con, clientID );
248  }
249
250
251  // now the data processing functions:
252
253  void PacketDecoder::processChat( chat *data, int clientId)
254  {
255    printChat(data, clientId);
256    delete[] data->message;
257    delete data;
258  }
259
260  void PacketDecoder::processGamestate( GameStateCompressed *state, int clientID )
261  {
262    COUT(3) << "PacketDecoder-process: processing Gamestate" << std::endl;
263    //printGamestate( state );
264//     delete[] state->data;
265//     delete state;
266  }
267
268  void PacketDecoder::processClassid( classid *cid)
269  {
270    printClassid(cid);
271    delete cid;
272    return;
273  }
274
275  void PacketDecoder::processAck( ack *data, int clientID)
276  {
277    printAck(data);
278    delete data;
279    return;
280  }
281 
282  bool PacketDecoder::processWelcome( welcome *w ){
283    delete w;
284    return true;
285  }
286 
287  bool PacketDecoder::processConnectRequest( connectRequest *con, int clientID ){
288    COUT(3) << "packetdecoder: processing connectRequest" << std::endl;
289    delete con;
290    return true;
291  }
292
293  //these are some print functions for test stuff
294
295  void PacketDecoder::printAck( ack* data )
296  {
297    COUT(5) << "data id: " << data->id << std::endl;
298    COUT(5) << "data:    " << data->a << std::endl;
299  }
300
301  void PacketDecoder::printMouse( mouse* data )
302  {
303    COUT(5) << "data id: " << data->id << std::endl;
304    COUT(5) << "data:    " << data->x << " " << data->y << std::endl;
305  }
306
307  void PacketDecoder::printKey( keyboard* data )
308  {
309    COUT(5) << "data id: " << data->id << std::endl;
310    COUT(5) << "data:    " << (char)data->press << std::endl;
311  }
312
313  void PacketDecoder::printChat( chat* data, int clientId )
314  {
315    if(clientId!=CLIENTID_CLIENT)
316      COUT(5) << "client: " << clientId << std::endl;
317    COUT(5) << "data id: " << data->id << std::endl;
318    COUT(5) << "data:    " << data->message << std::endl;
319  }
320
321  void PacketDecoder::printGamestate( GameStateCompressed* data )
322  {
323    COUT(5) << "id of GameStateCompressed:   " << data->id << std::endl;
324    COUT(5) << "size of GameStateCompressed: " << data->compsize << std::endl;
325  }
326
327  void PacketDecoder::printClassid( classid *cid)
328  {
329    COUT(5) << "id of classid:    " << cid->id << std::endl;
330    COUT(5) << "size of classid:  " << cid->length << std::endl;
331    COUT(5) << "ID of classid:    " << cid->clid << std::endl;
332    COUT(5) << "data of classid:  " << cid->message << std::endl;
333  }
334
335}
Note: See TracBrowser for help on using the repository browser.