Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/merge/src/network/PacketGenerator.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: 8.2 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 generates packets that can be send by enet
31* ->don't read this without the class PacketDecoder, since they belong together
32*
33* Autor: Dumeni Manatschal
34*
35*/
36
37#include "PacketManager.h"
38#include "PacketTypes.h"
39
40#include <iostream>
41#include <list>
42#include <string>
43#include <cstring>
44
45
46namespace network
47{
48  void calcCRCBit(uint32_t &crc32, int bit){
49    int hbit;
50 
51    hbit=(crc32 & 0x80000000) ? 1 : 0;
52    if (hbit != bit)
53      crc32=(crc32<<1) ^ NETWORK_CRC32POLY;
54    else
55      crc32=crc32<<1;
56  }
57 
58  uint32_t calcCRC(unsigned char *data, unsigned int dataLength){
59    uint32_t crc32=0;
60    for(unsigned int i=0; i<dataLength; i++){
61      calcCRCBit(crc32, (data[i]&0x1)>>0); // 1st bit
62      calcCRCBit(crc32, (data[i]&0x2)>>1); // 2nd bit
63      calcCRCBit(crc32, (data[i]&0x3)>>2); // 3rd bit
64      calcCRCBit(crc32, (data[i]&0x4)>>3); // 4th bit
65      calcCRCBit(crc32, (data[i]&0x5)>>4); // 5th bit
66      calcCRCBit(crc32, (data[i]&0x6)>>5); // 6th bit
67      calcCRCBit(crc32, (data[i]&0x7)>>6); // 7th bit
68      calcCRCBit(crc32, (data[i]&0x8)>>7); // 8th bit
69    }
70    return crc32;
71  }
72 
73  PacketGenerator::PacketGenerator() { }
74
75  //following functions create a packet in form of bytestream
76
77  ENetPacket* PacketGenerator::acknowledgement( int state, int reliable )
78  {
79    COUT(4) << "PacketGenerator: generating new acknowledgement, id: " << state << std::endl;
80    ack* ackreq = new ack;
81    ackreq->id = ACK;
82    ackreq->a = state;
83
84    ENetPacket *packet = enet_packet_create( ackreq , sizeof( *ackreq ), reliable );
85    delete ackreq;
86    return packet;
87  }
88 
89  ENetPacket* command( int dataLength, void *data, int reliable = ENET_PACKET_FLAG_RELIABLE )
90  {
91    unsigned char *stream = new unsigned char[dataLength + 2*sizeof(int)];
92    if(!stream)
93      return NULL;
94    packet_id a = COMMAND;
95    memcpy(stream, (void*)&a, sizeof(int));
96    memcpy((unsigned char *)stream+sizeof(int), (void*)&dataLength, sizeof(int));
97    memcpy((unsigned char *)stream+2*sizeof(int), data, dataLength);
98    ENetPacket *packet = enet_packet_create(stream, dataLength+2*sizeof(int), reliable);
99    delete[] stream; // TODO: we could also tell enet not to copy the data, but to use the exisiting memory
100    return packet;
101  }
102
103  /*### mouseupdates */
104  ENetPacket* PacketGenerator::mousem( double x, double y, int reliable )
105  {
106    COUT(4) << "PacketGenerator: generating new mouse" << std::endl;
107    mouse* mousemove = new mouse;
108    mousemove->id = MOUSE;
109    mousemove->x = x;
110    mousemove->y = y;
111
112    ENetPacket *packet = enet_packet_create( mousemove , sizeof( *mousemove ), reliable );
113    delete mousemove;
114    return packet;
115  }
116
117  /*### keystrikes updates */
118  ENetPacket* PacketGenerator::keystrike( char press, int reliable )
119  {
120    COUT(4) << "PacketGenerator: generating new keyboard" << std::endl;
121    keyboard* key = new keyboard;
122    key->id = KEYBOARD;
123    key->press = press;
124
125    ENetPacket *packet = enet_packet_create( key , sizeof( *key ), reliable );
126    delete key;
127    return packet;
128  }
129
130  /*### chat messages packet */
131  ENetPacket* PacketGenerator::chatMessage( const char* message, int reliable )
132  {
133    int* trans = new int[sizeof(int) + strlen(message) + 1];
134    *trans = CHAT;
135    //be carefull here, don't forget to allocate the space before using it ;-)
136    memcpy( &trans[1], (const void*)message, strlen( message ) + 1);
137    ENetPacket *packet = enet_packet_create( trans , sizeof( int ) + strlen( message ) + 1, reliable );
138    delete[] trans;
139    return packet;
140  }
141
142  /*### gamestate packet */
143  ENetPacket* PacketGenerator::gstate( GameStateCompressed* states, int reliable )
144  {
145    //std::cout << "packetgenerator" << std::endl;
146    //std::cout << "states->normsize " << states->normsize << std::endl;
147    //std::cout << "states->compsize " << states->compsize << std::endl;
148    int gid = GAMESTATE; //first assign the correct enet id
149    int totalLen = 5*sizeof( int ) + 2*sizeof(bool) + states->compsize; //calculate the total size of the datastream memory
150    //std::cout << "totalLen " << totalLen << std::endl;
151    //unsigned char *data = (unsigned char*)malloc( totalLen ); //allocate the memory for datastream
152    unsigned char *data = new unsigned char[totalLen];
153    memcpy( (void*)(data), (const void*)&gid, sizeof( int ) ); //this is the enet id
154    memcpy( (void*)(data+sizeof(int)), (const void*)&(states->id), sizeof(int) ); //the GameStateCompressed id
155    memcpy( (void*)(data+2*sizeof(int)), (const void*)&(states->compsize), sizeof(int));
156    memcpy( (void*)(data+3*sizeof(int)), (const void*)&(states->normsize), sizeof(int));
157    memcpy( (void*)(data+4*sizeof(int)), (const void*)&(states->base_id), sizeof(int));
158    memcpy( (void*)(data+5*sizeof(int)), (const void*)&(states->diffed), sizeof(bool));
159    //place the GameStateCompressed data at the end of the enet datastream
160    memcpy( (void*)(data+5*sizeof( int ) + sizeof(bool)), (const void*)&(states->complete), sizeof(bool) );
161    memcpy( (void*)(data+5*sizeof( int ) + 2*sizeof(bool)), (const void*)states->data, states->compsize );
162   
163    //create an enet packet with the generated bytestream
164    COUT(4) << "PacketGenerator generating totalLen " << totalLen << std::endl;
165    ENetPacket *packet = enet_packet_create( data , totalLen, reliable );
166    delete[] data;
167    if(!addCRC(packet))
168      COUT(3) << "could not add crc to gamestate packet" << std::endl;
169    return packet;
170  }
171
172  ENetPacket* PacketGenerator::clid( int classid, std::string classname, int reliable )
173  {
174    //unsigned char* data = (unsigned char *)malloc(3*sizeof(int)+classname.length()+1);
175    unsigned char *data = new unsigned char[3*sizeof(int)+classname.length()+1];
176    std::cout << "PacketGenerator: classid: " << classid << ", name: " << classname << std::endl;
177    *(int *)data = CLASSID;
178    *((int *)data+1) = classname.length()+1;
179    *((int *)data+2) = classid;
180    memcpy( (void *)(data+3*sizeof(int)), classname.c_str(), classname.length()+1);
181    ENetPacket *packet = enet_packet_create( data , 3*sizeof(int)+classname.length()+1, reliable );
182    delete[] data;
183    return packet;
184  }
185 
186  ENetPacket* PacketGenerator::generateWelcome( int clientID,int shipID, bool allowed , int reliable ){
187    welcome *wc = new welcome;
188    wc->id = WELCOME;
189    wc->clientID = clientID;
190    wc->shipID = shipID;
191    wc->allowed = true;
192    ENetPacket *packet = enet_packet_create( wc, sizeof(welcome), reliable);
193    delete wc;
194    return packet;
195  }
196 
197  ENetPacket* PacketGenerator::generateConnectRequest( int reliable ){
198    connectRequest *con = new connectRequest;
199    con->id=CONNECT;
200    ENetPacket *packet = enet_packet_create( con, sizeof(connectRequest), reliable);
201    delete con;
202    return packet;
203  }
204 
205 
206  bool PacketGenerator::addCRC( ENetPacket *packet){
207    unsigned char *data = packet->data;
208    uint32_t crc32=calcCRC(data, packet->dataLength);
209    // now append the crc to the packet data
210    int oldlength = packet->dataLength;
211    if(enet_packet_resize(packet, packet->dataLength+sizeof(uint32_t))==0){
212      memcpy(&packet->data[oldlength], &crc32, sizeof(uint32_t));
213      return true;
214    }else{
215      COUT(3) << "could not add crc to gamestate" << std::endl;
216      return false;
217    }
218  }
219
220}
Note: See TracBrowser for help on using the repository browser.