diff --git a/Code/Game/GameClient/GameClientState/NetLoadState.cpp b/Code/Game/GameClient/GameClientState/NetLoadState.cpp index 9ef0dac9..6d68eb58 100644 --- a/Code/Game/GameClient/GameClientState/NetLoadState.cpp +++ b/Code/Game/GameClient/GameClientState/NetLoadState.cpp @@ -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 ); diff --git a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp index 147cd19e..8cc47dcc 100644 --- a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp +++ b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp @@ -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(); } } diff --git a/Code/Game/LevelLoader/LevelParser.cpp b/Code/Game/LevelLoader/LevelParser.cpp index 5f5a5341..fe349988 100644 --- a/Code/Game/LevelLoader/LevelParser.cpp +++ b/Code/Game/LevelLoader/LevelParser.cpp @@ -166,16 +166,17 @@ std::vector> 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> LevelParser::Parse(std::string filen } break;*/ } + break; default: //Couldn't find typeID. FAIL!!!!!! break; diff --git a/Code/Game/LevelLoader/ObjectDefines.h b/Code/Game/LevelLoader/ObjectDefines.h index 918fb4e6..52f0e088 100644 --- a/Code/Game/LevelLoader/ObjectDefines.h +++ b/Code/Game/LevelLoader/ObjectDefines.h @@ -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 diff --git a/Code/Game/LevelLoader/ParseFunctions.cpp b/Code/Game/LevelLoader/ParseFunctions.cpp index 09adb298..ac361c46 100644 --- a/Code/Game/LevelLoader/ParseFunctions.cpp +++ b/Code/Game/LevelLoader/ParseFunctions.cpp @@ -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; } diff --git a/Code/Game/LevelLoader/ParseFunctions.h b/Code/Game/LevelLoader/ParseFunctions.h index 0fc6dbc6..21e43858 100644 --- a/Code/Game/LevelLoader/ParseFunctions.h +++ b/Code/Game/LevelLoader/ParseFunctions.h @@ -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); diff --git a/Code/Network/NetworkAPI/NetworkClient.cpp b/Code/Network/NetworkAPI/NetworkClient.cpp index 3463ed8a..56425109 100644 --- a/Code/Network/NetworkAPI/NetworkClient.cpp +++ b/Code/Network/NetworkAPI/NetworkClient.cpp @@ -56,6 +56,17 @@ struct NetworkClient::PrivateData : public IThreadObject ThreadSafeQueue sendQueue; ThreadSafeQueue> 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; @@ -65,14 +76,18 @@ struct NetworkClient::PrivateData : public IThreadObject , parent(0) , 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(); - - return true; + while(WaitForSingleObject(shutdownEvent, 0) != WAIT_OBJECT_0) + { + if(!this->connection.IsConnected()) return false; + + 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 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 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) diff --git a/Code/Network/NetworkDependencies/Connection.cpp b/Code/Network/NetworkDependencies/Connection.cpp index 2cd992a2..0b0a6a3d 100644 --- a/Code/Network/NetworkDependencies/Connection.cpp +++ b/Code/Network/NetworkDependencies/Connection.cpp @@ -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 /////////////////////////////////////// diff --git a/Code/Network/NetworkDependencies/Connection.h b/Code/Network/NetworkDependencies/Connection.h index 054537fc..e1c98a76 100644 --- a/Code/Network/NetworkDependencies/Connection.h +++ b/Code/Network/NetworkDependencies/Connection.h @@ -39,6 +39,8 @@ namespace Oyster int SetBlockingMode( bool blocking ); std::string GetIpAddress(); + int GetSocket(); + private: int InitiateSocket(); diff --git a/Code/Network/NetworkDependencies/ConnectionUDP.cpp b/Code/Network/NetworkDependencies/ConnectionUDP.cpp index e7d065a6..44a49d2d 100644 --- a/Code/Network/NetworkDependencies/ConnectionUDP.cpp +++ b/Code/Network/NetworkDependencies/ConnectionUDP.cpp @@ -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 diff --git a/Code/Network/NetworkDependencies/IConnection.h b/Code/Network/NetworkDependencies/IConnection.h index debdfe7b..b4c3627c 100644 --- a/Code/Network/NetworkDependencies/IConnection.h +++ b/Code/Network/NetworkDependencies/IConnection.h @@ -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; }; }; } }