Merge with physics

This commit is contained in:
Linda Andersson 2014-02-26 10:25:39 +01:00
commit a8055cfbf7
15 changed files with 490 additions and 63 deletions

View File

@ -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 );
@ -82,6 +88,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;
} }
@ -95,6 +106,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;
} }
@ -116,6 +129,11 @@ bool LanMenuState::Render( )
bool LanMenuState::Release() bool LanMenuState::Release()
{ {
if(privData)
{
this->privData->nwClient->StopListeningForBroadcasting();
}
privData = NULL; privData = NULL;
return true; return true;
} }
@ -156,3 +174,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;
}

View File

@ -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;

View File

@ -65,19 +65,16 @@ void Player::initPlayerData()
void Player::BeginFrame() void Player::BeginFrame()
{ {
if( this->playerState != PLAYER_STATE_DEAD && PLAYER_STATE_DIED) if( this->playerState != PLAYER_STATE_DEAD && this->playerState != PLAYER_STATE_DIED)
{ {
weapon->Update(0.002f); weapon->Update(0.002f);
Oyster::Math::Float maxSpeed = 30; Oyster::Math::Float maxSpeed = 30;
// Rotate player accordingly // Rotate player accordingly
this->rigidBody->AddRotationAroundY(this->rotationUp);
this->rigidBody->SetUp(this->rigidBody->GetState().centerPos.GetNormalized()); this->rigidBody->SetUp(this->rigidBody->GetState().centerPos.GetNormalized());
Oyster::Math::Quaternion firstUp = this->rigidBody->GetState().quaternion; this->rotationUp = 0;
this->rigidBody->SetRotationAsAngularAxis(Oyster::Math3D::Float4(this->rigidBody->GetState().centerPos.GetNormalized(), this->rotationUp));
Oyster::Math::Quaternion secondTurn = this->rigidBody->GetState().quaternion;
this->rigidBody->SetRotation(secondTurn*firstUp);
// Direction data // Direction data
Oyster::Math::Float4x4 xform; Oyster::Math::Float4x4 xform;
@ -125,7 +122,7 @@ void Player::BeginFrame()
} }
// Dampen velocity if certain keys are not pressed // Dampen velocity if certain keys are not pressed
if(key_jump <= 0.001 && this->rigidBody->GetLambda() < 0.9f) if(key_jump <= 0.001 && IsWalking())
{ {
if(key_forward <= 0.001 && key_backward <= 0.001) if(key_forward <= 0.001 && key_backward <= 0.001)
{ {
@ -152,7 +149,7 @@ void Player::BeginFrame()
walkDirection.Normalize(); walkDirection.Normalize();
// If on the ground, accelerate normally // If on the ground, accelerate normally
if(this->rigidBody->GetLambda() < 0.9f) if(IsWalking())
{ {
if(forwardSpeed < maxSpeed) if(forwardSpeed < maxSpeed)
{ {
@ -164,7 +161,7 @@ void Player::BeginFrame()
} }
} }
// If in the air, accelerate slower // If in the air, accelerate slower
if(this->rigidBody->GetLambda() >= 0.9f) if(IsJumping())
{ {
if(forwardSpeed < maxSpeed) if(forwardSpeed < maxSpeed)
{ {
@ -193,8 +190,8 @@ void Player::BeginFrame()
//Jump //Jump
if(key_jump > 0.001) if(key_jump > 0.001)
{ {
this->key_jump -= this->gameInstance->GetFrameTime(); this->key_jump -= this->gameInstance->GetFrameTime();
if(this->rigidBody->GetLambda() < 0.9f) if(IsWalking())
{ {
Oyster::Math::Float3 up = this->rigidBody->GetState().centerPos.GetNormalized(); Oyster::Math::Float3 up = this->rigidBody->GetState().centerPos.GetNormalized();
this->rigidBody->ApplyImpulse(up*this->rigidBody->GetState().mass * 20); this->rigidBody->ApplyImpulse(up*this->rigidBody->GetState().mass * 20);
@ -306,15 +303,15 @@ void Player::Jump()
bool Player::IsWalking() bool Player::IsWalking()
{ {
return (this->playerState == PLAYER_STATE::PLAYER_STATE_WALKING); return (this->rigidBody->GetLambda() < 0.99f);
} }
bool Player::IsJumping() bool Player::IsJumping()
{ {
return (this->playerState == PLAYER_STATE::PLAYER_STATE_JUMPING); return (this->rigidBody->GetLambda() == 1.0f);
} }
bool Player::IsIdle() bool Player::IsIdle()
{ {
return (this->playerState == PLAYER_STATE::PLAYER_STATE_IDLE); return (this->rigidBody->GetLambda() == 1.0f && this->rigidBody->GetLinearVelocity().GetMagnitude() < 0.0001f);
} }
void Player::Inactivate() void Player::Inactivate()

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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)
{ {

View File

@ -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>
@ -60,6 +63,15 @@ struct NetworkClient::PrivateData : public IThreadObject
HANDLE socketEvents[2]; HANDLE socketEvents[2];
HANDLE shutdownEvent; 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. //The OysterByte each message is packed in.
OysterByte tempMessage; OysterByte tempMessage;
@ -77,6 +89,7 @@ struct NetworkClient::PrivateData : public IThreadObject
, owner(0) , owner(0)
, outputEvent(0) , outputEvent(0)
{ {
broadcastingStarted = false;
numPackages = 0; numPackages = 0;
bufferedSend.Resize(MAX_NETWORK_MESSAGE_SIZE); bufferedSend.Resize(MAX_NETWORK_MESSAGE_SIZE);
tempMessage.Resize(MAX_NETWORK_MESSAGE_SIZE); tempMessage.Resize(MAX_NETWORK_MESSAGE_SIZE);
@ -120,6 +133,26 @@ struct NetworkClient::PrivateData : public IThreadObject
CloseHandle(shutdownEvent); 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
{ {
WSANETWORKEVENTS wsaEvents; WSANETWORKEVENTS wsaEvents;
@ -128,7 +161,7 @@ struct NetworkClient::PrivateData : public IThreadObject
{ {
if(!this->connection.IsConnected()) return false; if(!this->connection.IsConnected()) return false;
int result = WSAWaitForMultipleEvents(2, socketEvents, FALSE, 100, FALSE) - WSA_WAIT_EVENT_0; int result = WSAWaitForMultipleEvents(3, socketEvents, FALSE, 100, FALSE) - WSA_WAIT_EVENT_0;
if(result == 0) if(result == 0)
{ {
WSAEnumNetworkEvents(this->connection.GetSocket(), socketEvents[0], &wsaEvents); WSAEnumNetworkEvents(this->connection.GetSocket(), socketEvents[0], &wsaEvents);
@ -161,6 +194,47 @@ struct NetworkClient::PrivateData : public IThreadObject
return false; 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() void SendBuffer()
{ {
if(bufferedSend.GetSize() > 0) if(bufferedSend.GetSize() > 0)
@ -599,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;
}
}
}

View File

@ -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);

View File

@ -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();
}

View File

@ -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)
@ -201,6 +244,12 @@ int ConnectionUDP::SetBlockingMode( bool blocking )
//Success //Success
return 0; return 0;
} }
int ConnectionUDP::GetSocket()
{
return socket;
}
////////////////////////////////////// //////////////////////////////////////
// Private Methods // Private Methods
////////////////////////////////////// //////////////////////////////////////

View File

@ -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 );

View File

@ -163,30 +163,19 @@ void SimpleRigidBody::SetRotation(::Oyster::Math::Float4x4 rotation)
this->state.quaternion = Quaternion(Float3(quaternion.x(), quaternion.y(), quaternion.z()), quaternion.w()); this->state.quaternion = Quaternion(Float3(quaternion.x(), quaternion.y(), quaternion.z()), quaternion.w());
} }
void SimpleRigidBody::SetRotationAsAngularAxis(::Oyster::Math::Float4 angularAxis) void SimpleRigidBody::AddRotationAroundY(::Oyster::Math::Float angle)
{ {
if(angularAxis.xyz.GetMagnitude() == 0)
{
return;
}
float s = sin(angularAxis.w/2);
float x = angularAxis.x * s;
float y = angularAxis.y * s;
float z = angularAxis.z * s;
float w = cos(angularAxis.w/2);
btTransform trans; btTransform trans;
btVector3 vector(angularAxis.x, angularAxis.y, angularAxis.z); btQuaternion quaternion;
btQuaternion quaternion(x,y,z,w);
trans = this->rigidBody->getWorldTransform(); trans = this->rigidBody->getWorldTransform();
trans.setRotation(quaternion);
quaternion = btQuaternion(trans.getBasis().getColumn(1), angle);
trans.setRotation(quaternion*trans.getRotation());
this->rigidBody->setWorldTransform(trans); this->rigidBody->setWorldTransform(trans);
this->state.quaternion = Quaternion(Float3(quaternion.x(), quaternion.y(), quaternion.z()), quaternion.w()); this->state.quaternion = Quaternion(Float3(quaternion.x(), quaternion.y(), quaternion.z()), quaternion.w());
} }
void SimpleRigidBody::SetAngularFactor(Float factor) void SimpleRigidBody::SetAngularFactor(Float factor)
{ {
this->rigidBody->setAngularFactor(factor); this->rigidBody->setAngularFactor(factor);
@ -245,23 +234,45 @@ void SimpleRigidBody::SetUpAndForward(::Oyster::Math::Float3 up, ::Oyster::Math:
void SimpleRigidBody::SetUp(::Oyster::Math::Float3 up) void SimpleRigidBody::SetUp(::Oyster::Math::Float3 up)
{ {
Float3 vector = Float3(0, 1, 0).Cross(up); btQuaternion newRotation;
if(vector == Float3::null)
{
return;
}
Float sine = vector.GetLength();
Float cosine = acos(Float3(0, 1, 0).Dot(up));
btQuaternion quaternion(btVector3(vector.x, vector.y, vector.z),cosine);
btTransform trans; btTransform trans;
trans = this->rigidBody->getWorldTransform(); trans = this->rigidBody->getWorldTransform();
trans.setRotation(quaternion);
btVector3 v1 = trans.getBasis().getColumn(1);
btVector3 v2(up.x, up.y, up.z);
btQuaternion q;
btVector3 a = v1.cross(v2);
if (v1.dot(v2) < -0.999999)
{
btVector3 xCrossPre = btVector3(1, 0 ,0).cross(v1);
if(xCrossPre.length() < 0.000001)
xCrossPre = btVector3(0, 1 ,0).cross(v1);
xCrossPre.normalize();
q.setRotation(xCrossPre, 3.1415);
}
else if (v1.dot(v2) > 0.999999)
{
q = btQuaternion(0, 0, 0, 1);
}
else
{
q.setX(a.x());
q.setY(a.y());
q.setZ(a.z());
q.setW(1 + v1.dot(v2));
q.normalize();
}
newRotation = q*trans.getRotation();
trans.setRotation(newRotation);
this->rigidBody->setWorldTransform(trans); this->rigidBody->setWorldTransform(trans);
this->state.quaternion = Quaternion(Float3(quaternion.x(), quaternion.y(), quaternion.z()), quaternion.w());
this->state.quaternion = Quaternion(Float3(newRotation.x(), newRotation.y(), newRotation.z()), newRotation.w());
} }
Float4x4 SimpleRigidBody::GetRotation() const Float4x4 SimpleRigidBody::GetRotation() const

View File

@ -29,7 +29,7 @@ namespace Oyster
void SetRotation(Math::Quaternion quaternion); void SetRotation(Math::Quaternion quaternion);
void SetRotation(Math::Float3 eulerAngles); void SetRotation(Math::Float3 eulerAngles);
void SetRotation(::Oyster::Math::Float4x4 rotation); void SetRotation(::Oyster::Math::Float4x4 rotation);
void SetRotationAsAngularAxis(Math::Float4 angularAxis); void AddRotationAroundY(::Oyster::Math::Float angle);
void SetAngularFactor(Math::Float factor); void SetAngularFactor(Math::Float factor);
void SetMass(Math::Float mass); void SetMass(Math::Float mass);

View File

@ -147,7 +147,7 @@ namespace Oyster
virtual void SetRotation(::Oyster::Math::Quaternion quaternion) = 0; virtual void SetRotation(::Oyster::Math::Quaternion quaternion) = 0;
virtual void SetRotation(::Oyster::Math::Float3 eulerAngles) = 0; virtual void SetRotation(::Oyster::Math::Float3 eulerAngles) = 0;
virtual void SetRotation(::Oyster::Math::Float4x4 rotation) = 0; virtual void SetRotation(::Oyster::Math::Float4x4 rotation) = 0;
virtual void SetRotationAsAngularAxis(::Oyster::Math::Float4 angularAxis) = 0; virtual void AddRotationAroundY(::Oyster::Math::Float angle) = 0;
virtual void SetAngularFactor(::Oyster::Math::Float factor) = 0; virtual void SetAngularFactor(::Oyster::Math::Float factor) = 0;
virtual void SetMass(::Oyster::Math::Float mass) = 0; virtual void SetMass(::Oyster::Math::Float mass) = 0;