Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/network/PacketDecoder.cc @ 1663

Last change on this file since 1663 was 1639, checked in by rgrieder, 16 years ago

merged nico's fixes for gcc 4.3 back to trunk.
I'm not going to delete branch yet.

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