Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/input/src/network/PacketGenerator.cc @ 1528

Last change on this file since 1528 was 1505, checked in by rgrieder, 16 years ago

f* svn: It doesn't even inform you if you attempt to set a non existing property. It is svn:eol-style and not eol-style when using the command by the way…

  • 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.