|
|
@@ -30,17 +30,19 @@ 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;
|
|
|
|
double maxFrameCountLagAllowed = 30;
|
|
|
|
double maxClientLagTimeAllowed = 20;
|
|
|
|
double maxClientLagTimeAllowed = 20;
|
|
|
|
double maxFrameCountLagAllowedEver = 50;
|
|
|
|
double maxFrameCountLagAllowedEver = 50;
|
|
|
|
double warnFrameCountLagPercent = 0.65;
|
|
|
|
double warnFrameCountLagPercent = 0.65;
|
|
|
|
double LAG_CHECK_GRACE_PERIOD = 15;
|
|
|
|
double LAG_CHECK_GRACE_PERIOD = 15;
|
|
|
|
double MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE = 1;
|
|
|
|
double MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE = 1;
|
|
|
|
ServerInterface::ServerInterface()
|
|
|
|
const int MAX_SLOT_THREAD_WAIT_TIME = 3;
|
|
|
|
:GameNetworkInterface()
|
|
|
|
const int MASTERSERVER_HEARTBEAT_GAME_STATUS_SECONDS = 30;
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
exitServer = false;
|
|
|
|
exitServer = false;
|
|
|
@@ -51,21 +53,26 @@ namespace Glest{ namespace Game{
|
|
|
|
lastMasterserverHeartbeatTime = 0;
|
|
|
|
lastMasterserverHeartbeatTime = 0;
|
|
|
|
needToRepublishToMasterserver = false;
|
|
|
|
needToRepublishToMasterserver = false;
|
|
|
|
ftpServer = NULL;
|
|
|
|
ftpServer = NULL;
|
|
|
|
enabledThreadedClientCommandBroadcast = Config::getInstance().getBool("EnableThreadedClientCommandBroadcast", "false");
|
|
|
|
inBroadcastMessage = 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] maxFrameCountLagAllowed = %f, maxFrameCountLagAllowedEver = %f, maxClientLagTimeAllowed = %f\n",__FILE__,__FUNCTION__,__LINE__,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;
|
|
|
|
vector<string> pathList = Config::getInstance().getPathListForType(ptMaps);
|
|
|
|
vector<string> pathList = Config::getInstance().getPathListForType(ptMaps);
|
|
|
@@ -94,8 +101,7 @@ namespace Glest{ namespace Game{
|
|
|
|
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) {
|
|
|
@@ -110,6 +116,7 @@ namespace Glest{ namespace Game{
|
|
|
|
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) {
|
|
|
@@ -128,8 +135,7 @@ namespace Glest{ namespace Game{
|
|
|
|
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) {
|
|
|
@@ -148,13 +154,11 @@ namespace Glest{ namespace Game{
|
|
|
|
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__));
|
|
|
@@ -162,6 +166,7 @@ namespace Glest{ namespace Game{
|
|
|
|
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__);
|
|
|
@@ -180,14 +185,14 @@ namespace Glest{ namespace Game{
|
|
|
|
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;
|
|
|
|
bool result = false;
|
|
|
|
assert(fromPlayerIndex >= 0 && fromPlayerIndex < GameConstants::maxPlayers);
|
|
|
|
assert(fromPlayerIndex >= 0 && fromPlayerIndex < GameConstants::maxPlayers);
|
|
|
|
assert(toPlayerIndex >= 0 && toPlayerIndex < GameConstants::maxPlayers);
|
|
|
|
assert(toPlayerIndex >= 0 && toPlayerIndex < GameConstants::maxPlayers);
|
|
|
|
if(fromPlayerIndex == toPlayerIndex)
|
|
|
|
if(fromPlayerIndex == toPlayerIndex) {
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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));
|
|
|
@@ -205,7 +210,8 @@ namespace Glest{ namespace Game{
|
|
|
|
safeMutexSlot2.ReleaseLock();
|
|
|
|
safeMutexSlot2.ReleaseLock();
|
|
|
|
result = true;
|
|
|
|
result = true;
|
|
|
|
updateListen();
|
|
|
|
updateListen();
|
|
|
|
}else{
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
safeMutexSlot.ReleaseLock();
|
|
|
|
safeMutexSlot.ReleaseLock();
|
|
|
|
safeMutexSlot2.ReleaseLock();
|
|
|
|
safeMutexSlot2.ReleaseLock();
|
|
|
|
safeMutex.ReleaseLock();
|
|
|
|
safeMutex.ReleaseLock();
|
|
|
@@ -214,8 +220,7 @@ namespace Glest{ namespace Game{
|
|
|
|
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__));
|
|
|
|
MutexSafeWrapper safeMutexSlot(NULL,intToStr(__LINE__) + "_" + intToStr(playerIndex));
|
|
|
|
MutexSafeWrapper safeMutexSlot(NULL,intToStr(__LINE__) + "_" + intToStr(playerIndex));
|
|
|
@@ -249,6 +254,7 @@ namespace Glest{ namespace Game{
|
|
|
|
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);
|
|
|
@@ -259,13 +265,11 @@ namespace Glest{ namespace Game{
|
|
|
|
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) {
|
|
|
|
{
|
|
|
|
|
|
|
|
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));
|
|
|
@@ -277,8 +281,7 @@ namespace Glest{ namespace Game{
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int ServerInterface::getConnectedSlotCount()
|
|
|
|
int ServerInterface::getConnectedSlotCount() {
|
|
|
|
{
|
|
|
|
|
|
|
|
int connectedSlotCount = 0;
|
|
|
|
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));
|
|
|
@@ -289,8 +292,7 @@ namespace Glest{ namespace Game{
|
|
|
|
return connectedSlotCount;
|
|
|
|
return connectedSlotCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int64 ServerInterface::getNextEventId()
|
|
|
|
int64 ServerInterface::getNextEventId() {
|
|
|
|
{
|
|
|
|
|
|
|
|
nextEventId++;
|
|
|
|
nextEventId++;
|
|
|
|
if(nextEventId > INT_MAX) {
|
|
|
|
if(nextEventId > INT_MAX) {
|
|
|
|
nextEventId = 1;
|
|
|
|
nextEventId = 1;
|
|
|
@@ -298,8 +300,7 @@ namespace Glest{ namespace Game{
|
|
|
|
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);
|
|
|
@@ -320,8 +321,7 @@ namespace Glest{ namespace Game{
|
|
|
|
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)
|
|
|
|
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;
|
|
|
@@ -343,7 +343,7 @@ namespace Glest{ namespace Game{
|
|
|
|
(gameHasBeenInitiated == false ||
|
|
|
|
(gameHasBeenInitiated == false ||
|
|
|
|
(connectionSlot->getSocket() != NULL && socketTriggered == true))) {
|
|
|
|
(connectionSlot->getSocket() != NULL && socketTriggered == true))) {
|
|
|
|
if(connectionSlot->isConnected() == false || socketTriggered == true) {
|
|
|
|
if(connectionSlot->isConnected() == false || socketTriggered == true) {
|
|
|
|
connectionSlot->update(checkForNewClients);
|
|
|
|
connectionSlot->update(checkForNewClients,event->triggerId);
|
|
|
|
|
|
|
|
|
|
|
|
// This means no clients are trying to connect at the moment
|
|
|
|
// This means no clients are trying to connect at the moment
|
|
|
|
if(connectionSlot != NULL && connectionSlot->getSocket() == NULL) {
|
|
|
|
if(connectionSlot != NULL && connectionSlot->getSocket() == NULL) {
|
|
|
@@ -356,13 +356,13 @@ namespace Glest{ namespace Game{
|
|
|
|
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__);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::pair<bool,bool> ServerInterface::clientLagCheck(ConnectionSlot *connectionSlot, bool skipNetworkBroadCast)
|
|
|
|
std::pair<bool,bool> ServerInterface::clientLagCheck(ConnectionSlot *connectionSlot, bool skipNetworkBroadCast) {
|
|
|
|
{
|
|
|
|
|
|
|
|
std::pair<bool,bool> clientLagExceededOrWarned = std::make_pair(false, false);
|
|
|
|
std::pair<bool,bool> clientLagExceededOrWarned = std::make_pair(false, false);
|
|
|
|
static bool alreadyInLagCheck = false;
|
|
|
|
static bool alreadyInLagCheck = false;
|
|
|
|
if(alreadyInLagCheck == true) {
|
|
|
|
if(alreadyInLagCheck == true) {
|
|
|
|
return clientLagExceededOrWarned;
|
|
|
|
return clientLagExceededOrWarned;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
alreadyInLagCheck = true;
|
|
|
|
alreadyInLagCheck = true;
|
|
|
|
|
|
|
|
|
|
|
@@ -471,18 +471,18 @@ namespace Glest{ namespace Game{
|
|
|
|
|
|
|
|
|
|
|
|
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 slotSignalled = false;
|
|
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
|
|
if(connectionSlot != NULL) {
|
|
|
|
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) {
|
|
|
|
if(socketTriggered == true || connectionSlot->isConnected() == false) {
|
|
|
|
connectionSlot->signalUpdate(&event);
|
|
|
|
connectionSlot->signalUpdate(&event);
|
|
|
|
slotSignalled = true;
|
|
|
|
slotSignalled = true;
|
|
|
|
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return slotSignalled;
|
|
|
|
return slotSignalled;
|
|
|
@@ -504,52 +504,15 @@ namespace Glest{ namespace Game{
|
|
|
|
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] Slot # %d\n",__FILE__,__FUNCTION__,__LINE__,i);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(connectionSlot != NULL) {
|
|
|
|
if(connectionSlot != NULL) {
|
|
|
|
connectionSlot->validateConnection();
|
|
|
|
connectionSlot->validateConnection();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ServerInterface::signalClientsToRecieveDataX(std::map<PLATFORM_SOCKET,bool> & socketTriggeredList, std::map<int,ConnectionSlotEvent> & eventList, std::map<int,bool> & mapSlotSignalledList)
|
|
|
|
void ServerInterface::signalClientsToRecieveData(std::map<PLATFORM_SOCKET,bool> &socketTriggeredList,
|
|
|
|
{
|
|
|
|
std::map<int,ConnectionSlotEvent> &eventList,
|
|
|
|
bool checkForNewClients = true;
|
|
|
|
std::map<int,bool> & mapSlotSignalledList) {
|
|
|
|
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::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;
|
|
|
|
bool checkForNewClients = true;
|
|
|
|
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));
|
|
|
@@ -564,47 +527,9 @@ namespace Glest{ namespace Game{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ServerInterface::update() {
|
|
|
|
void ServerInterface::checkForCompletedClients(std::map<int,bool> & mapSlotSignalledList,
|
|
|
|
const int MAX_SLOT_THREAD_WAIT_TIME = 3;
|
|
|
|
std::vector <string> &errorMsgList,
|
|
|
|
std::vector < string > errorMsgList;
|
|
|
|
std::map<int,ConnectionSlotEvent> &eventList) {
|
|
|
|
try {
|
|
|
|
|
|
|
|
// The first thing we will do is check all clients to ensure they have
|
|
|
|
|
|
|
|
// properly identified themselves within the alloted time period
|
|
|
|
|
|
|
|
validateConnectedClients();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
processTextMessageQueue();
|
|
|
|
|
|
|
|
processBroadCastMessageQueue();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::map<PLATFORM_SOCKET,bool> socketTriggeredList;
|
|
|
|
|
|
|
|
//update all slots
|
|
|
|
|
|
|
|
updateSocketTriggeredList(socketTriggeredList);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(gameHasBeenInitiated == false || socketTriggeredList.size() > 0) {
|
|
|
|
|
|
|
|
std::map<int,ConnectionSlotEvent> eventList;
|
|
|
|
|
|
|
|
bool hasData = Socket::hasDataToRead(socketTriggeredList);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(hasData) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] hasData == true\n",__FILE__,__FUNCTION__);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(gameHasBeenInitiated == false || hasData == true) {
|
|
|
|
|
|
|
|
std::map<int,bool> mapSlotSignalledList;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Step #1 tell all connection slot worker threads to receive socket data
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ============ Step #2\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Step #2 check all connection slot worker threads for completed status
|
|
|
|
|
|
|
|
time_t waitForThreadElapsed = time(NULL);
|
|
|
|
time_t waitForThreadElapsed = time(NULL);
|
|
|
|
std::map<int,bool> slotsCompleted;
|
|
|
|
std::map<int,bool> slotsCompleted;
|
|
|
|
for(bool threadsDone = false;
|
|
|
|
for(bool threadsDone = false;
|
|
|
@@ -648,14 +573,15 @@ namespace Glest{ namespace Game{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ============ Step #3\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
void ServerInterface::checForLaggingClients(std::map<int,bool> &mapSlotSignalledList,
|
|
|
|
|
|
|
|
std::map<int,ConnectionSlotEvent> &eventList,
|
|
|
|
// Step #3 check clients for any lagging scenarios and try to deal with them
|
|
|
|
std::map<PLATFORM_SOCKET,bool> &socketTriggeredList,
|
|
|
|
|
|
|
|
std::vector <string> &errorMsgList) {
|
|
|
|
time_t waitForClientsElapsed = time(NULL);
|
|
|
|
time_t waitForClientsElapsed = time(NULL);
|
|
|
|
waitForThreadElapsed = time(NULL);
|
|
|
|
time_t waitForThreadElapsed = time(NULL);
|
|
|
|
slotsCompleted.clear();
|
|
|
|
std::map<int,bool> slotsCompleted;
|
|
|
|
//std::map<int,bool> slotsWarnedAndRetried;
|
|
|
|
|
|
|
|
std::map<int,bool> slotsWarnedList;
|
|
|
|
std::map<int,bool> slotsWarnedList;
|
|
|
|
for(bool threadsDone = false;
|
|
|
|
for(bool threadsDone = false;
|
|
|
|
exitServer == false && threadsDone == false &&
|
|
|
|
exitServer == false && threadsDone == false &&
|
|
|
@@ -735,10 +661,9 @@ namespace Glest{ namespace Game{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ============ Step #4\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
void ServerInterface::executeNetworkCommandsFromClients() {
|
|
|
|
|
|
|
|
|
|
|
|
// Step #4 dispatch network commands to the pending list so that they are done in proper order
|
|
|
|
|
|
|
|
if(gameHasBeenInitiated == true) {
|
|
|
|
if(gameHasBeenInitiated == true) {
|
|
|
|
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));
|
|
|
@@ -754,9 +679,9 @@ namespace Glest{ namespace Game{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ============ Step #5\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Step #5 dispatch pending chat messages
|
|
|
|
void ServerInterface::dispatchPendingChatMessages(std::vector <string> &errorMsgList) {
|
|
|
|
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];
|
|
|
@@ -798,7 +723,49 @@ namespace Glest{ namespace Game{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ServerInterface::update() {
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
validateConnectedClients();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
processTextMessageQueue();
|
|
|
|
|
|
|
|
processBroadCastMessageQueue();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::map<PLATFORM_SOCKET,bool> socketTriggeredList;
|
|
|
|
|
|
|
|
//update all slots
|
|
|
|
|
|
|
|
updateSocketTriggeredList(socketTriggeredList);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(gameHasBeenInitiated == false || socketTriggeredList.size() > 0) {
|
|
|
|
|
|
|
|
std::map<int,ConnectionSlotEvent> eventList;
|
|
|
|
|
|
|
|
bool hasData = Socket::hasDataToRead(socketTriggeredList);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(hasData) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] hasData == true\n",__FILE__,__FUNCTION__);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(gameHasBeenInitiated == false || hasData == true) {
|
|
|
|
|
|
|
|
std::map<int,bool> mapSlotSignalledList;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Step #1 tell all connection slot worker threads to receive socket data
|
|
|
|
|
|
|
|
signalClientsToRecieveData(socketTriggeredList, eventList, mapSlotSignalledList);
|
|
|
|
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ============ Step #2\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Step #2 check all connection slot worker threads for completed status
|
|
|
|
|
|
|
|
checkForCompletedClients(mapSlotSignalledList,errorMsgList, eventList);
|
|
|
|
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ============ Step #3\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Step #3 check clients for any lagging scenarios and try to deal with them
|
|
|
|
|
|
|
|
checForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList,errorMsgList);
|
|
|
|
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ============ Step #4\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Step #4 dispatch network commands to the pending list so that they are done in proper order
|
|
|
|
|
|
|
|
executeNetworkCommandsFromClients();
|
|
|
|
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ============ Step #5\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Step #5 dispatch pending chat messages
|
|
|
|
|
|
|
|
dispatchPendingChatMessages(errorMsgList);
|
|
|
|
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__);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -820,8 +787,7 @@ namespace Glest{ namespace Game{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ServerInterface::updateKeyframe(int frameCount)
|
|
|
|
void ServerInterface::updateKeyframe(int frameCount) {
|
|
|
|
{
|
|
|
|
|
|
|
|
Chrono chrono;
|
|
|
|
Chrono chrono;
|
|
|
|
chrono.start();
|
|
|
|
chrono.start();
|
|
|
|
currentFrameCount = frameCount;
|
|
|
|
currentFrameCount = frameCount;
|
|
|
@@ -831,7 +797,8 @@ namespace Glest{ namespace Game{
|
|
|
|
if(networkMessageCommandList.addCommand(&requestedCommands.back())){
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -861,8 +828,7 @@ namespace Glest{ namespace Game{
|
|
|
|
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, ConnectionSlot *connectionSlot)
|
|
|
|
bool ServerInterface::shouldDiscardNetworkMessage(NetworkMessageType networkMessageType, ConnectionSlot *connectionSlot) {
|
|
|
|
{
|
|
|
|
|
|
|
|
bool discard = false;
|
|
|
|
bool discard = false;
|
|
|
|
if(connectionSlot != NULL) {
|
|
|
|
if(connectionSlot != NULL) {
|
|
|
|
switch(networkMessageType) {
|
|
|
|
switch(networkMessageType) {
|
|
|
@@ -959,14 +925,15 @@ namespace Glest{ namespace Game{
|
|
|
|
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;
|
|
|
|
|
|
|
|
chrono.start();
|
|
|
|
chrono.start();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool allReady = false;
|
|
|
|
|
|
|
|
|
|
|
|
while(exitServer == false && allReady == false) {
|
|
|
|
while(exitServer == false && allReady == false) {
|
|
|
|
vector<string> waitingForHosts;
|
|
|
|
vector<string> waitingForHosts;
|
|
|
|
allReady= true;
|
|
|
|
allReady= true;
|
|
|
@@ -988,14 +955,12 @@ namespace Glest{ namespace Game{
|
|
|
|
connectionSlot->setReady();
|
|
|
|
connectionSlot->setReady();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(networkMessageType != nmtInvalid) {
|
|
|
|
else if(networkMessageType != nmtInvalid) {
|
|
|
|
//throw runtime_error("Unexpected network message: " + intToStr(networkMessageType));
|
|
|
|
|
|
|
|
string sErr = "Unexpected network message: " + intToStr(networkMessageType);
|
|
|
|
string sErr = "Unexpected network message: " + intToStr(networkMessageType);
|
|
|
|
sendTextMessage(sErr,-1, true,i);
|
|
|
|
sendTextMessage(sErr,-1, true,i);
|
|
|
|
DisplayErrorMessage(sErr);
|
|
|
|
DisplayErrorMessage(sErr);
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//waitingForHosts.push_back(connectionSlot->getHostName());
|
|
|
|
|
|
|
|
waitingForHosts.push_back(connectionSlot->getName());
|
|
|
|
waitingForHosts.push_back(connectionSlot->getName());
|
|
|
|
|
|
|
|
|
|
|
|
allReady= false;
|
|
|
|
allReady= false;
|
|
|
@@ -1006,7 +971,6 @@ namespace Glest{ namespace Game{
|
|
|
|
//check for timeout
|
|
|
|
//check for timeout
|
|
|
|
if(allReady == false) {
|
|
|
|
if(allReady == false) {
|
|
|
|
if(chrono.getMillis() > readyWaitTimeout) {
|
|
|
|
if(chrono.getMillis() > readyWaitTimeout) {
|
|
|
|
//throw runtime_error("Timeout waiting for clients");
|
|
|
|
|
|
|
|
string sErr = "Timeout waiting for clients.";
|
|
|
|
string sErr = "Timeout waiting for clients.";
|
|
|
|
sendTextMessage(sErr,-1, true);
|
|
|
|
sendTextMessage(sErr,-1, true);
|
|
|
|
DisplayErrorMessage(sErr);
|
|
|
|
DisplayErrorMessage(sErr);
|
|
|
@@ -1051,8 +1015,7 @@ namespace Glest{ namespace Game{
|
|
|
|
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());
|
|
|
@@ -1068,8 +1031,7 @@ namespace Glest{ namespace Game{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
@@ -1077,8 +1039,7 @@ namespace Glest{ namespace Game{
|
|
|
|
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());
|
|
|
@@ -1090,8 +1051,7 @@ namespace Glest{ namespace Game{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
@@ -1100,13 +1060,11 @@ namespace Glest{ namespace Game{
|
|
|
|
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, teamIndex, getHumanPlayerIndex());
|
|
|
|
NetworkMessageText networkMessageText(text, teamIndex, getHumanPlayerIndex());
|
|
|
|
broadcastMessage(&networkMessageText, -1, lockedSlotIndex);
|
|
|
|
broadcastMessage(&networkMessageText, -1, lockedSlotIndex);
|
|
|
@@ -1120,20 +1078,16 @@ namespace Glest{ namespace Game{
|
|
|
|
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)
|
|
|
|
void ServerInterface::quitGame(bool userManuallyQuit) {
|
|
|
|
{
|
|
|
|
|
|
|
|
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(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="";
|
|
|
|
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];
|
|
|
@@ -1145,10 +1099,9 @@ namespace Glest{ namespace Game{
|
|
|
|
int clientLagCount = connectionSlot->getCurrentLagCount();
|
|
|
|
int clientLagCount = connectionSlot->getCurrentLagCount();
|
|
|
|
double lastClientCommandListTimeLag = difftime(time(NULL),connectionSlot->getLastReceiveCommandListTime());
|
|
|
|
double lastClientCommandListTimeLag = difftime(time(NULL),connectionSlot->getLastReceiveCommandListTime());
|
|
|
|
//float pingTime = connectionSlot->getThreadedPingMS(connectionSlot->getIpAddress().c_str());
|
|
|
|
//float pingTime = connectionSlot->getThreadedPingMS(connectionSlot->getIpAddress().c_str());
|
|
|
|
char szBuf[100]="";
|
|
|
|
char szBuf[1024]="";
|
|
|
|
//sprintf(szBuf,", lag = %d [%.2f], ping = %.2fms",clientLagCount,lastClientCommandListTimeLag,pingTime);
|
|
|
|
//sprintf(szBuf,", lag = %d [%.2f], ping = %.2fms",clientLagCount,lastClientCommandListTimeLag,pingTime);
|
|
|
|
sprintf(szBuf,", lag = %d [%.2f]",clientLagCount,lastClientCommandListTimeLag);
|
|
|
|
sprintf(szBuf,", lag = %d [%.2f]",clientLagCount,lastClientCommandListTimeLag);
|
|
|
|
|
|
|
|
|
|
|
|
str+= connectionSlot->getName() + string(szBuf);
|
|
|
|
str+= connectionSlot->getName() + string(szBuf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -1161,8 +1114,7 @@ namespace Glest{ namespace Game{
|
|
|
|
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) {
|
|
|
@@ -1205,7 +1157,6 @@ namespace Glest{ namespace Game{
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
|
|
if(needToRepublishToMasterserver == true) {
|
|
|
|
if(needToRepublishToMasterserver == true) {
|
|
|
|
//publishToMasterserverThread = new SimpleTaskThread(this,0,25);
|
|
|
|
|
|
|
|
publishToMasterserverThread = new SimpleTaskThread(this,0,125);
|
|
|
|
publishToMasterserverThread = new SimpleTaskThread(this,0,125);
|
|
|
|
publishToMasterserverThread->setUniqueID(__FILE__);
|
|
|
|
publishToMasterserverThread->setUniqueID(__FILE__);
|
|
|
|
publishToMasterserverThread->start();
|
|
|
|
publishToMasterserverThread->start();
|
|
|
@@ -1223,8 +1174,7 @@ namespace Glest{ namespace Game{
|
|
|
|
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);
|
|
|
@@ -1232,93 +1182,27 @@ namespace Glest{ namespace Game{
|
|
|
|
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)
|
|
|
|
void ServerInterface::broadcastMessage(const NetworkMessage *networkMessage, int excludeSlot, int lockedSlotIndex) {
|
|
|
|
{
|
|
|
|
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
if(enabledThreadedClientCommandBroadcast == true) {
|
|
|
|
|
|
|
|
// Step #1 signal worker threads to send this broadcast to each client
|
|
|
|
|
|
|
|
std::map<int,ConnectionSlotEvent> eventList;
|
|
|
|
|
|
|
|
for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
|
|
|
|
|
|
|
|
MutexSafeWrapper safeMutexSlot(NULL,intToStr(__LINE__) + "_" + intToStr(i));
|
|
|
|
|
|
|
|
if(i != lockedSlotIndex) {
|
|
|
|
|
|
|
|
safeMutexSlot.setMutex(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ConnectionSlot* connectionSlot = slots[i];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] networkMessage = %p\n",__FILE__,__FUNCTION__,__LINE__,networkMessage);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ConnectionSlotEvent &event = eventList[i];
|
|
|
|
|
|
|
|
event.eventType = eSendSocketData;
|
|
|
|
|
|
|
|
event.networkMessage = networkMessage;
|
|
|
|
|
|
|
|
event.connectionSlot = connectionSlot;
|
|
|
|
|
|
|
|
event.socketTriggered = true;
|
|
|
|
|
|
|
|
event.triggerId = i;
|
|
|
|
|
|
|
|
event.eventId = getNextEventId();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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__);
|
|
|
|
|
|
|
|
|
|
|
|
// Step #1 tell all connection slot worker threads to receive socket data
|
|
|
|
MutexSafeWrapper safeMutexSlotBroadCastAccessor(&inBroadcastMessageThreadAccessor,intToStr(__LINE__));
|
|
|
|
if(i != excludeSlot && connectionSlot != NULL) {
|
|
|
|
if(inBroadcastMessage == true && dynamic_cast<const NetworkMessageText *>(networkMessage) != NULL) {
|
|
|
|
if(connectionSlot->isConnected()) {
|
|
|
|
safeMutexSlotBroadCastAccessor.ReleaseLock();
|
|
|
|
connectionSlot->signalUpdate(&event);
|
|
|
|
const NetworkMessageText *txtMsg = dynamic_cast<const NetworkMessageText *>(networkMessage);
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
const NetworkMessageText *msgCopy = txtMsg->getCopy();
|
|
|
|
}
|
|
|
|
queueBroadcastMessage(msgCopy, excludeSlot);
|
|
|
|
else if(gameHasBeenInitiated == true) {
|
|
|
|
return;
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #1 before removeSlot for slot# %d\n",__FILE__,__FUNCTION__,__LINE__,i);
|
|
|
|
|
|
|
|
removeSlot(i,i);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if(i == excludeSlot &&
|
|
|
|
|
|
|
|
gameHasBeenInitiated == true &&
|
|
|
|
|
|
|
|
connectionSlot != NULL &&
|
|
|
|
|
|
|
|
connectionSlot->isConnected() == false) {
|
|
|
|
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #2 before removeSlot for slot# %d\n",__FILE__,__FUNCTION__,__LINE__,i);
|
|
|
|
|
|
|
|
removeSlot(i,i);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Step #2 check all connection slot worker threads for completed status
|
|
|
|
|
|
|
|
std::map<int,bool> slotsCompleted;
|
|
|
|
|
|
|
|
for(bool threadsDone = false; exitServer == false && threadsDone == false;) {
|
|
|
|
|
|
|
|
threadsDone = true;
|
|
|
|
|
|
|
|
// Examine all threads for completion of delegation
|
|
|
|
|
|
|
|
for(int i = 0; exitServer == false && i < GameConstants::maxPlayers; ++i) {
|
|
|
|
|
|
|
|
MutexSafeWrapper safeMutexSlot(NULL,intToStr(__LINE__) + "_" + intToStr(i));
|
|
|
|
|
|
|
|
if(i != lockedSlotIndex) {
|
|
|
|
|
|
|
|
safeMutexSlot.setMutex(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ConnectionSlot* connectionSlot = slots[i];
|
|
|
|
|
|
|
|
if(connectionSlot != NULL && slotsCompleted.find(i) == slotsCompleted.end()) {
|
|
|
|
|
|
|
|
std::vector<std::string> errorList = connectionSlot->getThreadErrorList();
|
|
|
|
|
|
|
|
if(errorList.size() > 0) {
|
|
|
|
|
|
|
|
for(int iErrIdx = 0; iErrIdx < errorList.size(); ++iErrIdx) {
|
|
|
|
|
|
|
|
string &sErr = errorList[iErrIdx];
|
|
|
|
|
|
|
|
DisplayErrorMessage(sErr);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
connectionSlot->clearThreadErrorList();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(connectionSlot->updateCompleted(&eventList[i]) == false) {
|
|
|
|
|
|
|
|
threadsDone = false;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else {
|
|
|
|
slotsCompleted[i] = true;
|
|
|
|
inBroadcastMessage = true;
|
|
|
|
|
|
|
|
safeMutexSlotBroadCastAccessor.ReleaseLock(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
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(NULL,intToStr(__LINE__) + "_" + intToStr(i));
|
|
|
|
MutexSafeWrapper safeMutexSlot(NULL,intToStr(__LINE__) + "_" + intToStr(i));
|
|
|
|
if(i != lockedSlotIndex) {
|
|
|
|
if(i != lockedSlotIndex) {
|
|
|
|
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] i = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,i,lockedSlotIndex);
|
|
|
|
safeMutexSlot.setMutex(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
|
|
|
|
safeMutexSlot.setMutex(&slotAccessorMutexes[i],intToStr(__LINE__) + "_" + intToStr(i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@@ -1328,11 +1212,13 @@ namespace Glest{ namespace Game{
|
|
|
|
if(connectionSlot->isConnected()) {
|
|
|
|
if(connectionSlot->isConnected()) {
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] before sendMessage\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] before sendMessage\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
connectionSlot->sendMessage(networkMessage);
|
|
|
|
connectionSlot->sendMessage(networkMessage);
|
|
|
|
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] after sendMessage\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(gameHasBeenInitiated == true) {
|
|
|
|
if(gameHasBeenInitiated == true && connectionSlot->isConnected() == false) {
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #1 before removeSlot for slot# %d\n",__FILE__,__FUNCTION__,__LINE__,i);
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #1 before removeSlot for slot# %d\n",__FILE__,__FUNCTION__,__LINE__,i);
|
|
|
|
//safeMutexSlot.ReleaseLock();
|
|
|
|
//safeMutexSlot.ReleaseLock();
|
|
|
|
removeSlot(i,i);
|
|
|
|
removeSlot(i,i);
|
|
|
|
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #1 after removeSlot for slot# %d\n",__FILE__,__FUNCTION__,__LINE__,i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(i == excludeSlot && gameHasBeenInitiated == true &&
|
|
|
|
else if(i == excludeSlot && gameHasBeenInitiated == true &&
|
|
|
@@ -1340,23 +1226,28 @@ namespace Glest{ namespace Game{
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #2 before removeSlot for slot# %d\n",__FILE__,__FUNCTION__,__LINE__,i);
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #2 before removeSlot for slot# %d\n",__FILE__,__FUNCTION__,__LINE__,i);
|
|
|
|
//safeMutexSlot.ReleaseLock();
|
|
|
|
//safeMutexSlot.ReleaseLock();
|
|
|
|
removeSlot(i,i);
|
|
|
|
removeSlot(i,i);
|
|
|
|
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #2 after removeSlot for slot# %d\n",__FILE__,__FUNCTION__,__LINE__,i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
safeMutexSlotBroadCastAccessor.Lock();
|
|
|
|
|
|
|
|
inBroadcastMessage = false;
|
|
|
|
|
|
|
|
safeMutexSlotBroadCastAccessor.ReleaseLock();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch(const exception &ex) {
|
|
|
|
catch(const exception &ex) {
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
|
|
|
|
//throw runtime_error(ex.what());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//DisplayErrorMessage(ex.what());
|
|
|
|
MutexSafeWrapper safeMutexSlotBroadCastAccessor(&inBroadcastMessageThreadAccessor,intToStr(__LINE__));
|
|
|
|
|
|
|
|
inBroadcastMessage = false;
|
|
|
|
|
|
|
|
safeMutexSlotBroadCastAccessor.ReleaseLock();
|
|
|
|
|
|
|
|
|
|
|
|
string sMsg = ex.what();
|
|
|
|
string sMsg = ex.what();
|
|
|
|
sendTextMessage(sMsg,-1, true, lockedSlotIndex);
|
|
|
|
sendTextMessage(sMsg,-1, true, lockedSlotIndex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
@@ -1365,8 +1256,6 @@ namespace Glest{ namespace Game{
|
|
|
|
|
|
|
|
|
|
|
|
if(i != excludeSlot && connectionSlot != NULL) {
|
|
|
|
if(i != excludeSlot && connectionSlot != NULL) {
|
|
|
|
if(connectionSlot->isConnected()) {
|
|
|
|
if(connectionSlot->isConnected()) {
|
|
|
|
|
|
|
|
|
|
|
|
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] before sendMessage\n",__FILE__,__FUNCTION__);
|
|
|
|
|
|
|
|
connectionSlot->sendMessage(networkMessage);
|
|
|
|
connectionSlot->sendMessage(networkMessage);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -1375,14 +1264,12 @@ namespace Glest{ namespace Game{
|
|
|
|
catch(const exception &ex) {
|
|
|
|
catch(const exception &ex) {
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR [%s]\n",__FILE__,__FUNCTION__,__LINE__,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;
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -1398,8 +1285,7 @@ namespace Glest{ namespace Game{
|
|
|
|
serverSocket.listen(openSlotCount);
|
|
|
|
serverSocket.listen(openSlotCount);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int ServerInterface::getOpenSlotCount()
|
|
|
|
int ServerInterface::getOpenSlotCount() {
|
|
|
|
{
|
|
|
|
|
|
|
|
int openSlotCount = 0;
|
|
|
|
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));
|
|
|
@@ -1412,21 +1298,17 @@ namespace Glest{ namespace Game{
|
|
|
|
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)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Waiting for client acks #1\n",__FILE__,__FUNCTION__);
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Waiting for client acks #1\n",__FILE__,__FUNCTION__);
|
|
|
|
|
|
|
|
|
|
|
|
time_t tStart = time(NULL);
|
|
|
|
time_t tStart = time(NULL);
|
|
|
|
bool gotAckFromAllClients = false;
|
|
|
|
bool gotAckFromAllClients = false;
|
|
|
|
while(gotAckFromAllClients == false && difftime(time(NULL),tStart) <= 5)
|
|
|
|
while(gotAckFromAllClients == false && difftime(time(NULL),tStart) <= 5) {
|
|
|
|
{
|
|
|
|
|
|
|
|
gotAckFromAllClients = true;
|
|
|
|
gotAckFromAllClients = true;
|
|
|
|
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));
|
|
|
@@ -1436,7 +1318,7 @@ namespace Glest{ namespace Game{
|
|
|
|
gotAckFromAllClients = false;
|
|
|
|
gotAckFromAllClients = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
connectionSlot->update();
|
|
|
|
connectionSlot->update(true,i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -1468,7 +1350,7 @@ namespace Glest{ namespace Game{
|
|
|
|
gotAckFromAllClients = false;
|
|
|
|
gotAckFromAllClients = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
connectionSlot->update();
|
|
|
|
connectionSlot->update(true,i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -1479,13 +1361,11 @@ namespace Glest{ namespace Game{
|
|
|
|
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()
|
|
|
|
void ServerInterface::close() {
|
|
|
|
{
|
|
|
|
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START\n",__FILE__,__FUNCTION__);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string ServerInterface::getHumanPlayerName(int index)
|
|
|
|
string ServerInterface::getHumanPlayerName(int index) {
|
|
|
|
{
|
|
|
|
|
|
|
|
string result = Config::getInstance().getString("NetPlayerName", Socket::getHostName().c_str());
|
|
|
|
string result = Config::getInstance().getString("NetPlayerName", Socket::getHostName().c_str());
|
|
|
|
if(index >= 0 || gameSettings.getThisFactionIndex() >= 0) {
|
|
|
|
if(index >= 0 || gameSettings.getThisFactionIndex() >= 0) {
|
|
|
|
if(index < 0) {
|
|
|
|
if(index < 0) {
|
|
|
@@ -1499,13 +1379,11 @@ namespace Glest{ namespace Game{
|
|
|
|
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;
|
|
|
|
int slotCountUsed = 1;
|
|
|
|
int slotCountHumans = 1;
|
|
|
|
int slotCountHumans = 1;
|
|
|
@@ -1544,19 +1422,15 @@ namespace Glest{ namespace Game{
|
|
|
|
return publishToServerInfo;
|
|
|
|
return publishToServerInfo;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ServerInterface::simpleTask(BaseThread *callingThread)
|
|
|
|
void ServerInterface::simpleTask(BaseThread *callingThread) {
|
|
|
|
{
|
|
|
|
|
|
|
|
MutexSafeWrapper safeMutex(&masterServerThreadAccessor,intToStr(__LINE__));
|
|
|
|
MutexSafeWrapper safeMutex(&masterServerThreadAccessor,intToStr(__LINE__));
|
|
|
|
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) {
|
|
|
|
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__);
|
|
|
|
|
|
|
|
|
|
|
|
lastMasterserverHeartbeatTime = time(NULL);
|
|
|
|
lastMasterserverHeartbeatTime = time(NULL);
|
|
|
|
|
|
|
|
|
|
|
|
if(needToRepublishToMasterserver == true) {
|
|
|
|
if(needToRepublishToMasterserver == true) {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
if(Config::getInstance().getString("Masterserver","") != "") {
|
|
|
|
if(Config::getInstance().getString("Masterserver","") != "") {
|
|
|
|
//string request = Config::getInstance().getString("Masterserver") + "addServerInfo.php?" + newPublishToServerInfo;
|
|
|
|
|
|
|
|
string request = Config::getInstance().getString("Masterserver") + "addServerInfo.php?";
|
|
|
|
string request = Config::getInstance().getString("Masterserver") + "addServerInfo.php?";
|
|
|
|
|
|
|
|
|
|
|
|
std::map<string,string> newPublishToServerInfo = publishToMasterserver();
|
|
|
|
std::map<string,string> newPublishToServerInfo = publishToMasterserver();
|
|
|
@@ -1579,12 +1453,6 @@ namespace Glest{ namespace Game{
|
|
|
|
|
|
|
|
|
|
|
|
//printf("the result is:\n'%s'\n",serverInfo.c_str());
|
|
|
|
//printf("the result is:\n'%s'\n",serverInfo.c_str());
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] the result is:\n'%s'\n",__FILE__,__FUNCTION__,__LINE__,serverInfo.c_str());
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] the result is:\n'%s'\n",__FILE__,__FUNCTION__,__LINE__,serverInfo.c_str());
|
|
|
|
|
|
|
|
|
|
|
|
// uncomment to enable router setup check of this server
|
|
|
|
|
|
|
|
if(EndsWith(serverInfo, "OK") == false) {
|
|
|
|
|
|
|
|
//showMasterserverError=true;
|
|
|
|
|
|
|
|
//masterServererErrorToShow = (serverInfo != "" ? serverInfo : "No Reply");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else {
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line %d] error, no masterserver defined!\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line %d] error, no masterserver defined!\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|