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:
parent
4fdc297dec
commit
7c71b19968
5 changed files with 746 additions and 467 deletions
|
@ -2,8 +2,8 @@ INCLUDE(../../../cmake/macros.cmake)
|
|||
|
||||
#PROJECT(networking)
|
||||
|
||||
SET(SD_NETWORK_SOURCES network.cpp server.cpp client.cpp robotxml.cpp)
|
||||
SET(SD_NETWORK_HEADERS network.h robotxml.h)
|
||||
SET(SD_NETWORK_SOURCES network.cpp server.cpp client.cpp robotxml.cpp pack.cpp)
|
||||
SET(SD_NETWORK_HEADERS network.h robotxml.h pack.h)
|
||||
|
||||
#disable developer warning
|
||||
if (COMMAND cmake_policy)
|
||||
|
|
|
@ -17,12 +17,13 @@
|
|||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include <cstdio>
|
||||
#include <portability.h>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "network.h"
|
||||
#include "robotxml.h"
|
||||
#include "pack.h"
|
||||
|
||||
NetClient::NetClient()
|
||||
{
|
||||
|
@ -263,24 +264,24 @@ void NetClient::SetDriverReady(bool bReady)
|
|||
pNData->m_vecReadyStatus[idx-1] = bReady;
|
||||
UnlockNetworkData();
|
||||
|
||||
int packetSize = 1+sizeof(idx)+sizeof(bReady);
|
||||
unsigned char packetId = DRIVERREADY_PACKET;
|
||||
PackedBuffer msg;
|
||||
|
||||
unsigned char *pData = new unsigned char[packetSize];
|
||||
unsigned char *pDataStart = pData;
|
||||
try
|
||||
{
|
||||
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);
|
||||
pData++;
|
||||
|
||||
memcpy(pData,&idx,sizeof(idx));
|
||||
pData+=sizeof(idx);
|
||||
memcpy(pData,&bReady,sizeof(bReady));
|
||||
|
||||
ENetPacket * pPacket = enet_packet_create (pDataStart,
|
||||
packetSize,
|
||||
ENetPacket *pPacket = enet_packet_create (msg.buffer(),
|
||||
msg.length(),
|
||||
ENET_PACKET_FLAG_RELIABLE);
|
||||
|
||||
delete [] pDataStart;
|
||||
if (enet_peer_send (m_pServer, RELIABLECHANNEL, pPacket)==0)
|
||||
return;
|
||||
}
|
||||
|
@ -290,19 +291,54 @@ bool NetClient::SendDriverInfoPacket(NetDriver *pDriver)
|
|||
SetDriverName(pDriver->name);
|
||||
pDriver->address.port = m_pHost->address.port;
|
||||
|
||||
unsigned char packetId = PLAYERINFO_PACKET;
|
||||
int datasize = sizeof(NetDriver)+1;
|
||||
GfLogTrace("SendDriverInfoPacket: pDriver\n");
|
||||
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];
|
||||
memcpy(&pData[0],&packetId,1);
|
||||
memcpy(&pData[1],pDriver,sizeof(NetDriver));
|
||||
PackedBuffer msg;
|
||||
|
||||
ENetPacket * pPacket = enet_packet_create (pData,
|
||||
datasize,
|
||||
try
|
||||
{
|
||||
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);
|
||||
|
||||
delete [] pData;
|
||||
|
||||
if (enet_peer_send (m_pServer, RELIABLECHANNEL, pPacket)==0)
|
||||
return true;
|
||||
|
||||
|
@ -314,20 +350,23 @@ void NetClient::SendReadyToStartPacket()
|
|||
|
||||
std::string strDName = GetDriverName();
|
||||
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,
|
||||
datasize,
|
||||
PackedBuffer msg;
|
||||
|
||||
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);
|
||||
|
||||
if (enet_peer_send (m_pServer, RELIABLECHANNEL, pPacket))
|
||||
|
@ -338,9 +377,23 @@ void NetClient::SendReadyToStartPacket()
|
|||
void NetClient::SendServerTimeRequest()
|
||||
{
|
||||
m_packetsendtime = GfTimeClock();
|
||||
unsigned char packetId = SERVER_TIME_REQUEST_PACKET;
|
||||
ENetPacket * pPacket = enet_packet_create (&packetId,
|
||||
1,
|
||||
|
||||
PackedBuffer msg;
|
||||
|
||||
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);
|
||||
|
||||
if (enet_peer_send (m_pServer, UNRELIABLECHANNEL, pPacket))
|
||||
|
@ -361,10 +414,22 @@ double NetClient::WaitForRaceStart()
|
|||
void NetClient::ReadStartTimePacket(ENetPacket *pPacket)
|
||||
{
|
||||
GfLogTrace("Recieved the start race Packet\n");
|
||||
unsigned char *pData = &pPacket->data[1];
|
||||
memcpy(&m_racestarttime,pData,sizeof(m_racestarttime));
|
||||
//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
|
||||
m_racestarttime= m_racestarttime+m_servertimedifference;
|
||||
m_bBeginRace = true;
|
||||
|
@ -454,8 +519,7 @@ void NetClient::ReadPacket(ENetEvent event)
|
|||
{
|
||||
ENetPacket *pPacket = event.packet;
|
||||
assert(pPacket->dataLength>=1);
|
||||
unsigned char packetId;
|
||||
memcpy(&packetId,&pPacket->data[0],1);
|
||||
unsigned char packetId = pPacket->data[0];
|
||||
//unsigned char *pData = &pPacket->data[1];
|
||||
//int datasize = pPacket->dataLength-1;
|
||||
|
||||
|
@ -596,30 +660,53 @@ void NetClient::ReadWeatherPacket(ENetPacket *pPacket)
|
|||
}
|
||||
void NetClient::ReadAllDriverReadyPacket(ENetPacket *pPacket)
|
||||
{
|
||||
unsigned char *pData = &pPacket->data[1];
|
||||
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();
|
||||
SetRaceInfoChanged(true);
|
||||
PackedBuffer msg(pPacket->data, pPacket->dataLength);
|
||||
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");
|
||||
}
|
||||
|
||||
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();
|
||||
memcpy(&pNData->m_finishTime,pData,sizeof(pNData->m_finishTime));
|
||||
UnlockNetworkData();
|
||||
try
|
||||
{
|
||||
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");
|
||||
}
|
||||
|
||||
|
@ -629,37 +716,68 @@ void NetClient::ReadTimePacket(ENetPacket *pPacket)
|
|||
m_lag = (curTime-m_packetsendtime)/2.0;
|
||||
GfLogTrace ("Connection lag is %lf seconds\n",m_lag);
|
||||
|
||||
unsigned char *pData = &pPacket->data[1];
|
||||
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_bTimeSynced = true;
|
||||
}
|
||||
void NetClient::ReadFilePacket(ENetPacket *pPacket)
|
||||
{
|
||||
|
||||
unsigned char *pData = &pPacket->data[1];
|
||||
short len;
|
||||
size_t writeSize;
|
||||
memcpy(&len,pData,sizeof(short));
|
||||
pData+=sizeof(short);
|
||||
char file[255];
|
||||
memset(&file[0],0,255);
|
||||
memcpy(file,pData,len);
|
||||
pData+=len;
|
||||
unsigned int filesize;
|
||||
memcpy(&filesize,pData,sizeof(unsigned int));
|
||||
pData+=sizeof(unsigned int);
|
||||
GfLogTrace("Client file size %u\n",filesize);
|
||||
char *filedata;
|
||||
|
||||
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];
|
||||
sprintf(filepath, "%s%s", GfLocalDir(), file);
|
||||
snprintf(filepath, sizeof filepath, "%s%s", GfLocalDir(), file);
|
||||
|
||||
FILE *pFile = fopen(filepath,"w+b");
|
||||
GfLogTrace("Reading file packet: File- %s\n",filepath);
|
||||
writeSize = fwrite(pData,filesize,1,pFile);
|
||||
|
||||
writeSize = fwrite(filedata, filesize, 1, pFile);
|
||||
if( writeSize <= 0 )
|
||||
GfLogTrace("Not all bytes are send to file");
|
||||
fclose(pFile);
|
||||
|
||||
delete [] filedata;
|
||||
}
|
||||
|
||||
void NetClient::BroadcastPacket(ENetPacket *pPacket,enet_uint8 channel)
|
||||
|
|
|
@ -42,6 +42,7 @@ based on the server values.
|
|||
#include <graphic.h>
|
||||
|
||||
#include "network.h"
|
||||
#include "pack.h"
|
||||
|
||||
|
||||
bool g_bInit = false;
|
||||
|
@ -434,31 +435,28 @@ bool NetNetwork::SetCurrentDriver()
|
|||
|
||||
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;
|
||||
status.bestSplitTime = (float)*pCar->race.bestSplitTime;
|
||||
status.laps = pCar->race.laps;
|
||||
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);
|
||||
ENetPacket *pPacket = enet_packet_create (msg.buffer(),
|
||||
msg.length(),
|
||||
ENET_PACKET_FLAG_RELIABLE);
|
||||
|
||||
BroadcastPacket(pPacket,RELIABLECHANNEL);
|
||||
|
||||
delete [] pDataStart;
|
||||
}
|
||||
|
||||
|
||||
|
@ -479,7 +477,7 @@ void NetNetwork::SendCarStatusPacket(tSituation *s,bool bForce)
|
|||
return;
|
||||
}
|
||||
|
||||
std::vector<CarStatusPacked> vecCarStatus;
|
||||
std::vector<tCarElt *> local;
|
||||
double time = 0.0;
|
||||
|
||||
|
||||
|
@ -490,15 +488,7 @@ void NetNetwork::SendCarStatusPacket(tSituation *s,bool bForce)
|
|||
//Only transmit local drivers to other clients
|
||||
if (m_setLocalDrivers.find(pCar->info.startRank)!=m_setLocalDrivers.end())
|
||||
{
|
||||
GfLogTrace("Sending car info: %s,startRank=%i\n",pCar->info.name,pCar->info.startRank);
|
||||
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);
|
||||
local.push_back(pCar);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -507,31 +497,39 @@ void NetNetwork::SendCarStatusPacket(tSituation *s,bool bForce)
|
|||
m_sendCarDataTime = s->currentTime;
|
||||
|
||||
|
||||
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;
|
||||
int iNumCars = local.size();
|
||||
|
||||
memcpy(pData,&packetId,1);
|
||||
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);
|
||||
}
|
||||
PackedBuffer msg;
|
||||
|
||||
ENetPacket * pPacket = enet_packet_create (pDataStart,
|
||||
packetSize,
|
||||
try
|
||||
{
|
||||
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);
|
||||
|
||||
BroadcastPacket(pPacket,RELIABLECHANNEL);
|
||||
|
||||
delete [] pDataStart;
|
||||
}
|
||||
|
||||
void NetNetwork::SendCarControlsPacket(tSituation *s)
|
||||
|
@ -553,7 +551,7 @@ void NetNetwork::SendCarControlsPacket(tSituation *s)
|
|||
return;
|
||||
}
|
||||
|
||||
std::vector<CarControlsPacked> vecPackedCtrls;
|
||||
std::vector<tCarElt *> local;
|
||||
double time = 0.0;
|
||||
|
||||
//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
|
||||
if (m_setLocalDrivers.find(pCar->info.startRank)!=m_setLocalDrivers.end())
|
||||
{
|
||||
CarControlsPacked ctrl;
|
||||
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);
|
||||
local.push_back(pCar);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -581,40 +569,80 @@ void NetNetwork::SendCarControlsPacket(tSituation *s)
|
|||
|
||||
m_sendCtrlTime = s->currentTime;
|
||||
|
||||
int iNumCars = vecPackedCtrls.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;
|
||||
int iNumCars = local.size();
|
||||
|
||||
memcpy(pData,&packetId,1);
|
||||
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);
|
||||
}
|
||||
PackedBuffer msg;
|
||||
|
||||
ENetPacket * pPacket = enet_packet_create (pDataStart,
|
||||
packetSize,
|
||||
try
|
||||
{
|
||||
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);
|
||||
|
||||
BroadcastPacket(pPacket,UNRELIABLECHANNEL);
|
||||
|
||||
delete [] pDataStart;
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
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();
|
||||
bool bFound = false;
|
||||
|
@ -636,64 +664,64 @@ void NetNetwork::ReadLapStatusPacket(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=0;
|
||||
memcpy(&packettime,pData,sizeof(packettime));
|
||||
pData+=sizeof(packettime);
|
||||
double packettime;
|
||||
int iNumCars;
|
||||
|
||||
try
|
||||
{
|
||||
msg.unpack_ubyte();
|
||||
packettime = msg.unpack_double();
|
||||
iNumCars = msg.unpack_int();
|
||||
|
||||
int iNumCars = 0;
|
||||
memcpy(&iNumCars,pData,sizeof(iNumCars));
|
||||
pData+=sizeof(iNumCars);
|
||||
NetMutexData *pNData = LockNetworkData();
|
||||
|
||||
//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();
|
||||
|
||||
//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.time = packettime;
|
||||
|
||||
status.state = statusPacked.state;
|
||||
status.startRank =statusPacked.startRank;
|
||||
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);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
status.topSpeed = statusPacked.topSpeed;
|
||||
status.fuel = statusPacked.fuel;
|
||||
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)
|
||||
pNData->m_vecCarStatus.push_back(status);
|
||||
}
|
||||
|
||||
if (!bFound)
|
||||
pNData->m_vecCarStatus.push_back(status);
|
||||
|
||||
pData+=sizeof(CarStatusPacked);
|
||||
}
|
||||
|
||||
UnlockNetworkData();
|
||||
UnlockNetworkData();
|
||||
}
|
||||
catch (PackedBufferException &e)
|
||||
{
|
||||
GfLogFatal("ReadCarStatusPacket: packed buffer error\n");
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
unsigned char *pData = &pPacket->data[1];
|
||||
|
||||
//time
|
||||
double packettime=0;
|
||||
memcpy(&packettime,pData,sizeof(packettime));
|
||||
pData+=sizeof(packettime);
|
||||
PackedBuffer msg(pPacket->data, pPacket->dataLength);
|
||||
GfLogTrace("ReadCarControlsPacket: packed data length=%d\n",
|
||||
msg.length());
|
||||
|
||||
double packettime;
|
||||
int iNumCars;
|
||||
|
||||
int iNumCars = 0;
|
||||
memcpy(&iNumCars,pData,sizeof(iNumCars));
|
||||
pData+=sizeof(iNumCars);
|
||||
try
|
||||
{
|
||||
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();
|
||||
|
||||
//Car conrols values (steering,brake,gas,and etc
|
||||
for (int i=0;i<iNumCars;i++)
|
||||
{
|
||||
CarControlsPacked ctrlPacked;
|
||||
memcpy(&ctrlPacked,pData,sizeof(CarControlsPacked));
|
||||
|
||||
//Unpack values
|
||||
CarControlsData ctrl;
|
||||
ctrl.throttle = (float)(ctrlPacked.throttle/256.0);
|
||||
ctrl.brake = (float)(ctrlPacked.brake/256.0);
|
||||
ctrl.clutch = (float)(ctrlPacked.clutch/256.0);
|
||||
ctrl.gear = ctrlPacked.gear;
|
||||
ctrl.steering = (float)(ctrlPacked.steering/256.0);
|
||||
ctrl.DynGCg = ctrlPacked.DynGCg;
|
||||
ctrl.startRank = ctrlPacked.startRank;
|
||||
ctrl.time = packettime;
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
ctrl.gear = msg.unpack_int();
|
||||
ctrl.brake = msg.unpack_float();
|
||||
ctrl.steering = msg.unpack_float();
|
||||
ctrl.throttle = msg.unpack_float();
|
||||
ctrl.clutch = msg.unpack_float();
|
||||
ctrl.startRank = msg.unpack_int();
|
||||
ctrl.DynGCg.pos.x = msg.unpack_float();
|
||||
ctrl.DynGCg.pos.y = msg.unpack_float();
|
||||
ctrl.DynGCg.pos.z = msg.unpack_float();
|
||||
ctrl.DynGCg.pos.xy = msg.unpack_float();
|
||||
ctrl.DynGCg.pos.ax = msg.unpack_float();
|
||||
ctrl.DynGCg.pos.ay = msg.unpack_float();
|
||||
ctrl.DynGCg.pos.az = msg.unpack_float();
|
||||
ctrl.DynGCg.vel.x = msg.unpack_float();
|
||||
ctrl.DynGCg.vel.y = msg.unpack_float();
|
||||
ctrl.DynGCg.vel.z = msg.unpack_float();
|
||||
ctrl.DynGCg.vel.xy = msg.unpack_float();
|
||||
ctrl.DynGCg.vel.ax = msg.unpack_float();
|
||||
ctrl.DynGCg.vel.ay = msg.unpack_float();
|
||||
ctrl.DynGCg.vel.az = msg.unpack_float();
|
||||
ctrl.DynGCg.acc.x = msg.unpack_float();
|
||||
ctrl.DynGCg.acc.y = msg.unpack_float();
|
||||
ctrl.DynGCg.acc.z = msg.unpack_float();
|
||||
ctrl.DynGCg.acc.xy = msg.unpack_float();
|
||||
ctrl.DynGCg.acc.ax = msg.unpack_float();
|
||||
ctrl.DynGCg.acc.ay = msg.unpack_float();
|
||||
ctrl.DynGCg.acc.az = msg.unpack_float();
|
||||
|
||||
if (!bFound)
|
||||
pNData->m_vecCarCtrls.push_back(ctrl);
|
||||
ctrl.time = packettime;
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================
|
||||
|
|
|
@ -101,34 +101,33 @@ struct CarControlsPacked
|
|||
//Uncompressed car controls pack
|
||||
struct CarControlsData
|
||||
{
|
||||
unsigned char startRank;
|
||||
tDynPt DynGCg; /* GC global data */
|
||||
|
||||
int startRank;
|
||||
tDynPt DynGCg; /* GC global data */
|
||||
float steering;
|
||||
float throttle;
|
||||
float brake;
|
||||
float clutch;
|
||||
unsigned char gear;
|
||||
int gear;
|
||||
double time;
|
||||
};
|
||||
|
||||
|
||||
struct LapStatus
|
||||
{
|
||||
float bestLapTime;
|
||||
float bestSplitTime;
|
||||
unsigned short laps;
|
||||
unsigned char startRank;
|
||||
double bestLapTime;
|
||||
double bestSplitTime;
|
||||
int laps;
|
||||
int startRank;
|
||||
};
|
||||
|
||||
struct CarStatus
|
||||
{
|
||||
float topSpeed;
|
||||
short state;
|
||||
int state;
|
||||
double time;
|
||||
float fuel;
|
||||
int dammage;
|
||||
unsigned char startRank;
|
||||
int startRank;
|
||||
};
|
||||
|
||||
struct CarStatusPacked
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "network.h"
|
||||
#include "robotxml.h"
|
||||
#include "pack.h"
|
||||
|
||||
|
||||
NetServer::NetServer()
|
||||
|
@ -180,23 +181,29 @@ void NetServer::WaitForClientsStartPacket()
|
|||
|
||||
void NetServer::SendStartTimePacket(int &startTime)
|
||||
{
|
||||
unsigned char packetId = RACESTARTTIME_PACKET;
|
||||
|
||||
//Wait RACESTARTDELEAY seconds to start race
|
||||
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,
|
||||
datasize,
|
||||
try
|
||||
{
|
||||
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);
|
||||
|
||||
BroadcastPacket(pPacket,RELIABLECHANNEL);
|
||||
|
||||
delete [] pData;
|
||||
GfLogInfo("Server Start time is %lf\n",m_racestarttime);
|
||||
}
|
||||
double NetServer::WaitForRaceStart()
|
||||
|
@ -482,19 +489,23 @@ bool NetServer::SendPlayerAcceptedPacket(ENetPeer * pPeer)
|
|||
{
|
||||
|
||||
//Send to client requesting connection
|
||||
unsigned char packetId = PLAYERACCEPTED_PACKET;
|
||||
int datasize = 1;
|
||||
PackedBuffer msg;
|
||||
|
||||
unsigned char *pData = new unsigned char[datasize];
|
||||
unsigned char *pDataSpot = pData;
|
||||
memcpy(pDataSpot,&packetId,1);
|
||||
try
|
||||
{
|
||||
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,
|
||||
datasize,
|
||||
ENetPacket * pPacket = enet_packet_create (msg.buffer(),
|
||||
msg.length(),
|
||||
ENET_PACKET_FLAG_RELIABLE);
|
||||
|
||||
delete [] pData;
|
||||
|
||||
if (enet_peer_send (pPeer, RELIABLECHANNEL, pPacket)==0)
|
||||
return true;
|
||||
|
||||
|
@ -503,27 +514,26 @@ bool NetServer::SendPlayerAcceptedPacket(ENetPeer * pPeer)
|
|||
|
||||
bool NetServer::SendPlayerRejectedPacket(ENetPeer * pPeer,std::string strReason)
|
||||
{
|
||||
unsigned int l = strReason.length();
|
||||
|
||||
//Send to client requesting connection
|
||||
unsigned char packetId = PLAYERREJECTED_PACKET;
|
||||
int datasize = sizeof(l)+l+1;
|
||||
|
||||
unsigned char *pData = new unsigned char[datasize];
|
||||
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;
|
||||
PackedBuffer msg;
|
||||
|
||||
ENetPacket * pPacket = enet_packet_create (pData,
|
||||
datasize,
|
||||
try
|
||||
{
|
||||
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);
|
||||
|
||||
delete [] pData;
|
||||
|
||||
if (enet_peer_send (pPeer, RELIABLECHANNEL, pPacket)==0)
|
||||
return true;
|
||||
|
||||
|
@ -533,51 +543,57 @@ bool NetServer::SendPlayerRejectedPacket(ENetPeer * pPeer,std::string strReason)
|
|||
void NetServer::SendDriversReadyPacket()
|
||||
{
|
||||
|
||||
unsigned char packetId = ALLDRIVERREADY_PACKET;
|
||||
NetMutexData *pNData = LockNetworkData();
|
||||
|
||||
int rsize = pNData->m_vecReadyStatus.size();
|
||||
int datasize = 1+sizeof(rsize)+sizeof(bool)*rsize;
|
||||
|
||||
unsigned char *pData = new unsigned char[datasize];
|
||||
unsigned char *pDataSpot = pData;
|
||||
memcpy(pDataSpot,&packetId,1);
|
||||
pDataSpot++;
|
||||
memcpy(pDataSpot,&rsize,sizeof(rsize));
|
||||
pDataSpot+=sizeof(rsize);
|
||||
bool *pReady = (bool*)pDataSpot;
|
||||
for (int i=0;i<rsize;i++)
|
||||
{
|
||||
pReady[i] = pNData->m_vecReadyStatus[i];
|
||||
}
|
||||
PackedBuffer msg;
|
||||
|
||||
try
|
||||
{
|
||||
msg.pack_ubyte(ALLDRIVERREADY_PACKET);
|
||||
msg.pack_int(rsize);
|
||||
for (int i = 0; i < rsize; i++)
|
||||
{
|
||||
msg.pack_int(pNData->m_vecReadyStatus[i]);
|
||||
}
|
||||
}
|
||||
catch (PackedBufferException &e)
|
||||
{
|
||||
GfLogFatal("SendDriversReadyPacket: packed buffer error\n");
|
||||
}
|
||||
GfLogTrace("SendDriversReadyPacket: packed data length=%d\n",
|
||||
msg.length());
|
||||
|
||||
UnlockNetworkData();
|
||||
|
||||
ENetPacket * pPacket = enet_packet_create (pData,
|
||||
datasize,
|
||||
ENetPacket * pPacket = enet_packet_create (msg.buffer(),
|
||||
msg.length(),
|
||||
ENET_PACKET_FLAG_RELIABLE);
|
||||
|
||||
delete [] pData;
|
||||
|
||||
BroadcastPacket(pPacket,RELIABLECHANNEL);
|
||||
m_bRefreshDisplay = true;
|
||||
}
|
||||
|
||||
void NetServer::SendRaceSetupPacket()
|
||||
{
|
||||
unsigned char packetId = RACEINFOCHANGE_PACKET;
|
||||
int datasize = 1;
|
||||
PackedBuffer msg;
|
||||
|
||||
unsigned char *pData = new unsigned char[datasize];
|
||||
unsigned char *pDataSpot = pData;
|
||||
memcpy(pDataSpot,&packetId,1);
|
||||
try
|
||||
{
|
||||
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,
|
||||
datasize,
|
||||
ENetPacket * pPacket = enet_packet_create (msg.buffer(),
|
||||
msg.length(),
|
||||
ENET_PACKET_FLAG_RELIABLE);
|
||||
|
||||
delete [] pData;
|
||||
|
||||
BroadcastPacket(pPacket,RELIABLECHANNEL);
|
||||
|
||||
SetRaceInfoChanged(true);
|
||||
|
@ -589,10 +605,22 @@ void NetServer::ReadDriverReadyPacket(ENetPacket *pPacket)
|
|||
GfLogTrace ("Read Driver Ready Packet\n");
|
||||
|
||||
int idx;
|
||||
memcpy(&idx,&pPacket->data[1],sizeof(idx));
|
||||
int spot = sizeof(idx)+1;
|
||||
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();
|
||||
pNData->m_vecReadyStatus[idx-1] = bReady;
|
||||
|
@ -603,8 +631,6 @@ void NetServer::ReadDriverReadyPacket(ENetPacket *pPacket)
|
|||
|
||||
void NetServer::ReadDriverInfoPacket(ENetPacket *pPacket, ENetPeer * pPeer)
|
||||
{
|
||||
assert(pPacket->dataLength==(sizeof(NetDriver)+1));
|
||||
|
||||
NetDriver driver;
|
||||
|
||||
char hostName[256];
|
||||
|
@ -612,7 +638,48 @@ void NetServer::ReadDriverInfoPacket(ENetPacket *pPacket, ENetPeer * pPeer)
|
|||
|
||||
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
|
||||
NetServerMutexData *pSData = LockServerData();
|
||||
|
@ -659,12 +726,23 @@ void NetServer::SendWeatherPacket()
|
|||
{
|
||||
GfLogTrace("Sending Weather Packet\n");
|
||||
|
||||
unsigned char packetId = WEATHERCHANGE_PACKET;
|
||||
//TODO add weather data here
|
||||
|
||||
ENetPacket * pWeatherPacket = enet_packet_create (&packetId,
|
||||
1,
|
||||
ENET_PACKET_FLAG_RELIABLE);
|
||||
PackedBuffer msg;
|
||||
|
||||
try
|
||||
{
|
||||
msg.pack_ubyte(WEATHERCHANGE_PACKET);
|
||||
//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);
|
||||
|
@ -673,22 +751,27 @@ void NetServer::SendWeatherPacket()
|
|||
void NetServer::SendTimePacket(ENetPacket *pPacketRec, ENetPeer * pPeer)
|
||||
{
|
||||
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();
|
||||
GfLogTrace("\nServer time is %lf",time);
|
||||
|
||||
memcpy(pData,&time,sizeof(time));
|
||||
pData+=sizeof(time);
|
||||
PackedBuffer msg;
|
||||
|
||||
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
|
||||
ENetPacket * pPacket = enet_packet_create (pDataStart,
|
||||
packetSize,
|
||||
ENetPacket * pPacket = enet_packet_create (msg.buffer(),
|
||||
msg.length(),
|
||||
ENET_PACKET_FLAG_UNSEQUENCED);
|
||||
|
||||
enet_peer_send (pPeer, UNRELIABLECHANNEL, pPacket);
|
||||
|
@ -723,29 +806,36 @@ void NetServer::SendFilePacket(const char *pszFile)
|
|||
|
||||
fclose(pFile);
|
||||
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);
|
||||
pData+=sizeof(unsigned int);
|
||||
|
||||
memcpy(pData,buf,size);
|
||||
|
||||
ENetPacket * pPacket = enet_packet_create (pDataPacket,
|
||||
datasize,
|
||||
short namelen = strlen(pszFile);
|
||||
|
||||
/* 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);
|
||||
|
||||
BroadcastPacket(pPacket,RELIABLECHANNEL);
|
||||
|
@ -811,7 +901,7 @@ bool NetServer::listen()
|
|||
void NetServer::RemovePlayerFromRace(unsigned int idx)
|
||||
{
|
||||
GfLogTrace("Removing disconnected player\n");
|
||||
std::vector<CarStatusPacked> vecCarStatus;
|
||||
std::vector<CarStatus> vecCarStatus;
|
||||
double time = 0.0;
|
||||
|
||||
int startRank = GetDriverStartRank(idx);
|
||||
|
@ -827,103 +917,110 @@ void NetServer::RemovePlayerFromRace(unsigned int idx)
|
|||
pNData->m_vecCarStatus.push_back(cstatus);
|
||||
UnlockNetworkData();
|
||||
|
||||
|
||||
//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);
|
||||
vecCarStatus.push_back(cstatus);
|
||||
|
||||
time = m_currentTime;
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
PackedBuffer msg;
|
||||
|
||||
ENetPacket * pPacket = enet_packet_create (pDataStart,
|
||||
packetSize,
|
||||
try
|
||||
{
|
||||
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);
|
||||
|
||||
BroadcastPacket(pPacket,RELIABLECHANNEL);
|
||||
|
||||
delete [] pDataStart;
|
||||
}
|
||||
|
||||
void NetServer::ReadPacket(ENetEvent event)
|
||||
{
|
||||
ENetPacket *pPacket = event.packet;
|
||||
assert(pPacket->dataLength>=1);
|
||||
unsigned char packetId;
|
||||
memcpy(&packetId,&pPacket->data[0],1);
|
||||
unsigned char *pData = &pPacket->data[1];
|
||||
unsigned char packetId = pPacket->data[0];
|
||||
//int datasize = pPacket->dataLength-1;
|
||||
|
||||
switch (packetId)
|
||||
{
|
||||
case PLAYERINFO_PACKET:
|
||||
GfLogTrace("PlayerInfo Packet\n");
|
||||
ReadDriverInfoPacket(pPacket,event.peer);
|
||||
break;
|
||||
case CLIENTREADYTOSTART_PACKET:
|
||||
{
|
||||
int l;
|
||||
char name[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;
|
||||
}
|
||||
switch (packetId)
|
||||
{
|
||||
case PLAYERINFO_PACKET:
|
||||
GfLogTrace("PlayerInfo Packet\n");
|
||||
ReadDriverInfoPacket(pPacket,event.peer);
|
||||
break;
|
||||
case CLIENTREADYTOSTART_PACKET:
|
||||
{
|
||||
int l;
|
||||
char name[256];
|
||||
memset(&name[0],0,256);
|
||||
|
||||
p++;
|
||||
}
|
||||
PackedBuffer msg(pPacket->data, pPacket->dataLength);
|
||||
GfLogTrace("ReadPacket: packed data length=%d\n",
|
||||
msg.length());
|
||||
|
||||
if (m_vecWaitForPlayers.size()==0)
|
||||
m_bBeginRace = true;
|
||||
try
|
||||
{
|
||||
msg.unpack_ubyte();
|
||||
l = msg.unpack_int();
|
||||
msg.unpack_string(name, l);
|
||||
}
|
||||
catch (PackedBufferException &e)
|
||||
{
|
||||
GfLogFatal("ReadPacket: packed buffer error\n");
|
||||
}
|
||||
|
||||
}
|
||||
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;
|
||||
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++;
|
||||
}
|
||||
|
||||
if (m_vecWaitForPlayers.size()==0)
|
||||
m_bBeginRace = true;
|
||||
|
||||
}
|
||||
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:
|
||||
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");
|
||||
|
||||
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();
|
||||
double time = pNData->m_finishTime;
|
||||
UnlockNetworkData();
|
||||
|
||||
GfLogInfo("Server finish time is %lf\n",time);
|
||||
|
||||
PackedBuffer msg;
|
||||
|
||||
memcpy(pData,&time,sizeof(time));
|
||||
pData+=sizeof(time);
|
||||
try
|
||||
{
|
||||
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,
|
||||
packetSize,
|
||||
ENetPacket * pPacket = enet_packet_create (msg.buffer(),
|
||||
msg.length(),
|
||||
ENET_PACKET_FLAG_RELIABLE);
|
||||
BroadcastPacket(pPacket,RELIABLECHANNEL);
|
||||
}
|
||||
|
@ -980,9 +1081,22 @@ void NetServer::SendPrepareToRacePacket()
|
|||
m_bBeginRace = true;
|
||||
|
||||
////TODO send needed xml files to race
|
||||
unsigned char packetId = PREPARETORACE_PACKET;
|
||||
ENetPacket * pPacket = enet_packet_create (&packetId,
|
||||
1,
|
||||
|
||||
PackedBuffer msg;
|
||||
|
||||
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);
|
||||
|
||||
BroadcastPacket(pPacket,RELIABLECHANNEL);
|
||||
|
|
Loading…
Reference in a new issue