- 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" #include "cache_manager.h"
// For gcc backtrace on crash! // For gcc backtrace on crash!
#if defined(__GNUC__) && !defined(__MINGW32__) #if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD)
#include <execinfo.h> #include <execinfo.h>
#include <cxxabi.h> #include <cxxabi.h>
#include <signal.h> #include <signal.h>
@@ -201,7 +201,7 @@ public:
message(msg.c_str()); message(msg.c_str());
} }
#ifdef __GNUC__ #if defined(__GNUC__) && !defined(__FreeBSD__) && !defined(BSD)
static int getFileAndLine(void *address, char *file, size_t flen) { static int getFileAndLine(void *address, char *file, size_t flen) {
int line=-1; int line=-1;
static char buf[256]=""; static char buf[256]="";
@@ -261,7 +261,7 @@ public:
string errMsg = (msg != NULL ? msg : "null"); 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 += "\nStack Trace:\n";
//errMsg += "To find line #'s use:\n"; //errMsg += "To find line #'s use:\n";
//errMsg += "readelf --debug-dump=decodedline %s | egrep 0xaddress-of-stack\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) { void handleSIGSEGV(int sig) {
char szBuf[4096]=""; char szBuf[4096]="";
sprintf(szBuf, "In [%s::%s Line: %d] Error detected: signal %d:\n",__FILE__,__FUNCTION__,__LINE__, sig); 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; using namespace Shared::Util;
namespace Glest{ namespace Game{ namespace Glest{ namespace Game{
bool enabledThreadedClientCommandBroadcast = false;
// ===================================================== double maxFrameCountLagAllowed = 30;
// class ServerInterface double maxClientLagTimeAllowed = 20;
// ===================================================== double maxFrameCountLagAllowedEver = 50;
double warnFrameCountLagPercent = 0.65;
// Experimental threading of broadcasts to clients double LAG_CHECK_GRACE_PERIOD = 15;
//bool enabledThreadedClientCommandBroadcast = true; double MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE = 1;
bool enabledThreadedClientCommandBroadcast = false; ServerInterface::ServerInterface()
:GameNetworkInterface()
// 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() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
nextEventId = 1; nextEventId = 1;
gameHasBeenInitiated = false; gameHasBeenInitiated = false;
@@ -72,25 +51,20 @@ ServerInterface::ServerInterface() : GameNetworkInterface() {
lastMasterserverHeartbeatTime = 0; lastMasterserverHeartbeatTime = 0;
needToRepublishToMasterserver = false; needToRepublishToMasterserver = false;
ftpServer = NULL; ftpServer = NULL;
enabledThreadedClientCommandBroadcast = Config::getInstance().getBool("EnableThreadedClientCommandBroadcast", "false");
enabledThreadedClientCommandBroadcast = Config::getInstance().getBool("EnableThreadedClientCommandBroadcast","false"); maxFrameCountLagAllowed = Config::getInstance().getInt("MaxFrameCountLagAllowed", intToStr(maxFrameCountLagAllowed).c_str());
maxFrameCountLagAllowed = Config::getInstance().getInt("MaxFrameCountLagAllowed",intToStr(maxFrameCountLagAllowed).c_str()); maxFrameCountLagAllowedEver = Config::getInstance().getInt("MaxFrameCountLagAllowedEver", intToStr(maxFrameCountLagAllowedEver).c_str());
maxFrameCountLagAllowedEver = Config::getInstance().getInt("MaxFrameCountLagAllowedEver",intToStr(maxFrameCountLagAllowedEver).c_str()); maxClientLagTimeAllowed = Config::getInstance().getInt("MaxClientLagTimeAllowed", intToStr(maxClientLagTimeAllowed).c_str());
maxClientLagTimeAllowed = Config::getInstance().getInt("MaxClientLagTimeAllowed",intToStr(maxClientLagTimeAllowed).c_str()); warnFrameCountLagPercent = Config::getInstance().getFloat("WarnFrameCountLagPercent", doubleToStr(warnFrameCountLagPercent).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); 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){ for(int i= 0; i < GameConstants::maxPlayers; ++i){
slots[i]= NULL; slots[i]= NULL;
switchSetupRequests[i]= NULL; switchSetupRequests[i]= NULL;
} }
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
serverSocket.setBlock(false); serverSocket.setBlock(false);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); 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__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(Config::getInstance().getBool("EnableFTPServer","true") == true) { if(Config::getInstance().getBool("EnableFTPServer","true") == true) {
std::pair<string,string> mapsPath; std::pair<string,string> mapsPath;
@@ -118,12 +92,12 @@ ServerInterface::ServerInterface() : GameNetworkInterface() {
ftpServer->start(); ftpServer->start();
} }
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); 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__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
exitServer = true; exitServer = true;
for(int i= 0; i < GameConstants::maxPlayers; ++i) { for(int i= 0; i < GameConstants::maxPlayers; ++i) {
if(slots[i] != NULL) { if(slots[i] != NULL) {
MutexSafeWrapper safeMutex(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i) + "_" + intToStr(i)); MutexSafeWrapper safeMutex(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i) + "_" + intToStr(i));
@@ -136,34 +110,27 @@ ServerInterface::~ServerInterface() {
switchSetupRequests[i]=NULL; switchSetupRequests[i]=NULL;
} }
} }
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
close(); close();
if(ftpServer != NULL) { if(ftpServer != NULL) {
ftpServer->shutdownAndWait(); ftpServer->shutdownAndWait();
delete ftpServer; delete ftpServer;
ftpServer = NULL; ftpServer = NULL;
} }
MutexSafeWrapper safeMutex(&masterServerThreadAccessor,intToStr(__LINE__)); MutexSafeWrapper safeMutex(&masterServerThreadAccessor,intToStr(__LINE__));
delete publishToMasterserverThread; delete publishToMasterserverThread;
publishToMasterserverThread = NULL; publishToMasterserverThread = NULL;
safeMutex.ReleaseLock(); safeMutex.ReleaseLock();
// This triggers a gameOver message to be sent to the masterserver
lastMasterserverHeartbeatTime = 0; lastMasterserverHeartbeatTime = 0;
if(needToRepublishToMasterserver == true) { if(needToRepublishToMasterserver == true) {
simpleTask(NULL); simpleTask(NULL);
} }
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); 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; int result = 0;
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
if(slots[i] != NULL) { if(slots[i] != NULL) {
MutexSafeWrapper safeMutex(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i) + "_" + intToStr(i)); MutexSafeWrapper safeMutex(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i) + "_" + intToStr(i));
@@ -179,106 +146,86 @@ int ServerInterface::isValidClientType(uint32 clientIp) {
} }
} }
return result; return result;
} }
void ServerInterface::addClientToServerIPAddress(uint32 clientIp,uint32 ServerIp) { void ServerInterface::addClientToServerIPAddress(uint32 clientIp, uint32 ServerIp)
FTPServerThread::addClientToServerIPAddress(clientIp,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__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
assert(playerIndex >= 0 && playerIndex < GameConstants::maxPlayers); assert(playerIndex >= 0 && playerIndex < GameConstants::maxPlayers);
MutexSafeWrapper safeMutex(&serverSynchAccessor,intToStr(__LINE__)); MutexSafeWrapper safeMutex(&serverSynchAccessor,intToStr(__LINE__));
if(serverSocket.isPortBound() == false) { if(serverSocket.isPortBound() == false) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
serverSocket.bind(serverSocket.getBindPort()); serverSocket.bind(serverSocket.getBindPort());
} }
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[playerIndex],intToStr(__LINE__) + "_" + intToStr(playerIndex)); MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[playerIndex],intToStr(__LINE__) + "_" + intToStr(playerIndex));
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
ConnectionSlot *slot = slots[playerIndex]; ConnectionSlot *slot = slots[playerIndex];
if(slot != NULL) { if(slot != NULL) {
slots[playerIndex]=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__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
safeMutexSlot.ReleaseLock(); safeMutexSlot.ReleaseLock();
delete slot; delete slot;
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
safeMutex.ReleaseLock(); safeMutex.ReleaseLock();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
updateListen(); updateListen();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); 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__); 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 safeMutex(&serverSynchAccessor,intToStr(__LINE__));
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[fromPlayerIndex],intToStr(__LINE__) + "_" + intToStr(fromPlayerIndex)); MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[fromPlayerIndex],intToStr(__LINE__) + "_" + intToStr(fromPlayerIndex));
MutexSafeWrapper safeMutexSlot2(&slotAccessorMutexes[toPlayerIndex],intToStr(__LINE__) + "_" + intToStr(toPlayerIndex)); MutexSafeWrapper safeMutexSlot2(&slotAccessorMutexes[toPlayerIndex],intToStr(__LINE__) + "_" + intToStr(toPlayerIndex));
if(slots[toPlayerIndex]->isConnected() == false){
if( slots[toPlayerIndex]->isConnected() == false) {
//printf(" yes, its free :)\n");
slots[fromPlayerIndex]->setPlayerIndex(toPlayerIndex); slots[fromPlayerIndex]->setPlayerIndex(toPlayerIndex);
slots[toPlayerIndex]->setPlayerIndex(fromPlayerIndex); slots[toPlayerIndex]->setPlayerIndex(fromPlayerIndex);
ConnectionSlot *tmp=slots[toPlayerIndex]; ConnectionSlot *tmp = slots[toPlayerIndex];
slots[toPlayerIndex]= slots[fromPlayerIndex]; slots[toPlayerIndex] = slots[fromPlayerIndex];
slots[fromPlayerIndex]=tmp; slots[fromPlayerIndex] = tmp;
safeMutex.ReleaseLock(); safeMutex.ReleaseLock();
PlayerIndexMessage playerIndexMessage(toPlayerIndex); PlayerIndexMessage playerIndexMessage(toPlayerIndex);
slots[toPlayerIndex]->sendMessage(&playerIndexMessage); slots[toPlayerIndex]->sendMessage(&playerIndexMessage);
safeMutexSlot.ReleaseLock(); safeMutexSlot.ReleaseLock();
safeMutexSlot2.ReleaseLock(); safeMutexSlot2.ReleaseLock();
result = true;
result=true;
updateListen(); updateListen();
} }else{
else {
safeMutexSlot.ReleaseLock(); safeMutexSlot.ReleaseLock();
safeMutexSlot2.ReleaseLock(); safeMutexSlot2.ReleaseLock();
safeMutex.ReleaseLock(); safeMutex.ReleaseLock();
} }
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
return result; 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); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
MutexSafeWrapper safeMutex(&serverSynchAccessor,intToStr(__LINE__)); MutexSafeWrapper safeMutex(&serverSynchAccessor,intToStr(__LINE__));
// Mention to everyone that this player is disconnected
MutexSafeWrapper safeMutexSlot(NULL,intToStr(__LINE__) + "_" + intToStr(playerIndex)); MutexSafeWrapper safeMutexSlot(NULL,intToStr(__LINE__) + "_" + intToStr(playerIndex));
if(playerIndex != lockedSlotIndex) { if(playerIndex != lockedSlotIndex) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,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)); safeMutexSlot.setMutex(&slotAccessorMutexes[playerIndex],intToStr(__LINE__) + string("_") + intToStr(playerIndex));
} }
ConnectionSlot *slot = slots[playerIndex]; ConnectionSlot *slot = slots[playerIndex];
bool notifyDisconnect = false; bool notifyDisconnect = false;
char szBuf[4096]=""; char szBuf[4096] = "";
if(slot != NULL) { if(slot != NULL) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex); 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); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
slots[playerIndex]= NULL; slots[playerIndex]= NULL;
safeMutexSlot.ReleaseLock(); safeMutexSlot.ReleaseLock();
safeMutex.ReleaseLock(); safeMutex.ReleaseLock();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
delete slot; delete slot;
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
updateListen(); updateListen();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
if(notifyDisconnect == true) { if(notifyDisconnect == true) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
string sMsg = szBuf; string sMsg = szBuf;
//sendTextMessage(sMsg,-1, true, lockedSlotIndex); //sendTextMessage(sMsg,-1, true, lockedSlotIndex);
queueTextMessage(sMsg,-1, true); queueTextMessage(sMsg,-1, true);
} }
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex);
} }
ConnectionSlot* ServerInterface::getSlot(int playerIndex) { ConnectionSlot *ServerInterface::getSlot(int playerIndex)
//!!! Don't think this is useful {
//MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[playerIndex],intToStr(__LINE__) + "_" + intToStr(playerIndex));
return slots[playerIndex]; return slots[playerIndex];
} }
bool ServerInterface::hasClientConnection() { bool ServerInterface::hasClientConnection()
{
bool result = false; bool result = false;
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i)); MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
if(slots[i] != NULL && slots[i]->isConnected() == true) { if(slots[i] != NULL && slots[i]->isConnected() == true) {
@@ -338,11 +275,11 @@ bool ServerInterface::hasClientConnection() {
} }
} }
return result; return result;
} }
int ServerInterface::getConnectedSlotCount() {
int connectedSlotCount= 0;
int ServerInterface::getConnectedSlotCount()
{
int connectedSlotCount = 0;
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i)); MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
if(slots[i] != NULL) { if(slots[i] != NULL) {
@@ -350,21 +287,20 @@ int ServerInterface::getConnectedSlotCount() {
} }
} }
return connectedSlotCount; return connectedSlotCount;
} }
int64 ServerInterface::getNextEventId() { int64 ServerInterface::getNextEventId()
{
nextEventId++; nextEventId++;
if(nextEventId > INT_MAX){
// Rollover when # gets large
if(nextEventId > INT_MAX) {
nextEventId = 1; nextEventId = 1;
} }
return nextEventId; 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__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(event != NULL) { if(event != NULL) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] event->eventType = %d\n",__FILE__,__FUNCTION__,__LINE__,event->eventType); 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__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
} }
// void ServerInterface::updateSlot(ConnectionSlotEvent *event)
// 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) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(event != NULL) { if(event != NULL) {
bool &socketTriggered = event->socketTriggered; bool &socketTriggered = event->socketTriggered;
bool checkForNewClients = true; bool checkForNewClients = true;
@@ -422,17 +354,15 @@ void ServerInterface::updateSlot(ConnectionSlotEvent *event) {
safeMutexSlot.ReleaseLock(); safeMutexSlot.ReleaseLock();
} }
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); 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 { try {
alreadyInLagCheck = true; alreadyInLagCheck = true;
@@ -536,27 +466,17 @@ std::pair<bool,bool> ServerInterface::clientLagCheck(ConnectionSlot* connectionS
throw runtime_error(ex.what()); throw runtime_error(ex.what());
} }
alreadyInLagCheck = false; alreadyInLagCheck = false;
return clientLagExceededOrWarned; return clientLagExceededOrWarned;
} }
bool ServerInterface::signalClientReceiveCommands(ConnectionSlot* connectionSlot, bool ServerInterface::signalClientReceiveCommands(ConnectionSlot *connectionSlot, int slotIndex, bool socketTriggered, ConnectionSlotEvent & event) {
int slotIndex,
bool socketTriggered,
ConnectionSlotEvent &event) {
bool slotSignalled = false; bool slotSignalled = false;
//bool socketTriggered = (connectionSlot != NULL && connectionSlot->getSocket() != NULL ? socketTriggeredList[connectionSlot->getSocket()->getSocketId()] : false);
//ConnectionSlotEvent &event = eventList[i];
event.eventType = eReceiveSocketData; event.eventType = eReceiveSocketData;
event.networkMessage = NULL; event.networkMessage = NULL;
event.connectionSlot = connectionSlot; event.connectionSlot = connectionSlot;
event.socketTriggered = socketTriggered; event.socketTriggered = socketTriggered;
event.triggerId = slotIndex; event.triggerId = slotIndex;
event.eventId = getNextEventId(); 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) { if(connectionSlot != NULL) {
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex); //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex);
if(socketTriggered == true || connectionSlot->isConnected() == false) { 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); //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex);
} }
} }
return slotSignalled; return slotSignalled;
} }
void ServerInterface::updateSocketTriggeredList(std::map<PLATFORM_SOCKET,bool> &socketTriggeredList) { void ServerInterface::updateSocketTriggeredList(std::map<PLATFORM_SOCKET,bool> & socketTriggeredList) {
//update all slots
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i)); MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
ConnectionSlot* connectionSlot= slots[i]; ConnectionSlot* connectionSlot= slots[i];
@@ -579,9 +497,9 @@ void ServerInterface::updateSocketTriggeredList(std::map<PLATFORM_SOCKET,bool> &
socketTriggeredList[connectionSlot->getSocket()->getSocketId()] = false; socketTriggeredList[connectionSlot->getSocket()->getSocketId()] = false;
} }
} }
} }
void ServerInterface::validateConnectedClients() { void ServerInterface::validateConnectedClients() {
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i)); MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
ConnectionSlot* connectionSlot = slots[i]; ConnectionSlot* connectionSlot = slots[i];
@@ -592,13 +510,63 @@ void ServerInterface::validateConnectedClients() {
connectionSlot->validateConnection(); 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__); //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; const int MAX_SLOT_THREAD_WAIT_TIME = 3;
std::vector<string> errorMsgList; std::vector < string > errorMsgList;
try { try {
// The first thing we will do is check all clients to ensure they have // The first thing we will do is check all clients to ensure they have
// properly identified themselves within the alloted time period // properly identified themselves within the alloted time period
@@ -626,8 +594,6 @@ void ServerInterface::update() {
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i)); MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
ConnectionSlot* connectionSlot = slots[i]; ConnectionSlot* connectionSlot = slots[i];
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
bool socketTriggered = false; bool socketTriggered = false;
if(connectionSlot != NULL && connectionSlot->getSocket() != NULL) { if(connectionSlot != NULL && connectionSlot->getSocket() != NULL) {
socketTriggered = socketTriggeredList[connectionSlot->getSocket()->getSocketId()]; 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()); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
errorMsgList.push_back(ex.what()); errorMsgList.push_back(ex.what());
} }
if(errorMsgList.size() > 0){
if(errorMsgList.size() > 0) { for(int iErrIdx = 0;iErrIdx < errorMsgList.size();++iErrIdx){
for(int iErrIdx = 0; iErrIdx < errorMsgList.size(); ++iErrIdx) { string & sErr = errorMsgList[iErrIdx];
string &sErr = errorMsgList[iErrIdx]; if(sErr != ""){
if(sErr != "") {
DisplayErrorMessage(sErr); DisplayErrorMessage(sErr);
} }
} }
}
}
void ServerInterface::updateKeyframe(int frameCount) { }
}
void ServerInterface::updateKeyframe(int frameCount)
{
Chrono chrono; Chrono chrono;
chrono.start(); chrono.start();
currentFrameCount = frameCount; currentFrameCount = frameCount;
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] currentFrameCount = %d\n",__FILE__,__FUNCTION__,__LINE__,currentFrameCount); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] currentFrameCount = %d\n",__FILE__,__FUNCTION__,__LINE__,currentFrameCount);
NetworkMessageCommandList networkMessageCommandList(frameCount); NetworkMessageCommandList networkMessageCommandList(frameCount);
while(requestedCommands.empty() == false){
//build command list, remove commands from requested and add to pending if(networkMessageCommandList.addCommand(&requestedCommands.back())){
while(requestedCommands.empty() == false) {
if(networkMessageCommandList.addCommand(&requestedCommands.back())) {
pendingCommands.push_back(requestedCommands.back()); pendingCommands.push_back(requestedCommands.back());
requestedCommands.pop_back(); requestedCommands.pop_back();
} }else{
else {
break; 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()); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
DisplayErrorMessage(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); 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, bool ServerInterface::shouldDiscardNetworkMessage(NetworkMessageType networkMessageType, ConnectionSlot *connectionSlot)
ConnectionSlot* connectionSlot) { {
bool discard = false; bool discard = false;
if(connectionSlot != NULL) { if(connectionSlot != NULL) {
switch(networkMessageType) { switch(networkMessageType) {
@@ -995,21 +957,16 @@ bool ServerInterface::shouldDiscardNetworkMessage(NetworkMessageType networkMess
} }
} }
return discard; return discard;
} }
void ServerInterface::waitUntilReady(Checksum* checksum) {
void ServerInterface::waitUntilReady(Checksum *checksum)
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] START\n",__FUNCTION__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] START\n",__FUNCTION__);
Logger & logger = Logger::getInstance();
Logger &logger= Logger::getInstance();
gameHasBeenInitiated = true; gameHasBeenInitiated = true;
Chrono chrono; Chrono chrono;
bool allReady= false; bool allReady = false;
chrono.start(); chrono.start();
//wait until we get a ready message from all clients
while(exitServer == false && allReady == false) { while(exitServer == false && allReady == false) {
vector<string> waitingForHosts; vector<string> waitingForHosts;
allReady= true; 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__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] PART B (telling client we are ready!\n",__FUNCTION__);
try { try {
//send ready message after, so clients start delayed //send ready message after, so clients start delayed
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { 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()); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
DisplayErrorMessage(ex.what()); DisplayErrorMessage(ex.what());
} }
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] END\n",__FUNCTION__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] END\n",__FUNCTION__);
} }
void ServerInterface::processBroadCastMessageQueue() { void ServerInterface::processBroadCastMessageQueue()
{
MutexSafeWrapper safeMutexSlot(&broadcastMessageQueueThreadAccessor,intToStr(__LINE__)); MutexSafeWrapper safeMutexSlot(&broadcastMessageQueueThreadAccessor,intToStr(__LINE__));
if(broadcastMessageQueue.size() > 0) { if(broadcastMessageQueue.size() > 0) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] broadcastMessageQueue.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,broadcastMessageQueue.size()); 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(); broadcastMessageQueue.clear();
} }
} }
void ServerInterface::queueBroadcastMessage(const NetworkMessage *networkMessage, int excludeSlot) { void ServerInterface::queueBroadcastMessage(const NetworkMessage *networkMessage, int excludeSlot)
{
MutexSafeWrapper safeMutexSlot(&broadcastMessageQueueThreadAccessor,intToStr(__LINE__)); MutexSafeWrapper safeMutexSlot(&broadcastMessageQueueThreadAccessor,intToStr(__LINE__));
pair<const NetworkMessage *,int> item; pair<const NetworkMessage*,int> item;
item.first = networkMessage; item.first = networkMessage;
item.second = excludeSlot; item.second = excludeSlot;
broadcastMessageQueue.push_back(item); broadcastMessageQueue.push_back(item);
} }
void ServerInterface::processTextMessageQueue() { void ServerInterface::processTextMessageQueue()
{
MutexSafeWrapper safeMutexSlot(&textMessageQueueThreadAccessor,intToStr(__LINE__)); MutexSafeWrapper safeMutexSlot(&textMessageQueueThreadAccessor,intToStr(__LINE__));
if(textMessageQueue.size() > 0) { if(textMessageQueue.size() > 0) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] textMessageQueue.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,textMessageQueue.size()); 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(); 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__)); MutexSafeWrapper safeMutexSlot(&textMessageQueueThreadAccessor,intToStr(__LINE__));
TextMessageQueue item; TextMessageQueue item;
item.text = text; item.text = text;
item.teamIndex = teamIndex; item.teamIndex = teamIndex;
item.echoLocal = echoLocal; item.echoLocal = echoLocal;
textMessageQueue.push_back(item); 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); 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); 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()); NetworkMessageText networkMessageText(text, teamIndex, getHumanPlayerIndex());
broadcastMessage(&networkMessageText,-1,lockedSlotIndex); broadcastMessage(&networkMessageText, -1, lockedSlotIndex);
if(echoLocal == true) { if(echoLocal == true) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); 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()); ChatMsgInfo msg(text.c_str(),teamIndex,networkMessageText.getPlayerIndex());
this->addChatInfo(msg); this->addChatInfo(msg);
} }
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); 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; NetworkMessageQuit networkMessageQuit;
broadcastMessage(&networkMessageQuit); broadcastMessage(&networkMessageQuit);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
} }
string ServerInterface::getNetworkStatus() { string ServerInterface::getNetworkStatus()
Lang &lang= Lang::getInstance(); {
Lang & lang = Lang::getInstance();
string str; 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){ for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i){
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i)); MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
ConnectionSlot* connectionSlot= slots[i]; ConnectionSlot* connectionSlot= slots[i];
@@ -1212,17 +1158,13 @@ string ServerInterface::getNetworkStatus() {
str+= '\n'; str+= '\n';
} }
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
return str; return str;
} }
bool ServerInterface::launchGame(const GameSettings* gameSettings) { bool ServerInterface::launchGame(const GameSettings *gameSettings)
{
bool bOkToStart = true; bool bOkToStart = true;
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i)); MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
ConnectionSlot *connectionSlot= slots[i]; ConnectionSlot *connectionSlot= slots[i];
@@ -1235,7 +1177,6 @@ bool ServerInterface::launchGame(const GameSettings* gameSettings) {
} }
} }
} }
if(bOkToStart == true) { if(bOkToStart == true) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] needToRepublishToMasterserver = %d\n",__FILE__,__FUNCTION__,__LINE__,needToRepublishToMasterserver); 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; ftpServer = NULL;
} }
} }
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
return bOkToStart; 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__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
MutexSafeWrapper safeMutex(&serverSynchAccessor,intToStr(__LINE__)); MutexSafeWrapper safeMutex(&serverSynchAccessor,intToStr(__LINE__));
NetworkMessageLaunch networkMessageLaunch(gameSettings,nmtBroadCastSetup); NetworkMessageLaunch networkMessageLaunch(gameSettings, nmtBroadCastSetup);
broadcastMessage(&networkMessageLaunch); broadcastMessage(&networkMessageLaunch);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); 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 { try {
if(enabledThreadedClientCommandBroadcast == true) { if(enabledThreadedClientCommandBroadcast == true) {
// Step #1 signal worker threads to send this broadcast to each client // 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(); string sMsg = ex.what();
sendTextMessage(sMsg,-1, true, lockedSlotIndex); 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__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
try { try {
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i)); MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
@@ -1443,17 +1378,15 @@ void ServerInterface::broadcastMessageToConnectedClients(const NetworkMessage* n
//throw runtime_error(ex.what()); //throw runtime_error(ex.what());
DisplayErrorMessage(ex.what()); DisplayErrorMessage(ex.what());
} }
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
} }
void ServerInterface::updateListen() { void ServerInterface::updateListen()
if(gameHasBeenInitiated == true) { {
if(gameHasBeenInitiated == true){
return; return;
} }
int openSlotCount = 0;
//MutexSafeWrapper safeMutex(&serverSynchAccessor,intToStr(__LINE__));
int openSlotCount= 0;
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
//MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i)); //MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
bool isSlotOpen = (slots[i] != NULL && slots[i]->isConnected() == false); bool isSlotOpen = (slots[i] != NULL && slots[i]->isConnected() == false);
@@ -1462,15 +1395,12 @@ void ServerInterface::updateListen() {
++openSlotCount; ++openSlotCount;
} }
} }
//MutexSafeWrapper safeMutex(&serverSynchAccessor);
serverSocket.listen(openSlotCount); 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) { for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
//MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i)); //MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
bool isSlotOpen = (slots[i] != NULL && slots[i]->isConnected() == false); bool isSlotOpen = (slots[i] != NULL && slots[i]->isConnected() == false);
@@ -1479,17 +1409,14 @@ int ServerInterface::getOpenSlotCount() {
++openSlotCount; ++openSlotCount;
} }
} }
return 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); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START gameSettingsUpdateCount = %d, waitForClientAck = %d\n",__FILE__,__FUNCTION__,gameSettingsUpdateCount,waitForClientAck);
MutexSafeWrapper safeMutex(&serverSynchAccessor,intToStr(__LINE__)); MutexSafeWrapper safeMutex(&serverSynchAccessor,intToStr(__LINE__));
gameSettings = *serverGameSettings; gameSettings = *serverGameSettings;
if(getAllowGameDataSynchCheck() == true) if(getAllowGameDataSynchCheck() == true)
{ {
if(waitForClientAck == true && gameSettingsUpdateCount > 0) if(waitForClientAck == true && gameSettingsUpdateCount > 0)
@@ -1549,56 +1476,43 @@ void ServerInterface::setGameSettings(GameSettings *serverGameSettings, bool wai
gameSettingsUpdateCount++; gameSettingsUpdateCount++;
} }
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",__FILE__,__FUNCTION__); 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()); void ServerInterface::close()
//fflush(stdout); {
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); result = gameSettings.getNetworkPlayerName(index);
} }
} }
return result; return result;
} }
int ServerInterface::getHumanPlayerIndex() const { int ServerInterface::getHumanPlayerIndex() const
{
return gameSettings.getStartLocationIndex(gameSettings.getThisFactionIndex()); 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__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
int slotCountUsed = 1;
// The server player counts as 1 for each of these int slotCountHumans = 1;
int slotCountUsed=1; int slotCountConnectedPlayers = 1;
int slotCountHumans=1; Config & config = Config::getInstance();
int slotCountConnectedPlayers=1; std::map < string, string > publishToServerInfo;
Config &config= Config::getInstance();
//string serverinfo="";
std::map<string,string> publishToServerInfo;
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i)); MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
if(slots[i] != NULL) { if(slots[i] != NULL) {
@@ -1610,40 +1524,28 @@ std::map<string,string> ServerInterface::publishToMasterserver() {
} }
} }
} }
//?status=waiting&system=linux&info=titus
publishToServerInfo["glestVersion"] = glestVersionString; publishToServerInfo["glestVersion"] = glestVersionString;
publishToServerInfo["platform"] = getPlatformNameString(); publishToServerInfo["platform"] = getPlatformNameString();
publishToServerInfo["binaryCompileDate"] = getCompileDateTime(); publishToServerInfo["binaryCompileDate"] = getCompileDateTime();
//game info:
publishToServerInfo["serverTitle"] = getHumanPlayerName() + "'s game *IN PROGRESS*"; publishToServerInfo["serverTitle"] = getHumanPlayerName() + "'s game *IN PROGRESS*";
//ip is automatically set
//game setup info:
publishToServerInfo["tech"] = this->getGameSettings()->getTech(); publishToServerInfo["tech"] = this->getGameSettings()->getTech();
publishToServerInfo["map"] = this->getGameSettings()->getMap(); publishToServerInfo["map"] = this->getGameSettings()->getMap();
publishToServerInfo["tileset"] = this->getGameSettings()->getTileset(); publishToServerInfo["tileset"] = this->getGameSettings()->getTileset();
publishToServerInfo["activeSlots"] = intToStr(slotCountUsed); publishToServerInfo["activeSlots"] = intToStr(slotCountUsed);
publishToServerInfo["networkSlots"] = intToStr(slotCountHumans); publishToServerInfo["networkSlots"] = intToStr(slotCountHumans);
publishToServerInfo["connectedClients"] = intToStr(slotCountConnectedPlayers); publishToServerInfo["connectedClients"] = intToStr(slotCountConnectedPlayers);
//string externalport = intToStr(Config::getInstance().getInt("ExternalServerPort",intToStr(Config::getInstance().getInt("ServerPort")).c_str()));
string externalport = config.getString("MasterServerExternalPort", "61357"); string externalport = config.getString("MasterServerExternalPort", "61357");
publishToServerInfo["externalconnectport"] = externalport; publishToServerInfo["externalconnectport"] = externalport;
if(publishToMasterserverThread == NULL) { if(publishToMasterserverThread == NULL) {
publishToServerInfo["serverTitle"] = getHumanPlayerName() + "'s game *FINISHED*"; publishToServerInfo["serverTitle"] = getHumanPlayerName() + "'s game *FINISHED*";
publishToServerInfo["gameCmd"]= "gameOver"; publishToServerInfo["gameCmd"]= "gameOver";
} }
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
return publishToServerInfo; 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__)); MutexSafeWrapper safeMutex(&masterServerThreadAccessor,intToStr(__LINE__));
const int MASTERSERVER_HEARTBEAT_GAME_STATUS_SECONDS = 30; const int MASTERSERVER_HEARTBEAT_GAME_STATUS_SECONDS = 30;
if(difftime(time(NULL),lastMasterserverHeartbeatTime) >= MASTERSERVER_HEARTBEAT_GAME_STATUS_SECONDS) { if(difftime(time(NULL),lastMasterserverHeartbeatTime) >= MASTERSERVER_HEARTBEAT_GAME_STATUS_SECONDS) {

View File

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

View File

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

View File

@@ -1752,11 +1752,13 @@ void ServerSocket::stopBroadCastThread() {
if(broadCastThread != NULL) { if(broadCastThread != NULL) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); 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__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
delete broadCastThread; delete broadCastThread;
}
}
broadCastThread = NULL; broadCastThread = NULL;
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); 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__); 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() { void BroadCastSocketThread::execute() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//setRunningStatus(true); //setRunningStatus(true);
RunningStatusSafeWrapper runningStatus(this); RunningStatusSafeWrapper runningStatus(this);
ExecutingTaskSafeWrapper safeExecutingTaskMutex(this);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast thread is running\n"); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast thread is running\n");