Danbias/Code/Game/GameServer/Implementation/GameSession_General.cpp

288 lines
8.0 KiB
C++
Raw Normal View History

/////////////////////////////////////////////////////////////////////
// Created by [Dennis Andersen] [2013]
/////////////////////////////////////////////////////////////////////
2014-01-28 09:00:02 +01:00
#include "..\GameSession.h"
#include "..\GameClient.h"
#include "..\GameLobby.h"
#include <Protocols.h>
#include <PostBox\PostBox.h>
#include <GameLogicStates.h>
2014-01-29 10:18:01 +01:00
#define NOMINMAX
#include <Windows.h>
#include <Queue.h>
2014-02-15 09:29:54 +01:00
#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;
2014-02-18 08:55:38 +01:00
using namespace DanBias;
2014-02-18 08:55:38 +01:00
GameSession* GameSession::gameSession = nullptr;
2014-01-30 00:19:00 +01:00
2014-02-18 08:55:38 +01:00
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;
}
2014-02-18 13:12:08 +01:00
bool GameSession::Create(GameDescription& desc, bool forceStart)
2014-02-18 08:55:38 +01:00
{
this->description = desc;
/* Do some error checking */
2014-02-18 13:12:08 +01:00
if(!forceStart && desc.clients.Size() == 0) return false;
if(!desc.owner) return false;
if(this->isCreated) return false;
2014-02-18 08:55:38 +01:00
/* standard initialization of some data */
this->gClients.Resize((unsigned int)desc.maxClients);
for (unsigned int i = 0; i < desc.clients.Size(); i++)
{
if(desc.clients[i])
{
this->clientCount++;
this->gClients[i] = desc.clients[i];
this->gClients[i]->SetOwner(this);
}
}
2014-02-18 08:55:38 +01:00
this->owner = desc.owner;
2014-02-18 08:55:38 +01:00
/* Initiate the game instance */
if(!this->gameInstance.Initiate())
{
2014-02-18 08:55:38 +01:00
printf("Failed to initiate the game instance\n");
}
2014-02-18 08:55:38 +01:00
/* Create the players in the game instance */
GameLogic::IPlayerData* p = 0;
for (unsigned int i = 0; i < this->gClients.Size(); i++)
{
if(this->gClients[i])
2014-01-20 15:47:52 +01:00
{
2014-02-18 08:55:38 +01:00
if( (p = this->gameInstance.CreatePlayer()) )
2014-01-20 15:47:52 +01:00
{
this->gClients[i]->SetPlayer(p);
2014-02-18 08:55:38 +01:00
}
else
{
printf("Failed to create player (%i)\n", i);
2014-01-20 15:47:52 +01:00
}
}
2014-02-18 08:55:38 +01:00
}
2014-02-18 08:55:38 +01:00
/* Create the game level */
if(!(this->levelData = this->gameInstance.CreateLevel(this->description.mapName.c_str())))
2014-02-18 08:55:38 +01:00
{
printf("Level not created!");
return false;
}
2014-02-18 08:55:38 +01:00
/* Set some game instance data options */
this->gameInstance.SetSubscription(GameSession::ObjectMove);
this->gameInstance.SetSubscription(GameSession::ObjectDisabled);
this->gameInstance.SetFPS(60);
2014-02-18 08:55:38 +01:00
this->description.clients.Clear();
2014-01-20 15:47:52 +01:00
2014-02-18 08:55:38 +01:00
this->isCreated = true;
2014-02-18 08:55:38 +01:00
/* Create the worker thread */
if(this->worker.Create(this, false) != OYSTER_THREAD_ERROR_SUCCESS)
return false;
2014-02-18 08:55:38 +01:00
return this->isCreated;
}
2014-02-18 08:55:38 +01:00
void GameSession::Run()
{
if(this->isRunning) return;
2014-02-18 13:12:08 +01:00
this->worker.Start();
this->worker.SetPriority(OYSTER_THREAD_PRIORITY_1);
this->isRunning = true;
2014-02-18 08:55:38 +01:00
}
2014-02-18 08:55:38 +01:00
void GameSession::ThreadEntry( )
{
//List with clients that we are waiting on..
DynamicArray<gClient> readyList;// = this->clients;
2014-02-18 08:55:38 +01:00
//First we need to clean invalid clients, if any, and tell them to start loading game data
for (unsigned int i = 0; i < this->gClients.Size(); i++)
2014-02-18 08:55:38 +01:00
{
if(this->gClients[i])
{
readyList.Push(this->gClients[i]);
Protocol_LobbyCreateGame p((char)1, (char)0, Utility::String::WStringToString(this->description.mapName, std::string()));
2014-02-18 08:55:38 +01:00
readyList[readyList.Size() - 1]->GetClient()->Send(p);
}
2014-02-18 08:55:38 +01:00
}
2014-02-18 08:55:38 +01:00
unsigned int readyCounter = readyList.Size();
2014-02-18 08:55:38 +01:00
//Sync with clients
while (readyCounter != 0)
{
this->ProcessClients();
for (unsigned int i = 0; i < readyList.Size(); i++)
{
2014-02-18 08:55:38 +01:00
if(readyList[i] && readyList[i]->IsReady())
{
2014-02-18 08:55:38 +01:00
//Need to send information about other players, to all players
for (unsigned int k = 0; k < this->gClients.Size(); k++)
{
if((this->gClients[k] && readyList[i]) && readyList[i]->GetClient()->GetID() != this->gClients[k]->GetClient()->GetID())
{
IPlayerData* pl = this->gClients[k]->GetPlayer();
2014-02-18 08:55:38 +01:00
Protocol_ObjectCreatePlayer p( pl->GetPosition(), pl->GetRotation(), pl->GetScale(),
pl->GetID(), true, this->gClients[k]->GetPlayer()->GetTeamID(),
Utility::String::WStringToString(this->gClients[k]->GetAlias(), std::string()),
Utility::String::WStringToString(this->gClients[k]->GetCharacter(), std::string()));
2014-02-18 08:55:38 +01:00
readyList[i]->GetClient()->Send(p);
}
}
2014-02-18 08:55:38 +01:00
readyCounter-- ;
readyList[i] = 0;
}
}
2014-02-18 08:55:38 +01:00
Sleep(5); //TODO: This might not be needed here.
}
2014-02-18 08:55:38 +01:00
//Sync with clients before starting countdown
for (unsigned int i = 0; i < this->gClients.Size(); i++)
2014-02-18 08:55:38 +01:00
{
if(this->gClients[i])
{
this->gClients[i]->GetClient()->Send(GameLogic::Protocol_LobbyStartGame(5.0f));
}
}
2014-02-18 08:55:38 +01:00
}
bool GameSession::Join(gClient gameClient)
2014-02-18 08:55:38 +01:00
{
if(!this->isCreated) return false;
if(this->GetClientCount() == this->gClients.Capacity()) return false;
gameClient->SetOwner(this);
2014-02-18 08:55:38 +01:00
IPlayerData* playerData = this->gameInstance.CreatePlayer();
if(!playerData) return false;
gameClient->SetPlayer(playerData);
2014-02-18 08:55:38 +01:00
NetworkClient* nwClient = gameClient->GetClient();
2014-02-15 09:29:54 +01:00
2014-02-18 08:55:38 +01:00
// Send the player data only
{
Protocol_ObjectCreatePlayer oc( playerData->GetPosition(), playerData->GetRotation(), playerData->GetScale(),
playerData->GetID(), true, playerData->GetTeamID(),
Utility::String::WStringToString(gameClient->GetAlias(), std::string()),
Utility::String::WStringToString(gameClient->GetCharacter(), std::string()));
2014-02-18 08:55:38 +01:00
nwClient->Send(oc);
}
2014-02-15 09:29:54 +01:00
2014-02-18 08:55:38 +01:00
// Send information about other clients
{
for (unsigned int i = 0; i < this->gClients.Size(); i++)
2014-02-15 09:29:54 +01:00
{
if(this->gClients[i] && !this->gClients[i]->IsInvalid())
2014-02-15 09:29:54 +01:00
{
IPlayerData* temp = this->gClients[i]->GetPlayer();
2014-02-20 16:54:24 +01:00
Protocol_ObjectCreatePlayer p1( temp->GetPosition(), temp->GetRotation(), temp->GetScale(),
2014-02-18 08:55:38 +01:00
temp->GetID(), false, temp->GetTeamID(),
Utility::String::WStringToString(this->gClients[i]->GetAlias(), std::string()),
Utility::String::WStringToString(this->gClients[i]->GetCharacter(), std::string()));
2014-02-20 16:54:24 +01:00
nwClient->Send(p1);
temp = playerData;
Protocol_ObjectCreatePlayer p2( temp->GetPosition(), temp->GetRotation(), temp->GetScale(),
temp->GetID(), false, temp->GetTeamID(),
Utility::String::WStringToString(gameClient->GetAlias(), std::string()),
Utility::String::WStringToString(gameClient->GetCharacter(), std::string()));
this->gClients[i]->GetClient()->Send(p2);
2014-02-15 09:29:54 +01:00
}
}
2014-02-18 08:55:38 +01:00
}
2014-02-15 09:29:54 +01:00
2014-02-18 08:55:38 +01:00
//TODO: Need to be able to get the current gameplay data from the logic, to sync it with the client
{
DynamicArray<IObjectData*> objects;
this->levelData->GetAllDynamicObjects(objects);
for (unsigned int i = 0; i < objects.Size(); i++)
{
//Protocol_ObjectPosition p(movedObject->GetPosition(), id);
Protocol_ObjectPositionRotation p(objects[i]->GetPosition(), objects[i]->GetRotation(), objects[i]->GetID());
2014-02-21 10:54:30 +01:00
nwClient->Send(p.GetProtocol());
}
2014-02-18 08:55:38 +01:00
}
2014-02-15 09:29:54 +01:00
2014-02-18 08:55:38 +01:00
// Insert the new client to the update list
bool added = false;
2014-02-18 08:55:38 +01:00
{
for (unsigned int i = 0; !added && i < this->gClients.Size(); i++)
{
if(!this->gClients[i])
{
this->gClients[i] = gameClient;
// Send the start signal
{
nwClient->Send(GameLogic::Protocol_LobbyStartGame(0));
}
2014-02-18 08:55:38 +01:00
added = true;
this->clientCount++;
}
}
}
gameClient->SetState(GameClient::ClientState_Ready);
return added;
2014-02-18 08:55:38 +01:00
}
//DynamicArray<gClient> GameSession::CloseSession( bool dissconnectClients )
//{
// this->worker.Terminate();
// //TODO: Send clients to lobby
//
// //for (unsigned int i = 0; i < this->gClients.Size(); i++)
// //{
// // if(this->gClients[i])
// // {
// // ((GameLobby*)this->owner)-> this->gClients[i]
// // }
// //}
//
// this->gClients.Clear();
//}