- updated for compiling on BSD

- also bugfix for socket broadcast segfault (partial fix)
This commit is contained in:
Mark Vejvoda
2011-01-13 01:46:32 +00:00
parent fec68c872a
commit 8c4cdd037c
5 changed files with 582 additions and 642 deletions

View File

@@ -37,7 +37,7 @@
#include "cache_manager.h"
// For gcc backtrace on crash!
#if defined(__GNUC__) && !defined(__MINGW32__)
#if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD)
#include <execinfo.h>
#include <cxxabi.h>
#include <signal.h>
@@ -201,7 +201,7 @@ public:
message(msg.c_str());
}
#ifdef __GNUC__
#if defined(__GNUC__) && !defined(__FreeBSD__) && !defined(BSD)
static int getFileAndLine(void *address, char *file, size_t flen) {
int line=-1;
static char buf[256]="";
@@ -261,7 +261,7 @@ public:
string errMsg = (msg != NULL ? msg : "null");
#if defined(__GNUC__) && !defined(__MINGW32__)
#if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD)
errMsg += "\nStack Trace:\n";
//errMsg += "To find line #'s use:\n";
//errMsg += "readelf --debug-dump=decodedline %s | egrep 0xaddress-of-stack\n";
@@ -416,7 +416,7 @@ public:
}
};
#ifdef __GNUC__
#if defined(__GNUC__) && !defined(__FreeBSD__) && !defined(BSD)
void handleSIGSEGV(int sig) {
char szBuf[4096]="";
sprintf(szBuf, "In [%s::%s Line: %d] Error detected: signal %d:\n",__FILE__,__FUNCTION__,__LINE__, sig);

View File

@@ -30,37 +30,16 @@ using namespace Shared::Platform;
using namespace Shared::Util;
namespace Glest{ namespace Game{
// =====================================================
// class ServerInterface
// =====================================================
// Experimental threading of broadcasts to clients
//bool enabledThreadedClientCommandBroadcast = true;
bool enabledThreadedClientCommandBroadcast = false;
// The maximum amount of network update iterations a client is allowed to fall behind
double maxFrameCountLagAllowed = 30;
// The maximum amount of seconds a client is allowed to not communicate with the server
double maxClientLagTimeAllowed = 20;
// The maximum amount of network update iterations a client is allowed to fall behind before we
// for a disconnect regardless of other settings
double maxFrameCountLagAllowedEver = 50;
// 65% of max we warn all users about the lagged client
double warnFrameCountLagPercent = 0.65;
// Should we wait for lagged clients instead of disconnect them?
//bool pauseGameForLaggedClients = false;
// Seconds grace period before we start checking LAG
double LAG_CHECK_GRACE_PERIOD = 15;
// The max amount of time to 'freeze' gameplay per packet when a client is lagging
// badly and we want to give time for them to catch up
double MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE = 1;
ServerInterface::ServerInterface() : GameNetworkInterface() {
bool enabledThreadedClientCommandBroadcast = false;
double maxFrameCountLagAllowed = 30;
double maxClientLagTimeAllowed = 20;
double maxFrameCountLagAllowedEver = 50;
double warnFrameCountLagPercent = 0.65;
double LAG_CHECK_GRACE_PERIOD = 15;
double MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE = 1;
ServerInterface::ServerInterface()
:GameNetworkInterface()
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
nextEventId = 1;
gameHasBeenInitiated = false;
@@ -72,25 +51,20 @@ ServerInterface::ServerInterface() : GameNetworkInterface() {
lastMasterserverHeartbeatTime = 0;
needToRepublishToMasterserver = false;
ftpServer = NULL;
enabledThreadedClientCommandBroadcast = Config::getInstance().getBool("EnableThreadedClientCommandBroadcast","false");
maxFrameCountLagAllowed = Config::getInstance().getInt("MaxFrameCountLagAllowed",intToStr(maxFrameCountLagAllowed).c_str());
maxFrameCountLagAllowedEver = Config::getInstance().getInt("MaxFrameCountLagAllowedEver",intToStr(maxFrameCountLagAllowedEver).c_str());
maxClientLagTimeAllowed = Config::getInstance().getInt("MaxClientLagTimeAllowed",intToStr(maxClientLagTimeAllowed).c_str());
warnFrameCountLagPercent = Config::getInstance().getFloat("WarnFrameCountLagPercent",doubleToStr(warnFrameCountLagPercent).c_str());
enabledThreadedClientCommandBroadcast = Config::getInstance().getBool("EnableThreadedClientCommandBroadcast", "false");
maxFrameCountLagAllowed = Config::getInstance().getInt("MaxFrameCountLagAllowed", intToStr(maxFrameCountLagAllowed).c_str());
maxFrameCountLagAllowedEver = Config::getInstance().getInt("MaxFrameCountLagAllowedEver", intToStr(maxFrameCountLagAllowedEver).c_str());
maxClientLagTimeAllowed = Config::getInstance().getInt("MaxClientLagTimeAllowed", intToStr(maxClientLagTimeAllowed).c_str());
warnFrameCountLagPercent = Config::getInstance().getFloat("WarnFrameCountLagPercent", doubleToStr(warnFrameCountLagPercent).c_str());
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] enabledThreadedClientCommandBroadcast = %d, maxFrameCountLagAllowed = %f, maxFrameCountLagAllowedEver = %f, maxClientLagTimeAllowed = %f\n",__FILE__,__FUNCTION__,__LINE__,enabledThreadedClientCommandBroadcast,maxFrameCountLagAllowed,maxFrameCountLagAllowedEver,maxClientLagTimeAllowed);
for(int i= 0; i < GameConstants::maxPlayers; ++i){
slots[i]= NULL;
switchSetupRequests[i]= NULL;
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
serverSocket.setBlock(false);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
serverSocket.setBindPort(Config::getInstance().getInt("ServerPort",intToStr(GameConstants::serverPort).c_str()));
serverSocket.setBindPort(Config::getInstance().getInt("ServerPort", intToStr(GameConstants::serverPort).c_str()));
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(Config::getInstance().getBool("EnableFTPServer","true") == true) {
std::pair<string,string> mapsPath;
@@ -118,12 +92,12 @@ ServerInterface::ServerInterface() : GameNetworkInterface() {
ftpServer->start();
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
}
ServerInterface::~ServerInterface() {
ServerInterface::~ServerInterface()
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
exitServer = true;
for(int i= 0; i < GameConstants::maxPlayers; ++i) {
if(slots[i] != NULL) {
MutexSafeWrapper safeMutex(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i) + "_" + intToStr(i));
@@ -136,34 +110,27 @@ ServerInterface::~ServerInterface() {
switchSetupRequests[i]=NULL;
}
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
close();
if(ftpServer != NULL) {
ftpServer->shutdownAndWait();
delete ftpServer;
ftpServer = NULL;
}
MutexSafeWrapper safeMutex(&masterServerThreadAccessor,intToStr(__LINE__));
delete publishToMasterserverThread;
publishToMasterserverThread = NULL;
safeMutex.ReleaseLock();
// This triggers a gameOver message to be sent to the masterserver
lastMasterserverHeartbeatTime = 0;
if(needToRepublishToMasterserver == true) {
simpleTask(NULL);
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
}
int ServerInterface::isValidClientType(uint32 clientIp) {
int ServerInterface::isValidClientType(uint32 clientIp)
{
int result = 0;
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
if(slots[i] != NULL) {
MutexSafeWrapper safeMutex(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i) + "_" + intToStr(i));
@@ -179,106 +146,86 @@ int ServerInterface::isValidClientType(uint32 clientIp) {
}
}
return result;
}
}
void ServerInterface::addClientToServerIPAddress(uint32 clientIp,uint32 ServerIp) {
FTPServerThread::addClientToServerIPAddress(clientIp,ServerIp);
}
void ServerInterface::addClientToServerIPAddress(uint32 clientIp, uint32 ServerIp)
{
FTPServerThread::addClientToServerIPAddress(clientIp, ServerIp);
}
void ServerInterface::addSlot(int playerIndex) {
void ServerInterface::addSlot(int playerIndex)
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
assert(playerIndex >= 0 && playerIndex < GameConstants::maxPlayers);
MutexSafeWrapper safeMutex(&serverSynchAccessor,intToStr(__LINE__));
if(serverSocket.isPortBound() == false) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
serverSocket.bind(serverSocket.getBindPort());
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[playerIndex],intToStr(__LINE__) + "_" + intToStr(playerIndex));
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
ConnectionSlot *slot = slots[playerIndex];
if(slot != NULL) {
slots[playerIndex]=NULL;
}
slots[playerIndex]= new ConnectionSlot(this, playerIndex);
slots[playerIndex] = new ConnectionSlot(this, playerIndex);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
safeMutexSlot.ReleaseLock();
delete slot;
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
safeMutex.ReleaseLock();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
updateListen();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
}
bool ServerInterface::switchSlot(int fromPlayerIndex,int toPlayerIndex) {
bool ServerInterface::switchSlot(int fromPlayerIndex, int toPlayerIndex)
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
bool result = false;
assert(fromPlayerIndex >= 0 && fromPlayerIndex < GameConstants::maxPlayers);
assert(toPlayerIndex >= 0 && toPlayerIndex < GameConstants::maxPlayers);
if(fromPlayerIndex == toPlayerIndex)
return false;
bool result=false;
assert(fromPlayerIndex>=0 && fromPlayerIndex<GameConstants::maxPlayers);
assert(toPlayerIndex>=0 && toPlayerIndex<GameConstants::maxPlayers);
if(fromPlayerIndex==toPlayerIndex) return false;// doubleclicked or whatever
//printf(" checking if slot %d is free?\n",toPlayerIndex);
MutexSafeWrapper safeMutex(&serverSynchAccessor,intToStr(__LINE__));
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[fromPlayerIndex],intToStr(__LINE__) + "_" + intToStr(fromPlayerIndex));
MutexSafeWrapper safeMutexSlot2(&slotAccessorMutexes[toPlayerIndex],intToStr(__LINE__) + "_" + intToStr(toPlayerIndex));
if( slots[toPlayerIndex]->isConnected() == false) {
//printf(" yes, its free :)\n");
if(slots[toPlayerIndex]->isConnected() == false){
slots[fromPlayerIndex]->setPlayerIndex(toPlayerIndex);
slots[toPlayerIndex]->setPlayerIndex(fromPlayerIndex);
ConnectionSlot *tmp=slots[toPlayerIndex];
slots[toPlayerIndex]= slots[fromPlayerIndex];
slots[fromPlayerIndex]=tmp;
ConnectionSlot *tmp = slots[toPlayerIndex];
slots[toPlayerIndex] = slots[fromPlayerIndex];
slots[fromPlayerIndex] = tmp;
safeMutex.ReleaseLock();
PlayerIndexMessage playerIndexMessage(toPlayerIndex);
slots[toPlayerIndex]->sendMessage(&playerIndexMessage);
safeMutexSlot.ReleaseLock();
safeMutexSlot2.ReleaseLock();
result=true;
result = true;
updateListen();
}
else {
}else{
safeMutexSlot.ReleaseLock();
safeMutexSlot2.ReleaseLock();
safeMutex.ReleaseLock();
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
return result;
}
}
void ServerInterface::removeSlot(int playerIndex,int lockedSlotIndex) {
void ServerInterface::removeSlot(int playerIndex, int lockedSlotIndex)
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
MutexSafeWrapper safeMutex(&serverSynchAccessor,intToStr(__LINE__));
// Mention to everyone that this player is disconnected
MutexSafeWrapper safeMutexSlot(NULL,intToStr(__LINE__) + "_" + intToStr(playerIndex));
if(playerIndex != lockedSlotIndex) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
safeMutexSlot.setMutex(&slotAccessorMutexes[playerIndex],intToStr(__LINE__) + string("_") + intToStr(playerIndex));
}
ConnectionSlot *slot = slots[playerIndex];
bool notifyDisconnect = false;
char szBuf[4096]="";
char szBuf[4096] = "";
if(slot != NULL) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
@@ -295,41 +242,31 @@ void ServerInterface::removeSlot(int playerIndex,int lockedSlotIndex) {
}
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
slots[playerIndex]= NULL;
safeMutexSlot.ReleaseLock();
safeMutex.ReleaseLock();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
delete slot;
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
updateListen();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
if(notifyDisconnect == true) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
string sMsg = szBuf;
//sendTextMessage(sMsg,-1, true, lockedSlotIndex);
queueTextMessage(sMsg,-1, true);
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
}
}
ConnectionSlot* ServerInterface::getSlot(int playerIndex) {
//!!! Don't think this is useful
//MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[playerIndex],intToStr(__LINE__) + "_" + intToStr(playerIndex));
ConnectionSlot *ServerInterface::getSlot(int playerIndex)
{
return slots[playerIndex];
}
}
bool ServerInterface::hasClientConnection() {
bool ServerInterface::hasClientConnection()
{
bool result = false;
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
if(slots[i] != NULL && slots[i]->isConnected() == true) {
@@ -338,11 +275,11 @@ bool ServerInterface::hasClientConnection() {
}
}
return result;
}
int ServerInterface::getConnectedSlotCount() {
int connectedSlotCount= 0;
}
int ServerInterface::getConnectedSlotCount()
{
int connectedSlotCount = 0;
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
if(slots[i] != NULL) {
@@ -350,21 +287,20 @@ int ServerInterface::getConnectedSlotCount() {
}
}
return connectedSlotCount;
}
}
int64 ServerInterface::getNextEventId() {
int64 ServerInterface::getNextEventId()
{
nextEventId++;
// Rollover when # gets large
if(nextEventId > INT_MAX) {
if(nextEventId > INT_MAX){
nextEventId = 1;
}
return nextEventId;
}
}
void ServerInterface::slotUpdateTask(ConnectionSlotEvent *event) {
void ServerInterface::slotUpdateTask(ConnectionSlotEvent *event)
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(event != NULL) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] event->eventType = %d\n",__FILE__,__FUNCTION__,__LINE__,event->eventType);
@@ -382,15 +318,11 @@ void ServerInterface::slotUpdateTask(ConnectionSlotEvent *event) {
}
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
}
//
// WARNING!!! This method is executed from the slot worker threads so be careful
// what we do here (things need to be thread safe)
//
void ServerInterface::updateSlot(ConnectionSlotEvent *event) {
void ServerInterface::updateSlot(ConnectionSlotEvent *event)
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(event != NULL) {
bool &socketTriggered = event->socketTriggered;
bool checkForNewClients = true;
@@ -422,17 +354,15 @@ void ServerInterface::updateSlot(ConnectionSlotEvent *event) {
safeMutexSlot.ReleaseLock();
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
// Only call when client has just sent us data
std::pair<bool,bool> ServerInterface::clientLagCheck(ConnectionSlot* connectionSlot, bool skipNetworkBroadCast) {
std::pair<bool,bool> clientLagExceededOrWarned = std::make_pair(false,false);
static bool alreadyInLagCheck = false;
if(alreadyInLagCheck == true) {
return clientLagExceededOrWarned;
}
std::pair<bool,bool> ServerInterface::clientLagCheck(ConnectionSlot *connectionSlot, bool skipNetworkBroadCast)
{
std::pair<bool,bool> clientLagExceededOrWarned = std::make_pair(false, false);
static bool alreadyInLagCheck = false;
if(alreadyInLagCheck == true){
return clientLagExceededOrWarned;
}
try {
alreadyInLagCheck = true;
@@ -536,27 +466,17 @@ std::pair<bool,bool> ServerInterface::clientLagCheck(ConnectionSlot* connectionS
throw runtime_error(ex.what());
}
alreadyInLagCheck = false;
return clientLagExceededOrWarned;
}
}
bool ServerInterface::signalClientReceiveCommands(ConnectionSlot* connectionSlot,
int slotIndex,
bool socketTriggered,
ConnectionSlotEvent &event) {
bool ServerInterface::signalClientReceiveCommands(ConnectionSlot *connectionSlot, int slotIndex, bool socketTriggered, ConnectionSlotEvent & event) {
bool slotSignalled = false;
//bool socketTriggered = (connectionSlot != NULL && connectionSlot->getSocket() != NULL ? socketTriggeredList[connectionSlot->getSocket()->getSocketId()] : false);
//ConnectionSlotEvent &event = eventList[i];
event.eventType = eReceiveSocketData;
event.networkMessage = NULL;
event.connectionSlot = connectionSlot;
event.socketTriggered = socketTriggered;
event.triggerId = slotIndex;
event.eventId = getNextEventId();
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex);
// Step #1 tell all connection slot worker threads to receive socket data
if(connectionSlot != NULL) {
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex);
if(socketTriggered == true || connectionSlot->isConnected() == false) {
@@ -565,12 +485,10 @@ bool ServerInterface::signalClientReceiveCommands(ConnectionSlot* connectionSlot
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex);
}
}
return slotSignalled;
}
}
void ServerInterface::updateSocketTriggeredList(std::map<PLATFORM_SOCKET,bool> &socketTriggeredList) {
//update all slots
void ServerInterface::updateSocketTriggeredList(std::map<PLATFORM_SOCKET,bool> & socketTriggeredList) {
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
ConnectionSlot* connectionSlot= slots[i];
@@ -579,9 +497,9 @@ void ServerInterface::updateSocketTriggeredList(std::map<PLATFORM_SOCKET,bool> &
socketTriggeredList[connectionSlot->getSocket()->getSocketId()] = false;
}
}
}
}
void ServerInterface::validateConnectedClients() {
void ServerInterface::validateConnectedClients() {
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
ConnectionSlot* connectionSlot = slots[i];
@@ -592,13 +510,63 @@ void ServerInterface::validateConnectedClients() {
connectionSlot->validateConnection();
}
}
}
}
void ServerInterface::signalClientsToRecieveDataX(std::map<PLATFORM_SOCKET,bool> & socketTriggeredList, std::map<int,ConnectionSlotEvent> & eventList, std::map<int,bool> & mapSlotSignalledList)
{
bool checkForNewClients = true;
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
ConnectionSlot* connectionSlot = slots[i];
void ServerInterface::update() {
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
bool socketTriggered = false;
if(connectionSlot != NULL && connectionSlot->getSocket() != NULL) {
socketTriggered = socketTriggeredList[connectionSlot->getSocket()->getSocketId()];
}
ConnectionSlotEvent &event = eventList[i];
mapSlotSignalledList[i] = signalClientReceiveCommands(connectionSlot,i,socketTriggered,event);
}
}
void ServerInterface::test(std::map<PLATFORM_SOCKET,bool> & socketTriggeredList, std::map<int,ConnectionSlotEvent> & eventList, std::map<int,bool> & mapSlotSignalledList)
{
bool checkForNewClients = true;
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
ConnectionSlot* connectionSlot = slots[i];
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
bool socketTriggered = false;
if(connectionSlot != NULL && connectionSlot->getSocket() != NULL) {
socketTriggered = socketTriggeredList[connectionSlot->getSocket()->getSocketId()];
}
ConnectionSlotEvent &event = eventList[i];
mapSlotSignalledList[i] = signalClientReceiveCommands(connectionSlot,i,socketTriggered,event);
}
}
void ServerInterface::fsf(std::map<PLATFORM_SOCKET,bool> & socketTriggeredList, std::map<int,ConnectionSlotEvent> & eventList, std::map<int,bool> & mapSlotSignalledList)
{
bool checkForNewClients = true;
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
ConnectionSlot* connectionSlot = slots[i];
bool socketTriggered = false;
if(connectionSlot != NULL && connectionSlot->getSocket() != NULL) {
socketTriggered = socketTriggeredList[connectionSlot->getSocket()->getSocketId()];
}
ConnectionSlotEvent &event = eventList[i];
mapSlotSignalledList[i] = signalClientReceiveCommands(connectionSlot,i,socketTriggered,event);
}
}
void ServerInterface::update() {
const int MAX_SLOT_THREAD_WAIT_TIME = 3;
std::vector<string> errorMsgList;
std::vector < string > errorMsgList;
try {
// The first thing we will do is check all clients to ensure they have
// properly identified themselves within the alloted time period
@@ -626,8 +594,6 @@ void ServerInterface::update() {
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
ConnectionSlot* connectionSlot = slots[i];
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
bool socketTriggered = false;
if(connectionSlot != NULL && connectionSlot->getSocket() != NULL) {
socketTriggered = socketTriggeredList[connectionSlot->getSocket()->getSocketId()];
@@ -842,33 +808,30 @@ void ServerInterface::update() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
errorMsgList.push_back(ex.what());
}
if(errorMsgList.size() > 0) {
for(int iErrIdx = 0; iErrIdx < errorMsgList.size(); ++iErrIdx) {
string &sErr = errorMsgList[iErrIdx];
if(sErr != "") {
if(errorMsgList.size() > 0){
for(int iErrIdx = 0;iErrIdx < errorMsgList.size();++iErrIdx){
string & sErr = errorMsgList[iErrIdx];
if(sErr != ""){
DisplayErrorMessage(sErr);
}
}
}
}
void ServerInterface::updateKeyframe(int frameCount) {
}
}
void ServerInterface::updateKeyframe(int frameCount)
{
Chrono chrono;
chrono.start();
currentFrameCount = frameCount;
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] currentFrameCount = %d\n",__FILE__,__FUNCTION__,__LINE__,currentFrameCount);
NetworkMessageCommandList networkMessageCommandList(frameCount);
//build command list, remove commands from requested and add to pending
while(requestedCommands.empty() == false) {
if(networkMessageCommandList.addCommand(&requestedCommands.back())) {
while(requestedCommands.empty() == false){
if(networkMessageCommandList.addCommand(&requestedCommands.back())){
pendingCommands.push_back(requestedCommands.back());
requestedCommands.pop_back();
}
else {
}else{
break;
}
}
@@ -895,12 +858,11 @@ void ServerInterface::updateKeyframe(int frameCount) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
DisplayErrorMessage(ex.what());
}
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] broadcastMessage took %lld msecs, networkMessageCommandList.getCommandCount() = %d, frameCount = %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),networkMessageCommandList.getCommandCount(),frameCount);
}
}
bool ServerInterface::shouldDiscardNetworkMessage(NetworkMessageType networkMessageType,
ConnectionSlot* connectionSlot) {
bool ServerInterface::shouldDiscardNetworkMessage(NetworkMessageType networkMessageType, ConnectionSlot *connectionSlot)
{
bool discard = false;
if(connectionSlot != NULL) {
switch(networkMessageType) {
@@ -995,21 +957,16 @@ bool ServerInterface::shouldDiscardNetworkMessage(NetworkMessageType networkMess
}
}
return discard;
}
void ServerInterface::waitUntilReady(Checksum* checksum) {
}
void ServerInterface::waitUntilReady(Checksum *checksum)
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] START\n",__FUNCTION__);
Logger &logger= Logger::getInstance();
Logger & logger = Logger::getInstance();
gameHasBeenInitiated = true;
Chrono chrono;
bool allReady= false;
bool allReady = false;
chrono.start();
//wait until we get a ready message from all clients
while(exitServer == false && allReady == false) {
vector<string> waitingForHosts;
allReady= true;
@@ -1072,12 +1029,7 @@ void ServerInterface::waitUntilReady(Checksum* checksum) {
}
}
}
// FOR TESTING ONLY - delay to see the client count up while waiting
//sleep(5000);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] PART B (telling client we are ready!\n",__FUNCTION__);
try {
//send ready message after, so clients start delayed
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
@@ -1096,11 +1048,11 @@ void ServerInterface::waitUntilReady(Checksum* checksum) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
DisplayErrorMessage(ex.what());
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] END\n",__FUNCTION__);
}
}
void ServerInterface::processBroadCastMessageQueue() {
void ServerInterface::processBroadCastMessageQueue()
{
MutexSafeWrapper safeMutexSlot(&broadcastMessageQueueThreadAccessor,intToStr(__LINE__));
if(broadcastMessageQueue.size() > 0) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] broadcastMessageQueue.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,broadcastMessageQueue.size());
@@ -1114,17 +1066,19 @@ void ServerInterface::processBroadCastMessageQueue() {
}
broadcastMessageQueue.clear();
}
}
}
void ServerInterface::queueBroadcastMessage(const NetworkMessage *networkMessage, int excludeSlot) {
void ServerInterface::queueBroadcastMessage(const NetworkMessage *networkMessage, int excludeSlot)
{
MutexSafeWrapper safeMutexSlot(&broadcastMessageQueueThreadAccessor,intToStr(__LINE__));
pair<const NetworkMessage *,int> item;
pair<const NetworkMessage*,int> item;
item.first = networkMessage;
item.second = excludeSlot;
broadcastMessageQueue.push_back(item);
}
}
void ServerInterface::processTextMessageQueue() {
void ServerInterface::processTextMessageQueue()
{
MutexSafeWrapper safeMutexSlot(&textMessageQueueThreadAccessor,intToStr(__LINE__));
if(textMessageQueue.size() > 0) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] textMessageQueue.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,textMessageQueue.size());
@@ -1134,28 +1088,28 @@ void ServerInterface::processTextMessageQueue() {
}
textMessageQueue.clear();
}
}
}
void ServerInterface::queueTextMessage(const string &text, int teamIndex, bool echoLocal) {
void ServerInterface::queueTextMessage(const string & text, int teamIndex, bool echoLocal)
{
MutexSafeWrapper safeMutexSlot(&textMessageQueueThreadAccessor,intToStr(__LINE__));
TextMessageQueue item;
item.text = text;
item.teamIndex = teamIndex;
item.echoLocal = echoLocal;
textMessageQueue.push_back(item);
}
}
void ServerInterface::sendTextMessage(const string &text, int teamIndex, bool echoLocal) {
void ServerInterface::sendTextMessage(const string & text, int teamIndex, bool echoLocal)
{
sendTextMessage(text, teamIndex, echoLocal, -1);
}
}
void ServerInterface::sendTextMessage(const string &text, int teamIndex, bool echoLocal, int lockedSlotIndex) {
void ServerInterface::sendTextMessage(const string & text, int teamIndex, bool echoLocal, int lockedSlotIndex)
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] text [%s] teamIndex = %d, echoLocal = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,text.c_str(),teamIndex,echoLocal,lockedSlotIndex);
//NetworkMessageText networkMessageText(text, getHumanPlayerName().c_str(), teamIndex, getHumanPlayerIndex());
NetworkMessageText networkMessageText(text, teamIndex, getHumanPlayerIndex());
broadcastMessage(&networkMessageText,-1,lockedSlotIndex);
broadcastMessage(&networkMessageText, -1, lockedSlotIndex);
if(echoLocal == true) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
@@ -1163,31 +1117,23 @@ void ServerInterface::sendTextMessage(const string &text, int teamIndex, bool ec
ChatMsgInfo msg(text.c_str(),teamIndex,networkMessageText.getPlayerIndex());
this->addChatInfo(msg);
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
}
void ServerInterface::quitGame(bool userManuallyQuit) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
if(userManuallyQuit == true) {
//string sQuitText = Config::getInstance().getString("NetPlayerName",Socket::getHostName().c_str()) + " has chosen to leave the game!";
//NetworkMessageText networkMessageText(sQuitText,getHostName(),-1);
//broadcastMessage(&networkMessageText, -1);
}
void ServerInterface::quitGame(bool userManuallyQuit)
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
if(userManuallyQuit == true){
}
NetworkMessageQuit networkMessageQuit;
broadcastMessage(&networkMessageQuit);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
}
}
string ServerInterface::getNetworkStatus() {
Lang &lang= Lang::getInstance();
string ServerInterface::getNetworkStatus()
{
Lang & lang = Lang::getInstance();
string str;
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i){
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
ConnectionSlot* connectionSlot= slots[i];
@@ -1212,17 +1158,13 @@ string ServerInterface::getNetworkStatus() {
str+= '\n';
}
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
return str;
}
}
bool ServerInterface::launchGame(const GameSettings* gameSettings) {
bool ServerInterface::launchGame(const GameSettings *gameSettings)
{
bool bOkToStart = true;
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
ConnectionSlot *connectionSlot= slots[i];
@@ -1235,7 +1177,6 @@ bool ServerInterface::launchGame(const GameSettings* gameSettings) {
}
}
}
if(bOkToStart == true) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] needToRepublishToMasterserver = %d\n",__FILE__,__FUNCTION__,__LINE__,needToRepublishToMasterserver);
@@ -1278,25 +1219,21 @@ bool ServerInterface::launchGame(const GameSettings* gameSettings) {
ftpServer = NULL;
}
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
return bOkToStart;
}
}
void ServerInterface::broadcastGameSetup(const GameSettings* gameSettings) {
void ServerInterface::broadcastGameSetup(const GameSettings *gameSettings)
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
MutexSafeWrapper safeMutex(&serverSynchAccessor,intToStr(__LINE__));
NetworkMessageLaunch networkMessageLaunch(gameSettings,nmtBroadCastSetup);
NetworkMessageLaunch networkMessageLaunch(gameSettings, nmtBroadCastSetup);
broadcastMessage(&networkMessageLaunch);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
}
void ServerInterface::broadcastMessage(const NetworkMessage* networkMessage, int excludeSlot, int lockedSlotIndex) {
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
}
void ServerInterface::broadcastMessage(const NetworkMessage *networkMessage, int excludeSlot, int lockedSlotIndex)
{
try {
if(enabledThreadedClientCommandBroadcast == true) {
// Step #1 signal worker threads to send this broadcast to each client
@@ -1416,13 +1353,11 @@ void ServerInterface::broadcastMessage(const NetworkMessage* networkMessage, int
string sMsg = ex.what();
sendTextMessage(sMsg,-1, true, lockedSlotIndex);
}
}
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
}
void ServerInterface::broadcastMessageToConnectedClients(const NetworkMessage* networkMessage, int excludeSlot){
void ServerInterface::broadcastMessageToConnectedClients(const NetworkMessage *networkMessage, int excludeSlot)
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
try {
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
@@ -1443,17 +1378,15 @@ void ServerInterface::broadcastMessageToConnectedClients(const NetworkMessage* n
//throw runtime_error(ex.what());
DisplayErrorMessage(ex.what());
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
}
}
void ServerInterface::updateListen() {
if(gameHasBeenInitiated == true) {
void ServerInterface::updateListen()
{
if(gameHasBeenInitiated == true){
return;
}
//MutexSafeWrapper safeMutex(&serverSynchAccessor,intToStr(__LINE__));
int openSlotCount= 0;
int openSlotCount = 0;
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
//MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
bool isSlotOpen = (slots[i] != NULL && slots[i]->isConnected() == false);
@@ -1462,15 +1395,12 @@ void ServerInterface::updateListen() {
++openSlotCount;
}
}
//MutexSafeWrapper safeMutex(&serverSynchAccessor);
serverSocket.listen(openSlotCount);
//safeMutex.ReleaseLock();
}
int ServerInterface::getOpenSlotCount() {
int openSlotCount= 0;
}
int ServerInterface::getOpenSlotCount()
{
int openSlotCount = 0;
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
//MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
bool isSlotOpen = (slots[i] != NULL && slots[i]->isConnected() == false);
@@ -1479,17 +1409,14 @@ int ServerInterface::getOpenSlotCount() {
++openSlotCount;
}
}
return openSlotCount;
}
}
void ServerInterface::setGameSettings(GameSettings *serverGameSettings, bool waitForClientAck) {
void ServerInterface::setGameSettings(GameSettings *serverGameSettings, bool waitForClientAck)
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START gameSettingsUpdateCount = %d, waitForClientAck = %d\n",__FILE__,__FUNCTION__,gameSettingsUpdateCount,waitForClientAck);
MutexSafeWrapper safeMutex(&serverSynchAccessor,intToStr(__LINE__));
gameSettings = *serverGameSettings;
if(getAllowGameDataSynchCheck() == true)
{
if(waitForClientAck == true && gameSettingsUpdateCount > 0)
@@ -1549,56 +1476,43 @@ void ServerInterface::setGameSettings(GameSettings *serverGameSettings, bool wai
gameSettingsUpdateCount++;
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",__FILE__,__FUNCTION__);
}
void ServerInterface::close()
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START\n",__FILE__,__FUNCTION__);
//serverSocket = ServerSocket();
}
string ServerInterface::getHumanPlayerName(int index) {
string result = Config::getInstance().getString("NetPlayerName",Socket::getHostName().c_str());
//printf("\nIn [%s::%s Line: %d] index = %d, gameSettings.getThisFactionIndex() = %d\n",__FILE__,__FUNCTION__,__LINE__,index,gameSettings.getThisFactionIndex());
//fflush(stdout);
if(index >= 0 || gameSettings.getThisFactionIndex() >= 0) {
if(index < 0) {
index = gameSettings.getThisFactionIndex();
}
//printf("\nIn [%s::%s Line: %d] gameSettings.getNetworkPlayerName(index) = %s\n",__FILE__,__FUNCTION__,__LINE__,gameSettings.getNetworkPlayerName(index).c_str());
//fflush(stdout);
void ServerInterface::close()
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START\n",__FILE__,__FUNCTION__);
}
if(gameSettings.getNetworkPlayerName(index) != "") {
string ServerInterface::getHumanPlayerName(int index)
{
string result = Config::getInstance().getString("NetPlayerName", Socket::getHostName().c_str());
if(index >= 0 || gameSettings.getThisFactionIndex() >= 0){
if(index < 0){
index = gameSettings.getThisFactionIndex();
}
if(gameSettings.getNetworkPlayerName(index) != ""){
result = gameSettings.getNetworkPlayerName(index);
}
}
return result;
}
}
int ServerInterface::getHumanPlayerIndex() const {
int ServerInterface::getHumanPlayerIndex() const
{
return gameSettings.getStartLocationIndex(gameSettings.getThisFactionIndex());
}
}
std::map<string,string> ServerInterface::publishToMasterserver() {
std::map<string,string> ServerInterface::publishToMasterserver()
{
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
// The server player counts as 1 for each of these
int slotCountUsed=1;
int slotCountHumans=1;
int slotCountConnectedPlayers=1;
Config &config= Config::getInstance();
//string serverinfo="";
std::map<string,string> publishToServerInfo;
int slotCountUsed = 1;
int slotCountHumans = 1;
int slotCountConnectedPlayers = 1;
Config & config = Config::getInstance();
std::map < string, string > publishToServerInfo;
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
if(slots[i] != NULL) {
@@ -1610,40 +1524,28 @@ std::map<string,string> ServerInterface::publishToMasterserver() {
}
}
}
//?status=waiting&system=linux&info=titus
publishToServerInfo["glestVersion"] = glestVersionString;
publishToServerInfo["platform"] = getPlatformNameString();
publishToServerInfo["binaryCompileDate"] = getCompileDateTime();
//game info:
publishToServerInfo["serverTitle"] = getHumanPlayerName() + "'s game *IN PROGRESS*";
//ip is automatically set
//game setup info:
publishToServerInfo["tech"] = this->getGameSettings()->getTech();
publishToServerInfo["map"] = this->getGameSettings()->getMap();
publishToServerInfo["tileset"] = this->getGameSettings()->getTileset();
publishToServerInfo["activeSlots"] = intToStr(slotCountUsed);
publishToServerInfo["networkSlots"] = intToStr(slotCountHumans);
publishToServerInfo["connectedClients"] = intToStr(slotCountConnectedPlayers);
//string externalport = intToStr(Config::getInstance().getInt("ExternalServerPort",intToStr(Config::getInstance().getInt("ServerPort")).c_str()));
string externalport = config.getString("MasterServerExternalPort", "61357");
publishToServerInfo["externalconnectport"] = externalport;
if(publishToMasterserverThread == NULL) {
publishToServerInfo["serverTitle"] = getHumanPlayerName() + "'s game *FINISHED*";
publishToServerInfo["gameCmd"]= "gameOver";
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
return publishToServerInfo;
}
void ServerInterface::simpleTask(BaseThread *callingThread) {
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void ServerInterface::simpleTask(BaseThread *callingThread)
{
MutexSafeWrapper safeMutex(&masterServerThreadAccessor,intToStr(__LINE__));
const int MASTERSERVER_HEARTBEAT_GAME_STATUS_SECONDS = 30;
if(difftime(time(NULL),lastMasterserverHeartbeatTime) >= MASTERSERVER_HEARTBEAT_GAME_STATUS_SECONDS) {

View File

@@ -75,88 +75,112 @@ public:
virtual ~ServerInterface();
virtual Socket* getSocket() {return &serverSocket;}
virtual const Socket* getSocket() const {return &serverSocket;}
const virtual Socket *getSocket() const
{
return &serverSocket;
}
virtual void close();
//message processing
virtual void update();
virtual void updateLobby(){};
virtual void updateLobby()
{
}
;
virtual void updateKeyframe(int frameCount);
virtual void waitUntilReady(Checksum* checksum);
// message sending
virtual void sendTextMessage(const string &text, int teamIndex, bool echoLocal=false);
void sendTextMessage(const string &text, int teamIndex, bool echoLocal, int lockedSlotIndex);
void queueTextMessage(const string &text, int teamIndex, bool echoLocal=false);
virtual void waitUntilReady(Checksum *checksum);
virtual void sendTextMessage(const string & text, int teamIndex, bool echoLocal = false);
void sendTextMessage(const string & text, int teamIndex, bool echoLocal, int lockedSlotIndex);
void queueTextMessage(const string & text, int teamIndex, bool echoLocal = false);
virtual void quitGame(bool userManuallyQuit);
virtual string getNetworkStatus();
ServerSocket *getServerSocket()
{
return &serverSocket;
}
//misc
virtual string getNetworkStatus() ;
SwitchSetupRequest **getSwitchSetupRequests()
{
return &switchSetupRequests[0];
}
ServerSocket* getServerSocket() {return &serverSocket;}
SwitchSetupRequest** getSwitchSetupRequests() {return &switchSetupRequests[0];}
void addSlot(int playerIndex);
bool switchSlot(int fromPlayerIndex,int toPlayerIndex);
void removeSlot(int playerIndex, int lockedSlotIndex=-1);
ConnectionSlot* getSlot(int playerIndex);
bool switchSlot(int fromPlayerIndex, int toPlayerIndex);
void removeSlot(int playerIndex, int lockedSlotIndex = -1);
ConnectionSlot *getSlot(int playerIndex);
int getConnectedSlotCount();
int getOpenSlotCount();
bool launchGame(const GameSettings* gameSettings);
bool launchGame(const GameSettings *gameSettings);
void setGameSettings(GameSettings *serverGameSettings, bool waitForClientAck);
void broadcastGameSetup(const GameSettings* gameSettings);
void broadcastGameSetup(const GameSettings *gameSettings);
void updateListen();
virtual bool getConnectHasHandshaked() const { return false; }
virtual bool getConnectHasHandshaked() const
{
return false;
}
virtual void slotUpdateTask(ConnectionSlotEvent *event);
bool hasClientConnection();
int getCurrentFrameCount() const { return currentFrameCount; }
std::pair<bool,bool> clientLagCheck(ConnectionSlot* connectionSlot,bool skipNetworkBroadCast=false);
bool signalClientReceiveCommands(ConnectionSlot* connectionSlot,
int slotIndex,
bool socketTriggered,
ConnectionSlotEvent &event);
void updateSocketTriggeredList(std::map<PLATFORM_SOCKET,bool> &socketTriggeredList);
bool isPortBound() const { return serverSocket.isPortBound(); }
int getBindPort() const { return serverSocket.getBindPort(); }
void broadcastPing(const NetworkMessagePing* networkMessage, int excludeSlot= -1) {
this->broadcastMessage(networkMessage,excludeSlot);
int getCurrentFrameCount() const
{
return currentFrameCount;
}
void queueBroadcastMessage(const NetworkMessage *networkMessage, int excludeSlot=-1);
std::pair<bool,bool> clientLagCheck(ConnectionSlot *connectionSlot, bool skipNetworkBroadCast = false);
bool signalClientReceiveCommands(ConnectionSlot *connectionSlot, int slotIndex, bool socketTriggered, ConnectionSlotEvent & event);
void updateSocketTriggeredList(std::map<PLATFORM_SOCKET,bool> & socketTriggeredList);
bool isPortBound() const
{
return serverSocket.isPortBound();
}
virtual string getHumanPlayerName(int index=-1);
int getBindPort() const
{
return serverSocket.getBindPort();
}
void broadcastPing(const NetworkMessagePing *networkMessage, int excludeSlot = -1)
{
this->broadcastMessage(networkMessage, excludeSlot);
}
void queueBroadcastMessage(const NetworkMessage *networkMessage, int excludeSlot = -1);
virtual string getHumanPlayerName(int index = -1);
virtual int getHumanPlayerIndex() const;
bool getNeedToRepublishToMasterserver() const
{
return needToRepublishToMasterserver;
}
bool getNeedToRepublishToMasterserver() const {return needToRepublishToMasterserver;}
void setNeedToRepublishToMasterserver(bool value) {needToRepublishToMasterserver = value;}
void setNeedToRepublishToMasterserver(bool value)
{
needToRepublishToMasterserver = value;
}
public:
Mutex * getServerSynchAccessor() { return &serverSynchAccessor; }
Mutex *getServerSynchAccessor()
{
return &serverSynchAccessor;
}
virtual void simpleTask(BaseThread *callingThread);
void addClientToServerIPAddress(uint32 clientIp,uint32 ServerIp);
void addClientToServerIPAddress(uint32 clientIp, uint32 ServerIp);
virtual int isValidClientType(uint32 clientIp);
private:
void broadcastMessage(const NetworkMessage* networkMessage, int excludeSlot= -1,int lockedSlotIndex=-1);
void broadcastMessageToConnectedClients(const NetworkMessage* networkMessage, int excludeSlot = -1);
bool shouldDiscardNetworkMessage(NetworkMessageType networkMessageType,ConnectionSlot* connectionSlot);
void broadcastMessage(const NetworkMessage *networkMessage, int excludeSlot = -1, int lockedSlotIndex = -1);
void broadcastMessageToConnectedClients(const NetworkMessage *networkMessage, int excludeSlot = -1);
bool shouldDiscardNetworkMessage(NetworkMessageType networkMessageType, ConnectionSlot *connectionSlot);
void updateSlot(ConnectionSlotEvent *event);
void validateConnectedClients();
std::map<string,string> publishToMasterserver();
int64 getNextEventId();
void processTextMessageQueue();
void processBroadCastMessageQueue();
void fsf(std::map<PLATFORM_SOCKET,bool> & socketTriggeredList, std::map<int,ConnectionSlotEvent> & eventList, std::map<int,bool> & mapSlotSignalledList);
protected:
void signalClientsToRecieveDataX(std::map<PLATFORM_SOCKET,bool> & socketTriggeredList, std::map<int,ConnectionSlotEvent> & eventList, std::map<int,bool> & mapSlotSignalledList);
void test(std::map<PLATFORM_SOCKET,bool> & socketTriggeredList, std::map<int,ConnectionSlotEvent> & eventList, std::map<int,bool> & mapSlotSignalledList);
};
}}//end namespace

View File

@@ -206,6 +206,7 @@ private:
public:
BroadCastSocketThread();
virtual void execute();
virtual bool canShutdown(bool deleteSelfIfShutdownDelayed=false);
};
// =====================================================

View File

@@ -1752,11 +1752,13 @@ void ServerSocket::stopBroadCastThread() {
if(broadCastThread != NULL) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
broadCastThread->shutdownAndWait();
if(broadCastThread->canShutdown(true) == true) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(broadCastThread->shutdownAndWait() == true) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
delete broadCastThread;
}
}
broadCastThread = NULL;
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
@@ -2121,10 +2123,21 @@ BroadCastSocketThread::BroadCastSocketThread() : BaseThread() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
bool BroadCastSocketThread::canShutdown(bool deleteSelfIfShutdownDelayed) {
bool ret = (getExecutingTask() == false);
if(ret == false && deleteSelfIfShutdownDelayed == true) {
setDeleteSelfOnExecutionDone(deleteSelfIfShutdownDelayed);
signalQuit();
}
return ret;
}
void BroadCastSocketThread::execute() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//setRunningStatus(true);
RunningStatusSafeWrapper runningStatus(this);
ExecutingTaskSafeWrapper safeExecutingTaskMutex(this);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast thread is running\n");