241 lines
6.4 KiB
C++
241 lines
6.4 KiB
C++
/////////////////////////////////////////////////////////////////////
|
|
// Created by [Dennis Andersen] [2013]
|
|
/////////////////////////////////////////////////////////////////////
|
|
#include "..\GameSession.h"
|
|
#include "..\GameClient.h"
|
|
#include <Protocols.h>
|
|
#include <PostBox\PostBox.h>
|
|
#include <GameLogicStates.h>
|
|
|
|
#define NOMINMAX
|
|
#include <Windows.h>
|
|
#include <Queue.h>
|
|
#include <future>
|
|
|
|
#define DELTA_TIME_20 0.05f
|
|
#define DELTA_TIME_24 0.04166666666666666666666666666667f
|
|
#define DELTA_TIME_30 0.03333333333333333333333333333333f
|
|
#define DELTA_TIME_60 0.01666666666666666666666666666667f
|
|
#define DELTA_TIME_120 0.00833333333333333333333333333333f
|
|
|
|
|
|
using namespace Utility::DynamicMemory;
|
|
using namespace Oyster;
|
|
using namespace Oyster::Network;
|
|
using namespace Oyster::Thread;
|
|
using namespace GameLogic;
|
|
|
|
namespace DanBias
|
|
{
|
|
GameSession* GameSession::gameSession = nullptr;
|
|
|
|
GameSession::GameSession()
|
|
:gameInstance(GameAPI::Instance())
|
|
{
|
|
this->owner = 0;
|
|
this->isCreated = false;
|
|
this->isRunning = false;
|
|
this->gameSession = this;
|
|
this->logicFrameTime = DELTA_TIME_20;
|
|
this->networkFrameTime = DELTA_TIME_20;
|
|
this->networkTimer.reset();
|
|
this->logicTimer.reset();
|
|
|
|
memset(&this->description, 0, sizeof(GameDescription));
|
|
}
|
|
|
|
GameSession::~GameSession()
|
|
{
|
|
this->worker.Terminate();
|
|
this->clients.Clear();
|
|
this->gameInstance;
|
|
this->owner = 0;
|
|
this->isCreated = false;
|
|
this->isRunning = false;
|
|
}
|
|
|
|
bool GameSession::Create(GameDescription& desc)
|
|
{
|
|
this->description = desc;
|
|
/* Do some error checking */
|
|
if(desc.clients.Size() == 0) return false;
|
|
if(!desc.owner) return false;
|
|
if(this->isCreated) return false;
|
|
|
|
/* standard initialization of some data */
|
|
NetworkSession::clients = desc.clients;
|
|
NetworkSession::clients.Resize((unsigned int)desc.maxClients);
|
|
this->clients.Resize((unsigned int)desc.maxClients);
|
|
this->owner = desc.owner;
|
|
|
|
/* Initiate the game instance */
|
|
if(!this->gameInstance.Initiate())
|
|
{
|
|
printf("Failed to initiate the game instance\n");
|
|
}
|
|
|
|
/* Create the players in the game instance */
|
|
GameLogic::IPlayerData* p = 0;
|
|
for (unsigned int i = 0; i < desc.clients.Size(); i++)
|
|
{
|
|
if(desc.clients[i])
|
|
{
|
|
if( (p = this->gameInstance.CreatePlayer()) )
|
|
{
|
|
desc.clients[i]->SetOwner(this);
|
|
this->clients[i] = (new GameClient(desc.clients[i], p));
|
|
}
|
|
else
|
|
{
|
|
printf("Failed to create player (%i)\n", i);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Create the game level */
|
|
if(!(this->levelData = this->gameInstance.CreateLevel()))
|
|
{
|
|
printf("Level not created!");
|
|
return false;
|
|
}
|
|
|
|
/* Set some game instance data options */
|
|
this->gameInstance.SetSubscription(GameSession::ObjectMove);
|
|
this->gameInstance.SetSubscription(GameSession::ObjectDisabled);
|
|
this->gameInstance.SetFPS(60);
|
|
|
|
this->description.clients.Clear();
|
|
|
|
this->isCreated = true;
|
|
|
|
/* Create the worker thread */
|
|
if(this->worker.Create(this, false) != OYSTER_THREAD_ERROR_SUCCESS)
|
|
return false;
|
|
|
|
return this->isCreated;
|
|
}
|
|
|
|
void GameSession::Run()
|
|
{
|
|
if(this->isRunning) return;
|
|
|
|
if(this->clients.Size() > 0)
|
|
{
|
|
this->worker.Start();
|
|
this->worker.SetPriority(OYSTER_THREAD_PRIORITY_1);
|
|
this->isRunning = true;
|
|
}
|
|
}
|
|
|
|
void GameSession::ThreadEntry( )
|
|
{
|
|
//List with clients that we are waiting on..
|
|
DynamicArray<SmartPointer<GameClient>> readyList;// = this->clients;
|
|
|
|
//First we need to clean invalid clients, if any, and tell them to start loading game data
|
|
for (unsigned int i = 0; i < this->clients.Size(); i++)
|
|
{
|
|
if(this->clients[i])
|
|
{
|
|
if(this->clients[i]->IsReady())
|
|
{
|
|
readyList.Push(this->clients[i]);
|
|
Protocol_LobbyCreateGame p(readyList[i]->GetPlayer()->GetID(), "char_white.dan", readyList[i]->GetPlayer()->GetOrientation());
|
|
readyList[readyList.Size() - 1]->GetClient()->Send(p);
|
|
}
|
|
}
|
|
}
|
|
|
|
unsigned int readyCounter = readyList.Size();
|
|
|
|
//Sync with clients
|
|
while (readyCounter != 0)
|
|
{
|
|
this->ProcessClients();
|
|
for (unsigned int i = 0; i < readyList.Size(); i++)
|
|
{
|
|
if(readyList[i] && readyList[i]->IsReady())
|
|
{
|
|
//Need to send information about other players, to all players
|
|
for (unsigned int k = 0; k < this->clients.Size(); k++)
|
|
{
|
|
if((this->clients[k] && readyList[i]) && readyList[i]->GetClient()->GetID() != this->clients[k]->GetClient()->GetID())
|
|
{
|
|
//Protocol_ObjectCreatePlayer
|
|
Protocol_ObjectCreate p( this->clients[k]->GetPlayer()->GetPosition(),
|
|
this->clients[k]->GetPlayer()->GetRotation(),
|
|
this->clients[k]->GetPlayer()->GetScale(),
|
|
this->clients[k]->GetPlayer()->GetID(), "char_white.dan"); //The model name will be custom later..
|
|
readyList[i]->GetClient()->Send(p);
|
|
}
|
|
}
|
|
|
|
readyCounter-- ;
|
|
readyList[i] = 0;
|
|
}
|
|
}
|
|
Sleep(5); //TODO: This might not be needed here.
|
|
}
|
|
|
|
for (unsigned int i = 0; i < this->clients.Size(); i++)
|
|
{
|
|
if(this->clients[i])
|
|
{
|
|
this->clients[i]->GetClient()->Send(GameLogic::Protocol_LobbyStartGame(5));
|
|
}
|
|
}
|
|
}
|
|
|
|
bool GameSession::Attach(Utility::DynamicMemory::SmartPointer<NetworkClient> client)
|
|
{
|
|
if(!this->isCreated) return false;
|
|
if(this->GetClientCount() == this->clients.Capacity()) return false;
|
|
|
|
client->SetOwner(this);
|
|
|
|
IPlayerData* player = this->gameInstance.CreatePlayer();
|
|
if(!player) return false;
|
|
|
|
SmartPointer<GameClient> obj = new GameClient(client, player);
|
|
|
|
// Send the chosen mesh name
|
|
Protocol_LobbyCreateGame lcg(obj->GetPlayer()->GetID(), "char_white.dan", obj->GetPlayer()->GetOrientation());
|
|
obj->GetClient()->Send(lcg);
|
|
|
|
// Send the player data only
|
|
for (unsigned int i = 0; i < this->clients.Capacity(); i++)
|
|
{
|
|
if(this->clients[i])
|
|
{
|
|
IPlayerData* p = this->clients[i]->GetPlayer();
|
|
Protocol_ObjectCreate oc(p->GetPosition(), p->GetRotation(), p->GetScale(), p->GetID(), "char_white.dan");
|
|
//Protocol_ObjectCreatePlayer oc(p->GetPosition(), p->GetRotation(), p->GetScale(), p->GetID(), "char_white.dan");
|
|
this->clients[i]->GetClient()->Send(oc);
|
|
}
|
|
}
|
|
|
|
obj->GetClient()->Send(GameLogic::Protocol_LobbyStartGame(0));
|
|
|
|
for (unsigned int i = 0; i < this->clients.Size(); i++)
|
|
{
|
|
if(!clients[i])
|
|
{
|
|
NetworkSession::clients[i] = client;
|
|
clients[i] = obj;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void GameSession::CloseSession( bool dissconnectClients )
|
|
{
|
|
this->worker.Terminate();
|
|
NetworkSession::CloseSession(true);
|
|
this->clients.Clear();
|
|
}
|
|
|
|
}//End namespace DanBias
|
|
|