Merge branch 'GameServer' into GameClient

This commit is contained in:
Linda Andersson 2014-02-24 14:48:36 +01:00
commit 704e562d01
11 changed files with 248 additions and 30 deletions

View File

@ -231,7 +231,7 @@ void NetLoadState::LoadGame( const ::std::string &fileName )
pointLight.Color = light->color;
pointLight.Pos = light->position;
pointLight.Bright = light->intensity;
pointLight.Radius = light->raduis;
pointLight.Radius = light->radius;
C_Light *newLight = new C_Light( pointLight, objectID );

View File

@ -29,10 +29,10 @@ using namespace DanBias;
float dt = (float)this->logicTimer.getElapsedSeconds();
if( dt >= this->logicFrameTime )
{
this->logicTimer.reset();
this->ProcessClients();
this->gameInstance.NewFrame();
this->logicTimer.reset();
}
}

View File

@ -166,16 +166,17 @@ std::vector<SmartPointer<ObjectTypeHeader>> LevelParser::Parse(std::string filen
case ObjectType_Light:
{
LightType lightType;
//LightType lightType;
//Get Light type
ParseObject(&buffer[counter+4], &lightType, sizeof(lightType));
//ParseObject(&buffer[counter+4], &lightType, sizeof(lightType));
//We only support PointLight for now.
BasicLight* header = new BasicLight;
ParseObject(&buffer[counter], header, sizeof(*header));
counter += sizeof(*header);
ParseLight(&buffer[counter], *header, counter);
objects.push_back(header);
/*switch(lightType)
{
case LightType_PointLight:
@ -208,6 +209,7 @@ std::vector<SmartPointer<ObjectTypeHeader>> LevelParser::Parse(std::string filen
}
break;*/
}
break;
default:
//Couldn't find typeID. FAIL!!!!!!
break;

View File

@ -52,6 +52,7 @@ namespace GameLogic
CollisionGeometryType_Box,
CollisionGeometryType_Sphere,
CollisionGeometryType_Cylinder,
CollisionGeometryType_CG_MESH,
CollisionGeometryType_Count,
CollisionGeometryType_Unknown = -1
@ -161,6 +162,11 @@ namespace GameLogic
float radius;
};
struct BoundingVolumeCGMesh : public BoundingVolumeBase
{
wchar_t filename[128];
};
struct BoundingVolume
{
CollisionGeometryType geoType;
@ -169,9 +175,9 @@ namespace GameLogic
LevelLoaderInternal::BoundingVolumeBox box;
LevelLoaderInternal::BoundingVolumeSphere sphere;
LevelLoaderInternal::BoundingVolumeCylinder cylinder;
LevelLoaderInternal::BoundingVolumeCGMesh cgMesh;
};
};
}
struct LevelMetaData : public ObjectTypeHeader
@ -253,8 +259,10 @@ namespace GameLogic
LightType lightType; //Is not used right now
float color[3];
float position[3];
float raduis;
float radius;
float intensity;
virtual ~BasicLight(){}
};
/* We only support pointlight right now.
struct PointLight : public BasicLight

View File

@ -20,6 +20,32 @@ namespace GameLogic
memcpy(header, buffer, size);
}
void ParseLight(char* buffer, BasicLight& header, int& size)
{
int start = 0;
memcpy(&header.typeID, &buffer[start], 40);
start += 40;
/*
memcpy(&header.lightType, &buffer[start], 4);
start += 4;
memcpy(&header.color, &buffer[start], 12);
start += 12;
memcpy(&header.position, &buffer[start], 12);
start += 12;
memcpy(&header.radius, &buffer[start], 4);
start += 4;
memcpy(&header.intensity, &buffer[start], 4);
start += 4;*/
size += start;
//memcpy(&header, buffer, size);
}
void ParseObject(char* buffer, ObjectHeader& header, int& size, bool loadCgf)
{
char tempName[128];
@ -173,6 +199,22 @@ namespace GameLogic
start += sizeof(volume.cylinder);
break;
case CollisionGeometryType_CG_MESH:
{
memcpy(&volume.cgMesh, &buf[start], sizeof(float)*12);
start += sizeof(float)*12;
memcpy(&tempSize, &buf[start], sizeof(tempSize));
start += 4;
memcpy(&tempName, &buf[start], tempSize);
tempName[tempSize] = '\0';
//convert from char[] to wchar_t[]
mbstowcs_s(NULL, volume.cgMesh.filename, tempSize+1, tempName, _TRUNCATE);
start += tempSize;
}
break;
default:
break;
}

View File

@ -18,6 +18,7 @@ namespace GameLogic
*/
void ParseObject(char* buffer, void *header, int size);
void ParseLight(char* buffer, BasicLight& header, int& size);
void ParseObject(char* buffer, ObjectHeader& header, int& size , bool loadCgf);
void ParseLevelMetaData(char* buffer, LevelMetaData &header, int &size);
void ParseBoundingVolume(char* buffer, LevelLoaderInternal::BoundingVolume& volume, int &size);

View File

@ -56,6 +56,17 @@ struct NetworkClient::PrivateData : public IThreadObject
ThreadSafeQueue<CustomNetProtocol> sendQueue;
ThreadSafeQueue<NetEvent<NetworkClient*, NetworkClient::ClientEventArgs>> recieveQueue;
//Testing for eventSelect.
HANDLE socketEvents[2];
HANDLE shutdownEvent;
//The OysterByte each message is packed in.
OysterByte tempMessage;
//Used to buffer messages
OysterByte bufferedSend;
int numPackages;
//ID
static unsigned int currID;
const unsigned int ID;
@ -66,13 +77,17 @@ struct NetworkClient::PrivateData : public IThreadObject
, owner(0)
, outputEvent(0)
{
numPackages = 0;
bufferedSend.Resize(MAX_NETWORK_MESSAGE_SIZE);
tempMessage.Resize(MAX_NETWORK_MESSAGE_SIZE);
InitWinSock();
this->thread.Create(this, false);
this->thread.SetPriority(Oyster::Thread::OYSTER_THREAD_PRIORITY_1);
}
~PrivateData()
{
this->thread.Terminate();
SetEvent(shutdownEvent);
this->thread.Wait();
ShutdownWinSock();
this->connection.Disconnect();
@ -80,15 +95,150 @@ struct NetworkClient::PrivateData : public IThreadObject
this->parent = 0;
}
void ThreadEntry()
{
//Create alla events used in the thread
shutdownEvent = CreateEvent(NULL, true, false, NULL);
socketEvents[0] = WSACreateEvent();
socketEvents[1] = WSACreateEvent();
if(socketEvents[0] == WSA_INVALID_EVENT)
{
//Error
}
if(WSAEventSelect(this->connection.GetSocket(), socketEvents[0], FD_READ) == SOCKET_ERROR)
{
//Error
}
}
void ThreadExit()
{
WSACloseEvent(socketEvents[0]);
WSACloseEvent(socketEvents[1]);
CloseHandle(shutdownEvent);
}
bool DoWork() override
{
if(!this->connection.IsConnected()) return false;
WSANETWORKEVENTS wsaEvents;
Send();
Recv();
while(WaitForSingleObject(shutdownEvent, 0) != WAIT_OBJECT_0)
{
if(!this->connection.IsConnected()) return false;
return true;
int result = WSAWaitForMultipleEvents(2, socketEvents, FALSE, 100, FALSE) - WSA_WAIT_EVENT_0;
if(result == 0)
{
WSAEnumNetworkEvents(this->connection.GetSocket(), socketEvents[0], &wsaEvents);
if((wsaEvents.lNetworkEvents & FD_READ) && (wsaEvents.iErrorCode[FD_READ_BIT] == 0))
{
//Recieve a message
Recv();
}
}
else if(result == 1)
{
//Send all messages in the sendQueue
int i = this->sendQueue.Size();
WSAResetEvent(socketEvents[1]);
if(i == 1)
{
Send();
}
else if(i > 1)
{
for(int j = 0; j < i; j++)
BufferMessage();
SendBuffer();
}
}
}
return false;
}
void SendBuffer()
{
if(bufferedSend.GetSize() > 0)
{
this->connection.Send(bufferedSend);
//printf("2. %d, %d\n", numPackages, bufferedSend.GetSize());
bufferedSend.Clear();
//Debug
numPackages = 0;
}
}
void BufferMessage()
{
int errorCode = 0;
if(!this->sendQueue.IsEmpty())
{
CustomNetProtocol p = this->sendQueue.Pop();
this->translator.Pack(tempMessage, p);
if(tempMessage.GetSize() > MAX_NETWORK_MESSAGE_SIZE - bufferedSend.GetSize())
{
//Send buffered message
errorCode = this->connection.Send(bufferedSend);
//printf("2. %d, %d\n", numPackages, bufferedSend.GetSize());
bufferedSend.Clear();
//Debug
numPackages = 0;
}
bufferedSend += tempMessage;
tempMessage.Clear();
//Debug
numPackages++;
if(errorCode != 0 && errorCode != WSAEWOULDBLOCK)
{
if( errorCode == WSAECONNABORTED || errorCode == WSAENOTCONN)
{
CEA parg;
parg.type = CEA::EventType_Disconnect;
parg.data.protocol = p;
NetEvent<NetworkClient*, CEA> e = { this->parent, parg };
this->recieveQueue.Push(e);
if(this->outputEvent)
{
printf("\t(ID: %i | IP: %s | Protocol: %i) - EventType_Disconnect && EventType_ProtocolFailedToSend \n", this->ID, this->connection.GetIpAddress().c_str(), p[0].value.netShort);
}
}
else
{
CEA parg;
parg.type = CEA::EventType_ProtocolFailedToSend;
parg.data.protocol = p;
NetEvent<NetworkClient*, CEA> e = { this->parent, parg };
this->recieveQueue.Push(e);
if(this->outputEvent)
{
printf("\t(ID: %i | IP: %s | Protocol: %i) - EventType_ProtocolFailedToSend\n", this->ID, this->connection.GetIpAddress().c_str(), p[0].value.netShort);
}
}
}
if(this->outputEvent)
{
printf("\t(ID: %i | IP: %s | Protocol: %i) Message sent!\n", this->ID, this->connection.GetIpAddress().c_str(), p[0].value.netShort);
}
}
}
int Send()
{
int errorCode = 0;
@ -96,11 +246,11 @@ struct NetworkClient::PrivateData : public IThreadObject
if(!this->sendQueue.IsEmpty())
{
//printf("\t(%i)\n", this->sendQueue.Size());
OysterByte temp;
CustomNetProtocol p = this->sendQueue.Pop();
this->translator.Pack(temp, p);
errorCode = this->connection.Send(temp);
this->translator.Pack(tempMessage, p);
errorCode = this->connection.Send(tempMessage);
tempMessage.Clear();
if(errorCode != 0 && errorCode != WSAEWOULDBLOCK)
{
@ -144,12 +294,12 @@ struct NetworkClient::PrivateData : public IThreadObject
{
int errorCode = -1;
OysterByte temp = OysterByte();
errorCode = this->connection.Recieve(temp);
errorCode = this->connection.Recieve(tempMessage);
if(errorCode == 0 && temp.GetSize())
if(errorCode == 0 && tempMessage.GetSize())
{
HandleRecievedData(temp);
HandleRecievedData(tempMessage);
tempMessage.Clear();
/* Replaced with EmptyOutbufferedQueue() and HandleRecievedData(OysterByte)
@ -312,7 +462,7 @@ bool NetworkClient::Connect(ConnectionInfo& socket)
if(this->privateData) return false;
if(!this->privateData) this->privateData = new PrivateData();
int result = this->privateData->connection.Connect(socket, false);
int result = this->privateData->connection.Connect(socket, true);
//Connect has succeeded
if(result != 0) return false;
@ -333,7 +483,7 @@ bool NetworkClient::Connect(unsigned short port, const char serverIP[])
if(!this->privateData)
this->privateData = new PrivateData();
int result = this->privateData->connection.Connect(port, serverIP, false);
int result = this->privateData->connection.Connect(port, serverIP, true);
//Connect has succeeded
if(result != 0) return false;
@ -381,7 +531,9 @@ void NetworkClient::Disconnect()
{
if(!privateData) return;
privateData->thread.Stop();
SetEvent(privateData->shutdownEvent);
privateData->thread.Wait();
privateData->connection.Disconnect();
this->privateData->sendQueue.Clear();
this->privateData->recieveQueue.Clear();
@ -390,11 +542,13 @@ void NetworkClient::Disconnect()
void NetworkClient::Send(CustomProtocolObject& protocol)
{
this->privateData->sendQueue.Push(protocol.GetProtocol());
WSASetEvent(this->privateData->socketEvents[1]);
}
void NetworkClient::Send(CustomNetProtocol& protocol)
{
this->privateData->sendQueue.Push(protocol);
WSASetEvent(this->privateData->socketEvents[1]);
}
void NetworkClient::SetOwner(NetworkSession* owner)

View File

@ -188,8 +188,8 @@ int Connection::Recieve(OysterByte &bytes)
if(this->closed) return -1;
int nBytes;
bytes.Resize(1000);
nBytes = recv(this->socket, bytes, 1000, 0);
bytes.Resize(MAX_NETWORK_MESSAGE_SIZE);
nBytes = recv(this->socket, bytes, MAX_NETWORK_MESSAGE_SIZE, 0);
if(nBytes == SOCKET_ERROR)
{
bytes.SetSize(0);
@ -263,6 +263,11 @@ std::string Connection::GetIpAddress()
return this->addr;
}
int Connection::GetSocket()
{
return socket;
}
///////////////////////////////////////
//Private functions
///////////////////////////////////////

View File

@ -39,6 +39,8 @@ namespace Oyster
int SetBlockingMode( bool blocking );
std::string GetIpAddress();
int GetSocket();
private:
int InitiateSocket();

View File

@ -135,10 +135,10 @@ int ConnectionUDP::Recieve(OysterByte &bytes)
sockaddr_in from;
int fromLength = sizeof( from );
bytes.Resize(1000);
bytes.Resize(MAX_NETWORK_MESSAGE_SIZE);
nBytes = recvfrom(this->socket,
bytes,
1000,
MAX_NETWORK_MESSAGE_SIZE,
0,
(sockaddr*)&from,
&fromLength

View File

@ -11,6 +11,8 @@ namespace Oyster
{
namespace Network
{
const int MAX_NETWORK_MESSAGE_SIZE = 1400;
struct ConnectionInfo
{
int socket;
@ -44,6 +46,8 @@ namespace Oyster
//Disconnects the client or server TODO: optimize!
virtual int Disconnect() = 0;
virtual int GetSocket() { return -1; };
};
}
}