MegaGlest/source/glest_game/network/connection_slot.cpp
Mark Vejvoda b6dd5e266b - hardening the masterserver mode:
1.  missing maps, techs and tilesets should no longer crash the server and server will revert to last valid value for each (server must have the data)
2. clients now get truly unique session id's which fixes client admin mode when connecting to masterserver
2011-09-25 05:38:35 +00:00

960 lines
48 KiB
C++

// ==============================================================
// This file is part of Glest (www.glest.org)
//
// Copyright (C) 2001-2008 Martio Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#include "connection_slot.h"
#include <stdexcept>
#include "conversion.h"
#include "game_util.h"
#include "config.h"
#include "server_interface.h"
#include "network_message.h"
#include "leak_dumper.h"
#include "platform_util.h"
#include "map.h"
using namespace std;
using namespace Shared::Util;
namespace Glest{ namespace Game{
// =====================================================
// class ConnectionSlotThread
// =====================================================
ConnectionSlotThread::ConnectionSlotThread(int slotIndex) : BaseThread() {
this->slotIndex = slotIndex;
this->slotInterface = NULL;
//this->event = NULL;
eventList.clear();
eventList.reserve(100);
}
ConnectionSlotThread::ConnectionSlotThread(ConnectionSlotCallbackInterface *slotInterface,int slotIndex) : BaseThread() {
this->slotIndex = slotIndex;
this->slotInterface = slotInterface;
//this->event = NULL;
eventList.clear();
}
void ConnectionSlotThread::setQuitStatus(bool value) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d value = %d\n",__FILE__,__FUNCTION__,__LINE__,value);
BaseThread::setQuitStatus(value);
if(value == true) {
signalUpdate(NULL);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
}
void ConnectionSlotThread::signalUpdate(ConnectionSlotEvent *event) {
if(event != NULL) {
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId);
eventList.push_back(*event);
safeMutex.ReleaseLock();
}
semTaskSignalled.signal();
}
void ConnectionSlotThread::setTaskCompleted(int eventId) {
if(eventId > 0) {
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId);
//event->eventCompleted = true;
for(int i = 0; i < eventList.size(); ++i) {
ConnectionSlotEvent &slotEvent = eventList[i];
if(slotEvent.eventId == eventId) {
//eventList.erase(eventList.begin() + i);
slotEvent.eventCompleted = true;
break;
}
}
safeMutex.ReleaseLock();
}
}
void ConnectionSlotThread::purgeAllEvents() {
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId);
eventList.clear();
safeMutex.ReleaseLock();
}
void ConnectionSlotThread::setAllEventsCompleted() {
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId);
for(int i = 0; i < eventList.size(); ++i) {
ConnectionSlotEvent &slotEvent = eventList[i];
if(slotEvent.eventCompleted == false) {
slotEvent.eventCompleted = true;
}
}
safeMutex.ReleaseLock();
}
void ConnectionSlotThread::purgeCompletedEvents() {
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId);
//event->eventCompleted = true;
for(int i = eventList.size() - 1; i >= 0; i--) {
ConnectionSlotEvent &slotEvent = eventList[i];
if(slotEvent.eventCompleted == true) {
eventList.erase(eventList.begin() + i);
}
}
safeMutex.ReleaseLock();
}
bool ConnectionSlotThread::canShutdown(bool deleteSelfIfShutdownDelayed) {
bool ret = (getExecutingTask() == false);
if(ret == false && deleteSelfIfShutdownDelayed == true) {
setDeleteSelfOnExecutionDone(deleteSelfIfShutdownDelayed);
signalQuit();
}
return ret;
}
bool ConnectionSlotThread::isSignalCompleted(ConnectionSlotEvent *event) {
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId);
bool result = false;
if(event != NULL) {
for(int i = 0; i < eventList.size(); ++i) {
ConnectionSlotEvent &slotEvent = eventList[i];
if(slotEvent.eventId == event->eventId) {
result = slotEvent.eventCompleted;
break;
}
}
}
safeMutex.ReleaseLock();
return result;
}
void ConnectionSlotThread::execute() {
RunningStatusSafeWrapper runningStatus(this);
try {
//setRunningStatus(true);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//unsigned int idx = 0;
for(;this->slotInterface != NULL;) {
if(getQuitStatus() == true) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
break;
}
semTaskSignalled.waitTillSignalled();
if(getQuitStatus() == true) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
break;
}
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId);
int eventCount = eventList.size();
if(eventCount > 0) {
ConnectionSlotEvent eventCopy;
eventCopy.eventId = -1;
for(int i = 0; i < eventList.size(); ++i) {
ConnectionSlotEvent &slotEvent = eventList[i];
if(slotEvent.eventCompleted == false) {
eventCopy = slotEvent;
break;
}
}
safeMutex.ReleaseLock();
if(getQuitStatus() == true) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
break;
}
if(eventCopy.eventId > 0) {
ExecutingTaskSafeWrapper safeExecutingTaskMutex(this);
this->slotInterface->slotUpdateTask(&eventCopy);
setTaskCompleted(eventCopy.eventId);
}
}
else {
safeMutex.ReleaseLock();
}
if(getQuitStatus() == true) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
break;
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
catch(const exception &ex) {
//setRunningStatus(false);
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
throw runtime_error(ex.what());
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
}
// =====================================================
// class ConnectionSlot
// =====================================================
ConnectionSlot::ConnectionSlot(ServerInterface* serverInterface, int playerIndex) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
this->connectedRemoteIPAddress = 0;
this->sessionKey = 0;
this->serverInterface = serverInterface;
this->playerIndex = playerIndex;
this->playerStatus = 0;
this->playerLanguage = "";
this->currentFrameCount = 0;
this->currentLagCount = 0;
this->gotLagCountWarning = false;
this->lastReceiveCommandListTime = 0;
this->receivedNetworkGameStatus = false;
this->socket = NULL;
this->slotThreadWorker = NULL;
this->slotThreadWorker = new ConnectionSlotThread(this->serverInterface,playerIndex);
this->slotThreadWorker->setUniqueID(__FILE__);
this->slotThreadWorker->start();
this->ready = false;
this->gotIntro = false;
this->connectedTime = 0;
networkGameDataSynchCheckOkMap = false;
networkGameDataSynchCheckOkTile = false;
networkGameDataSynchCheckOkTech = false;
this->setNetworkGameDataSynchCheckTechMismatchReport("");
this->setReceivedDataSynchCheck(false);
this->clearChatInfo();
}
ConnectionSlot::~ConnectionSlot() {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] START\n",__FILE__,__FUNCTION__,__LINE__);
close();
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(BaseThread::shutdownAndWait(slotThreadWorker) == true) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
delete slotThreadWorker;
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
slotThreadWorker = NULL;
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",__FILE__,__FUNCTION__);
}
void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) {
//Chrono chrono;
//chrono.start();
try {
clearThreadErrorList();
if(slotThreadWorker != NULL) {
slotThreadWorker->purgeCompletedEvents();
}
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
if(socket == NULL) {
if(networkGameDataSynchCheckOkMap) networkGameDataSynchCheckOkMap = false;
if(networkGameDataSynchCheckOkTile) networkGameDataSynchCheckOkTile = false;
if(networkGameDataSynchCheckOkTech) networkGameDataSynchCheckOkTech = false;
this->setReceivedDataSynchCheck(false);
// Is the listener socket ready to be read?
if(checkForNewClients == true) {
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] BEFORE accept new client connection, serverInterface->getOpenSlotCount() = %d\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getOpenSlotCount());
bool hasOpenSlots = (serverInterface->getOpenSlotCount() > 0);
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
bool hasData = (serverInterface->getServerSocket() != NULL && serverInterface->getServerSocket()->hasDataToRead() == true);
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
if(hasData == true) {
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] about to accept new client connection playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex);
Socket *newSocket = serverInterface->getServerSocket()->accept();
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] called accept new client connection playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex);
if(newSocket != NULL) {
// Set Socket as non-blocking
newSocket->setBlock(false);
socket = newSocket;
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
this->connectedTime = time(NULL);
this->clearChatInfo();
this->name = "";
this->playerStatus = npst_PickSettings;
this->playerLanguage = "";
this->ready = false;
this->vctFileList.clear();
this->receivedNetworkGameStatus = false;
this->gotIntro = false;
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutexSlot(&mutexPendingNetworkCommandList,mutexOwnerId);
this->vctPendingNetworkCommandList.clear();
safeMutexSlot.ReleaseLock();
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
this->currentFrameCount = 0;
this->currentLagCount = 0;
this->lastReceiveCommandListTime = 0;
this->gotLagCountWarning = false;
this->versionString = "";
//if(this->slotThreadWorker == NULL) {
// this->slotThreadWorker = new ConnectionSlotThread(this->serverInterface,playerIndex);
// this->slotThreadWorker->setUniqueID(__FILE__);
// this->slotThreadWorker->start();
//}
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
serverInterface->updateListen();
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex);
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
}
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
}
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
//send intro message when connected
if(socket != NULL) {
//RandomGen random;
//sessionKey = random.randRange(-100000, 100000);
srand(time(NULL));
sessionKey = rand() % 1000000;
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] accepted new client connection, serverInterface->getOpenSlotCount() = %d, sessionKey = %d\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getOpenSlotCount(),sessionKey);
if(hasOpenSlots == false) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] !!!!!!!!WARNING - no open slots, disconnecting client\n",__FILE__,__FUNCTION__,__LINE__);
if(socket != NULL) {
NetworkMessageIntro networkMessageIntro(sessionKey,getNetworkVersionSVNString(), getHostName(), playerIndex, nmgstNoSlots, 0, ServerSocket::getFTPServerPort(),"");
sendMessage(&networkMessageIntro);
}
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
close();
}
else {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] client will be assigned to the next open slot\n",__FILE__,__FUNCTION__,__LINE__);
if(socket != NULL) {
NetworkMessageIntro networkMessageIntro(sessionKey,getNetworkVersionSVNString(), getHostName(), playerIndex, nmgstOk, 0, ServerSocket::getFTPServerPort(),"");
sendMessage(&networkMessageIntro);
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
}
}
}
}
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
}
else {
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(socket != NULL && socket->isConnected()) {
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
this->clearChatInfo();
bool gotTextMsg = true;
for(;socket != NULL && socket->hasDataToRead() == true && gotTextMsg == true;) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] polling for networkMessageType...\n",__FILE__,__FUNCTION__,__LINE__);
NetworkMessageType networkMessageType= getNextMessageType(true);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] networkMessageType = %d\n",__FILE__,__FUNCTION__,__LINE__,networkMessageType);
gotTextMsg = false;
//process incoming commands
switch(networkMessageType) {
case nmtInvalid:
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got nmtInvalid\n",__FILE__,__FUNCTION__,__LINE__);
break;
case nmtPing:
{
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtPing\n",__FILE__,__FUNCTION__);
// client REQUIRES a ping before completing intro
// authentication
//if(gotIntro == true) {
NetworkMessagePing networkMessagePing;
if(receiveMessage(&networkMessagePing)) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
lastPingInfo = networkMessagePing;
}
//}
}
break;
case nmtText:
{
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got nmtText gotIntro = %d\n",__FILE__,__FUNCTION__,__LINE__,gotIntro);
if(gotIntro == true) {
NetworkMessageText networkMessageText;
if(receiveMessage(&networkMessageText)) {
ChatMsgInfo msg(networkMessageText.getText().c_str(),networkMessageText.getTeamIndex(),networkMessageText.getPlayerIndex(),networkMessageText.getTargetLanguage());
this->addChatInfo(msg);
gotTextMsg = true;
}
}
}
break;
//command list
case nmtCommandList: {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got nmtCommandList gotIntro = %d\n",__FILE__,__FUNCTION__,__LINE__,gotIntro);
//throw runtime_error("test");
if(gotIntro == true) {
NetworkMessageCommandList networkMessageCommandList;
if(receiveMessage(&networkMessageCommandList)) {
currentFrameCount = networkMessageCommandList.getFrameCount();
lastReceiveCommandListTime = time(NULL);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] currentFrameCount = %d\n",__FILE__,__FUNCTION__,__LINE__,currentFrameCount);
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutexSlot(&mutexPendingNetworkCommandList,mutexOwnerId);
for(int i = 0; i < networkMessageCommandList.getCommandCount(); ++i) {
vctPendingNetworkCommandList.push_back(*networkMessageCommandList.getCommand(i));
}
safeMutexSlot.ReleaseLock();
}
}
}
break;
//process intro messages
case nmtIntro:
{
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtIntro\n",__FILE__,__FUNCTION__);
NetworkMessageIntro networkMessageIntro;
if(receiveMessage(&networkMessageIntro)) {
int msgSessionId = networkMessageIntro.getSessionId();
this->name= networkMessageIntro.getName();
this->versionString = networkMessageIntro.getVersionString();
this->connectedRemoteIPAddress = networkMessageIntro.getExternalIp();
this->playerLanguage = networkMessageIntro.getPlayerLanguage();
//printf("\n\n\n ##### GOT this->playerLanguage [%s]\n\n\n",this->playerLanguage.c_str());
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got name [%s] versionString [%s], msgSessionId = %d\n",__FILE__,__FUNCTION__,name.c_str(),versionString.c_str(),msgSessionId);
if(msgSessionId != sessionKey) {
string playerNameStr = name;
string sErr = "Client gave invalid sessionid for player [" + playerNameStr + "]";
printf("%s\n",sErr.c_str());
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,sErr.c_str());
close();
return;
}
//check consistency
bool compatible = checkVersionComptability(getNetworkVersionSVNString(), networkMessageIntro.getVersionString());
if(compatible == false) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
bool versionMatched = false;
string platformFreeVersion = getNetworkPlatformFreeVersionString();
string sErr = "";
if(strncmp(platformFreeVersion.c_str(),networkMessageIntro.getVersionString().c_str(),strlen(platformFreeVersion.c_str())) != 0) {
string playerNameStr = name;
sErr = "Server and client binary mismatch!\nYou have to use the exactly same binaries!\n\nServer: " + getNetworkVersionSVNString() +
"\nClient: " + networkMessageIntro.getVersionString() + " player [" + playerNameStr + "]";
printf("%s\n",sErr.c_str());
serverInterface->sendTextMessage("Server and client binary mismatch!!",-1, true,"",lockedSlotIndex);
serverInterface->sendTextMessage(" Server:" + getNetworkVersionSVNString(),-1, true,"",lockedSlotIndex);
serverInterface->sendTextMessage(" Client: "+ networkMessageIntro.getVersionString(),-1, true,"",lockedSlotIndex);
serverInterface->sendTextMessage(" Client player [" + playerNameStr + "]",-1, true,"",lockedSlotIndex);
}
else {
versionMatched = true;
string playerNameStr = name;
sErr = "Warning, Server and client are using the same version but different platforms.\n\nServer: " + getNetworkVersionSVNString() +
"\nClient: " + networkMessageIntro.getVersionString() + " player [" + playerNameStr + "]";
//printf("%s\n",sErr.c_str());
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,sErr.c_str());
}
if(Config::getInstance().getBool("PlatformConsistencyChecks","true") &&
versionMatched == false) { // error message and disconnect only if checked
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,sErr.c_str());
close();
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,sErr.c_str());
return;
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
gotIntro = true;
this->serverInterface->addClientToServerIPAddress(this->getSocket()->getConnectedIPAddress(this->getSocket()->getIpAddress()),this->connectedRemoteIPAddress);
if(getAllowGameDataSynchCheck() == true && serverInterface->getGameSettings() != NULL) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] sending NetworkMessageSynchNetworkGameData\n",__FILE__,__FUNCTION__,__LINE__);
NetworkMessageSynchNetworkGameData networkMessageSynchNetworkGameData(serverInterface->getGameSettings());
sendMessage(&networkMessageSynchNetworkGameData);
}
}
}
break;
case nmtLaunch:
case nmtBroadCastSetup:
{
if(this->serverInterface->getGameSettings() == NULL ||
sessionKey != this->serverInterface->getGameSettings()->getMasterserver_admin()) {
string playerNameStr = name;
string sErr = "Client has invalid admin sessionid for player [" + playerNameStr + "]";
printf("%s\n",sErr.c_str());
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,sErr.c_str());
close();
return;
}
NetworkMessageLaunch networkMessageLaunch;
if(receiveMessage(&networkMessageLaunch)) {
if(networkMessageLaunch.getMessageType() == nmtLaunch) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got nmtLaunch\n",__FILE__,__FUNCTION__,__LINE__);
}
else if(networkMessageLaunch.getMessageType() == nmtBroadCastSetup) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got nmtBroadCastSetup\n",__FILE__,__FUNCTION__,__LINE__);
}
else {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got networkMessageLaunch.getMessageType() = %d\n",__FILE__,__FUNCTION__,__LINE__,networkMessageLaunch.getMessageType());
char szBuf[1024]="";
snprintf(szBuf,1023,"In [%s::%s Line: %d] Invalid networkMessageLaunch.getMessageType() = %d",__FILE__,__FUNCTION__,__LINE__,networkMessageLaunch.getMessageType());
throw runtime_error(szBuf);
}
GameSettings gameSettings;
networkMessageLaunch.buildGameSettings(&gameSettings);
//printf("Connection slot got networkMessageLaunch.getMessageType() = %d, got map [%s]\n",networkMessageLaunch.getMessageType(),gameSettings.getMap().c_str());
this->serverInterface->setGameSettings(&gameSettings,false);
this->serverInterface->broadcastGameSetup(&gameSettings);
if(networkMessageLaunch.getMessageType() == nmtLaunch) {
this->serverInterface->setMasterserverAdminRequestLaunch(true);
}
}
}
break;
//process datasynch messages
case nmtSynchNetworkGameDataStatus:
{
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got nmtSynchNetworkGameDataStatus, gotIntro = %d\n",__FILE__,__FUNCTION__,__LINE__,gotIntro);
if(gotIntro == true) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
NetworkMessageSynchNetworkGameDataStatus networkMessageSynchNetworkGameDataStatus;
if(receiveMessage(&networkMessageSynchNetworkGameDataStatus)) {
this->setNetworkGameDataSynchCheckTechMismatchReport("");
this->setReceivedDataSynchCheck(false);
Config &config = Config::getInstance();
string scenarioDir = "";
if(serverInterface->getGameSettings()->getScenarioDir() != "") {
scenarioDir = serverInterface->getGameSettings()->getScenarioDir();
if(EndsWith(scenarioDir, ".xml") == true) {
scenarioDir = scenarioDir.erase(scenarioDir.size() - 4, 4);
scenarioDir = scenarioDir.erase(scenarioDir.size() - serverInterface->getGameSettings()->getScenario().size(), serverInterface->getGameSettings()->getScenario().size() + 1);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] gameSettings.getScenarioDir() = [%s] gameSettings.getScenario() = [%s] scenarioDir = [%s]\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getGameSettings()->getScenarioDir().c_str(),serverInterface->getGameSettings()->getScenario().c_str(),scenarioDir.c_str());
}
//tileset
int32 tilesetCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets,scenarioDir), string("/") + serverInterface->getGameSettings()->getTileset() + string("/*"), ".xml", NULL);
int32 techCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,scenarioDir), "/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", NULL);
Checksum checksum;
string file = Map::getMapPath(serverInterface->getGameSettings()->getMap(),scenarioDir,false);
checksum.addFile(file);
int32 mapCRC = checksum.getSum();
networkGameDataSynchCheckOkMap = (networkMessageSynchNetworkGameDataStatus.getMapCRC() == mapCRC);
networkGameDataSynchCheckOkTile = (networkMessageSynchNetworkGameDataStatus.getTilesetCRC() == tilesetCRC);
networkGameDataSynchCheckOkTech = (networkMessageSynchNetworkGameDataStatus.getTechCRC() == techCRC);
// For testing
//techCRC++;
if( networkGameDataSynchCheckOkMap == true &&
networkGameDataSynchCheckOkTile == true &&
networkGameDataSynchCheckOkTech == true) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] client data synch ok\n",__FILE__,__FUNCTION__);
}
else {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] mapCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,mapCRC,networkMessageSynchNetworkGameDataStatus.getMapCRC());
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] tilesetCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,tilesetCRC,networkMessageSynchNetworkGameDataStatus.getTilesetCRC());
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] techCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,techCRC,networkMessageSynchNetworkGameDataStatus.getTechCRC());
if(allowDownloadDataSynch == true) {
// Now get all filenames with their CRC values and send to the client
vctFileList.clear();
Config &config = Config::getInstance();
string scenarioDir = "";
if(serverInterface->getGameSettings()->getScenarioDir() != "") {
scenarioDir = serverInterface->getGameSettings()->getScenarioDir();
if(EndsWith(scenarioDir, ".xml") == true) {
scenarioDir = scenarioDir.erase(scenarioDir.size() - 4, 4);
scenarioDir = scenarioDir.erase(scenarioDir.size() - serverInterface->getGameSettings()->getScenario().size(), serverInterface->getGameSettings()->getScenario().size() + 1);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] gameSettings.getScenarioDir() = [%s] gameSettings.getScenario() = [%s] scenarioDir = [%s]\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getGameSettings()->getScenarioDir().c_str(),serverInterface->getGameSettings()->getScenario().c_str(),scenarioDir.c_str());
}
if(networkGameDataSynchCheckOkTile == false) {
if(tilesetCRC == 0) {
vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTilesets,scenarioDir), string("/") + serverInterface->getGameSettings()->getTileset() + string("/*"), "", &vctFileList);
}
else {
vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTilesets,scenarioDir), "/" + serverInterface->getGameSettings()->getTileset() + "/*", ".xml", &vctFileList);
}
}
if(networkGameDataSynchCheckOkTech == false) {
if(techCRC == 0) {
vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs,scenarioDir),"/" + serverInterface->getGameSettings()->getTech() + "/*", "", &vctFileList);
}
else {
vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs,scenarioDir),"/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", &vctFileList);
}
string report = networkMessageSynchNetworkGameDataStatus.getTechCRCFileMismatchReport(serverInterface->getGameSettings()->getTech(),vctFileList);
this->setNetworkGameDataSynchCheckTechMismatchReport(report);
}
if(networkGameDataSynchCheckOkMap == false) {
vctFileList.push_back(std::pair<string,int32>(Map::getMapPath(serverInterface->getGameSettings()->getMap(),scenarioDir,false),mapCRC));
}
//for(int i = 0; i < vctFileList.size(); i++)
//{
NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck(vctFileList.size(), 1, vctFileList[0].second, vctFileList[0].first);
sendMessage(&networkMessageSynchNetworkGameDataFileCRCCheck);
//}
}
else {
if(networkGameDataSynchCheckOkTech == false) {
vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs,scenarioDir),"/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", NULL);
string report = networkMessageSynchNetworkGameDataStatus.getTechCRCFileMismatchReport(serverInterface->getGameSettings()->getTech(),vctFileList);
this->setNetworkGameDataSynchCheckTechMismatchReport(report);
}
}
}
this->setReceivedDataSynchCheck(true);
receivedNetworkGameStatus = true;
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
}
}
break;
case nmtSynchNetworkGameDataFileCRCCheck:
{
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtSynchNetworkGameDataFileCRCCheck\n",__FILE__,__FUNCTION__);
if(gotIntro == true) {
NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck;
if(receiveMessage(&networkMessageSynchNetworkGameDataFileCRCCheck))
{
int fileIndex = networkMessageSynchNetworkGameDataFileCRCCheck.getFileIndex();
NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck(vctFileList.size(), fileIndex, vctFileList[fileIndex-1].second, vctFileList[fileIndex-1].first);
sendMessage(&networkMessageSynchNetworkGameDataFileCRCCheck);
}
}
}
break;
case nmtSynchNetworkGameDataFileGet:
{
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtSynchNetworkGameDataFileGet\n",__FILE__,__FUNCTION__);
if(gotIntro == true) {
NetworkMessageSynchNetworkGameDataFileGet networkMessageSynchNetworkGameDataFileGet;
if(receiveMessage(&networkMessageSynchNetworkGameDataFileGet)) {
FileTransferInfo fileInfo;
fileInfo.hostType = eServer;
//fileInfo.serverIP = this->ip.getString();
fileInfo.serverPort = Config::getInstance().getInt("ServerPort",intToStr(GameConstants::serverPort).c_str());
fileInfo.fileName = networkMessageSynchNetworkGameDataFileGet.getFileName();
FileTransferSocketThread *fileXferThread = new FileTransferSocketThread(fileInfo);
fileXferThread->start();
}
}
}
break;
case nmtSwitchSetupRequest:
{
//printf("Got nmtSwitchSetupRequest A\n");
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got nmtSwitchSetupRequest gotIntro = %d\n",__FILE__,__FUNCTION__,__LINE__,gotIntro);
if(gotIntro == true) {
//printf("Got nmtSwitchSetupRequest B\n");
SwitchSetupRequest switchSetupRequest;
if(receiveMessage(&switchSetupRequest)) {
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutex(getServerSynchAccessor(),mutexOwnerId);
int factionIdx = switchSetupRequest.getCurrentFactionIndex();
if(serverInterface->getSwitchSetupRequests()[factionIdx] == NULL) {
serverInterface->getSwitchSetupRequests()[factionIdx]= new SwitchSetupRequest();
}
*(serverInterface->getSwitchSetupRequests()[factionIdx]) = switchSetupRequest;
this->playerStatus = switchSetupRequest.getNetworkPlayerStatus();
this->name = switchSetupRequest.getNetworkPlayerName();
this->playerLanguage = switchSetupRequest.getNetworkPlayerLanguage();
//printf("Got nmtSwitchSetupRequest C\n");
//printf("In [%s::%s Line %d] networkPlayerName [%s]\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getSwitchSetupRequests()[factionIdx]->getNetworkPlayerName().c_str());
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] networkPlayerName [%s]\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getSwitchSetupRequests()[factionIdx]->getNetworkPlayerName().c_str());
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] factionIdx = %d, switchSetupRequest.getNetworkPlayerName() [%s] switchSetupRequest.getNetworkPlayerStatus() = %d, switchSetupRequest.getSwitchFlags() = %d\n",__FILE__,__FUNCTION__,__LINE__,factionIdx,switchSetupRequest.getNetworkPlayerName().c_str(),switchSetupRequest.getNetworkPlayerStatus(),switchSetupRequest.getSwitchFlags());
}
}
break;
}
case nmtReady:
{
// its simply ignored here. Probably we are starting a game
break;
}
case nmtLoadingStatusMessage:
break;
default:
{
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] networkMessageType = %d\n",__FILE__,__FUNCTION__,__LINE__,networkMessageType);
if(gotIntro == true) {
//throw runtime_error("Unexpected message in connection slot: " + intToStr(networkMessageType));
string sErr = "Unexpected message in connection slot: " + intToStr(networkMessageType);
//sendTextMessage(sErr,-1);
//DisplayErrorMessage(sErr);
threadErrorList.push_back(sErr);
return;
}
else {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got invalid message type before intro, disconnecting socket.\n",__FILE__,__FUNCTION__,__LINE__);
close();
}
}
}
}
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
validateConnection();
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
}
else {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] calling close...\n",__FILE__,__FUNCTION__,__LINE__);
close();
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
}
catch(const exception &ex) {
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
threadErrorList.push_back(ex.what());
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
}
//if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis());
}
void ConnectionSlot::validateConnection() {
if(gotIntro == false && connectedTime > 0 &&
difftime(time(NULL),connectedTime) > GameConstants::maxClientConnectHandshakeSecs) {
close();
}
}
void ConnectionSlot::close() {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s LINE: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(this->slotThreadWorker != NULL) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
this->slotThreadWorker->setAllEventsCompleted();
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutex(&mutexCloseConnection,mutexOwnerId);
bool updateServerListener = (socket != NULL);
delete socket;
socket= NULL;
safeMutex.ReleaseLock();
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s LINE: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(updateServerListener == true && ready == false) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s LINE: %d]\n",__FILE__,__FUNCTION__,__LINE__);
serverInterface->updateListen();
}
ready = false;
gotIntro = false;
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",__FILE__,__FUNCTION__);
}
bool ConnectionSlot::hasValidSocketId() {
bool result = (socket != NULL && socket->getSocketId() > 0);
return result;
}
Mutex * ConnectionSlot::getServerSynchAccessor() {
return (serverInterface != NULL ? serverInterface->getServerSynchAccessor() : NULL);
}
void ConnectionSlot::signalUpdate(ConnectionSlotEvent *event) {
//assert(slotThreadWorker != NULL);
if(slotThreadWorker != NULL) {
slotThreadWorker->signalUpdate(event);
}
}
bool ConnectionSlot::updateCompleted(ConnectionSlotEvent *event) {
bool waitingForThread = (slotThreadWorker != NULL &&
slotThreadWorker->isSignalCompleted(event) == false &&
slotThreadWorker->getQuitStatus() == false &&
slotThreadWorker->getRunningStatus() == true);
return (waitingForThread == false);
}
void ConnectionSlot::sendMessage(const NetworkMessage* networkMessage) {
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutex(&socketSynchAccessor,mutexOwnerId);
// Skip text messages not intended for the players preferred language
const NetworkMessageText *textMsg = dynamic_cast<const NetworkMessageText *>(networkMessage);
if(textMsg != NULL) {
//printf("\n\n\n~~~ SERVER HAS NetworkMessageText target [%s] player [%s] msg[%s]\n\n\n",textMsg->getTargetLanguage().c_str(),this->getNetworkPlayerLanguage().c_str(), textMsg->getText().c_str());
if(textMsg->getTargetLanguage() != "" &&
textMsg->getTargetLanguage() != this->getNetworkPlayerLanguage()) {
return;
}
}
NetworkInterface::sendMessage(networkMessage);
}
string ConnectionSlot::getHumanPlayerName(int index) {
return serverInterface->getHumanPlayerName(index);
}
vector<NetworkCommand> ConnectionSlot::getPendingNetworkCommandList(bool clearList) {
vector<NetworkCommand> ret;
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutexSlot(&mutexPendingNetworkCommandList,mutexOwnerId);
if(vctPendingNetworkCommandList.empty() == false) {
ret = vctPendingNetworkCommandList;
if(clearList == true) {
vctPendingNetworkCommandList.clear();
}
}
safeMutexSlot.ReleaseLock();
return ret;
}
void ConnectionSlot::clearPendingNetworkCommandList() {
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutexSlot(&mutexPendingNetworkCommandList,mutexOwnerId);
if(vctPendingNetworkCommandList.empty() == false) {
vctPendingNetworkCommandList.clear();
}
safeMutexSlot.ReleaseLock();
}
}}//end namespace