patch network by Tom

git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@4973 30fe4595-0a0c-4342-8851-515496e4dcbd

Former-commit-id: c4f437261298b723f149a901f615e1064b94bbf5
Former-commit-id: 3daa5a7d47becc105a5e9276435c1e743e6333f2
This commit is contained in:
torcs-ng 2012-09-30 16:05:20 +00:00
parent 4fdc297dec
commit 7c71b19968
5 changed files with 746 additions and 467 deletions

View file

@ -2,8 +2,8 @@ INCLUDE(../../../cmake/macros.cmake)
#PROJECT(networking) #PROJECT(networking)
SET(SD_NETWORK_SOURCES network.cpp server.cpp client.cpp robotxml.cpp) SET(SD_NETWORK_SOURCES network.cpp server.cpp client.cpp robotxml.cpp pack.cpp)
SET(SD_NETWORK_HEADERS network.h robotxml.h) SET(SD_NETWORK_HEADERS network.h robotxml.h pack.h)
#disable developer warning #disable developer warning
if (COMMAND cmake_policy) if (COMMAND cmake_policy)

View file

@ -17,12 +17,13 @@
* * * *
***************************************************************************/ ***************************************************************************/
#include <cstdio> #include <portability.h>
#include <SDL.h> #include <SDL.h>
#include "network.h" #include "network.h"
#include "robotxml.h" #include "robotxml.h"
#include "pack.h"
NetClient::NetClient() NetClient::NetClient()
{ {
@ -263,24 +264,24 @@ void NetClient::SetDriverReady(bool bReady)
pNData->m_vecReadyStatus[idx-1] = bReady; pNData->m_vecReadyStatus[idx-1] = bReady;
UnlockNetworkData(); UnlockNetworkData();
int packetSize = 1+sizeof(idx)+sizeof(bReady); PackedBuffer msg;
unsigned char packetId = DRIVERREADY_PACKET;
unsigned char *pData = new unsigned char[packetSize]; try
unsigned char *pDataStart = pData; {
msg.pack_ubyte(DRIVERREADY_PACKET);
msg.pack_int(idx);
msg.pack_int(bReady);
}
catch (PackedBufferException &e)
{
GfLogFatal("SetDriverReady: packed buffer error\n");
}
GfLogTrace("SetDriverReady: packed data length=%d\n", msg.length());
memcpy(pData,&packetId,1); ENetPacket *pPacket = enet_packet_create (msg.buffer(),
pData++; msg.length(),
memcpy(pData,&idx,sizeof(idx));
pData+=sizeof(idx);
memcpy(pData,&bReady,sizeof(bReady));
ENetPacket * pPacket = enet_packet_create (pDataStart,
packetSize,
ENET_PACKET_FLAG_RELIABLE); ENET_PACKET_FLAG_RELIABLE);
delete [] pDataStart;
if (enet_peer_send (m_pServer, RELIABLECHANNEL, pPacket)==0) if (enet_peer_send (m_pServer, RELIABLECHANNEL, pPacket)==0)
return; return;
} }
@ -290,19 +291,54 @@ bool NetClient::SendDriverInfoPacket(NetDriver *pDriver)
SetDriverName(pDriver->name); SetDriverName(pDriver->name);
pDriver->address.port = m_pHost->address.port; pDriver->address.port = m_pHost->address.port;
unsigned char packetId = PLAYERINFO_PACKET; GfLogTrace("SendDriverInfoPacket: pDriver\n");
int datasize = sizeof(NetDriver)+1; GfLogTrace("->host=%d\n", pDriver->address.host);
GfLogTrace("->port=%d\n", pDriver->address.port);
GfLogTrace("->idx=%d\n", pDriver->idx);
GfLogTrace("->name=%s\n", pDriver->name);
GfLogTrace("->car=%s\n", pDriver->car);
GfLogTrace("->team=%s\n", pDriver->team);
GfLogTrace("->author=%s\n", pDriver->author);
GfLogTrace("->racenumber=%d\n", pDriver->racenumber);
GfLogTrace("->skilllevel=%s\n", pDriver->skilllevel);
GfLogTrace("->red=%.1f\n", pDriver->red);
GfLogTrace("->green=%.1f\n", pDriver->green);
GfLogTrace("->blue=%.1f\n", pDriver->blue);
GfLogTrace("->module=%s\n", pDriver->module);
GfLogTrace("->type=%s\n", pDriver->type);
GfLogTrace("->client=%d\n", pDriver->client);
unsigned char *pData = new unsigned char[datasize]; PackedBuffer msg;
memcpy(&pData[0],&packetId,1);
memcpy(&pData[1],pDriver,sizeof(NetDriver));
ENetPacket * pPacket = enet_packet_create (pData, try
datasize, {
msg.pack_ubyte(PLAYERINFO_PACKET);
msg.pack_int(pDriver->idx);
msg.pack_string(pDriver->name, sizeof pDriver->name);
msg.pack_string(pDriver->car, sizeof pDriver->car);
msg.pack_string(pDriver->team, sizeof pDriver->team);
msg.pack_string(pDriver->author, sizeof pDriver->author);
msg.pack_int(pDriver->racenumber);
msg.pack_string(pDriver->skilllevel,
sizeof pDriver->skilllevel);
msg.pack_float(pDriver->red);
msg.pack_float(pDriver->green);
msg.pack_float(pDriver->blue);
msg.pack_string(pDriver->module, sizeof pDriver->module);
msg.pack_string(pDriver->type, sizeof pDriver->type);
msg.pack_int(pDriver->client);
}
catch (PackedBufferException &e)
{
GfLogFatal("SendDriverInfoPacket: packed buffer error\n");
}
GfLogTrace("SendDriverInfoPacket: packed data length=%d\n",
msg.length());
ENetPacket * pPacket = enet_packet_create (msg.buffer(),
msg.length(),
ENET_PACKET_FLAG_RELIABLE); ENET_PACKET_FLAG_RELIABLE);
delete [] pData;
if (enet_peer_send (m_pServer, RELIABLECHANNEL, pPacket)==0) if (enet_peer_send (m_pServer, RELIABLECHANNEL, pPacket)==0)
return true; return true;
@ -314,20 +350,23 @@ void NetClient::SendReadyToStartPacket()
std::string strDName = GetDriverName(); std::string strDName = GetDriverName();
GfLogTrace("Sending ready to start packet\n"); GfLogTrace("Sending ready to start packet\n");
int l = strDName.size();
int datasize = 1+sizeof(l)+l*sizeof(char);
unsigned char *pData = new unsigned char[datasize];
unsigned char packetId = CLIENTREADYTOSTART_PACKET;
unsigned char *pCurData = pData;
memcpy(pCurData,&packetId,1);
pCurData++;
memcpy(pCurData,&l,sizeof(l));
pCurData+=sizeof(l);
memcpy(pCurData,strDName.c_str(),l);
ENetPacket * pPacket = enet_packet_create (pData, PackedBuffer msg;
datasize,
try
{
msg.pack_ubyte(CLIENTREADYTOSTART_PACKET);
msg.pack_stdstring(strDName);
}
catch (PackedBufferException &e)
{
GfLogFatal("SendReadyToStartPacket: packed buffer error\n");
}
GfLogTrace("SendReadyToStartPacket: packed data length=%d\n",
msg.length());
ENetPacket *pPacket = enet_packet_create (msg.buffer(),
msg.length(),
ENET_PACKET_FLAG_RELIABLE); ENET_PACKET_FLAG_RELIABLE);
if (enet_peer_send (m_pServer, RELIABLECHANNEL, pPacket)) if (enet_peer_send (m_pServer, RELIABLECHANNEL, pPacket))
@ -338,9 +377,23 @@ void NetClient::SendReadyToStartPacket()
void NetClient::SendServerTimeRequest() void NetClient::SendServerTimeRequest()
{ {
m_packetsendtime = GfTimeClock(); m_packetsendtime = GfTimeClock();
unsigned char packetId = SERVER_TIME_REQUEST_PACKET;
ENetPacket * pPacket = enet_packet_create (&packetId, PackedBuffer msg;
1,
try
{
msg.pack_ubyte(SERVER_TIME_REQUEST_PACKET);
}
catch (PackedBufferException &e)
{
GfLogFatal("SendServerTimeRequest: packed buffer error\n");
}
GfLogTrace("SendServerTimeRequest: packed data length=%d\n",
msg.length());
ENetPacket *pPacket = enet_packet_create (msg.buffer(),
msg.length(),
ENET_PACKET_FLAG_UNSEQUENCED); ENET_PACKET_FLAG_UNSEQUENCED);
if (enet_peer_send (m_pServer, UNRELIABLECHANNEL, pPacket)) if (enet_peer_send (m_pServer, UNRELIABLECHANNEL, pPacket))
@ -361,10 +414,22 @@ double NetClient::WaitForRaceStart()
void NetClient::ReadStartTimePacket(ENetPacket *pPacket) void NetClient::ReadStartTimePacket(ENetPacket *pPacket)
{ {
GfLogTrace("Recieved the start race Packet\n"); GfLogTrace("Recieved the start race Packet\n");
unsigned char *pData = &pPacket->data[1];
memcpy(&m_racestarttime,pData,sizeof(m_racestarttime));
//double time = GfTimeClock(); //double time = GfTimeClock();
PackedBuffer msg(pPacket->data, pPacket->dataLength);
GfLogTrace("ReadStartTimePacket: packed data length=%d\n",
msg.length());
try
{
msg.unpack_ubyte();
m_racestarttime = msg.unpack_double();
}
catch (PackedBufferException &e)
{
GfLogFatal("ReadStartTimePacket: packed buffer error\n");
}
//Adjust start time based on client clock //Adjust start time based on client clock
m_racestarttime= m_racestarttime+m_servertimedifference; m_racestarttime= m_racestarttime+m_servertimedifference;
m_bBeginRace = true; m_bBeginRace = true;
@ -454,8 +519,7 @@ void NetClient::ReadPacket(ENetEvent event)
{ {
ENetPacket *pPacket = event.packet; ENetPacket *pPacket = event.packet;
assert(pPacket->dataLength>=1); assert(pPacket->dataLength>=1);
unsigned char packetId; unsigned char packetId = pPacket->data[0];
memcpy(&packetId,&pPacket->data[0],1);
//unsigned char *pData = &pPacket->data[1]; //unsigned char *pData = &pPacket->data[1];
//int datasize = pPacket->dataLength-1; //int datasize = pPacket->dataLength-1;
@ -596,30 +660,53 @@ void NetClient::ReadWeatherPacket(ENetPacket *pPacket)
} }
void NetClient::ReadAllDriverReadyPacket(ENetPacket *pPacket) void NetClient::ReadAllDriverReadyPacket(ENetPacket *pPacket)
{ {
unsigned char *pData = &pPacket->data[1];
int rsize; int rsize;
memcpy(&rsize,pData,sizeof(rsize));
pData+=sizeof(rsize);
NetMutexData *pNData = LockNetworkData();
pNData->m_vecReadyStatus.clear();
pNData->m_vecReadyStatus.resize(rsize);
bool *pReady = (bool*)pData;
for (int i=0;i<rsize;i++)
pNData->m_vecReadyStatus[i] = pReady[i];
UnlockNetworkData(); PackedBuffer msg(pPacket->data, pPacket->dataLength);
SetRaceInfoChanged(true); GfLogTrace("ReadAllDriverReadyPacket: packed data length=%d\n",
msg.length());
try
{
msg.unpack_ubyte();
rsize = msg.unpack_int();
NetMutexData *pNData = LockNetworkData();
pNData->m_vecReadyStatus.clear();
pNData->m_vecReadyStatus.resize(rsize);
for (int i=0;i<rsize;i++)
pNData->m_vecReadyStatus[i] = msg.unpack_int();
UnlockNetworkData();
SetRaceInfoChanged(true);
}
catch (PackedBufferException &e)
{
GfLogFatal("ReadAllDriverReadyPacket: packed buffer error\n");
}
GfLogTrace("Recieved All Driver Ready Packet\n"); GfLogTrace("Recieved All Driver Ready Packet\n");
} }
void NetClient::ReadFinishTimePacket(ENetPacket *pPacket) void NetClient::ReadFinishTimePacket(ENetPacket *pPacket)
{ {
unsigned char *pData = &pPacket->data[1]; PackedBuffer msg(pPacket->data, pPacket->dataLength);
GfLogTrace("ReadFinishTimePacket: packed data length=%d\n",
msg.length());
NetMutexData *pNData = LockNetworkData(); try
memcpy(&pNData->m_finishTime,pData,sizeof(pNData->m_finishTime)); {
UnlockNetworkData(); msg.unpack_ubyte();
NetMutexData *pNData = LockNetworkData();
pNData->m_finishTime = msg.unpack_double();
UnlockNetworkData();
}
catch (PackedBufferException &e)
{
GfLogFatal("ReadFinishTimePacket: packed buffer error\n");
}
GfOut("Recieved finish time packet\n"); GfOut("Recieved finish time packet\n");
} }
@ -629,37 +716,68 @@ void NetClient::ReadTimePacket(ENetPacket *pPacket)
m_lag = (curTime-m_packetsendtime)/2.0; m_lag = (curTime-m_packetsendtime)/2.0;
GfLogTrace ("Connection lag is %lf seconds\n",m_lag); GfLogTrace ("Connection lag is %lf seconds\n",m_lag);
unsigned char *pData = &pPacket->data[1];
double time; double time;
memcpy(&time,pData,sizeof(double));
PackedBuffer msg(pPacket->data, pPacket->dataLength);
GfLogTrace("ReadTimePacket: packed data length=%d\n",
msg.length());
try
{
msg.unpack_ubyte();
time = msg.unpack_double();
}
catch (PackedBufferException &e)
{
GfLogFatal("ReadTimePacket: packed buffer error\n");
}
m_servertimedifference = curTime-time; m_servertimedifference = curTime-time;
m_bTimeSynced = true; m_bTimeSynced = true;
} }
void NetClient::ReadFilePacket(ENetPacket *pPacket) void NetClient::ReadFilePacket(ENetPacket *pPacket)
{ {
unsigned char *pData = &pPacket->data[1];
short len; short len;
size_t writeSize; size_t writeSize;
memcpy(&len,pData,sizeof(short));
pData+=sizeof(short);
char file[255]; char file[255];
memset(&file[0],0,255);
memcpy(file,pData,len);
pData+=len;
unsigned int filesize; unsigned int filesize;
memcpy(&filesize,pData,sizeof(unsigned int)); char *filedata;
pData+=sizeof(unsigned int);
GfLogTrace("Client file size %u\n",filesize); memset(file, 0, sizeof file);
PackedBuffer msg(pPacket->data, pPacket->dataLength);
GfLogTrace("ReadFilePacket: packed data length=%d\n",
msg.length());
try
{
msg.unpack_ubyte();
len = msg.unpack_short();
msg.unpack_string(file, len);
filesize = msg.unpack_int();
GfLogTrace("Client file size %u\n",filesize);
filedata = new char[filesize];
msg.unpack_string(filedata, filesize);
}
catch (PackedBufferException &e)
{
GfLogFatal("ReadFilePacket: packed buffer error\n");
}
char filepath[255]; char filepath[255];
sprintf(filepath, "%s%s", GfLocalDir(), file); snprintf(filepath, sizeof filepath, "%s%s", GfLocalDir(), file);
FILE *pFile = fopen(filepath,"w+b"); FILE *pFile = fopen(filepath,"w+b");
GfLogTrace("Reading file packet: File- %s\n",filepath); GfLogTrace("Reading file packet: File- %s\n",filepath);
writeSize = fwrite(pData,filesize,1,pFile);
writeSize = fwrite(filedata, filesize, 1, pFile);
if( writeSize <= 0 ) if( writeSize <= 0 )
GfLogTrace("Not all bytes are send to file"); GfLogTrace("Not all bytes are send to file");
fclose(pFile); fclose(pFile);
delete [] filedata;
} }
void NetClient::BroadcastPacket(ENetPacket *pPacket,enet_uint8 channel) void NetClient::BroadcastPacket(ENetPacket *pPacket,enet_uint8 channel)

View file

@ -42,6 +42,7 @@ based on the server values.
#include <graphic.h> #include <graphic.h>
#include "network.h" #include "network.h"
#include "pack.h"
bool g_bInit = false; bool g_bInit = false;
@ -434,31 +435,28 @@ bool NetNetwork::SetCurrentDriver()
void NetNetwork::SendLapStatusPacket(tCarElt *pCar) void NetNetwork::SendLapStatusPacket(tCarElt *pCar)
{ {
PackedBuffer msg;
LapStatus status; try
{
msg.pack_ubyte(LAPSTATUS_PACKET);
msg.pack_double(pCar->race.bestLapTime);
msg.pack_double(*pCar->race.bestSplitTime);
msg.pack_int(pCar->race.laps);
msg.pack_int(pCar->info.startRank);
}
catch (PackedBufferException &e)
{
GfLogFatal("SendLapStatusPacket: packed buffer error\n");
}
GfLogTrace("SendLapStatusPacket: packed data length=%d\n",
msg.length());
status.bestLapTime = (float)pCar->race.bestLapTime; ENetPacket *pPacket = enet_packet_create (msg.buffer(),
status.bestSplitTime = (float)*pCar->race.bestSplitTime; msg.length(),
status.laps = pCar->race.laps; ENET_PACKET_FLAG_RELIABLE);
status.startRank = pCar->info.startRank;
int packetSize = 1+(sizeof(LapStatus));
unsigned char packetId = LAPSTATUS_PACKET;
unsigned char *pData = new unsigned char[packetSize];
unsigned char *pDataStart = pData;
memcpy(pData,&packetId,1);
pData++;
memcpy(pData,&status,sizeof(status));
ENetPacket * pPacket = enet_packet_create (pDataStart,
packetSize,
ENET_PACKET_FLAG_RELIABLE);
BroadcastPacket(pPacket,RELIABLECHANNEL); BroadcastPacket(pPacket,RELIABLECHANNEL);
delete [] pDataStart;
} }
@ -479,7 +477,7 @@ void NetNetwork::SendCarStatusPacket(tSituation *s,bool bForce)
return; return;
} }
std::vector<CarStatusPacked> vecCarStatus; std::vector<tCarElt *> local;
double time = 0.0; double time = 0.0;
@ -490,15 +488,7 @@ void NetNetwork::SendCarStatusPacket(tSituation *s,bool bForce)
//Only transmit local drivers to other clients //Only transmit local drivers to other clients
if (m_setLocalDrivers.find(pCar->info.startRank)!=m_setLocalDrivers.end()) if (m_setLocalDrivers.find(pCar->info.startRank)!=m_setLocalDrivers.end())
{ {
GfLogTrace("Sending car info: %s,startRank=%i\n",pCar->info.name,pCar->info.startRank); local.push_back(pCar);
CarStatusPacked status;
status.topSpeed = pCar->race.topSpeed;
status.state = pCar->pub.state;
status.startRank = pCar->info.startRank;
status.dammage = pCar->priv.dammage;
status.fuel = pCar->priv.fuel;
vecCarStatus.push_back(status);
} }
} }
@ -507,31 +497,39 @@ void NetNetwork::SendCarStatusPacket(tSituation *s,bool bForce)
m_sendCarDataTime = s->currentTime; m_sendCarDataTime = s->currentTime;
int iNumCars = vecCarStatus.size(); int iNumCars = local.size();
int packetSize = 1+sizeof(time)+iNumCars*sizeof(iNumCars)+iNumCars*(sizeof(CarStatusPacked));
unsigned char packetId = CARSTATUS_PACKET;
unsigned char *pData = new unsigned char[packetSize];
unsigned char *pDataStart = pData;
memcpy(pData,&packetId,1); PackedBuffer msg;
pData++;
memcpy(pData,&time,sizeof(time));
pData+=sizeof(time);
memcpy(pData,&iNumCars,sizeof(iNumCars));
pData+=sizeof(iNumCars);
for (int i=0;i<iNumCars;i++)
{
memcpy(pData,(unsigned char*)&vecCarStatus[i],sizeof(CarStatusPacked));
pData+=sizeof(CarStatusPacked);
}
ENetPacket * pPacket = enet_packet_create (pDataStart, try
packetSize, {
msg.pack_ubyte(CARSTATUS_PACKET);
msg.pack_double(time);
msg.pack_int(iNumCars);
for (int i=0;i<iNumCars;i++)
{
GfLogTrace("Sending car info: %s,startRank=%i\n",
local[i]->info.name, local[i]->info.startRank);
msg.pack_float(local[i]->race.topSpeed);
msg.pack_int(local[i]->pub.state);
msg.pack_int(local[i]->info.startRank);
msg.pack_int(local[i]->priv.dammage);
msg.pack_float(local[i]->priv.fuel);
}
}
catch (PackedBufferException &e)
{
GfLogFatal("SendCarStatusPacket: packed buffer error\n");
}
GfLogTrace("SendCarStatusPacket: packed data length=%d\n",
msg.length());
ENetPacket * pPacket = enet_packet_create (msg.buffer(),
msg.length(),
ENET_PACKET_FLAG_RELIABLE); ENET_PACKET_FLAG_RELIABLE);
BroadcastPacket(pPacket,RELIABLECHANNEL); BroadcastPacket(pPacket,RELIABLECHANNEL);
delete [] pDataStart;
} }
void NetNetwork::SendCarControlsPacket(tSituation *s) void NetNetwork::SendCarControlsPacket(tSituation *s)
@ -553,7 +551,7 @@ void NetNetwork::SendCarControlsPacket(tSituation *s)
return; return;
} }
std::vector<CarControlsPacked> vecPackedCtrls; std::vector<tCarElt *> local;
double time = 0.0; double time = 0.0;
//Pack controls values to reduce data size of packet //Pack controls values to reduce data size of packet
@ -563,17 +561,7 @@ void NetNetwork::SendCarControlsPacket(tSituation *s)
//Only transmit local drivers to other clients //Only transmit local drivers to other clients
if (m_setLocalDrivers.find(pCar->info.startRank)!=m_setLocalDrivers.end()) if (m_setLocalDrivers.find(pCar->info.startRank)!=m_setLocalDrivers.end())
{ {
CarControlsPacked ctrl; local.push_back(pCar);
ctrl.gear = pCar->ctrl.gear;
ctrl.brake = (short)(pCar->ctrl.brakeCmd*256);
ctrl.steering = (short)(pCar->ctrl.steer*256);
ctrl.throttle = (short)(pCar->ctrl.accelCmd*256);
ctrl.clutch = (short)(pCar->ctrl.clutchCmd*256);
memcpy(&ctrl.DynGCg,&pCar->pub.DynGCg,sizeof(tDynPt));
ctrl.startRank = pCar->info.startRank;
vecPackedCtrls.push_back(ctrl);
} }
} }
@ -581,40 +569,80 @@ void NetNetwork::SendCarControlsPacket(tSituation *s)
m_sendCtrlTime = s->currentTime; m_sendCtrlTime = s->currentTime;
int iNumCars = vecPackedCtrls.size(); int iNumCars = local.size();
int packetSize = 1+sizeof(time)+iNumCars*sizeof(iNumCars)+iNumCars*(sizeof(CarControlsPacked));
unsigned char packetId = CARCONTROLS_PACKET;
unsigned char *pData = new unsigned char[packetSize];
unsigned char *pDataStart = pData;
memcpy(pData,&packetId,1); PackedBuffer msg;
pData++;
memcpy(pData,&time,sizeof(time));
pData+=sizeof(time);
memcpy(pData,&iNumCars,sizeof(iNumCars));
pData+=sizeof(iNumCars);
for (int i=0;i<iNumCars;i++)
{
memcpy(pData,(unsigned char*)&vecPackedCtrls[i],sizeof(CarControlsPacked));
pData+=sizeof(CarControlsPacked);
}
ENetPacket * pPacket = enet_packet_create (pDataStart, try
packetSize, {
msg.pack_ubyte(CARCONTROLS_PACKET);
msg.pack_double(time);
msg.pack_int(iNumCars);
for (int i = 0; i < iNumCars; i++)
{
msg.pack_int(local[i]->ctrl.gear);
msg.pack_float(local[i]->ctrl.brakeCmd);
msg.pack_float(local[i]->ctrl.steer);
msg.pack_float(local[i]->ctrl.accelCmd);
msg.pack_float(local[i]->ctrl.clutchCmd);
msg.pack_int(local[i]->info.startRank);
msg.pack_float(local[i]->pub.DynGCg.pos.x);
msg.pack_float(local[i]->pub.DynGCg.pos.y);
msg.pack_float(local[i]->pub.DynGCg.pos.z);
msg.pack_float(local[i]->pub.DynGCg.pos.xy);
msg.pack_float(local[i]->pub.DynGCg.pos.ax);
msg.pack_float(local[i]->pub.DynGCg.pos.ay);
msg.pack_float(local[i]->pub.DynGCg.pos.az);
msg.pack_float(local[i]->pub.DynGCg.vel.x);
msg.pack_float(local[i]->pub.DynGCg.vel.y);
msg.pack_float(local[i]->pub.DynGCg.vel.z);
msg.pack_float(local[i]->pub.DynGCg.vel.xy);
msg.pack_float(local[i]->pub.DynGCg.vel.ax);
msg.pack_float(local[i]->pub.DynGCg.vel.ay);
msg.pack_float(local[i]->pub.DynGCg.vel.az);
msg.pack_float(local[i]->pub.DynGCg.acc.x);
msg.pack_float(local[i]->pub.DynGCg.acc.y);
msg.pack_float(local[i]->pub.DynGCg.acc.z);
msg.pack_float(local[i]->pub.DynGCg.acc.xy);
msg.pack_float(local[i]->pub.DynGCg.acc.ax);
msg.pack_float(local[i]->pub.DynGCg.acc.ay);
msg.pack_float(local[i]->pub.DynGCg.acc.az);
}
}
catch (PackedBufferException &e)
{
GfLogFatal("SendCarControlsPacket: packed buffer error\n");
}
GfLogTrace("SendCarControlsPacket: packed data length=%d\n",
msg.length());
ENetPacket * pPacket = enet_packet_create (msg.buffer(),
msg.length(),
ENET_PACKET_FLAG_UNSEQUENCED); ENET_PACKET_FLAG_UNSEQUENCED);
BroadcastPacket(pPacket,UNRELIABLECHANNEL); BroadcastPacket(pPacket,UNRELIABLECHANNEL);
delete [] pDataStart;
} }
void NetNetwork::ReadLapStatusPacket(ENetPacket *pPacket) void NetNetwork::ReadLapStatusPacket(ENetPacket *pPacket)
{ {
unsigned char *pData = &pPacket->data[1]; PackedBuffer msg(pPacket->data, pPacket->dataLength);
GfLogTrace("ReadLapStatusPacket: packed data length=%d\n",
msg.length());
LapStatus lstatus; LapStatus lstatus;
memcpy(&lstatus,pData,sizeof(lstatus));
try
{
msg.unpack_ubyte();
lstatus.bestLapTime = msg.unpack_double();
lstatus.bestSplitTime = msg.unpack_double();
lstatus.laps = msg.unpack_int();
lstatus.startRank = msg.unpack_int();
}
catch (PackedBufferException &e)
{
GfLogFatal("ReadLapStatusPacket: packed buffer error\n");
}
NetMutexData *pNData = LockNetworkData(); NetMutexData *pNData = LockNetworkData();
bool bFound = false; bool bFound = false;
@ -636,64 +664,64 @@ void NetNetwork::ReadLapStatusPacket(ENetPacket *pPacket)
void NetNetwork::ReadCarStatusPacket(ENetPacket *pPacket) void NetNetwork::ReadCarStatusPacket(ENetPacket *pPacket)
{ {
unsigned char *pData = &pPacket->data[1]; PackedBuffer msg(pPacket->data, pPacket->dataLength);
GfLogTrace("ReadCarStatusPacket: packed data length=%d\n",
msg.length());
//time double packettime;
double packettime=0; int iNumCars;
memcpy(&packettime,pData,sizeof(packettime));
pData+=sizeof(packettime);
try
{
msg.unpack_ubyte();
packettime = msg.unpack_double();
iNumCars = msg.unpack_int();
int iNumCars = 0; NetMutexData *pNData = LockNetworkData();
memcpy(&iNumCars,pData,sizeof(iNumCars));
pData+=sizeof(iNumCars); //Car conrols values (steering,brake,gas,and etc
for (int i=0;i<iNumCars;i++)
{
CarStatus status;
status.topSpeed = msg.unpack_float();
status.state = msg.unpack_int();
status.startRank = msg.unpack_int();
status.dammage = msg.unpack_int();
status.fuel = msg.unpack_float();
NetMutexData *pNData = LockNetworkData(); status.time = packettime;
//Car conrols values (steering,brake,gas,and etc
for (int i=0;i<iNumCars;i++)
{
CarStatusPacked statusPacked;
memcpy(&statusPacked,pData,sizeof(CarStatusPacked));
//Unpack values
CarStatus status;
status.state = statusPacked.state; bool bFound = false;
status.startRank =statusPacked.startRank; for (unsigned int i=0;i<pNData->m_vecCarStatus.size();i++)
{
if (pNData->m_vecCarStatus[i].startRank == status.startRank)
{
bFound = true;
//Only use the data if the time is newer. Prevent out of order packet
if (pNData->m_vecCarStatus[i].time < status.time)
{
pNData->m_vecCarStatus[i] = status;
}
else
{
GfLogTrace("Rejected car status from startRank %i\n",status.startRank);
}
GfLogTrace("Recieved car status from startRank %i\n",status.startRank);
break;
}
}
status.topSpeed = statusPacked.topSpeed; if (!bFound)
status.fuel = statusPacked.fuel; pNData->m_vecCarStatus.push_back(status);
status.dammage = statusPacked.dammage; }
status.time = packettime;
bool bFound = false;
for (unsigned int i=0;i<pNData->m_vecCarStatus.size();i++)
{
if (pNData->m_vecCarStatus[i].startRank == status.startRank)
{
bFound = true;
//Only use the data if the time is newer. Prevent out of order packet
if (pNData->m_vecCarStatus[i].time < status.time)
{
pNData->m_vecCarStatus[i] = status;
}
else
{
GfLogTrace("Rejected car status from startRank %i\n",status.startRank);
}
GfLogTrace("Recieved car status from startRank %i\n",status.startRank);
}
}
if (!bFound) UnlockNetworkData();
pNData->m_vecCarStatus.push_back(status); }
catch (PackedBufferException &e)
pData+=sizeof(CarStatusPacked); {
} GfLogFatal("ReadCarStatusPacket: packed buffer error\n");
}
UnlockNetworkData();
} }
void NetNetwork::GetHostSettings(std::string &strCarCat,bool &bCollisions) void NetNetwork::GetHostSettings(std::string &strCarCat,bool &bCollisions)
@ -711,64 +739,84 @@ void NetNetwork::GetHostSettings(std::string &strCarCat,bool &bCollisions)
void NetNetwork::ReadCarControlsPacket(ENetPacket *pPacket) void NetNetwork::ReadCarControlsPacket(ENetPacket *pPacket)
{ {
unsigned char *pData = &pPacket->data[1]; PackedBuffer msg(pPacket->data, pPacket->dataLength);
GfLogTrace("ReadCarControlsPacket: packed data length=%d\n",
//time msg.length());
double packettime=0;
memcpy(&packettime,pData,sizeof(packettime));
pData+=sizeof(packettime);
double packettime;
int iNumCars;
int iNumCars = 0; try
memcpy(&iNumCars,pData,sizeof(iNumCars)); {
pData+=sizeof(iNumCars); msg.unpack_ubyte();
packettime = msg.unpack_double();
iNumCars = msg.unpack_int();
NetMutexData *pNData = LockNetworkData();
//Car conrols values (steering,brake,gas,and etc
for (int i=0;i<iNumCars;i++)
{
CarControlsData ctrl;
NetMutexData *pNData = LockNetworkData(); ctrl.gear = msg.unpack_int();
ctrl.brake = msg.unpack_float();
//Car conrols values (steering,brake,gas,and etc ctrl.steering = msg.unpack_float();
for (int i=0;i<iNumCars;i++) ctrl.throttle = msg.unpack_float();
{ ctrl.clutch = msg.unpack_float();
CarControlsPacked ctrlPacked; ctrl.startRank = msg.unpack_int();
memcpy(&ctrlPacked,pData,sizeof(CarControlsPacked)); ctrl.DynGCg.pos.x = msg.unpack_float();
ctrl.DynGCg.pos.y = msg.unpack_float();
//Unpack values ctrl.DynGCg.pos.z = msg.unpack_float();
CarControlsData ctrl; ctrl.DynGCg.pos.xy = msg.unpack_float();
ctrl.throttle = (float)(ctrlPacked.throttle/256.0); ctrl.DynGCg.pos.ax = msg.unpack_float();
ctrl.brake = (float)(ctrlPacked.brake/256.0); ctrl.DynGCg.pos.ay = msg.unpack_float();
ctrl.clutch = (float)(ctrlPacked.clutch/256.0); ctrl.DynGCg.pos.az = msg.unpack_float();
ctrl.gear = ctrlPacked.gear; ctrl.DynGCg.vel.x = msg.unpack_float();
ctrl.steering = (float)(ctrlPacked.steering/256.0); ctrl.DynGCg.vel.y = msg.unpack_float();
ctrl.DynGCg = ctrlPacked.DynGCg; ctrl.DynGCg.vel.z = msg.unpack_float();
ctrl.startRank = ctrlPacked.startRank; ctrl.DynGCg.vel.xy = msg.unpack_float();
ctrl.time = packettime; ctrl.DynGCg.vel.ax = msg.unpack_float();
ctrl.DynGCg.vel.ay = msg.unpack_float();
ctrl.DynGCg.vel.az = msg.unpack_float();
bool bFound = false; ctrl.DynGCg.acc.x = msg.unpack_float();
for (unsigned int i=0;i<pNData->m_vecCarCtrls.size();i++) ctrl.DynGCg.acc.y = msg.unpack_float();
{ ctrl.DynGCg.acc.z = msg.unpack_float();
if (pNData->m_vecCarCtrls[i].startRank == ctrl.startRank) ctrl.DynGCg.acc.xy = msg.unpack_float();
{ ctrl.DynGCg.acc.ax = msg.unpack_float();
bFound = true; ctrl.DynGCg.acc.ay = msg.unpack_float();
//Only use the data if the time is newer. Prevent out of order packet ctrl.DynGCg.acc.az = msg.unpack_float();
if (pNData->m_vecCarCtrls[i].time < ctrl.time)
{
pNData->m_vecCarCtrls[i] = ctrl;
}
else
{
GfLogTrace("Rejected car control from startRank %i\n",ctrl.startRank);
}
}
}
if (!bFound) ctrl.time = packettime;
pNData->m_vecCarCtrls.push_back(ctrl);
pData+=sizeof(ctrlPacked); bool bFound = false;
} for (unsigned int i=0;i<pNData->m_vecCarCtrls.size();i++)
{
if (pNData->m_vecCarCtrls[i].startRank == ctrl.startRank)
{
bFound = true;
//Only use the data if the time is newer. Prevent out of order packet
if (pNData->m_vecCarCtrls[i].time < ctrl.time)
{
pNData->m_vecCarCtrls[i] = ctrl;
}
else
{
GfLogTrace("Rejected car control from startRank %i\n",ctrl.startRank);
}
}
}
UnlockNetworkData(); if (!bFound)
pNData->m_vecCarCtrls.push_back(ctrl);
}
UnlockNetworkData();
}
catch (PackedBufferException &e)
{
GfLogFatal("ReadCarControlsPacket: packed buffer error\n");
}
} }
//========================================================== //==========================================================

View file

@ -101,34 +101,33 @@ struct CarControlsPacked
//Uncompressed car controls pack //Uncompressed car controls pack
struct CarControlsData struct CarControlsData
{ {
unsigned char startRank; int startRank;
tDynPt DynGCg; /* GC global data */ tDynPt DynGCg; /* GC global data */
float steering; float steering;
float throttle; float throttle;
float brake; float brake;
float clutch; float clutch;
unsigned char gear; int gear;
double time; double time;
}; };
struct LapStatus struct LapStatus
{ {
float bestLapTime; double bestLapTime;
float bestSplitTime; double bestSplitTime;
unsigned short laps; int laps;
unsigned char startRank; int startRank;
}; };
struct CarStatus struct CarStatus
{ {
float topSpeed; float topSpeed;
short state; int state;
double time; double time;
float fuel; float fuel;
int dammage; int dammage;
unsigned char startRank; int startRank;
}; };
struct CarStatusPacked struct CarStatusPacked

View file

@ -22,6 +22,7 @@
#include "network.h" #include "network.h"
#include "robotxml.h" #include "robotxml.h"
#include "pack.h"
NetServer::NetServer() NetServer::NetServer()
@ -180,23 +181,29 @@ void NetServer::WaitForClientsStartPacket()
void NetServer::SendStartTimePacket(int &startTime) void NetServer::SendStartTimePacket(int &startTime)
{ {
unsigned char packetId = RACESTARTTIME_PACKET;
//Wait RACESTARTDELEAY seconds to start race //Wait RACESTARTDELEAY seconds to start race
m_racestarttime = GfTimeClock()+RACESTARTDELEAY; m_racestarttime = GfTimeClock()+RACESTARTDELEAY;
int datasize = sizeof(m_racestarttime)+1;
unsigned char *pData = new unsigned char[datasize];
pData[0] = packetId;
memcpy(&pData[1],&m_racestarttime,sizeof(m_racestarttime));
PackedBuffer msg;
ENetPacket * pPacket = enet_packet_create (pData, try
datasize, {
msg.pack_ubyte(RACESTARTTIME_PACKET);
msg.pack_double(m_racestarttime);
}
catch (PackedBufferException &e)
{
GfLogFatal("SendStartTimePacket: packed buffer error\n");
}
GfLogTrace("SendStartTimePacket: packed data length=%d\n",
msg.length());
ENetPacket * pPacket = enet_packet_create (msg.buffer(),
msg.length(),
ENET_PACKET_FLAG_RELIABLE); ENET_PACKET_FLAG_RELIABLE);
BroadcastPacket(pPacket,RELIABLECHANNEL); BroadcastPacket(pPacket,RELIABLECHANNEL);
delete [] pData;
GfLogInfo("Server Start time is %lf\n",m_racestarttime); GfLogInfo("Server Start time is %lf\n",m_racestarttime);
} }
double NetServer::WaitForRaceStart() double NetServer::WaitForRaceStart()
@ -482,19 +489,23 @@ bool NetServer::SendPlayerAcceptedPacket(ENetPeer * pPeer)
{ {
//Send to client requesting connection //Send to client requesting connection
unsigned char packetId = PLAYERACCEPTED_PACKET; PackedBuffer msg;
int datasize = 1;
unsigned char *pData = new unsigned char[datasize]; try
unsigned char *pDataSpot = pData; {
memcpy(pDataSpot,&packetId,1); msg.pack_ubyte(PLAYERACCEPTED_PACKET);
}
catch (PackedBufferException &e)
{
GfLogFatal("SendPlayerAcceptedPacket: packed buffer error\n");
}
GfLogTrace("SendPlayerAcceptedPacket: packed data length=%d\n",
msg.length());
ENetPacket * pPacket = enet_packet_create (pData, ENetPacket * pPacket = enet_packet_create (msg.buffer(),
datasize, msg.length(),
ENET_PACKET_FLAG_RELIABLE); ENET_PACKET_FLAG_RELIABLE);
delete [] pData;
if (enet_peer_send (pPeer, RELIABLECHANNEL, pPacket)==0) if (enet_peer_send (pPeer, RELIABLECHANNEL, pPacket)==0)
return true; return true;
@ -503,27 +514,26 @@ bool NetServer::SendPlayerAcceptedPacket(ENetPeer * pPeer)
bool NetServer::SendPlayerRejectedPacket(ENetPeer * pPeer,std::string strReason) bool NetServer::SendPlayerRejectedPacket(ENetPeer * pPeer,std::string strReason)
{ {
unsigned int l = strReason.length();
//Send to client requesting connection //Send to client requesting connection
unsigned char packetId = PLAYERREJECTED_PACKET;
int datasize = sizeof(l)+l+1;
unsigned char *pData = new unsigned char[datasize]; PackedBuffer msg;
unsigned char *pDataSpot = pData;
memcpy(pDataSpot,&packetId,1);
pDataSpot++;
memcpy(pDataSpot,&l,sizeof(l));
pDataSpot+=sizeof(l);
memcpy(pDataSpot,strReason.c_str(),l);
pDataSpot+=l;
ENetPacket * pPacket = enet_packet_create (pData, try
datasize, {
msg.pack_ubyte(PLAYERREJECTED_PACKET);
msg.pack_stdstring(strReason);
}
catch (PackedBufferException &e)
{
GfLogFatal("SendPlayerRejectedPacket: packed buffer error\n");
}
GfLogTrace("SendPlayerRejectedPacket: packed data length=%d\n",
msg.length());
ENetPacket * pPacket = enet_packet_create (msg.buffer(),
msg.length(),
ENET_PACKET_FLAG_RELIABLE); ENET_PACKET_FLAG_RELIABLE);
delete [] pData;
if (enet_peer_send (pPeer, RELIABLECHANNEL, pPacket)==0) if (enet_peer_send (pPeer, RELIABLECHANNEL, pPacket)==0)
return true; return true;
@ -533,51 +543,57 @@ bool NetServer::SendPlayerRejectedPacket(ENetPeer * pPeer,std::string strReason)
void NetServer::SendDriversReadyPacket() void NetServer::SendDriversReadyPacket()
{ {
unsigned char packetId = ALLDRIVERREADY_PACKET;
NetMutexData *pNData = LockNetworkData(); NetMutexData *pNData = LockNetworkData();
int rsize = pNData->m_vecReadyStatus.size(); int rsize = pNData->m_vecReadyStatus.size();
int datasize = 1+sizeof(rsize)+sizeof(bool)*rsize;
unsigned char *pData = new unsigned char[datasize]; PackedBuffer msg;
unsigned char *pDataSpot = pData;
memcpy(pDataSpot,&packetId,1); try
pDataSpot++; {
memcpy(pDataSpot,&rsize,sizeof(rsize)); msg.pack_ubyte(ALLDRIVERREADY_PACKET);
pDataSpot+=sizeof(rsize); msg.pack_int(rsize);
bool *pReady = (bool*)pDataSpot; for (int i = 0; i < rsize; i++)
for (int i=0;i<rsize;i++) {
{ msg.pack_int(pNData->m_vecReadyStatus[i]);
pReady[i] = pNData->m_vecReadyStatus[i]; }
} }
catch (PackedBufferException &e)
{
GfLogFatal("SendDriversReadyPacket: packed buffer error\n");
}
GfLogTrace("SendDriversReadyPacket: packed data length=%d\n",
msg.length());
UnlockNetworkData(); UnlockNetworkData();
ENetPacket * pPacket = enet_packet_create (pData, ENetPacket * pPacket = enet_packet_create (msg.buffer(),
datasize, msg.length(),
ENET_PACKET_FLAG_RELIABLE); ENET_PACKET_FLAG_RELIABLE);
delete [] pData;
BroadcastPacket(pPacket,RELIABLECHANNEL); BroadcastPacket(pPacket,RELIABLECHANNEL);
m_bRefreshDisplay = true; m_bRefreshDisplay = true;
} }
void NetServer::SendRaceSetupPacket() void NetServer::SendRaceSetupPacket()
{ {
unsigned char packetId = RACEINFOCHANGE_PACKET; PackedBuffer msg;
int datasize = 1;
unsigned char *pData = new unsigned char[datasize]; try
unsigned char *pDataSpot = pData; {
memcpy(pDataSpot,&packetId,1); msg.pack_ubyte(RACEINFOCHANGE_PACKET);
}
catch (PackedBufferException &e)
{
GfLogFatal("SendRaceSetupPacket: packed buffer error\n");
}
GfLogTrace("SendRaceSetupPacket: packed data length=%d\n",
msg.length());
ENetPacket * pPacket = enet_packet_create (pData, ENetPacket * pPacket = enet_packet_create (msg.buffer(),
datasize, msg.length(),
ENET_PACKET_FLAG_RELIABLE); ENET_PACKET_FLAG_RELIABLE);
delete [] pData;
BroadcastPacket(pPacket,RELIABLECHANNEL); BroadcastPacket(pPacket,RELIABLECHANNEL);
SetRaceInfoChanged(true); SetRaceInfoChanged(true);
@ -589,10 +605,22 @@ void NetServer::ReadDriverReadyPacket(ENetPacket *pPacket)
GfLogTrace ("Read Driver Ready Packet\n"); GfLogTrace ("Read Driver Ready Packet\n");
int idx; int idx;
memcpy(&idx,&pPacket->data[1],sizeof(idx));
int spot = sizeof(idx)+1;
bool bReady; bool bReady;
memcpy(&bReady,&pPacket->data[spot],sizeof(bReady));
PackedBuffer msg(pPacket->data, pPacket->dataLength);
GfLogTrace("ReadDriverReadyPacket: packed data length=%d\n",
msg.length());
try
{
msg.unpack_ubyte();
idx = msg.unpack_int();
bReady = msg.unpack_int();
}
catch (PackedBufferException &e)
{
GfLogFatal("SendRaceSetupPacket: packed buffer error\n");
}
NetMutexData *pNData = LockNetworkData(); NetMutexData *pNData = LockNetworkData();
pNData->m_vecReadyStatus[idx-1] = bReady; pNData->m_vecReadyStatus[idx-1] = bReady;
@ -603,8 +631,6 @@ void NetServer::ReadDriverReadyPacket(ENetPacket *pPacket)
void NetServer::ReadDriverInfoPacket(ENetPacket *pPacket, ENetPeer * pPeer) void NetServer::ReadDriverInfoPacket(ENetPacket *pPacket, ENetPeer * pPeer)
{ {
assert(pPacket->dataLength==(sizeof(NetDriver)+1));
NetDriver driver; NetDriver driver;
char hostName[256]; char hostName[256];
@ -612,7 +638,48 @@ void NetServer::ReadDriverInfoPacket(ENetPacket *pPacket, ENetPeer * pPeer)
GfLogTrace ("Client Player Info connected from %s\n",hostName); GfLogTrace ("Client Player Info connected from %s\n",hostName);
memcpy(&driver,&pPacket->data[1],sizeof(NetDriver)); PackedBuffer msg(pPacket->data, pPacket->dataLength);
GfLogTrace("ReadDriverInfoPacket: packed data length=%d\n",
msg.length());
try
{
msg.unpack_ubyte();
driver.idx = msg.unpack_int();
msg.unpack_string(driver.name, sizeof driver.name);
msg.unpack_string(driver.car, sizeof driver.car);
msg.unpack_string(driver.team, sizeof driver.team);
msg.unpack_string(driver.author, sizeof driver.author);
driver.racenumber = msg.unpack_int();
msg.unpack_string(driver.skilllevel, sizeof driver.skilllevel);
driver.red = msg.unpack_float();
driver.green = msg.unpack_float();
driver.blue = msg.unpack_float();
msg.unpack_string(driver.module, sizeof driver.module);
msg.unpack_string(driver.type, sizeof driver.type);
driver.client = msg.unpack_int();
}
catch (PackedBufferException &e)
{
GfLogFatal("ReadDriverInfoPacket: packed buffer error\n");
}
GfLogTrace("ReadDriverInfoPacket: driver\n");
GfLogTrace(".host=%d\n", driver.address.host);
GfLogTrace(".port=%d\n", driver.address.port);
GfLogTrace(".idx=%d\n", driver.idx);
GfLogTrace(".name=%s\n", driver.name);
GfLogTrace(".car=%s\n", driver.car);
GfLogTrace(".team=%s\n", driver.team);
GfLogTrace(".author=%s\n", driver.author);
GfLogTrace(".racenumber=%d\n", driver.racenumber);
GfLogTrace(".skilllevel=%s\n", driver.skilllevel);
GfLogTrace(".red=%.1f\n", driver.red);
GfLogTrace(".green=%.1f\n", driver.green);
GfLogTrace(".blue=%.1f\n", driver.blue);
GfLogTrace(".module=%s\n", driver.module);
GfLogTrace(".type=%s\n", driver.type);
GfLogTrace(".client=%d\n", driver.client);
//Make sure player name is unique otherwise disconnect player //Make sure player name is unique otherwise disconnect player
NetServerMutexData *pSData = LockServerData(); NetServerMutexData *pSData = LockServerData();
@ -659,12 +726,23 @@ void NetServer::SendWeatherPacket()
{ {
GfLogTrace("Sending Weather Packet\n"); GfLogTrace("Sending Weather Packet\n");
unsigned char packetId = WEATHERCHANGE_PACKET; PackedBuffer msg;
//TODO add weather data here
try
ENetPacket * pWeatherPacket = enet_packet_create (&packetId, {
1, msg.pack_ubyte(WEATHERCHANGE_PACKET);
ENET_PACKET_FLAG_RELIABLE); //TODO add weather data here
}
catch (PackedBufferException &e)
{
GfLogFatal("SendWeatherPacket: packed buffer error\n");
}
GfLogTrace("SendWeatherPacket: packed data length=%d\n",
msg.length());
ENetPacket *pWeatherPacket = enet_packet_create(msg.buffer(),
msg.length(),
ENET_PACKET_FLAG_RELIABLE);
BroadcastPacket(pWeatherPacket,RELIABLECHANNEL); BroadcastPacket(pWeatherPacket,RELIABLECHANNEL);
@ -673,22 +751,27 @@ void NetServer::SendWeatherPacket()
void NetServer::SendTimePacket(ENetPacket *pPacketRec, ENetPeer * pPeer) void NetServer::SendTimePacket(ENetPacket *pPacketRec, ENetPeer * pPeer)
{ {
GfLogTrace("Sending Time Packet\n"); GfLogTrace("Sending Time Packet\n");
int packetSize = 1+sizeof(double);
unsigned char *pData = new unsigned char[packetSize];
unsigned char *pDataStart = pData;
unsigned char packetId = SERVER_TIME_SYNC_PACKET;
memcpy(pData,&packetId,1);
pData++;
double time = GfTimeClock(); double time = GfTimeClock();
GfLogTrace("\nServer time is %lf",time); GfLogTrace("\nServer time is %lf",time);
memcpy(pData,&time,sizeof(time)); PackedBuffer msg;
pData+=sizeof(time);
try
{
msg.pack_ubyte(SERVER_TIME_SYNC_PACKET);
msg.pack_double(time);
}
catch (PackedBufferException &e)
{
GfLogFatal("SendTimePacket: packed buffer error\n");
}
GfLogTrace("SendTimePacket: packed data length=%d\n",
msg.length());
//TODO change to peer send //TODO change to peer send
ENetPacket * pPacket = enet_packet_create (pDataStart, ENetPacket * pPacket = enet_packet_create (msg.buffer(),
packetSize, msg.length(),
ENET_PACKET_FLAG_UNSEQUENCED); ENET_PACKET_FLAG_UNSEQUENCED);
enet_peer_send (pPeer, UNRELIABLECHANNEL, pPacket); enet_peer_send (pPeer, UNRELIABLECHANNEL, pPacket);
@ -723,29 +806,36 @@ void NetServer::SendFilePacket(const char *pszFile)
fclose(pFile); fclose(pFile);
unsigned int filesize = size; unsigned int filesize = size;
int datasize = filesize+sizeof(short)+sizeof(unsigned int)+strlen(pszFile)+1;
unsigned char *pDataPacket = new unsigned char[datasize];
memset(pDataPacket,0,datasize);
unsigned char *pData = pDataPacket;
unsigned char packetId = FILE_PACKET;
memcpy(&pData[0],&packetId,1);
pData++;
short namelen = strlen(pszFile);
memcpy(pData,&namelen,sizeof(short));
pData+=sizeof(short);
memcpy(pData,pszFile,namelen);
pData+=namelen;
memcpy(pData,&filesize,sizeof(unsigned int));
GfLogTrace("Server file size %u\n",filesize); GfLogTrace("Server file size %u\n",filesize);
pData+=sizeof(unsigned int);
memcpy(pData,buf,size);
ENetPacket * pPacket = enet_packet_create (pDataPacket, short namelen = strlen(pszFile);
datasize,
/* On 64 bit systems, the following calculates a buffer size that is
* bigger than necessary, but that is safe. Better too big than too
* small.
*/
size_t bufsize = 1 + sizeof namelen + namelen +
sizeof filesize + filesize;
PackedBuffer msg(bufsize);
try
{
msg.pack_ubyte(FILE_PACKET);
msg.pack_short(namelen);
msg.pack_string(pszFile, namelen);
msg.pack_uint(filesize);
msg.pack_string(buf, size);
}
catch (PackedBufferException &e)
{
GfLogFatal("SendFilePacket: packed buffer error\n");
}
GfLogTrace("SendFilePacket: packed data length=%d\n",
msg.length());
ENetPacket * pPacket = enet_packet_create (msg.buffer(),
msg.length(),
ENET_PACKET_FLAG_RELIABLE); ENET_PACKET_FLAG_RELIABLE);
BroadcastPacket(pPacket,RELIABLECHANNEL); BroadcastPacket(pPacket,RELIABLECHANNEL);
@ -811,7 +901,7 @@ bool NetServer::listen()
void NetServer::RemovePlayerFromRace(unsigned int idx) void NetServer::RemovePlayerFromRace(unsigned int idx)
{ {
GfLogTrace("Removing disconnected player\n"); GfLogTrace("Removing disconnected player\n");
std::vector<CarStatusPacked> vecCarStatus; std::vector<CarStatus> vecCarStatus;
double time = 0.0; double time = 0.0;
int startRank = GetDriverStartRank(idx); int startRank = GetDriverStartRank(idx);
@ -827,103 +917,110 @@ void NetServer::RemovePlayerFromRace(unsigned int idx)
pNData->m_vecCarStatus.push_back(cstatus); pNData->m_vecCarStatus.push_back(cstatus);
UnlockNetworkData(); UnlockNetworkData();
vecCarStatus.push_back(cstatus);
//Pack controls values to reduce data size of packet
CarStatusPacked status;
status.topSpeed = -1.0;
status.state = RM_CAR_STATE_ELIMINATED;
status.startRank = startRank;
status.dammage = -1;
status.fuel = -1.0;
vecCarStatus.push_back(status);
time = m_currentTime; time = m_currentTime;
int iNumCars = vecCarStatus.size(); int iNumCars = vecCarStatus.size();
int packetSize = 1+sizeof(time)+iNumCars*sizeof(iNumCars)+iNumCars*(sizeof(CarStatusPacked));
unsigned char packetId = CARSTATUS_PACKET;
unsigned char *pData = new unsigned char[packetSize];
unsigned char *pDataStart = pData;
memcpy(pData,&packetId,1); PackedBuffer msg;
pData++;
memcpy(pData,&time,sizeof(time));
pData+=sizeof(time);
memcpy(pData,&iNumCars,sizeof(iNumCars));
pData+=sizeof(iNumCars);
for (int i=0;i<iNumCars;i++)
{
memcpy(pData,(unsigned char*)&vecCarStatus[i],sizeof(CarStatusPacked));
pData+=sizeof(CarStatusPacked);
}
ENetPacket * pPacket = enet_packet_create (pDataStart, try
packetSize, {
msg.pack_ubyte(CARSTATUS_PACKET);
msg.pack_double(time);
msg.pack_int(iNumCars);
for (int i=0;i<iNumCars;i++)
{
msg.pack_float(vecCarStatus[i].topSpeed);
msg.pack_int(vecCarStatus[i].state);
msg.pack_int(vecCarStatus[i].startRank);
msg.pack_int(vecCarStatus[i].dammage);
msg.pack_float(vecCarStatus[i].fuel);
}
}
catch (PackedBufferException &e)
{
GfLogFatal("RemovePlayerFromRace: packed buffer error\n");
}
GfLogTrace("RemovePlayerFromRace: packed data length=%d\n",
msg.length());
ENetPacket * pPacket = enet_packet_create (msg.buffer(),
msg.length(),
ENET_PACKET_FLAG_RELIABLE); ENET_PACKET_FLAG_RELIABLE);
BroadcastPacket(pPacket,RELIABLECHANNEL); BroadcastPacket(pPacket,RELIABLECHANNEL);
delete [] pDataStart;
} }
void NetServer::ReadPacket(ENetEvent event) void NetServer::ReadPacket(ENetEvent event)
{ {
ENetPacket *pPacket = event.packet; ENetPacket *pPacket = event.packet;
assert(pPacket->dataLength>=1); assert(pPacket->dataLength>=1);
unsigned char packetId; unsigned char packetId = pPacket->data[0];
memcpy(&packetId,&pPacket->data[0],1);
unsigned char *pData = &pPacket->data[1];
//int datasize = pPacket->dataLength-1; //int datasize = pPacket->dataLength-1;
switch (packetId) switch (packetId)
{ {
case PLAYERINFO_PACKET: case PLAYERINFO_PACKET:
GfLogTrace("PlayerInfo Packet\n"); GfLogTrace("PlayerInfo Packet\n");
ReadDriverInfoPacket(pPacket,event.peer); ReadDriverInfoPacket(pPacket,event.peer);
break; break;
case CLIENTREADYTOSTART_PACKET: case CLIENTREADYTOSTART_PACKET:
{ {
int l; int l;
char name[256]; char name[256];
memset(&name[0],0,256); memset(&name[0],0,256);
memcpy(&l,pData,sizeof(l));
pData+=sizeof(l);
memcpy(name,pData,l);
std::vector<NetDriver>::iterator p;
p = m_vecWaitForPlayers.begin();
while(p!=m_vecWaitForPlayers.end())
{
if (strcmp(p->name,name)==0)
{
GfLogTrace("%s ready to start\n",&name[0]);
m_vecWaitForPlayers.erase(p);
break;
}
p++; PackedBuffer msg(pPacket->data, pPacket->dataLength);
} GfLogTrace("ReadPacket: packed data length=%d\n",
msg.length());
if (m_vecWaitForPlayers.size()==0) try
m_bBeginRace = true; {
msg.unpack_ubyte();
l = msg.unpack_int();
msg.unpack_string(name, l);
}
catch (PackedBufferException &e)
{
GfLogFatal("ReadPacket: packed buffer error\n");
}
} std::vector<NetDriver>::iterator p;
break; p = m_vecWaitForPlayers.begin();
case SERVER_TIME_REQUEST_PACKET: while(p!=m_vecWaitForPlayers.end())
SendTimePacket(pPacket,event.peer); {
break; if (strcmp(p->name,name)==0)
case CARCONTROLS_PACKET: {
ReadCarControlsPacket(event.packet); GfLogTrace("%s ready to start\n",&name[0]);
break; m_vecWaitForPlayers.erase(p);
case CARSTATUS_PACKET: break;
ReadCarStatusPacket(event.packet); }
break;
case LAPSTATUS_PACKET: p++;
ReadLapStatusPacket(event.packet); }
break;
case DRIVERREADY_PACKET: if (m_vecWaitForPlayers.size()==0)
ReadDriverReadyPacket(event.packet); m_bBeginRace = true;
break;
}
break;
case SERVER_TIME_REQUEST_PACKET:
SendTimePacket(pPacket,event.peer);
break;
case CARCONTROLS_PACKET:
ReadCarControlsPacket(event.packet);
break;
case CARSTATUS_PACKET:
ReadCarStatusPacket(event.packet);
break;
case LAPSTATUS_PACKET:
ReadLapStatusPacket(event.packet);
break;
case DRIVERREADY_PACKET:
ReadDriverReadyPacket(event.packet);
break;
default: default:
GfLogTrace ("A packet of length %u containing %s was received from %s on channel %u.\n", GfLogTrace ("A packet of length %u containing %s was received from %s on channel %u.\n",
@ -940,24 +1037,28 @@ void NetServer::SendFinishTimePacket()
{ {
GfLogTrace("Sending finish Time Packet\n"); GfLogTrace("Sending finish Time Packet\n");
int packetSize = 1+sizeof(double);
unsigned char *pData = new unsigned char[packetSize];
unsigned char *pDataStart = pData;
unsigned char packetId = FINISHTIME_PACKET;
memcpy(pData,&packetId,1);
pData++;
NetMutexData *pNData = LockNetworkData(); NetMutexData *pNData = LockNetworkData();
double time = pNData->m_finishTime; double time = pNData->m_finishTime;
UnlockNetworkData(); UnlockNetworkData();
GfLogInfo("Server finish time is %lf\n",time); GfLogInfo("Server finish time is %lf\n",time);
PackedBuffer msg;
memcpy(pData,&time,sizeof(time)); try
pData+=sizeof(time); {
msg.pack_ubyte(FINISHTIME_PACKET);
msg.pack_double(time);
}
catch (PackedBufferException &e)
{
GfLogFatal("SendFinishTimePacket: packed buffer error\n");
}
GfLogTrace("SendFinishTimePacket: packed data length=%d\n",
msg.length());
ENetPacket * pPacket = enet_packet_create (pDataStart, ENetPacket * pPacket = enet_packet_create (msg.buffer(),
packetSize, msg.length(),
ENET_PACKET_FLAG_RELIABLE); ENET_PACKET_FLAG_RELIABLE);
BroadcastPacket(pPacket,RELIABLECHANNEL); BroadcastPacket(pPacket,RELIABLECHANNEL);
} }
@ -980,9 +1081,22 @@ void NetServer::SendPrepareToRacePacket()
m_bBeginRace = true; m_bBeginRace = true;
////TODO send needed xml files to race ////TODO send needed xml files to race
unsigned char packetId = PREPARETORACE_PACKET;
ENetPacket * pPacket = enet_packet_create (&packetId, PackedBuffer msg;
1,
try
{
msg.pack_ubyte(PREPARETORACE_PACKET);
}
catch (PackedBufferException &e)
{
GfLogFatal("SendPrepareToRacePacket: packed buffer error\n");
}
GfLogTrace("SendPrepareToRacePacket: packed data length=%d\n",
msg.length());
ENetPacket * pPacket = enet_packet_create (msg.buffer(),
msg.length(),
ENET_PACKET_FLAG_RELIABLE); ENET_PACKET_FLAG_RELIABLE);
BroadcastPacket(pPacket,RELIABLECHANNEL); BroadcastPacket(pPacket,RELIABLECHANNEL);