Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/network/src/network/PacketGenerator.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: 7.5 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   
81    ENetPacket *packet = enet_packet_create( NULL , sizeof( ack ), reliable );
82    ack* ackreq = (ack *)packet->data;
83    ackreq->id = ACK;
84    ackreq->a = state;
85    //delete ackreq;
86    return packet;
87  }
88 
89  ENetPacket* command( int dataLength, void *data, int reliable = ENET_PACKET_FLAG_RELIABLE )
90  {
91    if(dataLength==0)
92      return NULL;
93    unsigned char *stream = new unsigned char[dataLength + 2*sizeof(int)];
94    if(!stream)
95      return NULL;
96    packet_id a = COMMAND;
97    memcpy(stream, (void*)&a, sizeof(int));
98    memcpy((unsigned char *)stream+sizeof(int), (void*)&dataLength, sizeof(int));
99    memcpy((unsigned char *)stream+2*sizeof(int), data, dataLength);
100    ENetPacket *packet = enet_packet_create(stream, dataLength+2*sizeof(int), reliable);
101    delete[] stream; // TODO: we could also tell enet not to copy the data, but to use the exisiting memory
102    return packet;
103  }
104
105
106  /*### chat messages packet */
107  ENetPacket* PacketGenerator::chatMessage( const char* message, int reliable )
108  {
109    int* trans = new int[sizeof(int) + strlen(message) + 1];
110    *trans = CHAT;
111    //be carefull here, don't forget to allocate the space before using it ;-)
112    memcpy( &trans[1], (const void*)message, strlen( message ) + 1);
113    ENetPacket *packet = enet_packet_create( trans , sizeof( int ) + strlen( message ) + 1, reliable );
114    delete[] trans;
115    return packet;
116  }
117
118  /*### gamestate packet */
119  ENetPacket* PacketGenerator::gstate( GameStateCompressed* states, int reliable )
120  {
121    //std::cout << "packetgenerator" << std::endl;
122    //std::cout << "states->normsize " << states->normsize << std::endl;
123    //std::cout << "states->compsize " << states->compsize << std::endl;
124    int gid = GAMESTATE; //first assign the correct enet id
125    int totalLen = 5*sizeof( int ) + 2*sizeof(bool) + states->compsize; //calculate the total size of the datastream memory
126    //std::cout << "totalLen " << totalLen << std::endl;
127    //unsigned char *data = (unsigned char*)malloc( totalLen ); //allocate the memory for datastream
128    if(totalLen==0)
129      return NULL;
130    ENetPacket *packet = enet_packet_create( NULL , totalLen+sizeof(uint32_t), reliable );
131    //unsigned char *data = new unsigned char[totalLen];
132    unsigned char *data = packet->data;
133    memcpy( (void*)(data), (const void*)&gid, sizeof( int ) ); //this is the enet id
134    memcpy( (void*)(data+sizeof(int)), (const void*)&(states->id), sizeof(int) ); //the GameStateCompressed id
135    memcpy( (void*)(data+2*sizeof(int)), (const void*)&(states->compsize), sizeof(int));
136    memcpy( (void*)(data+3*sizeof(int)), (const void*)&(states->normsize), sizeof(int));
137    memcpy( (void*)(data+4*sizeof(int)), (const void*)&(states->base_id), sizeof(int));
138    memcpy( (void*)(data+5*sizeof(int)), (const void*)&(states->diffed), sizeof(bool));
139    //place the GameStateCompressed data at the end of the enet datastream
140    memcpy( (void*)(data+5*sizeof( int ) + sizeof(bool)), (const void*)&(states->complete), sizeof(bool) );
141    memcpy( (void*)(data+5*sizeof( int ) + 2*sizeof(bool)), (const void*)states->data, states->compsize );
142   
143    //create an enet packet with the generated bytestream
144    COUT(4) << "PacketGenerator generating totalLen " << totalLen << std::endl;
145    //delete[] data;
146    if(!addCRC(packet))
147      COUT(3) << "could not add crc to gamestate packet" << std::endl;
148    return packet;
149  }
150
151  ENetPacket* PacketGenerator::clid( int classid, std::string classname, int reliable )
152  {
153    //unsigned char* data = (unsigned char *)malloc(3*sizeof(int)+classname.length()+1);
154    if(classname.length()==0)
155      return NULL;
156    unsigned char *data = new unsigned char[3*sizeof(int)+classname.length()+1];
157    std::cout << "PacketGenerator: classid: " << classid << ", name: " << classname << std::endl;
158    *(int *)data = CLASSID;
159    *((int *)data+1) = classname.length()+1;
160    *((int *)data+2) = classid;
161    memcpy( (void *)(data+3*sizeof(int)), classname.c_str(), classname.length()+1);
162    ENetPacket *packet = enet_packet_create( data , 3*sizeof(int)+classname.length()+1, reliable );
163    delete[] data;
164    return packet;
165  }
166 
167  ENetPacket* PacketGenerator::generateWelcome( int clientID,int shipID, bool allowed , int reliable ){
168    welcome *wc = new welcome;
169    wc->id = WELCOME;
170    wc->clientID = clientID;
171    wc->shipID = shipID;
172    wc->allowed = true;
173    ENetPacket *packet = enet_packet_create( wc, sizeof(welcome), reliable);
174    delete wc;
175    return packet;
176  }
177 
178  ENetPacket* PacketGenerator::generateConnectRequest( int reliable ){
179    connectRequest *con = new connectRequest;
180    con->id=CONNECT;
181    ENetPacket *packet = enet_packet_create( con, sizeof(connectRequest), reliable);
182    delete con;
183    return packet;
184  }
185 
186 
187  bool PacketGenerator::addCRC( ENetPacket *packet){
188    unsigned char *data = packet->data;
189    uint32_t crc32=calcCRC(data, packet->dataLength-sizeof(uint32_t));
190    // now append the crc to the packet data
191    int oldlength = packet->dataLength-sizeof(uint32_t);
192    //if(enet_packet_resize(packet, packet->dataLength+sizeof(uint32_t))==0){
193      memcpy(&packet->data[oldlength], &crc32, sizeof(uint32_t));
194      return true;
195    //}else{
196     // COUT(3) << "could not add crc to gamestate" << std::endl;
197     // return false;
198    //}
199  }
200
201}
Note: See TracBrowser for help on using the repository browser.