2014-07-09 18:29:07 -04:00
|
|
|
#include "stdafx.h"
|
2015-07-01 23:17:14 -04:00
|
|
|
#include <thread>
|
|
|
|
using std::thread;
|
|
|
|
|
|
|
|
#include "MessageManager.h"
|
2014-07-09 18:29:07 -04:00
|
|
|
#include "GameServer.h"
|
2014-07-09 19:05:07 -04:00
|
|
|
#include "Console.h"
|
2015-07-01 23:17:14 -04:00
|
|
|
#include "../Utilities/Socket.h"
|
2016-02-06 15:33:45 -05:00
|
|
|
#include "PlayerListMessage.h"
|
2014-07-09 18:29:07 -04:00
|
|
|
|
|
|
|
unique_ptr<GameServer> GameServer::Instance;
|
|
|
|
|
2016-02-06 15:33:45 -05:00
|
|
|
GameServer::GameServer(uint16_t listenPort, string hostPlayerName)
|
2015-07-01 23:17:14 -04:00
|
|
|
{
|
2016-02-06 15:33:45 -05:00
|
|
|
_port = listenPort;
|
|
|
|
_hostPlayerName = hostPlayerName;
|
|
|
|
_hostControllerPort = 0;
|
2015-07-01 23:17:14 -04:00
|
|
|
ControlManager::RegisterBroadcaster(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
GameServer::~GameServer()
|
|
|
|
{
|
|
|
|
_stop = true;
|
|
|
|
_serverThread->join();
|
|
|
|
|
|
|
|
Stop();
|
|
|
|
|
|
|
|
ControlManager::UnregisterBroadcaster(this);
|
|
|
|
}
|
|
|
|
|
2014-07-09 18:29:07 -04:00
|
|
|
void GameServer::AcceptConnections()
|
|
|
|
{
|
|
|
|
while(true) {
|
2015-07-11 10:01:06 -04:00
|
|
|
shared_ptr<Socket> socket = _listener->Accept();
|
2014-07-09 18:29:07 -04:00
|
|
|
if(!socket->ConnectionError()) {
|
2016-02-06 15:33:45 -05:00
|
|
|
_openConnections.push_back(shared_ptr<GameServerConnection>(new GameServerConnection(socket)));
|
2014-07-09 18:29:07 -04:00
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_listener->Listen(10);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GameServer::UpdateConnections()
|
|
|
|
{
|
|
|
|
vector<shared_ptr<GameServerConnection>> connectionsToRemove;
|
|
|
|
for(shared_ptr<GameServerConnection> connection : _openConnections) {
|
|
|
|
if(connection->ConnectionError()) {
|
|
|
|
connectionsToRemove.push_back(connection);
|
|
|
|
} else {
|
|
|
|
connection->ProcessMessages();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for(shared_ptr<GameServerConnection> gameConnection : connectionsToRemove) {
|
|
|
|
_openConnections.remove(gameConnection);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-06 15:33:45 -05:00
|
|
|
list<shared_ptr<GameServerConnection>> GameServer::GetConnectionList()
|
|
|
|
{
|
|
|
|
if(GameServer::Started()) {
|
|
|
|
return Instance->_openConnections;
|
|
|
|
} else {
|
|
|
|
return list<shared_ptr<GameServerConnection>>();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
void GameServer::Exec()
|
2014-07-09 18:29:07 -04:00
|
|
|
{
|
|
|
|
_listener.reset(new Socket());
|
2015-07-01 23:17:14 -04:00
|
|
|
_listener->Bind(_port);
|
2014-07-09 18:29:07 -04:00
|
|
|
_listener->Listen(10);
|
|
|
|
_stop = false;
|
|
|
|
_initialized = true;
|
2016-02-19 13:05:04 -05:00
|
|
|
MessageManager::DisplayMessage("NetPlay" , "ServerStarted", std::to_string(_port));
|
2014-07-09 18:29:07 -04:00
|
|
|
|
|
|
|
while(!_stop) {
|
|
|
|
AcceptConnections();
|
|
|
|
UpdateConnections();
|
|
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::duration<int, std::milli>(1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void GameServer::Stop()
|
|
|
|
{
|
|
|
|
_initialized = false;
|
|
|
|
_listener.reset();
|
2016-02-19 13:05:04 -05:00
|
|
|
MessageManager::DisplayMessage("NetPlay", "ServerStopped");
|
2014-07-09 18:29:07 -04:00
|
|
|
}
|
|
|
|
|
2016-02-06 15:33:45 -05:00
|
|
|
void GameServer::StartServer(uint16_t port, string hostPlayerName)
|
2014-07-09 18:29:07 -04:00
|
|
|
{
|
2016-02-06 15:33:45 -05:00
|
|
|
Instance.reset(new GameServer(port, hostPlayerName));
|
2014-07-09 18:29:07 -04:00
|
|
|
Instance->_serverThread.reset(new thread(&GameServer::Exec, Instance.get()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void GameServer::StopServer()
|
|
|
|
{
|
|
|
|
if(Instance) {
|
|
|
|
Instance.reset();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GameServer::Started()
|
|
|
|
{
|
|
|
|
if(Instance) {
|
|
|
|
return Instance->_initialized;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void GameServer::BroadcastInput(uint8_t inputData, uint8_t port)
|
|
|
|
{
|
|
|
|
for(shared_ptr<GameServerConnection> connection : _openConnections) {
|
|
|
|
if(!connection->ConnectionError()) {
|
|
|
|
//Send movie stream
|
|
|
|
connection->SendMovieData(inputData, port);
|
|
|
|
}
|
|
|
|
}
|
2016-02-06 15:33:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
string GameServer::GetHostPlayerName()
|
|
|
|
{
|
|
|
|
if(GameServer::Started()) {
|
|
|
|
return Instance->_hostPlayerName;
|
|
|
|
}
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t GameServer::GetHostControllerPort()
|
|
|
|
{
|
|
|
|
if(GameServer::Started()) {
|
|
|
|
return Instance->_hostControllerPort;
|
|
|
|
}
|
|
|
|
return GameConnection::SpectatorPort;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GameServer::SetHostControllerPort(uint8_t port)
|
|
|
|
{
|
|
|
|
if(GameServer::Started()) {
|
|
|
|
Console::Pause();
|
|
|
|
if(port == GameConnection::SpectatorPort || GetAvailableControllers() & (1 << port)) {
|
|
|
|
//Port is available
|
|
|
|
Instance->_hostControllerPort = port;
|
|
|
|
SendPlayerList();
|
|
|
|
}
|
|
|
|
Console::Resume();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t GameServer::GetAvailableControllers()
|
|
|
|
{
|
|
|
|
uint8_t availablePorts = 0x0F;
|
|
|
|
for(PlayerInfo &playerInfo : GetPlayerList()) {
|
|
|
|
if(playerInfo.ControllerPort < 4) {
|
|
|
|
availablePorts &= ~(1 << playerInfo.ControllerPort);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return availablePorts;
|
|
|
|
}
|
|
|
|
|
|
|
|
vector<PlayerInfo> GameServer::GetPlayerList()
|
|
|
|
{
|
|
|
|
vector<PlayerInfo> playerList;
|
|
|
|
|
|
|
|
PlayerInfo playerInfo;
|
|
|
|
playerInfo.Name = GetHostPlayerName();
|
|
|
|
playerInfo.ControllerPort = GetHostControllerPort();
|
|
|
|
playerInfo.IsHost = true;
|
|
|
|
playerList.push_back(playerInfo);
|
|
|
|
|
|
|
|
for(shared_ptr<GameServerConnection> &connection : GetConnectionList()) {
|
|
|
|
playerInfo.Name = connection->GetPlayerName();
|
|
|
|
playerInfo.ControllerPort = connection->GetControllerPort();
|
|
|
|
playerInfo.IsHost = false;
|
|
|
|
playerList.push_back(playerInfo);
|
|
|
|
}
|
|
|
|
|
|
|
|
return playerList;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GameServer::SendPlayerList()
|
|
|
|
{
|
|
|
|
vector<PlayerInfo> playerList = GetPlayerList();
|
|
|
|
|
|
|
|
for(shared_ptr<GameServerConnection> &connection : GetConnectionList()) {
|
|
|
|
//Send player list update to all connections
|
|
|
|
PlayerListMessage message(playerList);
|
|
|
|
connection->SendNetMessage(message);
|
|
|
|
}
|
2014-07-09 18:29:07 -04:00
|
|
|
}
|