Merge remote-tracking branch 'origin/GameServer' into Physics
This commit is contained in:
commit
08bec9470e
|
@ -9,6 +9,8 @@
|
||||||
#include "GameState.h"
|
#include "GameState.h"
|
||||||
#include "../Network/NetworkAPI/NetworkClient.h"
|
#include "../Network/NetworkAPI/NetworkClient.h"
|
||||||
|
|
||||||
|
#include <Protocols.h>
|
||||||
|
|
||||||
#include "EventHandler\EventHandler.h"
|
#include "EventHandler\EventHandler.h"
|
||||||
#include "Buttons\ButtonRectangle.h"
|
#include "Buttons\ButtonRectangle.h"
|
||||||
#include "Buttons\TextField.h"
|
#include "Buttons\TextField.h"
|
||||||
|
@ -21,6 +23,7 @@ using namespace ::Oyster;
|
||||||
using namespace ::Oyster::Network;
|
using namespace ::Oyster::Network;
|
||||||
using namespace ::Oyster::Event;
|
using namespace ::Oyster::Event;
|
||||||
using namespace ::Oyster::Math3D;
|
using namespace ::Oyster::Math3D;
|
||||||
|
using namespace ::GameLogic;
|
||||||
|
|
||||||
struct LanMenuState::MyData
|
struct LanMenuState::MyData
|
||||||
{
|
{
|
||||||
|
@ -34,6 +37,9 @@ struct LanMenuState::MyData
|
||||||
|
|
||||||
TextField<LanMenuState*> *connectIP;
|
TextField<LanMenuState*> *connectIP;
|
||||||
unsigned short connectPort;
|
unsigned short connectPort;
|
||||||
|
|
||||||
|
std::string ip;
|
||||||
|
|
||||||
} privData;
|
} privData;
|
||||||
|
|
||||||
void OnButtonInteract_Connect( Oyster::Event::ButtonEvent<LanMenuState*>& e );
|
void OnButtonInteract_Connect( Oyster::Event::ButtonEvent<LanMenuState*>& e );
|
||||||
|
@ -80,6 +86,11 @@ bool LanMenuState::Init( SharedStateContent &shared )
|
||||||
|
|
||||||
this->privData->connectPort = 15151;
|
this->privData->connectPort = 15151;
|
||||||
|
|
||||||
|
if(!this->privData->nwClient->StartListeningForBroadcasting(this->privData->connectPort))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,6 +104,8 @@ GameClientState::ClientState LanMenuState::Update( float deltaTime )
|
||||||
|
|
||||||
EventHandler::Instance().Update( mouseState );
|
EventHandler::Instance().Update( mouseState );
|
||||||
|
|
||||||
|
this->privData->nwClient->Update();
|
||||||
|
|
||||||
return this->privData->nextState;
|
return this->privData->nextState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,6 +127,11 @@ bool LanMenuState::Render( )
|
||||||
|
|
||||||
bool LanMenuState::Release()
|
bool LanMenuState::Release()
|
||||||
{
|
{
|
||||||
|
if(privData)
|
||||||
|
{
|
||||||
|
this->privData->nwClient->StopListeningForBroadcasting();
|
||||||
|
}
|
||||||
|
|
||||||
privData = NULL;
|
privData = NULL;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -154,3 +172,41 @@ void OnButtonInteract_Exit( Oyster::Event::ButtonEvent<LanMenuState*>& e )
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const GameClientState::NetEvent& LanMenuState::DataRecieved( const NetEvent &message )
|
||||||
|
{
|
||||||
|
if( message.args.type == NetworkClient::ClientEventArgs::EventType_ProtocolFailedToSend )
|
||||||
|
{ // TODO: Reconnect
|
||||||
|
const char *breakpoint = "temp trap";
|
||||||
|
this->privData->nwClient->Disconnect();
|
||||||
|
this->ChangeState( GameClientState::ClientState_Main );
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetching the id data.
|
||||||
|
short ID = message.args.data.protocol[0].value.netShort;
|
||||||
|
|
||||||
|
CustomNetProtocol data = message.args.data.protocol;
|
||||||
|
|
||||||
|
switch(ID)
|
||||||
|
{
|
||||||
|
case protocol_Broadcast_Test:
|
||||||
|
{
|
||||||
|
Protocol_Broadcast_Test decoded(data);
|
||||||
|
|
||||||
|
unsigned short port = decoded.port;
|
||||||
|
std::string ip = decoded.ip;
|
||||||
|
std::string name = decoded.name;
|
||||||
|
printf("Broadcast message: %d: %s: %s\n", port, ip.c_str(), name.c_str());
|
||||||
|
|
||||||
|
//this->privData->connectPort = port;
|
||||||
|
//this->privData->ip = ip;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
|
@ -21,6 +21,8 @@ namespace DanBias
|
||||||
virtual bool Release();
|
virtual bool Release();
|
||||||
void ChangeState( ClientState next );
|
void ChangeState( ClientState next );
|
||||||
|
|
||||||
|
virtual const NetEvent & DataRecieved( const NetEvent &message );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct MyData;
|
struct MyData;
|
||||||
::Utility::DynamicMemory::UniquePointer<MyData> privData;
|
::Utility::DynamicMemory::UniquePointer<MyData> privData;
|
||||||
|
|
|
@ -231,7 +231,7 @@ void NetLoadState::LoadGame( const ::std::string &fileName )
|
||||||
pointLight.Color = light->color;
|
pointLight.Color = light->color;
|
||||||
pointLight.Pos = light->position;
|
pointLight.Pos = light->position;
|
||||||
pointLight.Bright = light->intensity;
|
pointLight.Bright = light->intensity;
|
||||||
pointLight.Radius = light->raduis;
|
pointLight.Radius = light->radius;
|
||||||
|
|
||||||
C_Light *newLight = new C_Light( pointLight, objectID );
|
C_Light *newLight = new C_Light( pointLight, objectID );
|
||||||
|
|
||||||
|
|
|
@ -72,5 +72,50 @@ namespace GameLogic
|
||||||
Oyster::Network::CustomNetProtocol protocol;
|
Oyster::Network::CustomNetProtocol protocol;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//#define protocol_Broadcast_Test 102
|
||||||
|
struct Protocol_Broadcast_Test :public Oyster::Network::CustomProtocolObject
|
||||||
|
{
|
||||||
|
unsigned short port;
|
||||||
|
std::string ip;
|
||||||
|
std::string name;
|
||||||
|
|
||||||
|
Protocol_Broadcast_Test()
|
||||||
|
{
|
||||||
|
this->protocol[0].type = Oyster::Network::NetAttributeType_Short;
|
||||||
|
this->protocol[0].value.netShort = protocol_Broadcast_Test;
|
||||||
|
this->protocol[1].type = Oyster::Network::NetAttributeType_UnsignedShort;
|
||||||
|
this->protocol[2].type = Oyster::Network::NetAttributeType_CharArray;
|
||||||
|
this->protocol[3].type = Oyster::Network::NetAttributeType_CharArray;
|
||||||
|
this->port = 0;
|
||||||
|
}
|
||||||
|
Protocol_Broadcast_Test(unsigned short port, std::string ip, std::string name)
|
||||||
|
{
|
||||||
|
this->protocol[0].type = Oyster::Network::NetAttributeType_Short;
|
||||||
|
this->protocol[0].value.netShort = protocol_Broadcast_Test;
|
||||||
|
this->protocol[1].type = Oyster::Network::NetAttributeType_UnsignedShort;
|
||||||
|
this->port = port;
|
||||||
|
this->protocol[2].type = Oyster::Network::NetAttributeType_CharArray;
|
||||||
|
this->ip = ip;
|
||||||
|
this->protocol[3].type = Oyster::Network::NetAttributeType_CharArray;
|
||||||
|
this->name = name;
|
||||||
|
}
|
||||||
|
Protocol_Broadcast_Test(Oyster::Network::CustomNetProtocol& p)
|
||||||
|
{
|
||||||
|
this->port = p[1].value.netUShort;
|
||||||
|
this->ip.assign(p[2].value.netCharPtr);
|
||||||
|
this->name.assign(p[3].value.netCharPtr);
|
||||||
|
}
|
||||||
|
Oyster::Network::CustomNetProtocol GetProtocol() override
|
||||||
|
{
|
||||||
|
this->protocol[1].value = this->port;
|
||||||
|
this->protocol.Set(2, ip);
|
||||||
|
this->protocol.Set(3, name);
|
||||||
|
|
||||||
|
return protocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Oyster::Network::CustomNetProtocol protocol;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
#endif //!GAMELOGIC_CONTROL_PROTOCOLS_H
|
#endif //!GAMELOGIC_CONTROL_PROTOCOLS_H
|
|
@ -20,6 +20,7 @@
|
||||||
#define protocol_GeneralMIN 100
|
#define protocol_GeneralMIN 100
|
||||||
#define protocol_General_Status 100
|
#define protocol_General_Status 100
|
||||||
#define protocol_General_Text 101
|
#define protocol_General_Text 101
|
||||||
|
#define protocol_Broadcast_Test 102
|
||||||
#define protocol_GeneralMAX 199
|
#define protocol_GeneralMAX 199
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include "..\GameLobby.h"
|
#include "..\GameLobby.h"
|
||||||
#include "..\GameSession.h"
|
#include "..\GameSession.h"
|
||||||
|
|
||||||
|
#include "..\GameProtocols\GeneralProtocols.h"
|
||||||
|
|
||||||
#include <NetworkServer.h>
|
#include <NetworkServer.h>
|
||||||
#include <NetworkClient.h>
|
#include <NetworkClient.h>
|
||||||
|
|
||||||
|
@ -18,6 +20,9 @@
|
||||||
#include <WinTimer.h>
|
#include <WinTimer.h>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
//For conversion from wstring to string
|
||||||
|
#include <codecvt>
|
||||||
|
|
||||||
using namespace DanBias;
|
using namespace DanBias;
|
||||||
using namespace Oyster::Network;
|
using namespace Oyster::Network;
|
||||||
using namespace Oyster::Thread;
|
using namespace Oyster::Thread;
|
||||||
|
@ -41,12 +46,26 @@ namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string wstring_to_utf8 (const std::wstring& str)
|
||||||
|
{
|
||||||
|
std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
|
||||||
|
return myconv.to_bytes(str);
|
||||||
|
}
|
||||||
|
|
||||||
DanBiasServerReturn GameServerAPI::ServerInitiate(const ServerInitDesc& desc)
|
DanBiasServerReturn GameServerAPI::ServerInitiate(const ServerInitDesc& desc)
|
||||||
{
|
{
|
||||||
ServerOptions opt;
|
ServerOptions opt;
|
||||||
opt.mainOptions.listenPort = desc.listenPort;
|
opt.mainOptions.listenPort = desc.listenPort;
|
||||||
opt.mainOptions.ownerSession = &lobby;
|
opt.mainOptions.ownerSession = &lobby;
|
||||||
|
|
||||||
|
std::string serverName = wstring_to_utf8(desc.serverName);
|
||||||
|
|
||||||
|
GameLogic::Protocol_Broadcast_Test broadcastMessage(opt.mainOptions.listenPort, "127.0.0.1", serverName);
|
||||||
|
|
||||||
|
opt.broadcastOptions.broadcast = true;
|
||||||
|
opt.broadcastOptions.broadcastInterval = 1.0f;
|
||||||
|
opt.broadcastOptions.broadcastMessage = broadcastMessage.GetProtocol();
|
||||||
|
|
||||||
if(server.Init(opt) == NetworkServer::ServerReturnCode_Error)
|
if(server.Init(opt) == NetworkServer::ServerReturnCode_Error)
|
||||||
{
|
{
|
||||||
return DanBiasServerReturn_Error;
|
return DanBiasServerReturn_Error;
|
||||||
|
@ -55,6 +74,9 @@ DanBiasServerReturn GameServerAPI::ServerInitiate(const ServerInitDesc& desc)
|
||||||
|
|
||||||
std::printf("Server created!\t-\t%s: [%i]\n\n", server.GetLanAddress().c_str(), desc.listenPort);
|
std::printf("Server created!\t-\t%s: [%i]\n\n", server.GetLanAddress().c_str(), desc.listenPort);
|
||||||
|
|
||||||
|
GameLogic::Protocol_Broadcast_Test broadcastMessage2(opt.mainOptions.listenPort, server.GetLanAddress(), serverName);
|
||||||
|
server.SetBroadcastMessage(broadcastMessage2.GetProtocol());
|
||||||
|
|
||||||
return DanBiasServerReturn_Sucess;
|
return DanBiasServerReturn_Sucess;
|
||||||
}
|
}
|
||||||
void GameServerAPI::ServerStart()
|
void GameServerAPI::ServerStart()
|
||||||
|
|
|
@ -29,10 +29,10 @@ using namespace DanBias;
|
||||||
float dt = (float)this->logicTimer.getElapsedSeconds();
|
float dt = (float)this->logicTimer.getElapsedSeconds();
|
||||||
if( dt >= this->logicFrameTime )
|
if( dt >= this->logicFrameTime )
|
||||||
{
|
{
|
||||||
|
this->logicTimer.reset();
|
||||||
|
|
||||||
this->ProcessClients();
|
this->ProcessClients();
|
||||||
this->gameInstance.NewFrame();
|
this->gameInstance.NewFrame();
|
||||||
|
|
||||||
this->logicTimer.reset();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -166,16 +166,17 @@ std::vector<SmartPointer<ObjectTypeHeader>> LevelParser::Parse(std::string filen
|
||||||
|
|
||||||
case ObjectType_Light:
|
case ObjectType_Light:
|
||||||
{
|
{
|
||||||
LightType lightType;
|
//LightType lightType;
|
||||||
|
|
||||||
//Get Light type
|
//Get Light type
|
||||||
ParseObject(&buffer[counter+4], &lightType, sizeof(lightType));
|
//ParseObject(&buffer[counter+4], &lightType, sizeof(lightType));
|
||||||
|
|
||||||
//We only support PointLight for now.
|
//We only support PointLight for now.
|
||||||
BasicLight* header = new BasicLight;
|
BasicLight* header = new BasicLight;
|
||||||
ParseObject(&buffer[counter], header, sizeof(*header));
|
|
||||||
counter += sizeof(*header);
|
ParseLight(&buffer[counter], *header, counter);
|
||||||
objects.push_back(header);
|
objects.push_back(header);
|
||||||
|
|
||||||
/*switch(lightType)
|
/*switch(lightType)
|
||||||
{
|
{
|
||||||
case LightType_PointLight:
|
case LightType_PointLight:
|
||||||
|
@ -208,6 +209,7 @@ std::vector<SmartPointer<ObjectTypeHeader>> LevelParser::Parse(std::string filen
|
||||||
}
|
}
|
||||||
break;*/
|
break;*/
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
//Couldn't find typeID. FAIL!!!!!!
|
//Couldn't find typeID. FAIL!!!!!!
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -52,6 +52,7 @@ namespace GameLogic
|
||||||
CollisionGeometryType_Box,
|
CollisionGeometryType_Box,
|
||||||
CollisionGeometryType_Sphere,
|
CollisionGeometryType_Sphere,
|
||||||
CollisionGeometryType_Cylinder,
|
CollisionGeometryType_Cylinder,
|
||||||
|
CollisionGeometryType_CG_MESH,
|
||||||
|
|
||||||
CollisionGeometryType_Count,
|
CollisionGeometryType_Count,
|
||||||
CollisionGeometryType_Unknown = -1
|
CollisionGeometryType_Unknown = -1
|
||||||
|
@ -161,6 +162,11 @@ namespace GameLogic
|
||||||
float radius;
|
float radius;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BoundingVolumeCGMesh : public BoundingVolumeBase
|
||||||
|
{
|
||||||
|
wchar_t filename[128];
|
||||||
|
};
|
||||||
|
|
||||||
struct BoundingVolume
|
struct BoundingVolume
|
||||||
{
|
{
|
||||||
CollisionGeometryType geoType;
|
CollisionGeometryType geoType;
|
||||||
|
@ -169,9 +175,9 @@ namespace GameLogic
|
||||||
LevelLoaderInternal::BoundingVolumeBox box;
|
LevelLoaderInternal::BoundingVolumeBox box;
|
||||||
LevelLoaderInternal::BoundingVolumeSphere sphere;
|
LevelLoaderInternal::BoundingVolumeSphere sphere;
|
||||||
LevelLoaderInternal::BoundingVolumeCylinder cylinder;
|
LevelLoaderInternal::BoundingVolumeCylinder cylinder;
|
||||||
|
LevelLoaderInternal::BoundingVolumeCGMesh cgMesh;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LevelMetaData : public ObjectTypeHeader
|
struct LevelMetaData : public ObjectTypeHeader
|
||||||
|
@ -253,8 +259,10 @@ namespace GameLogic
|
||||||
LightType lightType; //Is not used right now
|
LightType lightType; //Is not used right now
|
||||||
float color[3];
|
float color[3];
|
||||||
float position[3];
|
float position[3];
|
||||||
float raduis;
|
float radius;
|
||||||
float intensity;
|
float intensity;
|
||||||
|
|
||||||
|
virtual ~BasicLight(){}
|
||||||
};
|
};
|
||||||
/* We only support pointlight right now.
|
/* We only support pointlight right now.
|
||||||
struct PointLight : public BasicLight
|
struct PointLight : public BasicLight
|
||||||
|
|
|
@ -20,6 +20,32 @@ namespace GameLogic
|
||||||
memcpy(header, buffer, size);
|
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)
|
void ParseObject(char* buffer, ObjectHeader& header, int& size, bool loadCgf)
|
||||||
{
|
{
|
||||||
char tempName[128];
|
char tempName[128];
|
||||||
|
@ -173,6 +199,22 @@ namespace GameLogic
|
||||||
start += sizeof(volume.cylinder);
|
start += sizeof(volume.cylinder);
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ namespace GameLogic
|
||||||
|
|
||||||
*/
|
*/
|
||||||
void ParseObject(char* buffer, void *header, int size);
|
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 ParseObject(char* buffer, ObjectHeader& header, int& size , bool loadCgf);
|
||||||
void ParseLevelMetaData(char* buffer, LevelMetaData &header, int &size);
|
void ParseLevelMetaData(char* buffer, LevelMetaData &header, int &size);
|
||||||
void ParseBoundingVolume(char* buffer, LevelLoaderInternal::BoundingVolume& volume, int &size);
|
void ParseBoundingVolume(char* buffer, LevelLoaderInternal::BoundingVolume& volume, int &size);
|
||||||
|
|
|
@ -194,7 +194,10 @@ using namespace Utility::DynamicMemory;
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(w->msec));
|
std::this_thread::sleep_for(std::chrono::milliseconds(w->msec));
|
||||||
|
|
||||||
while (w->state == OYSTER_THREAD_STATE_IDLE)
|
while (w->state == OYSTER_THREAD_STATE_IDLE)
|
||||||
|
{
|
||||||
|
CheckPriority(w);
|
||||||
std::this_thread::yield();
|
std::this_thread::yield();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
static void ThreadingFunction(ThreadData* w)
|
static void ThreadingFunction(ThreadData* w)
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "CustomNetProtocol.h"
|
#include "CustomNetProtocol.h"
|
||||||
#include "NetworkSession.h"
|
#include "NetworkSession.h"
|
||||||
|
|
||||||
|
#include "../NetworkDependencies/ConnectionUDP.h"
|
||||||
#include "../NetworkDependencies/Connection.h"
|
#include "../NetworkDependencies/Connection.h"
|
||||||
#include "../NetworkDependencies/PostBox.h"
|
#include "../NetworkDependencies/PostBox.h"
|
||||||
#include "../NetworkDependencies/WinsockFunctions.h"
|
#include "../NetworkDependencies/WinsockFunctions.h"
|
||||||
|
@ -25,6 +26,8 @@
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <WinSock2.h>
|
#include <WinSock2.h>
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
//For conversion from wstring to string
|
//For conversion from wstring to string
|
||||||
#include <codecvt>
|
#include <codecvt>
|
||||||
|
|
||||||
|
@ -56,6 +59,26 @@ struct NetworkClient::PrivateData : public IThreadObject
|
||||||
ThreadSafeQueue<CustomNetProtocol> sendQueue;
|
ThreadSafeQueue<CustomNetProtocol> sendQueue;
|
||||||
ThreadSafeQueue<NetEvent<NetworkClient*, NetworkClient::ClientEventArgs>> recieveQueue;
|
ThreadSafeQueue<NetEvent<NetworkClient*, NetworkClient::ClientEventArgs>> recieveQueue;
|
||||||
|
|
||||||
|
//Testing for eventSelect.
|
||||||
|
HANDLE socketEvents[2];
|
||||||
|
HANDLE shutdownEvent;
|
||||||
|
|
||||||
|
//Broadcasting
|
||||||
|
bool broadcastingStarted;
|
||||||
|
HANDLE broadcastEvent;
|
||||||
|
HANDLE broadcastShutdownEvent;
|
||||||
|
std::thread broadcastThread;
|
||||||
|
ConnectionUDP broadcastConnection;
|
||||||
|
OysterByte broadcastTempMessage;
|
||||||
|
Translator broadcastTranslator;
|
||||||
|
|
||||||
|
//The OysterByte each message is packed in.
|
||||||
|
OysterByte tempMessage;
|
||||||
|
|
||||||
|
//Used to buffer messages
|
||||||
|
OysterByte bufferedSend;
|
||||||
|
int numPackages;
|
||||||
|
|
||||||
//ID
|
//ID
|
||||||
static unsigned int currID;
|
static unsigned int currID;
|
||||||
const unsigned int ID;
|
const unsigned int ID;
|
||||||
|
@ -66,13 +89,18 @@ struct NetworkClient::PrivateData : public IThreadObject
|
||||||
, owner(0)
|
, owner(0)
|
||||||
, outputEvent(0)
|
, outputEvent(0)
|
||||||
{
|
{
|
||||||
|
broadcastingStarted = false;
|
||||||
|
numPackages = 0;
|
||||||
|
bufferedSend.Resize(MAX_NETWORK_MESSAGE_SIZE);
|
||||||
|
tempMessage.Resize(MAX_NETWORK_MESSAGE_SIZE);
|
||||||
InitWinSock();
|
InitWinSock();
|
||||||
this->thread.Create(this, false);
|
this->thread.Create(this, false);
|
||||||
this->thread.SetPriority(Oyster::Thread::OYSTER_THREAD_PRIORITY_1);
|
this->thread.SetPriority(Oyster::Thread::OYSTER_THREAD_PRIORITY_1);
|
||||||
}
|
}
|
||||||
~PrivateData()
|
~PrivateData()
|
||||||
{
|
{
|
||||||
this->thread.Terminate();
|
SetEvent(shutdownEvent);
|
||||||
|
this->thread.Wait();
|
||||||
|
|
||||||
ShutdownWinSock();
|
ShutdownWinSock();
|
||||||
this->connection.Disconnect();
|
this->connection.Disconnect();
|
||||||
|
@ -80,15 +108,211 @@ struct NetworkClient::PrivateData : public IThreadObject
|
||||||
this->parent = 0;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thread for receiving broadcast messages
|
||||||
|
void BroadcastThread()
|
||||||
|
{
|
||||||
|
WSANETWORKEVENTS wsaEvents;
|
||||||
|
|
||||||
|
while(WaitForSingleObject(broadcastShutdownEvent, 0) != WAIT_OBJECT_0)
|
||||||
|
{
|
||||||
|
int result = WSAWaitForMultipleEvents(1, &broadcastEvent, FALSE, 100, FALSE) - WSA_WAIT_EVENT_0;
|
||||||
|
if(result == 0)
|
||||||
|
{
|
||||||
|
WSAEnumNetworkEvents(this->broadcastConnection.GetSocket(), broadcastEvent, &wsaEvents);
|
||||||
|
if((wsaEvents.lNetworkEvents & FD_READ) && (wsaEvents.iErrorCode[FD_READ_BIT] == 0))
|
||||||
|
{
|
||||||
|
//Recieve a message
|
||||||
|
RecvUDP();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool DoWork() override
|
bool DoWork() override
|
||||||
{
|
{
|
||||||
if(!this->connection.IsConnected()) return false;
|
WSANETWORKEVENTS wsaEvents;
|
||||||
|
|
||||||
Send();
|
while(WaitForSingleObject(shutdownEvent, 0) != WAIT_OBJECT_0)
|
||||||
Recv();
|
{
|
||||||
|
if(!this->connection.IsConnected()) return false;
|
||||||
|
|
||||||
return true;
|
int result = WSAWaitForMultipleEvents(3, 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 RecvUDP()
|
||||||
|
{
|
||||||
|
int errorCode = -1;
|
||||||
|
|
||||||
|
errorCode = this->broadcastConnection.Recieve(broadcastTempMessage);
|
||||||
|
|
||||||
|
if(errorCode == 0 && broadcastTempMessage.GetSize())
|
||||||
|
{
|
||||||
|
CustomNetProtocol protocol;
|
||||||
|
bool ok = this->broadcastTranslator.Unpack(protocol, broadcastTempMessage);
|
||||||
|
|
||||||
|
//Check if the protocol was unpacked correctly
|
||||||
|
if(ok)
|
||||||
|
{
|
||||||
|
CEA parg;
|
||||||
|
parg.type = CEA::EventType_ProtocolRecieved;
|
||||||
|
parg.data.protocol = protocol;
|
||||||
|
NetEvent<NetworkClient*, NetworkClient::ClientEventArgs> e;
|
||||||
|
e.sender = this->parent;
|
||||||
|
e.args.data.protocol = parg.data.protocol;
|
||||||
|
e.args.type = parg.type;
|
||||||
|
|
||||||
|
this->recieveQueue.Push(e);
|
||||||
|
|
||||||
|
if(this->outputEvent)
|
||||||
|
{
|
||||||
|
printf("\t(ID: %i | IP: %s | Protocol: %i) Message recieved!\n", this->ID, this->connection.GetIpAddress().c_str(), protocol[0].value.netShort);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(this->outputEvent)
|
||||||
|
{
|
||||||
|
printf("\t(ID: %i | IP: %s) Failed to unpack CustomNetProtocol!\n", this->ID, this->connection.GetIpAddress().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
broadcastTempMessage.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 Send()
|
||||||
{
|
{
|
||||||
int errorCode = 0;
|
int errorCode = 0;
|
||||||
|
@ -96,11 +320,11 @@ struct NetworkClient::PrivateData : public IThreadObject
|
||||||
if(!this->sendQueue.IsEmpty())
|
if(!this->sendQueue.IsEmpty())
|
||||||
{
|
{
|
||||||
//printf("\t(%i)\n", this->sendQueue.Size());
|
//printf("\t(%i)\n", this->sendQueue.Size());
|
||||||
OysterByte temp;
|
|
||||||
CustomNetProtocol p = this->sendQueue.Pop();
|
CustomNetProtocol p = this->sendQueue.Pop();
|
||||||
|
|
||||||
this->translator.Pack(temp, p);
|
this->translator.Pack(tempMessage, p);
|
||||||
errorCode = this->connection.Send(temp);
|
errorCode = this->connection.Send(tempMessage);
|
||||||
|
tempMessage.Clear();
|
||||||
|
|
||||||
if(errorCode != 0 && errorCode != WSAEWOULDBLOCK)
|
if(errorCode != 0 && errorCode != WSAEWOULDBLOCK)
|
||||||
{
|
{
|
||||||
|
@ -144,12 +368,12 @@ struct NetworkClient::PrivateData : public IThreadObject
|
||||||
{
|
{
|
||||||
int errorCode = -1;
|
int errorCode = -1;
|
||||||
|
|
||||||
OysterByte temp = OysterByte();
|
errorCode = this->connection.Recieve(tempMessage);
|
||||||
errorCode = this->connection.Recieve(temp);
|
|
||||||
|
|
||||||
if(errorCode == 0 && temp.GetSize())
|
if(errorCode == 0 && tempMessage.GetSize())
|
||||||
{
|
{
|
||||||
HandleRecievedData(temp);
|
HandleRecievedData(tempMessage);
|
||||||
|
tempMessage.Clear();
|
||||||
|
|
||||||
|
|
||||||
/* Replaced with EmptyOutbufferedQueue() and HandleRecievedData(OysterByte)
|
/* Replaced with EmptyOutbufferedQueue() and HandleRecievedData(OysterByte)
|
||||||
|
@ -312,7 +536,7 @@ bool NetworkClient::Connect(ConnectionInfo& socket)
|
||||||
if(this->privateData) return false;
|
if(this->privateData) return false;
|
||||||
if(!this->privateData) this->privateData = new PrivateData();
|
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
|
//Connect has succeeded
|
||||||
if(result != 0) return false;
|
if(result != 0) return false;
|
||||||
|
@ -333,7 +557,7 @@ bool NetworkClient::Connect(unsigned short port, const char serverIP[])
|
||||||
if(!this->privateData)
|
if(!this->privateData)
|
||||||
this->privateData = new 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
|
//Connect has succeeded
|
||||||
if(result != 0) return false;
|
if(result != 0) return false;
|
||||||
|
@ -381,7 +605,9 @@ void NetworkClient::Disconnect()
|
||||||
{
|
{
|
||||||
if(!privateData) return;
|
if(!privateData) return;
|
||||||
|
|
||||||
privateData->thread.Stop();
|
SetEvent(privateData->shutdownEvent);
|
||||||
|
privateData->thread.Wait();
|
||||||
|
|
||||||
privateData->connection.Disconnect();
|
privateData->connection.Disconnect();
|
||||||
this->privateData->sendQueue.Clear();
|
this->privateData->sendQueue.Clear();
|
||||||
this->privateData->recieveQueue.Clear();
|
this->privateData->recieveQueue.Clear();
|
||||||
|
@ -390,11 +616,13 @@ void NetworkClient::Disconnect()
|
||||||
void NetworkClient::Send(CustomProtocolObject& protocol)
|
void NetworkClient::Send(CustomProtocolObject& protocol)
|
||||||
{
|
{
|
||||||
this->privateData->sendQueue.Push(protocol.GetProtocol());
|
this->privateData->sendQueue.Push(protocol.GetProtocol());
|
||||||
|
WSASetEvent(this->privateData->socketEvents[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkClient::Send(CustomNetProtocol& protocol)
|
void NetworkClient::Send(CustomNetProtocol& protocol)
|
||||||
{
|
{
|
||||||
this->privateData->sendQueue.Push(protocol);
|
this->privateData->sendQueue.Push(protocol);
|
||||||
|
WSASetEvent(this->privateData->socketEvents[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkClient::SetOwner(NetworkSession* owner)
|
void NetworkClient::SetOwner(NetworkSession* owner)
|
||||||
|
@ -445,3 +673,85 @@ void NetworkClient::OutputEventData(bool output)
|
||||||
{
|
{
|
||||||
this->privateData->outputEvent;
|
this->privateData->outputEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NetworkClient::StartListeningForBroadcasting(unsigned short port)
|
||||||
|
{
|
||||||
|
//Create privateData if it doesn't exists.
|
||||||
|
if(this->privateData == NULL)
|
||||||
|
{
|
||||||
|
privateData = new PrivateData;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Initiate broadcasting only if it's not started.
|
||||||
|
if(!this->privateData->broadcastingStarted)
|
||||||
|
{
|
||||||
|
//Create UDP connection
|
||||||
|
int result = this->privateData->broadcastConnection.InitiateBroadcastClient(port);
|
||||||
|
if(result)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create event for closing the thread.
|
||||||
|
this->privateData->broadcastShutdownEvent = CreateEvent(NULL, true, false, NULL);
|
||||||
|
if(this->privateData->broadcastShutdownEvent == NULL)
|
||||||
|
{
|
||||||
|
this->privateData->broadcastConnection.Disconnect();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Creating event for broadcast messages on the UDP connection.
|
||||||
|
this->privateData->broadcastEvent = WSACreateEvent();
|
||||||
|
if(this->privateData->broadcastEvent == WSA_INVALID_EVENT)
|
||||||
|
{
|
||||||
|
this->privateData->broadcastConnection.Disconnect();
|
||||||
|
CloseHandle(this->privateData->broadcastShutdownEvent);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the event for only Receiving.
|
||||||
|
if(WSAEventSelect(this->privateData->broadcastConnection.GetSocket(), this->privateData->broadcastEvent, FD_READ) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
this->privateData->broadcastConnection.Disconnect();
|
||||||
|
CloseHandle(this->privateData->broadcastShutdownEvent);
|
||||||
|
WSACloseEvent(this->privateData->broadcastEvent);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Start thread receiving broadcast messages.
|
||||||
|
this->privateData->broadcastThread = thread(&PrivateData::BroadcastThread, this->privateData);
|
||||||
|
if(!this->privateData->broadcastThread.joinable())
|
||||||
|
{
|
||||||
|
this->privateData->broadcastConnection.Disconnect();
|
||||||
|
CloseHandle(this->privateData->broadcastShutdownEvent);
|
||||||
|
WSACloseEvent(this->privateData->broadcastEvent);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->privateData->broadcastingStarted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkClient::StopListeningForBroadcasting()
|
||||||
|
{
|
||||||
|
if(this->privateData)
|
||||||
|
{
|
||||||
|
if(this->privateData->broadcastingStarted)
|
||||||
|
{
|
||||||
|
//Tell the thread to shutdown
|
||||||
|
WSASetEvent(this->privateData->broadcastShutdownEvent);
|
||||||
|
|
||||||
|
//Wait for thread
|
||||||
|
this->privateData->broadcastThread.join();
|
||||||
|
|
||||||
|
WSACloseEvent(this->privateData->broadcastEvent);
|
||||||
|
CloseHandle(this->privateData->broadcastShutdownEvent);
|
||||||
|
|
||||||
|
this->privateData->broadcastConnection.Disconnect();
|
||||||
|
|
||||||
|
this->privateData->broadcastingStarted = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -153,6 +153,19 @@ namespace Oyster
|
||||||
*/
|
*/
|
||||||
void SetOutputEventDataStream(FILE out);
|
void SetOutputEventDataStream(FILE out);
|
||||||
|
|
||||||
|
|
||||||
|
/** Starts a seperate thread for listening to broadcast messages.
|
||||||
|
* @param port: The port to listen for messages on.
|
||||||
|
* @return Returns true if broadcasting is already started or if it started now.
|
||||||
|
Returns false if it failed to start broadcasting.
|
||||||
|
*/
|
||||||
|
bool StartListeningForBroadcasting(unsigned short port);
|
||||||
|
|
||||||
|
/** Stops the seperate thread for broadcast messages.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void StopListeningForBroadcasting();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetworkClient(const NetworkClient& obj);
|
NetworkClient(const NetworkClient& obj);
|
||||||
NetworkClient& operator =(const NetworkClient& obj);
|
NetworkClient& operator =(const NetworkClient& obj);
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
#include "NetworkServer.h"
|
#include "NetworkServer.h"
|
||||||
|
|
||||||
|
#include "Translator.h"
|
||||||
|
#include "../NetworkDependencies/ConnectionUDP.h"
|
||||||
#include "../NetworkDependencies/Listener.h"
|
#include "../NetworkDependencies/Listener.h"
|
||||||
#include "../NetworkDependencies/PostBox.h"
|
#include "../NetworkDependencies/PostBox.h"
|
||||||
#include "../NetworkDependencies/WinsockFunctions.h"
|
#include "../NetworkDependencies/WinsockFunctions.h"
|
||||||
|
@ -18,6 +20,7 @@
|
||||||
#include "Thread/OysterThread.h"
|
#include "Thread/OysterThread.h"
|
||||||
#include "WinTimer.h"
|
#include "WinTimer.h"
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
using namespace Oyster::Network;
|
using namespace Oyster::Network;
|
||||||
using namespace Utility::DynamicMemory;
|
using namespace Utility::DynamicMemory;
|
||||||
|
@ -81,7 +84,15 @@ public:
|
||||||
, port(-1)
|
, port(-1)
|
||||||
, broadcast(0)
|
, broadcast(0)
|
||||||
, broadcastTime(1.0f, 0.0f)
|
, broadcastTime(1.0f, 0.0f)
|
||||||
{ }
|
, broadcastMutex(new std::mutex)
|
||||||
|
{
|
||||||
|
InitWinSock();
|
||||||
|
serverOptions.broadcastOptions.broadcastInterval = 1.0f;
|
||||||
|
serverOptions.broadcastOptions.broadcast = true;
|
||||||
|
broadcastMessage.Resize(MAX_NETWORK_MESSAGE_SIZE);
|
||||||
|
|
||||||
|
broadcastConnection.InitiateBroadcastServer(15151, "255.255.255.255");
|
||||||
|
}
|
||||||
~PrivateData()
|
~PrivateData()
|
||||||
{
|
{
|
||||||
if(listener)
|
if(listener)
|
||||||
|
@ -106,6 +117,12 @@ public:
|
||||||
int port;
|
int port;
|
||||||
bool broadcast;
|
bool broadcast;
|
||||||
|
|
||||||
|
ServerOptions serverOptions;
|
||||||
|
|
||||||
|
SmartPointer<std::mutex> broadcastMutex;
|
||||||
|
ConnectionUDP broadcastConnection;
|
||||||
|
OysterByte broadcastMessage;
|
||||||
|
|
||||||
TimeInstance broadcastTime;
|
TimeInstance broadcastTime;
|
||||||
|
|
||||||
Utility::WinTimer serverTimer;
|
Utility::WinTimer serverTimer;
|
||||||
|
@ -113,11 +130,18 @@ public:
|
||||||
|
|
||||||
bool NetworkServer::PrivateData::DoWork()
|
bool NetworkServer::PrivateData::DoWork()
|
||||||
{
|
{
|
||||||
if(broadcast)
|
if(serverOptions.broadcastOptions.broadcast)
|
||||||
{
|
{
|
||||||
if( (this->serverTimer.getElapsedSeconds() - this->broadcastTime.previous) >= this->broadcastTime.length )
|
if( (this->serverTimer.getElapsedSeconds() - this->broadcastTime.previous) >= this->serverOptions.broadcastOptions.broadcastInterval )
|
||||||
{
|
{
|
||||||
Broadcast();
|
//broadcastMessage.Clear();
|
||||||
|
//Translator t;
|
||||||
|
//t.Pack(broadcastMessage, serverOptions.broadcastOptions.broadcastMessage);
|
||||||
|
serverTimer.reset();
|
||||||
|
|
||||||
|
broadcastMutex->lock();
|
||||||
|
broadcastConnection.Send(broadcastMessage);
|
||||||
|
broadcastMutex->unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,6 +221,8 @@ NetworkServer::ServerReturnCode NetworkServer::Init(ServerOptions& options)
|
||||||
return NetworkServer::ServerReturnCode_Error;
|
return NetworkServer::ServerReturnCode_Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->privateData->serverOptions.broadcastOptions = options.broadcastOptions;
|
||||||
|
|
||||||
this->privateData->isInitiated = true;
|
this->privateData->isInitiated = true;
|
||||||
this->privateData->isReleased = false;
|
this->privateData->isReleased = false;
|
||||||
return NetworkServer::ServerReturnCode_Sucess;
|
return NetworkServer::ServerReturnCode_Sucess;
|
||||||
|
@ -319,6 +345,47 @@ int NetworkServer::GetPort()
|
||||||
return this->privateData->port;
|
return this->privateData->port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************
|
||||||
|
Broadcast functions
|
||||||
|
***************************************/
|
||||||
|
//Set broadcast settings.
|
||||||
|
void NetworkServer::SetBroadcast(CustomNetProtocol& broadcastMessage, float interval, bool enable)
|
||||||
|
{
|
||||||
|
this->privateData->broadcastMutex->lock();
|
||||||
|
this->privateData->serverOptions.broadcastOptions.broadcast = enable;
|
||||||
|
this->privateData->serverOptions.broadcastOptions.broadcastMessage = broadcastMessage;
|
||||||
|
this->privateData->serverOptions.broadcastOptions.broadcastInterval = interval;
|
||||||
|
|
||||||
|
this->privateData->broadcastMessage.Clear();
|
||||||
|
Translator t;
|
||||||
|
t.Pack(this->privateData->broadcastMessage, broadcastMessage);
|
||||||
|
this->privateData->broadcastMutex->unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set broadcast settings.
|
||||||
|
void NetworkServer::SetBroadcastMessage(CustomNetProtocol& broadcastMessage)
|
||||||
|
{
|
||||||
|
this->privateData->broadcastMutex->lock();
|
||||||
|
this->privateData->serverOptions.broadcastOptions.broadcastMessage = broadcastMessage;
|
||||||
|
|
||||||
|
this->privateData->broadcastMessage.Clear();
|
||||||
|
Translator t;
|
||||||
|
t.Pack(this->privateData->broadcastMessage, broadcastMessage);
|
||||||
|
this->privateData->broadcastMutex->unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Enable/disable broadcast.
|
||||||
|
void NetworkServer::SetBroadcast(bool enable)
|
||||||
|
{
|
||||||
|
this->privateData->broadcastMutex->lock();
|
||||||
|
this->privateData->serverOptions.broadcastOptions.broadcast = enable;
|
||||||
|
this->privateData->broadcastMutex->unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set interval between each broadcast message in seconds.
|
||||||
|
void NetworkServer::SetBroadcastInterval(float interval)
|
||||||
|
{
|
||||||
|
this->privateData->broadcastMutex->lock();
|
||||||
|
this->privateData->serverOptions.broadcastOptions.broadcastInterval = interval;
|
||||||
|
this->privateData->broadcastMutex->unlock();
|
||||||
|
}
|
|
@ -188,8 +188,8 @@ int Connection::Recieve(OysterByte &bytes)
|
||||||
if(this->closed) return -1;
|
if(this->closed) return -1;
|
||||||
int nBytes;
|
int nBytes;
|
||||||
|
|
||||||
bytes.Resize(1000);
|
bytes.Resize(MAX_NETWORK_MESSAGE_SIZE);
|
||||||
nBytes = recv(this->socket, bytes, 1000, 0);
|
nBytes = recv(this->socket, bytes, MAX_NETWORK_MESSAGE_SIZE, 0);
|
||||||
if(nBytes == SOCKET_ERROR)
|
if(nBytes == SOCKET_ERROR)
|
||||||
{
|
{
|
||||||
bytes.SetSize(0);
|
bytes.SetSize(0);
|
||||||
|
@ -263,6 +263,11 @@ std::string Connection::GetIpAddress()
|
||||||
return this->addr;
|
return this->addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Connection::GetSocket()
|
||||||
|
{
|
||||||
|
return socket;
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
//Private functions
|
//Private functions
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
|
|
@ -39,6 +39,8 @@ namespace Oyster
|
||||||
int SetBlockingMode( bool blocking );
|
int SetBlockingMode( bool blocking );
|
||||||
|
|
||||||
std::string GetIpAddress();
|
std::string GetIpAddress();
|
||||||
|
int GetSocket();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int InitiateSocket();
|
int InitiateSocket();
|
||||||
|
|
|
@ -41,8 +41,24 @@ int ConnectionUDP::Connect(unsigned short port, const char serverName[])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//this->Address = htonl(0xffffffff);
|
||||||
this->Address = *(unsigned long*)hostEnt->h_addr;
|
this->Address = *(unsigned long*)hostEnt->h_addr;
|
||||||
this->port = htons(this->port);
|
this->port = htons(this->port);
|
||||||
|
|
||||||
|
if(this->Address == 0)
|
||||||
|
{
|
||||||
|
sockaddr_in addr;
|
||||||
|
addr.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_port = this->port;
|
||||||
|
|
||||||
|
int result = bind(socket, (const sockaddr*)&addr, sizeof(addr));
|
||||||
|
if(result)
|
||||||
|
{
|
||||||
|
int a = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,19 +105,46 @@ int ConnectionUDP::InitiateClient()
|
||||||
return InitiateSocket();
|
return InitiateSocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ConnectionUDP::InitiateBroadcast(unsigned short port)
|
int ConnectionUDP::InitiateBroadcastServer(unsigned short port, const char serverName[])
|
||||||
{
|
{
|
||||||
int result = InitiateSocket();
|
int result = InitiateSocket();
|
||||||
|
|
||||||
|
|
||||||
int flag = 1;
|
int flag = 1;
|
||||||
result = setsockopt(this->socket, /* socket affected */
|
result = setsockopt(this->socket, SOL_SOCKET, SO_BROADCAST, (char *) &flag, sizeof(flag));
|
||||||
SOL_SOCKET, /* set option at TCP level */
|
|
||||||
SO_BROADCAST, /* name of option */
|
|
||||||
(char *) &flag, /* the cast is historical cruft */
|
|
||||||
sizeof(flag)); /* length of option value */
|
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
closed = false;
|
||||||
|
stillSending = true;
|
||||||
|
|
||||||
|
struct hostent *hostEnt;
|
||||||
|
if((hostEnt = gethostbyname(serverName)) == NULL)
|
||||||
|
{
|
||||||
|
return SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->Address = *(unsigned long*)hostEnt->h_addr;
|
||||||
|
this->port = htons(port);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConnectionUDP::InitiateBroadcastClient(unsigned short port)
|
||||||
|
{
|
||||||
|
int result = InitiateSocket();
|
||||||
|
|
||||||
|
struct sockaddr_in recvAddr;
|
||||||
|
recvAddr.sin_family = AF_INET;
|
||||||
|
recvAddr.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
recvAddr.sin_port = htons(port);
|
||||||
|
|
||||||
|
if(bind(this->socket, (sockaddr*)&recvAddr, sizeof(recvAddr)) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
closesocket(this->socket);
|
||||||
|
return SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ConnectionUDP::Send(OysterByte &bytes)
|
int ConnectionUDP::Send(OysterByte &bytes)
|
||||||
|
@ -135,10 +178,10 @@ int ConnectionUDP::Recieve(OysterByte &bytes)
|
||||||
sockaddr_in from;
|
sockaddr_in from;
|
||||||
int fromLength = sizeof( from );
|
int fromLength = sizeof( from );
|
||||||
|
|
||||||
bytes.Resize(1000);
|
bytes.Resize(MAX_NETWORK_MESSAGE_SIZE);
|
||||||
nBytes = recvfrom(this->socket,
|
nBytes = recvfrom(this->socket,
|
||||||
bytes,
|
bytes,
|
||||||
1000,
|
MAX_NETWORK_MESSAGE_SIZE,
|
||||||
0,
|
0,
|
||||||
(sockaddr*)&from,
|
(sockaddr*)&from,
|
||||||
&fromLength
|
&fromLength
|
||||||
|
@ -201,6 +244,12 @@ int ConnectionUDP::SetBlockingMode( bool blocking )
|
||||||
//Success
|
//Success
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ConnectionUDP::GetSocket()
|
||||||
|
{
|
||||||
|
return socket;
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////
|
//////////////////////////////////////
|
||||||
// Private Methods
|
// Private Methods
|
||||||
//////////////////////////////////////
|
//////////////////////////////////////
|
||||||
|
|
|
@ -22,18 +22,23 @@ namespace Oyster
|
||||||
virtual int InitiateServer( unsigned short port );
|
virtual int InitiateServer( unsigned short port );
|
||||||
virtual int InitiateClient();
|
virtual int InitiateClient();
|
||||||
|
|
||||||
virtual int InitiateBroadcast(unsigned short port);
|
virtual int InitiateBroadcastServer(unsigned short port, const char serverName[]);
|
||||||
|
virtual int InitiateBroadcastClient(unsigned short port);
|
||||||
|
|
||||||
virtual int Send ( OysterByte &byte );
|
virtual int Send ( OysterByte &byte );
|
||||||
virtual int Recieve( OysterByte &byte );
|
virtual int Recieve( OysterByte &byte );
|
||||||
|
|
||||||
virtual int Connect( unsigned short port, const char serverName[] );
|
virtual int Connect( unsigned short port, const char serverName[] );
|
||||||
|
|
||||||
|
//Doesn't do anything now.
|
||||||
|
virtual int Reconnect() { return 0; }
|
||||||
|
|
||||||
virtual int Disconnect();
|
virtual int Disconnect();
|
||||||
|
|
||||||
bool IsSending();
|
bool IsSending();
|
||||||
bool IsConnected();
|
bool IsConnected();
|
||||||
int GetIpSize();
|
int GetIpSize();
|
||||||
|
int GetSocket();
|
||||||
|
|
||||||
int SetBlockingMode( bool blocking );
|
int SetBlockingMode( bool blocking );
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@ namespace Oyster
|
||||||
{
|
{
|
||||||
namespace Network
|
namespace Network
|
||||||
{
|
{
|
||||||
|
const int MAX_NETWORK_MESSAGE_SIZE = 1400;
|
||||||
|
|
||||||
struct ConnectionInfo
|
struct ConnectionInfo
|
||||||
{
|
{
|
||||||
int socket;
|
int socket;
|
||||||
|
@ -44,6 +46,8 @@ namespace Oyster
|
||||||
|
|
||||||
//Disconnects the client or server TODO: optimize!
|
//Disconnects the client or server TODO: optimize!
|
||||||
virtual int Disconnect() = 0;
|
virtual int Disconnect() = 0;
|
||||||
|
|
||||||
|
virtual int GetSocket() { return -1; };
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue