diff --git a/source/glest_game/facilities/components.cpp b/source/glest_game/facilities/components.cpp index 5290dd716..2fc6c6634 100644 --- a/source/glest_game/facilities/components.cpp +++ b/source/glest_game/facilities/components.cpp @@ -450,8 +450,8 @@ bool GraphicListBox::mouseClick(int x, int y){ const int GraphicMessageBox::defH= 240; const int GraphicMessageBox::defW= 350; -void GraphicMessageBox::init(const string &button1Str, const string &button2Str) { - init(button1Str); +void GraphicMessageBox::init(const string &button1Str, const string &button2Str, int newWidth,int newHeight) { + init(button1Str,newWidth,newHeight); button1.init(x+(w-GraphicButton::defW)/4, y+25); button1.setText(button1Str); @@ -474,12 +474,12 @@ void GraphicMessageBox::setY(int y) { button2.init(x+3*(w-GraphicButton::defW)/4, y+25); } -void GraphicMessageBox::init(const string &button1Str) { +void GraphicMessageBox::init(const string &button1Str, int newWidth,int newHeight) { font= CoreData::getInstance().getMenuFontNormal(); font3D= CoreData::getInstance().getMenuFontNormal3D(); - h= defH; - w= defW; + h= (newHeight >= 0 ? newHeight : defH); + w= (newWidth >= 0 ? newWidth : defW); const Metrics &metrics= Metrics::getInstance(); diff --git a/source/glest_game/facilities/components.h b/source/glest_game/facilities/components.h index b9a996bc9..a02b1260e 100644 --- a/source/glest_game/facilities/components.h +++ b/source/glest_game/facilities/components.h @@ -243,8 +243,8 @@ private: string header; public: - void init(const string &button1Str, const string &button2Str); - void init(const string &button1Str); + void init(const string &button1Str, const string &button2Str, int newWidth=-1,int newHeight=-1); + void init(const string &button1Str, int newWidth=-1,int newHeight=-1); int getButtonCount() const {return buttonCount;} GraphicButton *getButton1() {return &button1;} diff --git a/source/glest_game/facilities/game_util.cpp b/source/glest_game/facilities/game_util.cpp index 5521c83bf..8de2f821e 100644 --- a/source/glest_game/facilities/game_util.cpp +++ b/source/glest_game/facilities/game_util.cpp @@ -42,7 +42,8 @@ string getCrashDumpFileName(){ } string getPlatformNameString() { - string platform = ""; + static string platform = ""; + if(platform == "") { #if defined(WIN32) platform = "Windows"; #if defined(__MINGW32__) @@ -66,7 +67,7 @@ string getPlatformNameString() { #if defined(_M_X64) || defined(_M_IA64) || defined(_M_AMD64) || defined(__x86_64__) || defined(_WIN64) platform += "_64bit"; #endif - + } return platform; } @@ -75,7 +76,8 @@ string getSVNRevisionString() { } string getCompilerNameString() { - string version = ""; + static string version = ""; + if(version == "") { #if defined(WIN32) && defined(_MSC_VER) version = "VC++: " + intToStr(_MSC_VER); @@ -109,22 +111,32 @@ version += " [DEBUG]"; #if defined(_M_X64) || defined(_M_IA64) || defined(_M_AMD64) || defined(__x86_64__) || defined(_WIN64) version += " [64bit]"; #endif - + } return version; } string getNetworkVersionString() { - string version = glestVersionString+"-"+getCompilerNameString()+"-"+getCompileDateTime(); + static string version = ""; + if(version == "") { + version = glestVersionString+"-"+getCompilerNameString()+"-"+getCompileDateTime(); + } return version; } string getNetworkVersionSVNString() { - string version = glestVersionString + "-" + getCompilerNameString() + "-" + getSVNRevisionString(); + static string version = ""; + if(version == "") { + version = glestVersionString + "-" + getCompilerNameString() + "-" + getSVNRevisionString(); + } return version; } string getCompileDateTime() { - return string(__DATE__) + " " + string(__TIME__); + static string result = ""; + if(result == "") { + result = string(__DATE__) + " " + string(__TIME__); + } + return result; } string getNetworkPlatformFreeVersionString() { @@ -132,7 +144,7 @@ string getNetworkPlatformFreeVersionString() { } string getAboutString1(int i) { - switch(i){ + switch(i) { case 0: return "MegaGlest " + glestVersionString + " (" + "Shared Library " + sharedLibVersionString + ")"; case 1: return "Built: " + string(__DATE__) + " " + SVN_Rev; case 2: return "Copyright 2001-2011 The MegaGlest Team"; @@ -140,8 +152,8 @@ string getAboutString1(int i) { return ""; } -string getAboutString2(int i){ - switch(i){ +string getAboutString2(int i) { + switch(i) { case 0: return "Web: http://www.megaglest.org http://glest.org"; case 1: return "Bug reports: " + string(mailString); case 2: return "Irc: irc://irc.freenode.net/glest"; @@ -186,7 +198,7 @@ string getTeammateRole(int i) { return ""; } -string formatString(const string &str){ +string formatString(string str) { string outStr = str; if(!outStr.empty()){ @@ -260,4 +272,15 @@ string getGameReadWritePath(string lookupKey) { return path; } +void initSpecialStrings() { + getCrashDumpFileName(); + getPlatformNameString(); + getSVNRevisionString(); + getCompilerNameString(); + getNetworkVersionString(); + getNetworkVersionSVNString(); + getNetworkPlatformFreeVersionString(); + getCompileDateTime(); +} + }}//end namespace diff --git a/source/glest_game/facilities/game_util.h b/source/glest_game/facilities/game_util.h index d79196e13..c78787ab7 100644 --- a/source/glest_game/facilities/game_util.h +++ b/source/glest_game/facilities/game_util.h @@ -27,6 +27,7 @@ extern const char *mailString; extern const string glestVersionString; extern const string networkVersionString; +void initSpecialStrings(); string getCrashDumpFileName(); string getPlatformNameString(); string getSVNRevisionString(); @@ -40,7 +41,7 @@ string getTeammateName(int i); string getTeammateRole(int i); string getCompileDateTime(); -string formatString(const string &str); +string formatString(string str); string getGameReadWritePath(string lookupKey=""); string getGameCustomCoreDataPath(string originalBasePath, string uniqueFilePath); diff --git a/source/glest_game/game/game_settings.h b/source/glest_game/game/game_settings.h index d283f714a..9777ef879 100644 --- a/source/glest_game/game/game_settings.h +++ b/source/glest_game/game/game_settings.h @@ -97,11 +97,12 @@ public: networkPauseGameForLaggedClients = false; pathFinderType = pfBasic; + static const string DEFAULT_LANG = "english"; for(int i = 0; i < GameConstants::maxPlayers; ++i) { factionTypeNames[i] = ""; networkPlayerNames[i] = ""; networkPlayerStatuses[i] = 0; - networkPlayerLanguages[i] = "english"; + networkPlayerLanguages[i] = DEFAULT_LANG; factionControls[i] = ctClosed; resourceMultiplierIndex[i] = 1.0f; teams[i] = 0; diff --git a/source/glest_game/graphics/renderer.cpp b/source/glest_game/graphics/renderer.cpp index 7770f3070..ff2e5ca15 100644 --- a/source/glest_game/graphics/renderer.cpp +++ b/source/glest_game/graphics/renderer.cpp @@ -876,8 +876,55 @@ enum PROJECTION_TO_INFINITY { D_IS_ZERO, N_OVER_D_IS_OUTSIDE }; static Vec2i _unprojectMap(const Vec2i& pt,const GLdouble* model,const GLdouble* projection,const GLint* viewport,const char* label=NULL) { Vec3d a,b; - gluUnProject(pt.x,viewport[3]-pt.y,0,model,projection,viewport,&a.x,&a.y,&a.z); - gluUnProject(pt.x,viewport[3]-pt.y,1,model,projection,viewport,&b.x,&b.y,&b.z); + /* note viewport[3] is height of window in pixels */ + GLint realy = viewport[3] - (GLint) pt.y; + gluUnProject(pt.x,realy,0,model,projection,viewport,&a.x,&a.y,&a.z); + gluUnProject(pt.x,realy,1,model,projection,viewport,&b.x,&b.y,&b.z); + +/* + //We could use some vector3d class, but this will do fine for now + //ray + b.x -= a.x; + b.y -= a.y; + b.z -= a.z; + float rayLength = streflop::sqrtf(a.x*a.x + a.y*a.y + a.z*a.z); + //normalize + b.x /= rayLength; + b.y /= rayLength; + b.z /= rayLength; + + //T = [planeNormal.(pointOnPlane - rayOrigin)]/planeNormal.rayDirection; + //pointInPlane = rayOrigin + (rayDirection * T); + + float dot1, dot2; + + float pointInPlaneX = 0; + float pointInPlaneY = 0; + float pointInPlaneZ = 0; + float planeNormalX = 0; + float planeNormalY = 0; + float planeNormalZ = -1; + + pointInPlaneX -= a.x; + pointInPlaneY -= a.y; + pointInPlaneZ -= a.z; + + dot1 = (planeNormalX * pointInPlaneX) + (planeNormalY * pointInPlaneY) + (planeNormalZ * pointInPlaneZ); + dot2 = (planeNormalX * b.x) + (planeNormalY * b.y) + (planeNormalZ * b.z); + + float t = dot1/dot2; + + b.x *= t; + b.y *= t; + //b.z *= t; + //we don't need the z coordinate in my case + + //return Vec2i(b.x + a.x, b.z + a.z); + return Vec2i(b.x + a.x, b.z + a.z); +*/ + + + // junk values if you were looking parallel to the XZ plane; this shouldn't happen as the camera can't do this? const Vec3f start(a.x,a.y,a.z), @@ -941,6 +988,7 @@ static Vec2i _unprojectMap(const Vec2i& pt,const GLdouble* model,const GLdouble* pos.x,pos.y); } return pos; + } //Matrix4 LookAt( Vector3 eye, Vector3 target, Vector3 up ) { @@ -975,6 +1023,16 @@ void Renderer::computeVisibleQuad() { //Matrix4 LookAt( gameCamera->getPos(), gameCamera->getPos(), Vector3 up ); //gluLookAt + //const Metrics &metrics= Metrics::getInstance(); + //float Hnear = 2.0 * streflop::tanf(gameCamera->getFov() / 2.0) * perspNearPlane; + //float Hnear = 2.0 * streflop::tanf(perspFov / 2.0) * perspNearPlane; + //float Wnear = Hnear * metrics.getAspectRatio(); + //The same reasoning can be applied to the far plane: + //float Hfar = 2.0 * streflop::tanf(perspFov / 2.0) * perspFarPlane; + //float Hfar = 2.0 * streflop::tanf(gameCamera->getFov() / 2.0) * perspFarPlane; + //float Wfar = Hfar * metrics.getAspectRatio(); + //printf("Hnear = %f, Wnear = %f, Hfar = %f, Wfar = %f\n",Hnear,Wnear,Hfar,Wfar); + const bool newVisibleQuadCalc = false; if(newVisibleQuadCalc) { const bool debug = false; @@ -987,6 +1045,8 @@ void Renderer::computeVisibleQuad() { visibleQuad.p[2].x,visibleQuad.p[2].y, visibleQuad.p[3].x,visibleQuad.p[3].y); } + + // compute the four corners using OpenGL GLdouble model[16], projection[16]; GLint viewport[4]; @@ -998,6 +1058,8 @@ void Renderer::computeVisibleQuad() { tr = _unprojectMap(Vec2i(viewport[2],0),model,projection,viewport,"tr"), br = _unprojectMap(Vec2i(viewport[2],viewport[3]),model,projection,viewport,"br"), bl = _unprojectMap(Vec2i(0,viewport[3]),model,projection,viewport,"bl"); + + // orientate it for map iterator //bool swapRequiredX = false; bool swapRequiredY = false; @@ -3629,8 +3691,9 @@ void Renderer::renderObjects(const int renderFps) { assertGl(); - const Texture2D *fowTex= NULL; - Vec3f baseFogColor; + const Texture2D *fowTex = world->getMinimap()->getFowTexture(); + const Pixmap2D *fowTexPixmap = fowTex->getPixmapConst(); + Vec3f baseFogColor = world->getTileset()->getFogColor() * computeLightColor(world->getTimeFlow()->getTime()); bool modelRenderStarted = false; @@ -3645,12 +3708,9 @@ void Renderer::renderObjects(const int renderFps) { if(modelRenderStarted == false) { modelRenderStarted = true; - fowTex= world->getMinimap()->getFowTexture(); - baseFogColor= world->getTileset()->getFogColor() * computeLightColor(world->getTimeFlow()->getTime()); - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_FOG_BIT | GL_LIGHTING_BIT | GL_TEXTURE_BIT); - if(!shadowsOffDueToMinRender && + if(shadowsOffDueToMinRender == false && shadows == sShadowMapping) { glActiveTexture(shadowTexUnit); glEnable(GL_TEXTURE_2D); @@ -3669,7 +3729,6 @@ void Renderer::renderObjects(const int renderFps) { } //ambient and diffuse color is taken from cell color - const Pixmap2D *fowTexPixmap = fowTex->getPixmapConst(); float fowFactor= fowTexPixmap->getPixelf(o->getMapPos().x / Map::cellScale, o->getMapPos().y / Map::cellScale); Vec4f color= Vec4f(Vec3f(fowFactor), 1.f); glColor4fv(color.ptr()); @@ -6682,10 +6741,12 @@ VisibleQuadContainerCache & Renderer::getQuadCache( bool updateOnDirtyFrame, } quadCache.clearNonVolatileCacheData(); + //int loops1=0; PosQuadIterator pqi(map,visibleQuad, Map::cellScale); while(pqi.next()) { const Vec2i &pos= pqi.getPos(); if(map->isInside(pos)) { + //loops1++; const Vec2i &mapPos = Map::toSurfCoords(pos); //quadCache.visibleCellList.push_back(mapPos); @@ -6709,15 +6770,20 @@ VisibleQuadContainerCache & Renderer::getQuadCache( bool updateOnDirtyFrame, } } + //printf("Frame # = %d loops1 = %d\n",world->getFrameCount(),loops1); + + //int loops2=0; const Rect2i mapBounds(0, 0, map->getSurfaceW()-1, map->getSurfaceH()-1); Quad2i scaledQuad = visibleQuad / Map::cellScale; PosQuadIterator pqis(map,scaledQuad); while(pqis.next()) { const Vec2i &pos= pqis.getPos(); if(mapBounds.isInside(pos)) { + //loops2++; quadCache.visibleScaledCellList.push_back(pos); } } + //printf("Frame # = %d loops2 = %d\n",world->getFrameCount(),loops2); } quadCache.cacheFrame = world->getFrameCount(); quadCache.lastVisibleQuad = visibleQuad; diff --git a/source/glest_game/graphics/renderer.h b/source/glest_game/graphics/renderer.h index 283663c6d..23ece9938 100644 --- a/source/glest_game/graphics/renderer.h +++ b/source/glest_game/graphics/renderer.h @@ -118,10 +118,16 @@ public: visibleUnitList.clear(); visibleQuadUnitList.clear(); //inVisibleUnitList.clear(); + + visibleUnitList.reserve(500); + visibleQuadUnitList.reserve(500); } void clearNonVolatileCacheData() { visibleObjectList.clear(); visibleScaledCellList.clear(); + + visibleObjectList.reserve(500); + visibleScaledCellList.reserve(500); } int cacheFrame; diff --git a/source/glest_game/main/main.cpp b/source/glest_game/main/main.cpp index 63a4ce5c8..d5820db49 100644 --- a/source/glest_game/main/main.cpp +++ b/source/glest_game/main/main.cpp @@ -644,8 +644,9 @@ void handleSIGSEGV(int sig) { char szBuf[4096]=""; sprintf(szBuf, "In [%s::%s Line: %d] Error detected: signal %d:\n",__FILE__,__FUNCTION__,__LINE__, sig); printf("%s",szBuf); + //abort(); - ExceptionHandler::handleRuntimeError(szBuf); + //ExceptionHandler::handleRuntimeError(szBuf); } #endif @@ -3638,7 +3639,6 @@ int glestMain(int argc, char** argv) { } int glestMainWrapper(int argc, char** argv) { - //setlocale(LC_ALL, "zh_TW.UTF-8"); //setlocale(LC_ALL, ""); @@ -3666,6 +3666,7 @@ __try { //signal(SIGPIPE, SIG_IGN); #endif + initSpecialStrings(); int result = glestMain(argc, argv); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); diff --git a/source/glest_game/menu/menu_state_custom_game.cpp b/source/glest_game/menu/menu_state_custom_game.cpp index f6501414e..271757b91 100644 --- a/source/glest_game/menu/menu_state_custom_game.cpp +++ b/source/glest_game/menu/menu_state_custom_game.cpp @@ -2570,6 +2570,15 @@ void MenuStateCustomGame::publishToMasterserver() { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); } +void MenuStateCustomGame::setupTask(BaseThread *callingThread) { + CURL *handle = SystemFlags::initHTTP(); + callingThread->setGenericData(handle); +} +void MenuStateCustomGame::shutdownTask(BaseThread *callingThread) { + CURL *handle = callingThread->getGenericData(); + SystemFlags::cleanupHTTP(&handle); +} + void MenuStateCustomGame::simpleTask(BaseThread *callingThread) { try { @@ -2613,7 +2622,8 @@ void MenuStateCustomGame::simpleTask(BaseThread *callingThread) { string request = Config::getInstance().getString("Masterserver") + "addServerInfo.php?"; - CURL *handle = SystemFlags::initHTTP(); + //CURL *handle = SystemFlags::initHTTP(); + CURL *handle = callingThread->getGenericData(); for(std::map::const_iterator iterMap = newPublishToServerInfo.begin(); iterMap != newPublishToServerInfo.end(); ++iterMap) { @@ -2629,7 +2639,7 @@ void MenuStateCustomGame::simpleTask(BaseThread *callingThread) { safeMutexThreadOwner.ReleaseLock(); std::string serverInfo = SystemFlags::getHTTP(request,handle); - SystemFlags::cleanupHTTP(&handle); + //SystemFlags::cleanupHTTP(&handle); MutexSafeWrapper safeMutexThreadOwner2(callingThread->getMutexThreadOwnerValid(),string(__FILE__) + "_" + intToStr(__LINE__)); if(callingThread->getQuitStatus() == true || safeMutexThreadOwner2.isValidMutex() == false) { diff --git a/source/glest_game/menu/menu_state_custom_game.h b/source/glest_game/menu/menu_state_custom_game.h index 0ea42ca8d..424a82ac0 100644 --- a/source/glest_game/menu/menu_state_custom_game.h +++ b/source/glest_game/menu/menu_state_custom_game.h @@ -195,6 +195,9 @@ public: virtual void simpleTask(BaseThread *callingThread); + virtual void setupTask(BaseThread *callingThread); + virtual void shutdownTask(BaseThread *callingThread); + virtual bool isInSpecialKeyCaptureEvent(); virtual bool isMasterserverMode() const; diff --git a/source/glest_game/menu/menu_state_mods.cpp b/source/glest_game/menu/menu_state_mods.cpp index 0140624e1..96afae266 100644 --- a/source/glest_game/menu/menu_state_mods.cpp +++ b/source/glest_game/menu/menu_state_mods.cpp @@ -130,10 +130,9 @@ MenuStateMods::MenuStateMods(Program *program, MainMenu *mainMenu) : mainMessageBoxState = ftpmsg_None; mainMessageBox.registerGraphicComponent(containerName,"mainMessageBox"); - mainMessageBox.init(lang.get("Yes"),lang.get("No")); + mainMessageBox.init(lang.get("Yes"),lang.get("No"),450); mainMessageBox.setEnabled(false); - lineHorizontal.init(0,installButtonYPos-60); lineVertical.init(500,returnLineY, 5, installButtonYPos-60-returnLineY); lineVertical.setHorizontal(false); @@ -330,7 +329,7 @@ void MenuStateMods::reloadUI() { keyScenarioScrollBarTitle1.setFont(CoreData::getInstance().getMenuFontBig()); keyScenarioScrollBarTitle1.setFont3D(CoreData::getInstance().getMenuFontBig3D()); - mainMessageBox.init(lang.get("Yes"),lang.get("No")); + mainMessageBox.init(lang.get("Yes"),lang.get("No"),450); modDescrLabel.setText("description is empty"); @@ -379,7 +378,7 @@ void MenuStateMods::simpleTask(BaseThread *callingThread) { bool findArchive = executeShellCommand(fileArchiveExtractCommand,expectedResult); if(findArchive == false) { mainMessageBoxState = ftpmsg_None; - mainMessageBox.init(lang.get("Ok")); + mainMessageBox.init(lang.get("Ok"),450); showMessageBox(lang.get("ModRequires7z"), lang.get("Notice"), true); } @@ -1107,7 +1106,7 @@ void MenuStateMods::mouseClick(int x, int y, MouseButton mouseButton) { if(fileFTPProgressList.empty() == false) { mainMessageBoxState = ftpmsg_Quit; - mainMessageBox.init(lang.get("Yes"),lang.get("No")); + mainMessageBox.init(lang.get("Yes"),lang.get("No"),450); char szBuf[1024]=""; sprintf(szBuf,lang.get("ModDownloadInProgressCancelQuestion").c_str(),fileFTPProgressList.size()); showMessageBox(szBuf, lang.get("Question"), true); @@ -1123,7 +1122,7 @@ void MenuStateMods::mouseClick(int x, int y, MouseButton mouseButton) { if(mainMessageBox.mouseClick(x, y, button)) { soundRenderer.playFx(coreData.getClickSoundA()); mainMessageBox.setEnabled(false); - mainMessageBox.init(lang.get("Yes"),lang.get("No")); + mainMessageBox.init(lang.get("Yes"),lang.get("No"),450); if(button == 1) { if(mainMessageBoxState == ftpmsg_Quit) { mainMessageBoxState = ftpmsg_None; @@ -1398,14 +1397,14 @@ void MenuStateMods::mouseClick(int x, int y, MouseButton mouseButton) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] local CRC [%d]\n",__FILE__,__FUNCTION__,__LINE__,getFolderTreeContentsCheckSumRecursively(itemPath, ".xml", NULL)); mainMessageBoxState = ftpmsg_ReplaceTechtree; - mainMessageBox.init(lang.get("Yes"),lang.get("No")); + mainMessageBox.init(lang.get("Yes"),lang.get("No"),450); char szBuf[1024]=""; sprintf(szBuf,lang.get("ModLocalRemoteMismatch").c_str(),selectedTechName.c_str()); showMessageBox(szBuf, lang.get("Notice"), true); } else { mainMessageBoxState = ftpmsg_None; - mainMessageBox.init(lang.get("Ok")); + mainMessageBox.init(lang.get("Ok"),450); char szBuf[1024]=""; sprintf(szBuf,lang.get("ModTechAlreadyInstalled").c_str(),selectedTechName.c_str()); showMessageBox(szBuf, lang.get("Notice"), true); @@ -1428,7 +1427,7 @@ void MenuStateMods::mouseClick(int x, int y, MouseButton mouseButton) { } else { mainMessageBoxState = ftpmsg_None; - mainMessageBox.init(lang.get("Ok")); + mainMessageBox.init(lang.get("Ok"),450); showMessageBox(lang.get("ModSelectTechToInstall"), lang.get("Notice"), true); } } @@ -1445,7 +1444,7 @@ void MenuStateMods::mouseClick(int x, int y, MouseButton mouseButton) { } else { mainMessageBoxState = ftpmsg_None; - mainMessageBox.init(lang.get("Ok")); + mainMessageBox.init(lang.get("Ok"),450); char szBuf[1024]=""; sprintf(szBuf,lang.get("ModCannotRemoveTechNotInstalled").c_str(),selectedTechName.c_str()); @@ -1454,7 +1453,7 @@ void MenuStateMods::mouseClick(int x, int y, MouseButton mouseButton) { } else { mainMessageBoxState = ftpmsg_None; - mainMessageBox.init(lang.get("Ok")); + mainMessageBox.init(lang.get("Ok"),450); showMessageBox(lang.get("ModSelectTechToRemove"), lang.get("Notice"), true); } @@ -1479,14 +1478,14 @@ void MenuStateMods::mouseClick(int x, int y, MouseButton mouseButton) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] local CRC [%d]\n",__FILE__,__FUNCTION__,__LINE__,getFolderTreeContentsCheckSumRecursively(itemPath, ".xml", NULL)); mainMessageBoxState = ftpmsg_ReplaceTileset; - mainMessageBox.init(lang.get("Yes"),lang.get("No")); + mainMessageBox.init(lang.get("Yes"),lang.get("No"),450); char szBuf[1024]=""; sprintf(szBuf,lang.get("ModLocalRemoteMismatch").c_str(),selectedTilesetName.c_str()); showMessageBox(szBuf, lang.get("Notice"), true); } else { mainMessageBoxState = ftpmsg_None; - mainMessageBox.init(lang.get("Ok")); + mainMessageBox.init(lang.get("Ok"),450); char szBuf[1024]=""; sprintf(szBuf,lang.get("ModTilesetAlreadyInstalled").c_str(),selectedTilesetName.c_str()); showMessageBox(szBuf, lang.get("Notice"), true); @@ -1508,7 +1507,7 @@ void MenuStateMods::mouseClick(int x, int y, MouseButton mouseButton) { } else { mainMessageBoxState = ftpmsg_None; - mainMessageBox.init(lang.get("Ok")); + mainMessageBox.init(lang.get("Ok"),450); showMessageBox(lang.get("ModSelectTilesetToInstall"), lang.get("Notice"), true); } } @@ -1525,7 +1524,7 @@ void MenuStateMods::mouseClick(int x, int y, MouseButton mouseButton) { } else { mainMessageBoxState = ftpmsg_None; - mainMessageBox.init(lang.get("Ok")); + mainMessageBox.init(lang.get("Ok"),450); char szBuf[1024]=""; sprintf(szBuf,lang.get("ModCannotRemoveTilesetNotInstalled").c_str(),selectedTilesetName.c_str()); @@ -1534,7 +1533,7 @@ void MenuStateMods::mouseClick(int x, int y, MouseButton mouseButton) { } else { mainMessageBoxState = ftpmsg_None; - mainMessageBox.init(lang.get("Ok")); + mainMessageBox.init(lang.get("Ok"),450); showMessageBox(lang.get("ModSelectTilesetToRemove"), lang.get("Notice"), true); } } @@ -1549,14 +1548,14 @@ void MenuStateMods::mouseClick(int x, int y, MouseButton mouseButton) { ModInfo &modInfo = mapCacheList[selectedMapName]; if( modInfo.crc != modInfo.localCRC ) { mainMessageBoxState = ftpmsg_ReplaceMap; - mainMessageBox.init(lang.get("Yes"),lang.get("No")); + mainMessageBox.init(lang.get("Yes"),lang.get("No"),450); char szBuf[1024]=""; sprintf(szBuf,lang.get("ModLocalRemoteMismatch").c_str(),selectedMapName.c_str()); showMessageBox(szBuf, lang.get("Notice"), true); } else { mainMessageBoxState = ftpmsg_None; - mainMessageBox.init(lang.get("Ok")); + mainMessageBox.init(lang.get("Ok"),450); char szBuf[1024]=""; sprintf(szBuf,lang.get("ModMapAlreadyInstalled").c_str(),selectedMapName.c_str()); showMessageBox(szBuf, lang.get("Notice"), true); @@ -1578,7 +1577,7 @@ void MenuStateMods::mouseClick(int x, int y, MouseButton mouseButton) { } else { mainMessageBoxState = ftpmsg_None; - mainMessageBox.init(lang.get("Ok")); + mainMessageBox.init(lang.get("Ok"),450); showMessageBox(lang.get("ModSelectMapToInstall"), lang.get("Notice"), true); } } @@ -1595,7 +1594,7 @@ void MenuStateMods::mouseClick(int x, int y, MouseButton mouseButton) { } else { mainMessageBoxState = ftpmsg_None; - mainMessageBox.init(lang.get("Ok")); + mainMessageBox.init(lang.get("Ok"),450); char szBuf[1024]=""; sprintf(szBuf,lang.get("ModCannotRemoveMapNotInstalled").c_str(),selectedMapName.c_str()); @@ -1604,7 +1603,7 @@ void MenuStateMods::mouseClick(int x, int y, MouseButton mouseButton) { } else { mainMessageBoxState = ftpmsg_None; - mainMessageBox.init(lang.get("Ok")); + mainMessageBox.init(lang.get("Ok"),450); showMessageBox(lang.get("ModSelectMapToRemove"), lang.get("Notice"), true); } } @@ -1628,14 +1627,14 @@ void MenuStateMods::mouseClick(int x, int y, MouseButton mouseButton) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] local CRC [%d]\n",__FILE__,__FUNCTION__,__LINE__,getFolderTreeContentsCheckSumRecursively(itemPath, "", NULL)); mainMessageBoxState = ftpmsg_ReplaceScenario; - mainMessageBox.init(lang.get("Yes"),lang.get("No")); + mainMessageBox.init(lang.get("Yes"),lang.get("No"),450); char szBuf[1024]=""; sprintf(szBuf,lang.get("ModLocalRemoteMismatch").c_str(),selectedScenarioName.c_str()); showMessageBox(szBuf, lang.get("Notice"), true); } else { mainMessageBoxState = ftpmsg_None; - mainMessageBox.init(lang.get("Ok")); + mainMessageBox.init(lang.get("Ok"),450); char szBuf[1024]=""; sprintf(szBuf,lang.get("ModScenarioAlreadyInstalled").c_str(),selectedScenarioName.c_str()); showMessageBox(szBuf, lang.get("Notice"), true); @@ -1659,7 +1658,7 @@ void MenuStateMods::mouseClick(int x, int y, MouseButton mouseButton) { } else { mainMessageBoxState = ftpmsg_None; - mainMessageBox.init(lang.get("Ok")); + mainMessageBox.init(lang.get("Ok"),450); showMessageBox(lang.get("ModSelectScenarioToInstall"), lang.get("Notice"), true); } } @@ -1676,7 +1675,7 @@ void MenuStateMods::mouseClick(int x, int y, MouseButton mouseButton) { } else { mainMessageBoxState = ftpmsg_None; - mainMessageBox.init(lang.get("Ok")); + mainMessageBox.init(lang.get("Ok"),450); char szBuf[1024]=""; sprintf(szBuf,lang.get("ModCannotRemoveScenarioNotInstalled").c_str(),selectedScenarioName.c_str()); @@ -1685,7 +1684,7 @@ void MenuStateMods::mouseClick(int x, int y, MouseButton mouseButton) { } else { mainMessageBoxState = ftpmsg_None; - mainMessageBox.init(lang.get("Ok")); + mainMessageBox.init(lang.get("Ok"),450); showMessageBox(lang.get("ModSelectScenarioToRemove"), lang.get("Notice"), true); } } @@ -2294,11 +2293,11 @@ void MenuStateMods::keyUp(SDL_KeyboardEvent key) { } void MenuStateMods::showMessageBox(const string &text, const string &header, bool toggle) { - if(!toggle){ + if(toggle == false) { mainMessageBox.setEnabled(false); } - if(!mainMessageBox.getEnabled()){ + if(mainMessageBox.getEnabled() == false) { mainMessageBox.setText(text); mainMessageBox.setHeader(header); mainMessageBox.setEnabled(true); diff --git a/source/glest_game/network/connection_slot.cpp b/source/glest_game/network/connection_slot.cpp index fa6377e4f..a5b7e7d03 100644 --- a/source/glest_game/network/connection_slot.cpp +++ b/source/glest_game/network/connection_slot.cpp @@ -60,8 +60,7 @@ void ConnectionSlotThread::setQuitStatus(bool value) { void ConnectionSlotThread::signalUpdate(ConnectionSlotEvent *event) { if(event != NULL) { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId); + MutexSafeWrapper safeMutex(&triggerIdMutex,CODE_AT_LINE); eventList.push_back(*event); safeMutex.ReleaseLock(); } @@ -70,8 +69,7 @@ void ConnectionSlotThread::signalUpdate(ConnectionSlotEvent *event) { void ConnectionSlotThread::setTaskCompleted(int eventId) { if(eventId > 0) { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId); + MutexSafeWrapper safeMutex(&triggerIdMutex,CODE_AT_LINE); //event->eventCompleted = true; for(int i = 0; i < eventList.size(); ++i) { ConnectionSlotEvent &slotEvent = eventList[i]; @@ -86,15 +84,13 @@ void ConnectionSlotThread::setTaskCompleted(int eventId) { } void ConnectionSlotThread::purgeAllEvents() { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId); + MutexSafeWrapper safeMutex(&triggerIdMutex,CODE_AT_LINE); eventList.clear(); safeMutex.ReleaseLock(); } void ConnectionSlotThread::setAllEventsCompleted() { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId); + MutexSafeWrapper safeMutex(&triggerIdMutex,CODE_AT_LINE); for(int i = 0; i < eventList.size(); ++i) { ConnectionSlotEvent &slotEvent = eventList[i]; if(slotEvent.eventCompleted == false) { @@ -105,8 +101,7 @@ void ConnectionSlotThread::setAllEventsCompleted() { } void ConnectionSlotThread::purgeCompletedEvents() { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId); + MutexSafeWrapper safeMutex(&triggerIdMutex,CODE_AT_LINE); //event->eventCompleted = true; for(int i = eventList.size() - 1; i >= 0; i--) { ConnectionSlotEvent &slotEvent = eventList[i]; @@ -128,8 +123,7 @@ bool ConnectionSlotThread::canShutdown(bool deleteSelfIfShutdownDelayed) { } bool ConnectionSlotThread::isSignalCompleted(ConnectionSlotEvent *event) { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId); + MutexSafeWrapper safeMutex(&triggerIdMutex,CODE_AT_LINE); bool result = false; if(event != NULL) { for(int i = 0; i < eventList.size(); ++i) { @@ -140,10 +134,29 @@ bool ConnectionSlotThread::isSignalCompleted(ConnectionSlotEvent *event) { } } } - safeMutex.ReleaseLock(); + //safeMutex.ReleaseLock(); return result; } +void ConnectionSlotThread::slotUpdateTask(ConnectionSlotEvent *event) { + if(event != NULL) { + if(event->eventType == eSendSocketData) { + if(event->connectionSlot != NULL) { + event->connectionSlot->sendMessage(event->networkMessage); + } + } + else if(event->eventType == eReceiveSocketData) { + //updateSlot(event); + if(event->connectionSlot != NULL) { + event->connectionSlot->updateSlot(event); + } + } + else { + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + } + } +} + void ConnectionSlotThread::execute() { RunningStatusSafeWrapper runningStatus(this); try { @@ -164,8 +177,7 @@ void ConnectionSlotThread::execute() { break; } - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId); + MutexSafeWrapper safeMutex(&triggerIdMutex,CODE_AT_LINE); int eventCount = eventList.size(); if(eventCount > 0) { ConnectionSlotEvent eventCopy; @@ -188,7 +200,8 @@ void ConnectionSlotThread::execute() { if(eventCopy.eventId > 0) { ExecutingTaskSafeWrapper safeExecutingTaskMutex(this); - this->slotInterface->slotUpdateTask(&eventCopy); + //this->slotInterface->slotUpdateTask(&eventCopy); + this->slotUpdateTask(&eventCopy); setTaskCompleted(eventCopy.eventId); } } @@ -235,7 +248,7 @@ ConnectionSlot::ConnectionSlot(ServerInterface* serverInterface, int playerIndex this->lastReceiveCommandListTime = 0; this->receivedNetworkGameStatus = false; - this->socket = NULL; + this->setSocket(NULL); this->slotThreadWorker = NULL; this->slotThreadWorker = new ConnectionSlotThread(this->serverInterface,playerIndex); this->slotThreadWorker->setUniqueID(__FILE__); @@ -255,6 +268,8 @@ ConnectionSlot::ConnectionSlot(ServerInterface* serverInterface, int playerIndex } ConnectionSlot::~ConnectionSlot() { + //printf("===> Destructor for ConnectionSlot = %d\n",playerIndex); + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] START\n",__FILE__,__FUNCTION__,__LINE__); close(); @@ -271,6 +286,42 @@ ConnectionSlot::~ConnectionSlot() { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",__FILE__,__FUNCTION__); } +void ConnectionSlot::updateSlot(ConnectionSlotEvent *event) { + Chrono chrono; + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); + + if(event != NULL) { + bool &socketTriggered = event->socketTriggered; + bool checkForNewClients = true; + + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + + //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] MUTEX LOCK held for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); + + if((serverInterface->getGameHasBeenInitiated() == false || + (this->getSocket() != NULL && socketTriggered == true))) { + if(this->isConnected() == false || socketTriggered == true) { + + //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] MUTEX LOCK held for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); + + this->update(checkForNewClients,event->triggerId); + + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 4) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + + //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] MUTEX LOCK held for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); + + // This means no clients are trying to connect at the moment + if(this->getSocket() == NULL) { + checkForNewClients = false; + } + } + //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] MUTEX LOCK held 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(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); +} + void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { //Chrono chrono; //chrono.start(); @@ -283,7 +334,7 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { //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(this->getSocket() == NULL) { if(networkGameDataSynchCheckOkMap) networkGameDataSynchCheckOkMap = false; if(networkGameDataSynchCheckOkTile) networkGameDataSynchCheckOkTile = false; if(networkGameDataSynchCheckOkTech) networkGameDataSynchCheckOkTech = false; @@ -313,7 +364,12 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { if(newSocket != NULL) { // Set Socket as non-blocking newSocket->setBlock(false); - socket = newSocket; + + //printf("Got new connection for slot = %d\n",playerIndex); + + MutexSafeWrapper safeMutex(&mutexCloseConnection,CODE_AT_LINE); + this->setSocket(newSocket); + safeMutex.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()); @@ -329,10 +385,9 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { //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); + MutexSafeWrapper safeMutexSlot1(&mutexPendingNetworkCommandList,CODE_AT_LINE); this->vctPendingNetworkCommandList.clear(); - safeMutexSlot.ReleaseLock(); + safeMutexSlot1.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()); @@ -361,7 +416,7 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { //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) { + if(this->getSocket() != NULL) { //RandomGen random; //sessionKey = random.randRange(-100000, 100000); srand(time(NULL) / (this->playerIndex + 1)); @@ -372,7 +427,7 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { 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) { + if(this->getSocket() != NULL) { NetworkMessageIntro networkMessageIntro(sessionKey,getNetworkVersionSVNString(), getHostName(), playerIndex, nmgstNoSlots, 0, ServerSocket::getFTPServerPort(),""); sendMessage(&networkMessageIntro); } @@ -384,7 +439,7 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { 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) { + if(this->getSocket() != NULL) { NetworkMessageIntro networkMessageIntro(sessionKey,getNetworkVersionSVNString(), getHostName(), playerIndex, nmgstOk, 0, ServerSocket::getFTPServerPort(),""); sendMessage(&networkMessageIntro); @@ -400,14 +455,14 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { 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(this->getSocket() != NULL && this->getSocket()->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;) { + for(;this->getSocket() != NULL && this->getSocket()->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); @@ -434,6 +489,12 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); lastPingInfo = networkMessagePing; } + else { + if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; + } //} } break; @@ -449,6 +510,18 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { this->addChatInfo(msg); gotTextMsg = true; } + else { + if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; + } + } + else { + if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; } } break; @@ -467,13 +540,24 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { 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); + MutexSafeWrapper safeMutexSlot(&mutexPendingNetworkCommandList,CODE_AT_LINE); for(int i = 0; i < networkMessageCommandList.getCommandCount(); ++i) { vctPendingNetworkCommandList.push_back(*networkMessageCommandList.getCommand(i)); } safeMutexSlot.ReleaseLock(); } + else { + if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; + } + } + else { + if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; } } break; @@ -496,64 +580,71 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { if(msgSessionId != sessionKey) { string playerNameStr = name; - string sErr = "Client gave invalid sessionid for player [" + playerNameStr + "]"; + string sErr = "Client gave invalid sessionid for player [" + playerNameStr + "] actual [" + intToStr(msgSessionId) + "] expected [" + intToStr(sessionKey) + "]"; 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; } + else { + //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; + } + } - //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__); + gotIntro = true; - bool versionMatched = false; - string platformFreeVersion = getNetworkPlatformFreeVersionString(); - string sErr = ""; + this->serverInterface->addClientToServerIPAddress(this->getSocket()->getConnectedIPAddress(this->getSocket()->getIpAddress()),this->connectedRemoteIPAddress); - 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()); + 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__); - 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; + NetworkMessageSynchNetworkGameData networkMessageSynchNetworkGameData(serverInterface->getGameSettings()); + sendMessage(&networkMessageSynchNetworkGameData); } } - - 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); - } + } + else { + if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; } } break; @@ -561,46 +652,60 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { 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()); + if(gotIntro == true) { + 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()); + //printf("\n\n\n\n=====Connection slot got settings:\n%s\n",gameSettings.toString().c_str()); + + this->serverInterface->setGameSettings(&gameSettings,false); + this->serverInterface->broadcastGameSetup(&gameSettings); + + if(networkMessageLaunch.getMessageType() == nmtLaunch) { + this->serverInterface->setMasterserverAdminRequestLaunch(true); + } + } + else { + if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; + } + } + else { + if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); 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()); - //printf("\n\n\n\n=====Connection slot got settings:\n%s\n",gameSettings.toString().c_str()); - - this->serverInterface->setGameSettings(&gameSettings,false); - this->serverInterface->broadcastGameSetup(&gameSettings); - - if(networkMessageLaunch.getMessageType() == nmtLaunch) { - this->serverInterface->setMasterserverAdminRequestLaunch(true); - } - } + } } break; @@ -713,6 +818,18 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { receivedNetworkGameStatus = true; if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } + else { + if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; + } + } + else { + if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; } } break; @@ -730,6 +847,18 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck(vctFileList.size(), fileIndex, vctFileList[fileIndex-1].second, vctFileList[fileIndex-1].first); sendMessage(&networkMessageSynchNetworkGameDataFileCRCCheck); } + else { + if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; + } + } + else { + if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; } } break; @@ -751,6 +880,18 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { FileTransferSocketThread *fileXferThread = new FileTransferSocketThread(fileInfo); fileXferThread->start(); } + else { + if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; + } + } + else { + if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; } } break; @@ -766,8 +907,7 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { SwitchSetupRequest switchSetupRequest; if(receiveMessage(&switchSetupRequest)) { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(getServerSynchAccessor(),mutexOwnerId); + MutexSafeWrapper safeMutex(getServerSynchAccessor(),CODE_AT_LINE); int factionIdx = switchSetupRequest.getCurrentFactionIndex(); if(serverInterface->getSwitchSetupRequests()[factionIdx] == NULL) { @@ -786,7 +926,20 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { 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()); } + else { + if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; + } } + else { + if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; + } + break; } case nmtReady: @@ -811,7 +964,11 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { } 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__); + + if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); close(); + return; } } } @@ -864,13 +1021,10 @@ void ConnectionSlot::close() { 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; + MutexSafeWrapper safeMutex(&mutexCloseConnection,CODE_AT_LINE); + bool updateServerListener = (this->getSocket() != NULL); + this->deleteSocket(); safeMutex.ReleaseLock(); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s LINE: %d]\n",__FILE__,__FUNCTION__,__LINE__); @@ -887,7 +1041,7 @@ void ConnectionSlot::close() { } bool ConnectionSlot::hasValidSocketId() { - bool result = (socket != NULL && socket->getSocketId() > 0); + bool result = (this->getSocket() != NULL && this->getSocket()->getSocketId() > 0); return result; } @@ -912,8 +1066,7 @@ bool ConnectionSlot::updateCompleted(ConnectionSlotEvent *event) { } void ConnectionSlot::sendMessage(const NetworkMessage* networkMessage) { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(&socketSynchAccessor,mutexOwnerId); + MutexSafeWrapper safeMutex(&socketSynchAccessor,CODE_AT_LINE); // Skip text messages not intended for the players preferred language const NetworkMessageText *textMsg = dynamic_cast(networkMessage); @@ -935,8 +1088,7 @@ string ConnectionSlot::getHumanPlayerName(int index) { vector ConnectionSlot::getPendingNetworkCommandList(bool clearList) { vector ret; - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutexSlot(&mutexPendingNetworkCommandList,mutexOwnerId); + MutexSafeWrapper safeMutexSlot(&mutexPendingNetworkCommandList,CODE_AT_LINE); if(vctPendingNetworkCommandList.empty() == false) { ret = vctPendingNetworkCommandList; if(clearList == true) { @@ -949,12 +1101,36 @@ vector ConnectionSlot::getPendingNetworkCommandList(bool clearLi } void ConnectionSlot::clearPendingNetworkCommandList() { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutexSlot(&mutexPendingNetworkCommandList,mutexOwnerId); + MutexSafeWrapper safeMutexSlot(&mutexPendingNetworkCommandList,CODE_AT_LINE); if(vctPendingNetworkCommandList.empty() == false) { vctPendingNetworkCommandList.clear(); } safeMutexSlot.ReleaseLock(); } +bool ConnectionSlot::isConnected() { + bool result = false; + MutexSafeWrapper safeMutexSlot(&mutexSocket,CODE_AT_LINE); + if(socket != NULL && socket->isConnected() == true) { + result = true; + } + return result; +} + +Socket* ConnectionSlot::getSocket() { + MutexSafeWrapper safeMutexSlot(&mutexSocket,CODE_AT_LINE); + return socket; +} + +void ConnectionSlot::setSocket(Socket *newSocket) { + MutexSafeWrapper safeMutexSlot(&mutexSocket,CODE_AT_LINE); + socket = newSocket; +} + +void ConnectionSlot::deleteSocket() { + MutexSafeWrapper safeMutexSlot(&mutexSocket,CODE_AT_LINE); + delete socket; + socket = NULL; +} + }}//end namespace diff --git a/source/glest_game/network/connection_slot.h b/source/glest_game/network/connection_slot.h index 9cd1b7e82..26a7c46c2 100644 --- a/source/glest_game/network/connection_slot.h +++ b/source/glest_game/network/connection_slot.h @@ -83,6 +83,8 @@ protected: virtual void setTaskCompleted(int eventId); virtual bool canShutdown(bool deleteSelfIfShutdownDelayed=false); + void slotUpdateTask(ConnectionSlotEvent *event); + public: ConnectionSlotThread(int slotIndex); ConnectionSlotThread(ConnectionSlotCallbackInterface *slotInterface,int slotIndex); @@ -103,6 +105,8 @@ public: class ConnectionSlot: public NetworkInterface { private: ServerInterface* serverInterface; + + Mutex mutexSocket; Socket* socket; int playerIndex; string name; @@ -142,8 +146,7 @@ public: void setName(string value) {name = value;} bool isReady() const {return ready;} - virtual Socket* getSocket() {return socket;} - virtual Socket* getSocket() const {return socket;} + virtual Socket* getSocket(); virtual void close(); //virtual bool getFogOfWar(); @@ -186,12 +189,17 @@ public: time_t getConnectedTime() const { return connectedTime; } int getSessionKey() const { return sessionKey; } + void updateSlot(ConnectionSlotEvent *event); + virtual bool isConnected(); + protected: Mutex * getServerSynchAccessor(); std::vector threadErrorList; Mutex socketSynchAccessor; + void setSocket(Socket *newSocket); + void deleteSocket(); virtual void update() {} }; diff --git a/source/glest_game/network/network_interface.h b/source/glest_game/network/network_interface.h index c179e5dc4..d812aa147 100644 --- a/source/glest_game/network/network_interface.h +++ b/source/glest_game/network/network_interface.h @@ -109,7 +109,6 @@ public: virtual ~NetworkInterface(){} virtual Socket* getSocket()= 0; - virtual const Socket* getSocket() const= 0; virtual void close()= 0; virtual string getHumanPlayerName(int index=-1) = 0; virtual int getHumanPlayerIndex() const = 0; @@ -124,7 +123,7 @@ public: NetworkMessageType getNextMessageType(bool checkHasDataFirst = false); bool receiveMessage(NetworkMessage* networkMessage); - bool isConnected(); + virtual bool isConnected(); const virtual GameSettings * getGameSettings() { return &gameSettings; } diff --git a/source/glest_game/network/network_message.cpp b/source/glest_game/network/network_message.cpp index 3b7420f01..e1b7dfb90 100644 --- a/source/glest_game/network/network_message.cpp +++ b/source/glest_game/network/network_message.cpp @@ -37,57 +37,7 @@ namespace Glest{ namespace Game{ // class NetworkMessage // ===================================================== -/* -bool NetworkMessage::peek(Socket* socket, void* data, int dataSize) { - if(socket != NULL) { - int ipeekdatalen = socket->getDataToRead(); - if(ipeekdatalen >= dataSize) { - if(socket->peek(data, dataSize)!=dataSize) { - if(socket != NULL && socket->getSocketId() > 0) { - throw runtime_error("Error peeking NetworkMessage"); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d socket has been disconnected\n",__FILE__,__FUNCTION__,__LINE__); - } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] dataSize = %d\n",__FILE__,__FUNCTION__,dataSize); - } - return true; - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] socket->getDataToRead() returned %d\n",__FILE__,__FUNCTION__,ipeekdatalen); - } - } - return false; -} -*/ - bool NetworkMessage::receive(Socket* socket, void* data, int dataSize, bool tryReceiveUntilDataSizeMet) { -/* - if(socket != NULL) { - int ipeekdatalen = socket->getDataToRead(); - if(ipeekdatalen >= dataSize) { - if(socket->receive(data, dataSize)!=dataSize) { - if(socket != NULL && socket->getSocketId() > 0) { - throw runtime_error("Error receiving NetworkMessage"); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] socket has been disconnected\n",__FILE__,__FUNCTION__); - } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] dataSize = %d\n",__FILE__,__FUNCTION__,dataSize); - } - return true; - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] socket->getDataToRead() returned %d\n",__FILE__,__FUNCTION__,ipeekdatalen); - } - } - return false; -*/ - if(socket != NULL) { int dataReceived = socket->receive(data, dataSize, tryReceiveUntilDataSizeMet); if(dataReceived != dataSize) { @@ -412,60 +362,8 @@ bool NetworkMessageCommandList::addCommand(const NetworkCommand* networkCommand) } bool NetworkMessageCommandList::receive(Socket* socket) { - // _peek_ type, commandCount & frame num first. if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -/* - const double MAX_MSG_WAIT_SECONDS = 3; - // Wait a max of x seconds for this message - for(time_t elapsedWait = time(NULL); difftime(time(NULL),elapsedWait) <= MAX_MSG_WAIT_SECONDS;) { - if (NetworkMessage::peek(socket, &data, commandListHeaderSize) == true) { - break; - } - } - - if (NetworkMessage::peek(socket, &data, commandListHeaderSize) == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR / WARNING!!! NetworkMessage::peek failed!\n",__FILE__,__FUNCTION__,__LINE__); - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] ERROR / WARNING!!! NetworkMessage::peek failed!\n",__FILE__,__FUNCTION__,__LINE__); - return false; - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] messageType = %d, frameCount = %d, data.commandCount = %d\n", - __FILE__,__FUNCTION__,__LINE__,data.header.messageType,data.header.frameCount,data.header.commandCount); - - // read header + data.commandCount commands. - int totalMsgSize = commandListHeaderSize + (sizeof(NetworkCommand) * data.header.commandCount); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - // _peek_ type, commandCount & frame num first. - // Wait a max of x seconds for this message - for(time_t elapsedWait = time(NULL); difftime(time(NULL),elapsedWait) <= MAX_MSG_WAIT_SECONDS;) { - if (NetworkMessage::peek(socket, &data, totalMsgSize) == true) { - break; - } - } - - - if (socket->getDataToRead() < totalMsgSize) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR / WARNING!!! Insufficient data to read entire command list [need %d bytes, only %d available].\n", - __FILE__,__FUNCTION__,__LINE__, totalMsgSize, socket->getDataToRead()); - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] ERROR / WARNING!!! Insufficient data to read entire command list [need %d bytes, only %d available].\n", - __FILE__,__FUNCTION__,__LINE__, totalMsgSize, socket->getDataToRead()); - - return false; - } - bool result = NetworkMessage::receive(socket, &data, totalMsgSize); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled == true) { - for(int idx = 0 ; idx < data.header.commandCount; ++idx) { - const NetworkCommand &cmd = data.commands[idx]; - - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] index = %d, received networkCommand [%s]\n", - __FILE__,__FUNCTION__,__LINE__,idx, cmd.toString().c_str()); - } - } - return result; -*/ - bool result = NetworkMessage::receive(socket, &data.header, commandListHeaderSize, true); if(result == true) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got header, messageType = %d, commandCount = %u, frameCount = %d\n",__FILE__,__FUNCTION__,__LINE__,data.header.messageType,data.header.commandCount,data.header.frameCount); @@ -704,83 +602,6 @@ string NetworkMessageSynchNetworkGameData::getTechCRCFileMismatchReport(vector 0) { - - // Here we loop possibly multiple times - int packetLoopCount = 1; - if(data.header.techCRCFileCount > NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount) { - packetLoopCount = (data.header.techCRCFileCount / NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount); - if(data.header.techCRCFileCount % NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount > 0) { - packetLoopCount++; - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] packetLoopCount = %d\n",__FILE__,__FUNCTION__,__LINE__,packetLoopCount); - - for(int iPacketLoop = 0; result == true && iPacketLoop < packetLoopCount; ++iPacketLoop) { - - int packetIndex = iPacketLoop * NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount; - int maxFileCountPerPacket = maxFileCRCPacketCount; - int packetFileCount = min(maxFileCountPerPacket,data.header.techCRCFileCount - packetIndex); - int packetDetail1DataSize = (DetailSize1 * packetFileCount); - int packetDetail2DataSize = (DetailSize2 * packetFileCount); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] iPacketLoop = %d, packetIndex = %d, maxFileCountPerPacket = %d, packetFileCount = %d, packetDetail1DataSize = %d, packetDetail2DataSize = %d\n",__FILE__,__FUNCTION__,__LINE__,iPacketLoop,packetIndex,maxFileCountPerPacket,packetFileCount,packetDetail1DataSize,packetDetail2DataSize); - - // Wait a max of x seconds for this message - for(time_t elapsedWait = time(NULL); difftime(time(NULL),elapsedWait) <= MAX_MSG_WAIT_SECONDS;) { - if (NetworkMessage::peek(socket, &data.detail.techCRCFileList[packetIndex], packetDetail1DataSize) == true) { - break; - } - } - - result = NetworkMessage::receive(socket, &data.detail.techCRCFileList[packetIndex], packetDetail1DataSize, true); - if(result == true) { - for(int i = 0; i < data.header.techCRCFileCount; ++i) { - data.detail.techCRCFileList[i].nullTerminate(); - } - - // Wait a max of x seconds for this message - for(time_t elapsedWait = time(NULL); difftime(time(NULL),elapsedWait) <= MAX_MSG_WAIT_SECONDS;) { - if (NetworkMessage::peek(socket, &data.detail.techCRCFileCRCList[packetIndex], packetDetail2DataSize) == true) { - break; - } - } - - result = NetworkMessage::receive(socket, &data.detail.techCRCFileCRCList[packetIndex], packetDetail2DataSize, true); - } - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] result = %d\n",__FILE__,__FUNCTION__,__LINE__,result); - return result; - -*/ - data.header.techCRCFileCount = 0; bool result = NetworkMessage::receive(socket, &data, HeaderSize, true); if(result == true && data.header.techCRCFileCount > 0) { @@ -937,76 +758,6 @@ string NetworkMessageSynchNetworkGameDataStatus::getTechCRCFileMismatchReport(st bool NetworkMessageSynchNetworkGameDataStatus::receive(Socket* socket) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] about to get nmtSynchNetworkGameDataStatus\n",__FILE__,__FUNCTION__,__LINE__); -/* - data.header.techCRCFileCount = 0; - - const double MAX_MSG_WAIT_SECONDS = 3; - - // Wait a max of x seconds for this message - for(time_t elapsedWait = time(NULL); difftime(time(NULL),elapsedWait) <= MAX_MSG_WAIT_SECONDS;) { - if (NetworkMessage::peek(socket, &data, HeaderSize) == true) { - break; - } - } - - if (NetworkMessage::peek(socket, &data, HeaderSize) == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR / WARNING!!! NetworkMessage::peek failed!\n",__FILE__,__FUNCTION__,__LINE__); - return false; - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] messageType = %d, data.techCRCFileCount = %d\n",__FILE__,__FUNCTION__,__LINE__,data.header.messageType,data.header.techCRCFileCount); - - bool result = NetworkMessage::receive(socket, &data, HeaderSize, true); - if(result == true && data.header.techCRCFileCount > 0) { - // Here we loop possibly multiple times - int packetLoopCount = 1; - if(data.header.techCRCFileCount > NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount) { - packetLoopCount = (data.header.techCRCFileCount / NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount); - if(data.header.techCRCFileCount % NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount > 0) { - packetLoopCount++; - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] packetLoopCount = %d\n",__FILE__,__FUNCTION__,__LINE__,packetLoopCount); - - for(int iPacketLoop = 0; iPacketLoop < packetLoopCount; ++iPacketLoop) { - - int packetIndex = iPacketLoop * NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount; - int maxFileCountPerPacket = maxFileCRCPacketCount; - int packetFileCount = min(maxFileCountPerPacket,data.header.techCRCFileCount - packetIndex); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] iPacketLoop = %d, packetIndex = %d, packetFileCount = %d\n",__FILE__,__FUNCTION__,__LINE__,iPacketLoop,packetIndex,packetFileCount); - - // Wait a max of x seconds for this message - for(time_t elapsedWait = time(NULL); difftime(time(NULL),elapsedWait) <= MAX_MSG_WAIT_SECONDS;) { - if (NetworkMessage::peek(socket, &data.detail.techCRCFileList[packetIndex], (DetailSize1 * packetFileCount)) == true) { - break; - } - } - - result = NetworkMessage::receive(socket, &data.detail.techCRCFileList[packetIndex], (DetailSize1 * packetFileCount),true); - if(result == true) { - for(int i = 0; i < data.header.techCRCFileCount; ++i) { - data.detail.techCRCFileList[i].nullTerminate(); - } - - // Wait a max of x seconds for this message - for(time_t elapsedWait = time(NULL); difftime(time(NULL),elapsedWait) <= MAX_MSG_WAIT_SECONDS;) { - if (NetworkMessage::peek(socket, &data.detail.techCRCFileCRCList[packetIndex], (DetailSize2 * packetFileCount)) == true) { - break; - } - } - - result = NetworkMessage::receive(socket, &data.detail.techCRCFileCRCList[packetIndex], (DetailSize2 * packetFileCount),true); - } - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] result = %d\n",__FILE__,__FUNCTION__,__LINE__,result); - - return result; -*/ - data.header.techCRCFileCount = 0; bool result = NetworkMessage::receive(socket, &data, HeaderSize, true); diff --git a/source/glest_game/network/network_types.h b/source/glest_game/network/network_types.h index 2caef030f..0be5e5b40 100644 --- a/source/glest_game/network/network_types.h +++ b/source/glest_game/network/network_types.h @@ -42,7 +42,9 @@ private: char buffer[S]; public: - NetworkString() {memset(buffer, 0, S);} + NetworkString() { + memset(buffer, 0, S); + } NetworkString & operator=(const string& str) { // ensure we don't have a buffer overflow int maxBufferSize = sizeof(buffer) / sizeof(buffer[0]); @@ -55,7 +57,7 @@ public: buffer[maxBufferSize-1] = '\0'; } - string getString() const {return buffer;} + string getString() const { return (buffer[0] != '\0' ? buffer : ""); } }; // ===================================================== diff --git a/source/glest_game/network/server_interface.cpp b/source/glest_game/network/server_interface.cpp index 2bc16ee69..64a70f70b 100644 --- a/source/glest_game/network/server_interface.cpp +++ b/source/glest_game/network/server_interface.cpp @@ -163,11 +163,13 @@ void ServerInterface::setPublishEnabled(bool value) { } ServerInterface::~ServerInterface() { + //printf("===> Destructor for ServerInterface\n"); + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); exitServer = true; for(int i= 0; i < GameConstants::maxPlayers; ++i) { if(slots[i] != NULL) { - MutexSafeWrapper safeMutex(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + MutexSafeWrapper safeMutex(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); delete slots[i]; slots[i]=NULL; } @@ -185,10 +187,11 @@ ServerInterface::~ServerInterface() { delete ftpServer; ftpServer = NULL; } - MutexSafeWrapper safeMutex(&masterServerThreadAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutex(&masterServerThreadAccessor,CODE_AT_LINE); delete publishToMasterserverThread; publishToMasterserverThread = NULL; safeMutex.ReleaseLock(); + lastMasterserverHeartbeatTime = 0; if(needToRepublishToMasterserver == true) { simpleTask(NULL); @@ -200,7 +203,7 @@ int ServerInterface::isValidClientType(uint32 clientIp) { int result = 0; for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { if(slots[i] != NULL) { - MutexSafeWrapper safeMutex(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + MutexSafeWrapper safeMutex(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); Socket *socket = slots[i]->getSocket(); if(socket != NULL) { @@ -222,14 +225,14 @@ void ServerInterface::addClientToServerIPAddress(uint32 clientIp, uint32 ServerI void ServerInterface::addSlot(int playerIndex) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); assert(playerIndex >= 0 && playerIndex < GameConstants::maxPlayers); - MutexSafeWrapper safeMutex(&serverSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutex(&serverSynchAccessor,CODE_AT_LINE); if(serverSocket.isPortBound() == false) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); serverSocket.bind(serverSocket.getBindPort()); } if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[playerIndex],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(playerIndex)); + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[playerIndex],CODE_AT_LINE_X(playerIndex)); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); ConnectionSlot *slot = slots[playerIndex]; if(slot != NULL) { @@ -255,9 +258,9 @@ bool ServerInterface::switchSlot(int fromPlayerIndex, int toPlayerIndex) { return false; } - MutexSafeWrapper safeMutex(&serverSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[fromPlayerIndex],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(fromPlayerIndex)); - MutexSafeWrapper safeMutexSlot2(&slotAccessorMutexes[toPlayerIndex],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(toPlayerIndex)); + MutexSafeWrapper safeMutex(&serverSynchAccessor,CODE_AT_LINE); + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[fromPlayerIndex],CODE_AT_LINE_X(fromPlayerIndex)); + MutexSafeWrapper safeMutexSlot2(&slotAccessorMutexes[toPlayerIndex],CODE_AT_LINE_X(toPlayerIndex)); if(slots[toPlayerIndex] != NULL && slots[toPlayerIndex] != NULL && slots[toPlayerIndex]->isConnected() == false) { slots[fromPlayerIndex]->setPlayerIndex(toPlayerIndex); @@ -285,11 +288,11 @@ bool ServerInterface::switchSlot(int fromPlayerIndex, int toPlayerIndex) { void ServerInterface::removeSlot(int playerIndex, int lockedSlotIndex) { Lang &lang= Lang::getInstance(); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex); - MutexSafeWrapper safeMutex(&serverSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); - MutexSafeWrapper safeMutexSlot(NULL,string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(playerIndex)); + MutexSafeWrapper safeMutex(&serverSynchAccessor,CODE_AT_LINE); + MutexSafeWrapper safeMutexSlot(NULL,CODE_AT_LINE_X(playerIndex)); if(playerIndex != lockedSlotIndex) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex); - safeMutexSlot.setMutex(&slotAccessorMutexes[playerIndex],string(__FILE__) + "_" + intToStr(__LINE__) + string("_") + intToStr(playerIndex)); + safeMutexSlot.setMutex(&slotAccessorMutexes[playerIndex],CODE_AT_LINE_X(playerIndex)); } ConnectionSlot *slot = slots[playerIndex]; bool notifyDisconnect = false; @@ -349,7 +352,7 @@ ConnectionSlot *ServerInterface::getSlot(int playerIndex) { bool ServerInterface::hasClientConnection() { bool result = false; for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); if(slots[i] != NULL && slots[i]->isConnected() == true) { result = true; break; @@ -361,7 +364,7 @@ bool ServerInterface::hasClientConnection() { int ServerInterface::getConnectedSlotCount() { int connectedSlotCount = 0; for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); if(slots[i] != NULL) { ++connectedSlotCount; } @@ -378,72 +381,84 @@ int64 ServerInterface::getNextEventId() { } void ServerInterface::slotUpdateTask(ConnectionSlotEvent *event) { - if(event != NULL) { - if(event->eventType == eSendSocketData) { - event->connectionSlot->sendMessage(event->networkMessage); - } - else if(event->eventType == eReceiveSocketData) { - updateSlot(event); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - } - } +// if(event != NULL) { +// if(event->eventType == eSendSocketData) { +// if(event->connectionSlot != NULL) { +// event->connectionSlot->sendMessage(event->networkMessage); +// } +// } +// else if(event->eventType == eReceiveSocketData) { +// //updateSlot(event); +// if(event->connectionSlot != NULL) { +// event->connectionSlot->updateSlot(event); +// } +// } +// else { +// if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); +// } +// } } -void ServerInterface::updateSlot(ConnectionSlotEvent *event) { - Chrono chrono; - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); - - if(event != NULL) { - bool &socketTriggered = event->socketTriggered; - bool checkForNewClients = true; - - // Safety check since we can experience a disconnect and the slot is NULL - ConnectionSlot *connectionSlot = NULL; - MutexSafeWrapper safeMutexSlot(NULL); - if(event->triggerId >= 0 && event->triggerId < GameConstants::maxPlayers) { - safeMutexSlot.setMutex(&slotAccessorMutexes[event->triggerId],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(event->triggerId)); - connectionSlot = slots[event->triggerId]; - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR CONDITION, event->triggerId = %d\n",__FILE__,__FUNCTION__,__LINE__,event->triggerId); - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] ERROR CONDITION, event->triggerId = %d\n",__FILE__,__FUNCTION__,__LINE__,event->triggerId); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] MUTEX LOCK held for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - - if(connectionSlot != NULL && - (gameHasBeenInitiated == false || - (connectionSlot->getSocket() != NULL && socketTriggered == true))) { - if(connectionSlot->isConnected() == false || socketTriggered == true) { - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] MUTEX LOCK held for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - - //safeMutexSlot.ReleaseLock(true); - connectionSlot->update(checkForNewClients,event->triggerId); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 4) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - //chrono.start(); - //safeMutexSlot.Lock(); - connectionSlot = slots[event->triggerId]; - - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] MUTEX LOCK held for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - - // This means no clients are trying to connect at the moment - if(connectionSlot != NULL && connectionSlot->getSocket() == NULL) { - checkForNewClients = false; - } - } - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] MUTEX LOCK held for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - } - safeMutexSlot.ReleaseLock(); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); -} +//void ServerInterface::updateSlot(ConnectionSlotEvent *event) { +// Chrono chrono; +// if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); +// +// if(event != NULL) { +// bool &socketTriggered = event->socketTriggered; +// bool checkForNewClients = true; +// +// // Safety check since we can experience a disconnect and the slot is NULL +// ConnectionSlot *connectionSlot = NULL; +// MutexSafeWrapper safeMutexSlot(NULL); +// if(event->triggerId >= 0 && event->triggerId < GameConstants::maxPlayers) { +// +// //printf("===> START slot %d [%d][%p] - About to updateSlot\n",event->triggerId,event->eventId,slots[event->triggerId]); +// +// safeMutexSlot.setMutex(&slotAccessorMutexes[event->triggerId],CODE_AT_LINE_X(event->triggerId)); +// connectionSlot = slots[event->triggerId]; +// } +// else { +// if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR CONDITION, event->triggerId = %d\n",__FILE__,__FUNCTION__,__LINE__,event->triggerId); +// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] ERROR CONDITION, event->triggerId = %d\n",__FILE__,__FUNCTION__,__LINE__,event->triggerId); +// } +// +// if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); +// +// //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] MUTEX LOCK held for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); +// +// if(connectionSlot != NULL && +// (gameHasBeenInitiated == false || +// (connectionSlot->getSocket() != NULL && socketTriggered == true))) { +// if(connectionSlot->isConnected() == false || socketTriggered == true) { +// //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] MUTEX LOCK held for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); +// +// //safeMutexSlot.ReleaseLock(true); +// connectionSlot->update(checkForNewClients,event->triggerId); +// +// if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 4) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); +// +// //chrono.start(); +// //safeMutexSlot.Lock(); +// //connectionSlot = slots[event->triggerId]; +// +// //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] MUTEX LOCK held for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); +// +// // This means no clients are trying to connect at the moment +// if(connectionSlot != NULL && connectionSlot->getSocket() == NULL) { +// checkForNewClients = false; +// } +// } +// //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] MUTEX LOCK held for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); +// } +// safeMutexSlot.ReleaseLock(); +// +// if(event->triggerId >= 0 && event->triggerId < GameConstants::maxPlayers) { +// //printf("===> END slot %d - About to updateSlot\n",event->triggerId); +// } +// } +// if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); +// if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took %lld msecs\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); +//} std::pair ServerInterface::clientLagCheck(ConnectionSlot *connectionSlot, bool skipNetworkBroadCast) { Chrono chrono; @@ -631,7 +646,7 @@ bool ServerInterface::signalClientReceiveCommands(ConnectionSlot *connectionSlot void ServerInterface::updateSocketTriggeredList(std::map & socketTriggeredList) { for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); ConnectionSlot* connectionSlot= slots[i]; if(connectionSlot != NULL && connectionSlot->getSocket() != NULL && connectionSlot->getSocket()->isSocketValid() == true) { @@ -642,7 +657,7 @@ void ServerInterface::updateSocketTriggeredList(std::map & void ServerInterface::validateConnectedClients() { for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); ConnectionSlot* connectionSlot = slots[i]; if(connectionSlot != NULL) { @@ -656,7 +671,7 @@ void ServerInterface::signalClientsToRecieveData(std::map std::map & mapSlotSignalledList) { //bool checkForNewClients = true; for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); ConnectionSlot* connectionSlot = slots[i]; bool socketTriggered = false; @@ -679,11 +694,19 @@ void ServerInterface::checkForCompletedClients(std::map & mapSlotSigna threadsDone = true; // Examine all threads for completion of delegation for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + string("_") + intToStr(i)); + + //printf("===> START slot %d [%p] - About to checkForCompletedClients\n",i,slots[i]); + + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); + + //printf("===> IN slot %d - About to checkForCompletedClients\n",i); + ConnectionSlot* connectionSlot = slots[i]; if(connectionSlot != NULL && mapSlotSignalledList[i] == true && slotsCompleted.find(i) == slotsCompleted.end()) { try { + + std::vector errorList = connectionSlot->getThreadErrorList(); // Collect any collected errors from threads if(errorList.empty() == false) { @@ -709,9 +732,12 @@ void ServerInterface::checkForCompletedClients(std::map & mapSlotSigna 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()); + errorMsgList.push_back(ex.what()); } } + + //printf("===> END slot %d - About to checkForCompletedClients\n",i); } } } @@ -731,7 +757,7 @@ void ServerInterface::checForLaggingClients(std::map &mapSlotSignalled threadsDone = true; // Examine all threads for completion of delegation for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); ConnectionSlot* connectionSlot = slots[i]; if(connectionSlot != NULL && mapSlotSignalledList[i] == true && slotsCompleted.find(i) == slotsCompleted.end()) { @@ -843,7 +869,7 @@ void ServerInterface::checForLaggingClients(std::map &mapSlotSignalled void ServerInterface::executeNetworkCommandsFromClients() { if(gameHasBeenInitiated == true) { for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); ConnectionSlot* connectionSlot= slots[i]; if(connectionSlot != NULL && connectionSlot->isConnected() == true) { vector pendingList = connectionSlot->getPendingNetworkCommandList(true); @@ -860,7 +886,7 @@ void ServerInterface::executeNetworkCommandsFromClients() { void ServerInterface::dispatchPendingChatMessages(std::vector &errorMsgList) { for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); ConnectionSlot* connectionSlot= slots[i]; if(connectionSlot != NULL && connectionSlot->getChatTextList().empty() == false) { @@ -1189,7 +1215,7 @@ void ServerInterface::waitUntilReady(Checksum *checksum) { vector waitingForHosts; allReady= true; for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); ConnectionSlot* connectionSlot= slots[i]; if(connectionSlot != NULL && connectionSlot->isConnected() == true) { if(connectionSlot->isReady() == false) { @@ -1268,7 +1294,7 @@ void ServerInterface::waitUntilReady(Checksum *checksum) { uint32 loadingStatus = nmls_NONE; //send ready message after, so clients start delayed for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); ConnectionSlot* connectionSlot= slots[i]; if(connectionSlot != NULL && connectionSlot->isConnected() == true) { switch(i) { @@ -1326,7 +1352,7 @@ void ServerInterface::waitUntilReady(Checksum *checksum) { // send loading status message for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); ConnectionSlot* connectionSlot= slots[i]; if(connectionSlot != NULL && connectionSlot->isConnected() == true) { NetworkMessageLoadingStatus networkMessageLoadingStatus(loadingStatus); @@ -1362,7 +1388,7 @@ void ServerInterface::waitUntilReady(Checksum *checksum) { try { //send ready message after, so clients start delayed for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); ConnectionSlot* connectionSlot= slots[i]; if(connectionSlot != NULL && connectionSlot->isConnected() == true) { NetworkMessageReady networkMessageReady(checksum->getSum()); @@ -1381,7 +1407,7 @@ void ServerInterface::waitUntilReady(Checksum *checksum) { } void ServerInterface::processBroadCastMessageQueue() { - MutexSafeWrapper safeMutexSlot(&broadcastMessageQueueThreadAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexSlot(&broadcastMessageQueueThreadAccessor,CODE_AT_LINE); if(broadcastMessageQueue.empty() == false) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] broadcastMessageQueue.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,broadcastMessageQueue.size()); for(int i = 0; i < broadcastMessageQueue.size(); ++i) { @@ -1397,7 +1423,7 @@ void ServerInterface::processBroadCastMessageQueue() { } void ServerInterface::queueBroadcastMessage(const NetworkMessage *networkMessage, int excludeSlot) { - MutexSafeWrapper safeMutexSlot(&broadcastMessageQueueThreadAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexSlot(&broadcastMessageQueueThreadAccessor,CODE_AT_LINE); pair item; item.first = networkMessage; item.second = excludeSlot; @@ -1405,7 +1431,7 @@ void ServerInterface::queueBroadcastMessage(const NetworkMessage *networkMessage } void ServerInterface::processTextMessageQueue() { - MutexSafeWrapper safeMutexSlot(&textMessageQueueThreadAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexSlot(&textMessageQueueThreadAccessor,CODE_AT_LINE); if(textMessageQueue.empty() == false) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] textMessageQueue.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,textMessageQueue.size()); for(int i = 0; i < textMessageQueue.size(); ++i) { @@ -1418,7 +1444,7 @@ void ServerInterface::processTextMessageQueue() { void ServerInterface::queueTextMessage(const string & text, int teamIndex, bool echoLocal, string targetLanguage) { - MutexSafeWrapper safeMutexSlot(&textMessageQueueThreadAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexSlot(&textMessageQueueThreadAccessor,CODE_AT_LINE); TextMessageQueue item; item.text = text; item.teamIndex = teamIndex; @@ -1458,7 +1484,7 @@ string ServerInterface::getNetworkStatus() { Lang &lang = Lang::getInstance(); string str=""; for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); ConnectionSlot* connectionSlot= slots[i]; str+= intToStr(i)+ ": "; @@ -1487,7 +1513,7 @@ bool ServerInterface::launchGame(const GameSettings *gameSettings) { bool bOkToStart = true; if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); ConnectionSlot *connectionSlot= slots[i]; if(connectionSlot != NULL && (connectionSlot->getAllowDownloadDataSynch() == true || connectionSlot->getAllowGameDataSynchCheck() == true) && @@ -1507,7 +1533,7 @@ bool ServerInterface::launchGame(const GameSettings *gameSettings) { if(useInGameBlockingClientSockets == true) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); for(int i= 0; i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); ConnectionSlot *connectionSlot= slots[i]; if(connectionSlot != NULL && connectionSlot->isConnected()) { connectionSlot->getSocket()->setBlock(true); @@ -1526,7 +1552,7 @@ bool ServerInterface::launchGame(const GameSettings *gameSettings) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] needToRepublishToMasterserver = %d\n",__FILE__,__FUNCTION__,__LINE__,needToRepublishToMasterserver); - MutexSafeWrapper safeMutex(&masterServerThreadAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutex(&masterServerThreadAccessor,CODE_AT_LINE); delete publishToMasterserverThread; publishToMasterserverThread = NULL; lastMasterserverHeartbeatTime = 0; @@ -1561,7 +1587,7 @@ bool ServerInterface::launchGame(const GameSettings *gameSettings) { void ServerInterface::broadcastGameSetup(const GameSettings *gameSettings) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); - MutexSafeWrapper safeMutex(&serverSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutex(&serverSynchAccessor,CODE_AT_LINE); NetworkMessageLaunch networkMessageLaunch(gameSettings, nmtBroadCastSetup); broadcastMessage(&networkMessageLaunch); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); @@ -1571,7 +1597,7 @@ void ServerInterface::broadcastMessage(const NetworkMessage *networkMessage, int try { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - MutexSafeWrapper safeMutexSlotBroadCastAccessor(&inBroadcastMessageThreadAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexSlotBroadCastAccessor(&inBroadcastMessageThreadAccessor,CODE_AT_LINE); if(inBroadcastMessage == true && dynamic_cast(networkMessage) != NULL) { safeMutexSlotBroadCastAccessor.ReleaseLock(); const NetworkMessageText *txtMsg = dynamic_cast(networkMessage); @@ -1585,10 +1611,10 @@ void ServerInterface::broadcastMessage(const NetworkMessage *networkMessage, int } for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(NULL,string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + MutexSafeWrapper safeMutexSlot(NULL,CODE_AT_LINE_X(i)); if(i != lockedSlotIndex) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] i = %d, lockedSlotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,i,lockedSlotIndex); - safeMutexSlot.setMutex(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + safeMutexSlot.setMutex(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); } ConnectionSlot* connectionSlot= slots[i]; @@ -1623,7 +1649,7 @@ void ServerInterface::broadcastMessage(const NetworkMessage *networkMessage, int 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 [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - MutexSafeWrapper safeMutexSlotBroadCastAccessor(&inBroadcastMessageThreadAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexSlotBroadCastAccessor(&inBroadcastMessageThreadAccessor,CODE_AT_LINE); inBroadcastMessage = false; safeMutexSlotBroadCastAccessor.ReleaseLock(); @@ -1636,7 +1662,7 @@ void ServerInterface::broadcastMessageToConnectedClients(const NetworkMessage *n if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); try { for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); ConnectionSlot *connectionSlot= slots[i]; if(i != excludeSlot && connectionSlot != NULL) { @@ -1685,7 +1711,7 @@ int ServerInterface::getOpenSlotCount() { int ServerInterface::getGameSettingsUpdateCount() { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START gameSettingsUpdateCount = %d\n",__FILE__,__FUNCTION__,gameSettingsUpdateCount); - MutexSafeWrapper safeMutex(&serverSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutex(&serverSynchAccessor,CODE_AT_LINE); int result = gameSettingsUpdateCount; safeMutex.ReleaseLock(); @@ -1694,7 +1720,7 @@ int ServerInterface::getGameSettingsUpdateCount() { void ServerInterface::setGameSettings(GameSettings *serverGameSettings, bool waitForClientAck) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START gameSettingsUpdateCount = %d, waitForClientAck = %d\n",__FILE__,__FUNCTION__,gameSettingsUpdateCount,waitForClientAck); - MutexSafeWrapper safeMutex(&serverSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutex(&serverSynchAccessor,CODE_AT_LINE); string mapFile = serverGameSettings->getMap(); if(find(mapFiles.begin(),mapFiles.end(),mapFile) == mapFiles.end()) { @@ -1731,7 +1757,9 @@ void ServerInterface::setGameSettings(GameSettings *serverGameSettings, bool wai while(gotAckFromAllClients == false && difftime(time(NULL),tStart) <= 5) { gotAckFromAllClients = true; for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + //printf("===> START slot %d - About to setGameSettings #1\n",i); + + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); ConnectionSlot *connectionSlot = slots[i]; if(connectionSlot != NULL && connectionSlot->isConnected()) { if(connectionSlot->getReceivedNetworkGameStatus() == false) { @@ -1740,12 +1768,14 @@ void ServerInterface::setGameSettings(GameSettings *serverGameSettings, bool wai connectionSlot->update(true,i); } + + //printf("===> END slot %d - About to setGameSettings #1\n",i); } } } for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); ConnectionSlot *connectionSlot = slots[i]; if(connectionSlot != NULL && connectionSlot->isConnected()) { connectionSlot->setReceivedNetworkGameStatus(false); @@ -1763,7 +1793,9 @@ void ServerInterface::setGameSettings(GameSettings *serverGameSettings, bool wai while(gotAckFromAllClients == false && difftime(time(NULL),tStart) <= 5) { gotAckFromAllClients = true; for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + //printf("===> START slot %d - About to setGameSettings 2\n",i); + + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); ConnectionSlot *connectionSlot = slots[i]; if(connectionSlot != NULL && connectionSlot->isConnected()) { if(connectionSlot->getReceivedNetworkGameStatus() == false) { @@ -1772,6 +1804,8 @@ void ServerInterface::setGameSettings(GameSettings *serverGameSettings, bool wai connectionSlot->update(true,i); } + + //printf("===> END slot %d - About to setGameSettings 2\n",i); } } } @@ -1812,7 +1846,7 @@ std::map ServerInterface::publishToMasterserver() { std::map < string, string > publishToServerInfo; if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(i)); + MutexSafeWrapper safeMutexSlot(&slotAccessorMutexes[i],CODE_AT_LINE_X(i)); if(slots[i] != NULL) { slotCountUsed++; slotCountHumans++; @@ -1846,7 +1880,7 @@ std::map ServerInterface::publishToMasterserver() { } void ServerInterface::simpleTask(BaseThread *callingThread) { - MutexSafeWrapper safeMutex(&masterServerThreadAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutex(&masterServerThreadAccessor,CODE_AT_LINE); if(difftime(time(NULL),lastMasterserverHeartbeatTime) >= MASTERSERVER_HEARTBEAT_GAME_STATUS_SECONDS) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); @@ -1888,5 +1922,45 @@ void ServerInterface::simpleTask(BaseThread *callingThread) { } } +void ServerInterface::notifyBadClientConnectAttempt(string ipAddress) { + //printf("In [%s::%s Line: %d] ipAddress [%s]\n",__FILE__,__FUNCTION__,__LINE__,ipAddress.c_str()); + + if(badClientConnectIPList.find(ipAddress) == badClientConnectIPList.end()) { + badClientConnectIPList[ipAddress] = make_pair(0,time(NULL)); + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + } + + pair &lastBadConnectionAttempt = badClientConnectIPList[ipAddress]; + + const uint64 BLOCK_BAD_CLIENT_CONNECT_MAX_SECONDS = Config::getInstance().getInt("BlockBadClientConnectMaxSeconds", "60"); + const uint64 BLOCK_BAD_CLIENT_CONNECT_MAX_ATTEMPTS = Config::getInstance().getInt("BlockBadClientConnectMaxAttempts", "6"); + bool addToBlockedClientsList = false; + + if(difftime(time(NULL),lastBadConnectionAttempt.second) <= BLOCK_BAD_CLIENT_CONNECT_MAX_SECONDS) { + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + if(lastBadConnectionAttempt.first+1 > BLOCK_BAD_CLIENT_CONNECT_MAX_ATTEMPTS) { + addToBlockedClientsList = true; + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + } + } + else { + // Reset after x seconds + lastBadConnectionAttempt.first = 0; + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + } + + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + if(addToBlockedClientsList == true) { + serverSocket.addIPAddressToBlockedList(ipAddress); + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + } + + lastBadConnectionAttempt.first++; + lastBadConnectionAttempt.second = time(NULL); + + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); +} }}//end namespace diff --git a/source/glest_game/network/server_interface.h b/source/glest_game/network/server_interface.h index c46d9043a..624de90ec 100644 --- a/source/glest_game/network/server_interface.h +++ b/source/glest_game/network/server_interface.h @@ -85,6 +85,8 @@ private: vector techTreeFiles; vector tilesetFiles; + map > badClientConnectIPList; + public: ServerInterface(bool publishEnabled); virtual ~ServerInterface(); @@ -176,6 +178,8 @@ public: void setPublishEnabled(bool value); + bool getGameHasBeenInitiated() const { return gameHasBeenInitiated; } + public: Mutex *getServerSynchAccessor() { return &serverSynchAccessor; @@ -184,6 +188,7 @@ public: virtual void simpleTask(BaseThread *callingThread); void addClientToServerIPAddress(uint32 clientIp, uint32 ServerIp); virtual int isValidClientType(uint32 clientIp); + void notifyBadClientConnectAttempt(string ipAddress); private: void broadcastMessage(const NetworkMessage *networkMessage, int excludeSlot = -1, int lockedSlotIndex = -1); diff --git a/source/glest_game/type_instances/object.cpp b/source/glest_game/type_instances/object.cpp index 9e55f24b7..5d99ecbb3 100644 --- a/source/glest_game/type_instances/object.cpp +++ b/source/glest_game/type_instances/object.cpp @@ -54,11 +54,14 @@ Object::Object(ObjectType *objectType, const Vec3f &pos, const Vec2i &mapPos) { } -Object::~Object(){ +Object::~Object() { Renderer &renderer= Renderer::getInstance(); // fade(and by this remove) all unit particle systems while(unitParticleSystems.empty() == false) { - unitParticleSystems.back()->fade(); + bool particleValid = Renderer::getInstance().validateParticleSystemStillExists(unitParticleSystems.back(),rsGame); + if(particleValid == true) { + unitParticleSystems.back()->fade(); + } unitParticleSystems.pop_back(); } renderer.removeObjectFromQuadCache(this); @@ -68,24 +71,27 @@ Object::~Object(){ delete resource; } -void Object::end(){ +void Object::end() { // set Objects to fading and remove them from list. // its needed because otherwise they will be accessed from the destructor while(unitParticleSystems.empty() == false) { - unitParticleSystems.back()->fade(); + bool particleValid = Renderer::getInstance().validateParticleSystemStillExists(unitParticleSystems.back(),rsGame); + if(particleValid == true) { + unitParticleSystems.back()->fade(); + } unitParticleSystems.pop_back(); } } -void Object::initParticles(){ - if(this->objectType==NULL) return; - if(this->objectType->getTilesetModelType(variation)->hasParticles()){ +void Object::initParticles() { + if(this->objectType == NULL) return; + if(this->objectType->getTilesetModelType(variation)->hasParticles()) { ModelParticleSystemTypes *particleTypes= this->objectType->getTilesetModelType(variation)->getParticleTypes(); initParticlesFromTypes(particleTypes); } } -void Object::initParticlesFromTypes(const ModelParticleSystemTypes *particleTypes){ +void Object::initParticlesFromTypes(const ModelParticleSystemTypes *particleTypes) { if(Config::getInstance().getBool("TilesetParticles", "true") && (particleTypes->empty() == false) && (unitParticleSystems.empty() == true)){ for(ObjectParticleSystemTypes::const_iterator it= particleTypes->begin(); it != particleTypes->end(); ++it){ @@ -101,12 +107,14 @@ void Object::initParticlesFromTypes(const ModelParticleSystemTypes *particleType } } - void Object::setHeight(float height){ pos.y=height; for(UnitParticleSystems::iterator it= unitParticleSystems.begin(); it != unitParticleSystems.end(); ++it) { - (*it)->setPos(this->pos); + bool particleValid = Renderer::getInstance().validateParticleSystemStillExists((*it),rsGame); + if(particleValid == true) { + (*it)->setPos(this->pos); + } } } @@ -156,8 +164,11 @@ void Object::setVisible( bool visible) { this->visible=visible; for(UnitParticleSystems::iterator it= unitParticleSystems.begin(); it != unitParticleSystems.end(); ++it) { + bool particleValid = Renderer::getInstance().validateParticleSystemStillExists((*it),rsGame); + if(particleValid == true) { (*it)->setVisible(visible); } + } } }}//end namespace diff --git a/source/shared_lib/include/platform/common/base_thread.h b/source/shared_lib/include/platform/common/base_thread.h index e580ba128..41746d592 100644 --- a/source/shared_lib/include/platform/common/base_thread.h +++ b/source/shared_lib/include/platform/common/base_thread.h @@ -50,6 +50,8 @@ protected: virtual void setQuitStatus(bool value); void deleteSelfIfRequired(); + void *genericData; + public: BaseThread(); virtual ~BaseThread(); @@ -83,6 +85,11 @@ public: Mutex * getMutexThreadOwnerValid(); Mutex * getMutexThreadObjectAccessor() { return &mutexThreadObjectAccessor; } + + template + T * getGenericData() { return genericData; } + template + void setGenericData(T *value) { genericData = value; } }; class RunningStatusSafeWrapper { diff --git a/source/shared_lib/include/platform/common/platform_common.h b/source/shared_lib/include/platform/common/platform_common.h index 704308a6c..21e9ce0c5 100644 --- a/source/shared_lib/include/platform/common/platform_common.h +++ b/source/shared_lib/include/platform/common/platform_common.h @@ -41,6 +41,11 @@ using Shared::Util::Checksum; namespace Shared { namespace PlatformCommon { +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) +#define CODE_AT_LINE __FILE__ ":" TOSTRING(__LINE__) +#define CODE_AT_LINE_X(x) __FILE__ ":" TOSTRING(__LINE__) ":" TOSTRING(x) + static const int IGNORE_CMD_RESULT_VALUE = -999999; // keycode constants (unfortunately designed after DirectInput and therefore not diff --git a/source/shared_lib/include/platform/common/simple_threads.h b/source/shared_lib/include/platform/common/simple_threads.h index 8e0fe3956..bf268b643 100644 --- a/source/shared_lib/include/platform/common/simple_threads.h +++ b/source/shared_lib/include/platform/common/simple_threads.h @@ -69,6 +69,9 @@ public: class SimpleTaskCallbackInterface { public: virtual void simpleTask(BaseThread *callingThread) = 0; + + virtual void setupTask(BaseThread *callingThread) {} + virtual void shutdownTask(BaseThread *callingThread) {} }; class SimpleTaskThread : public BaseThread @@ -87,11 +90,12 @@ protected: time_t lastExecuteTimestamp; public: - SimpleTaskThread(); SimpleTaskThread(SimpleTaskCallbackInterface *simpleTaskInterface, unsigned int executionCount=0, unsigned int millisecsBetweenExecutions=0, bool needTaskSignal = false); + virtual ~SimpleTaskThread(); + virtual void execute(); virtual bool canShutdown(bool deleteSelfIfShutdownDelayed=false); diff --git a/source/shared_lib/include/platform/posix/socket.h b/source/shared_lib/include/platform/posix/socket.h index 70cc20ef2..7dce84e4a 100644 --- a/source/shared_lib/include/platform/posix/socket.h +++ b/source/shared_lib/include/platform/posix/socket.h @@ -204,12 +204,17 @@ protected: class BroadCastSocketThread : public BaseThread { private: + Mutex mutexPauseBroadcast; + bool pauseBroadcast; public: BroadCastSocketThread(); virtual ~BroadCastSocketThread(); virtual void execute(); virtual bool canShutdown(bool deleteSelfIfShutdownDelayed=false); + + bool getPauseBroadcast(); + void setPauseBroadcast(bool value); }; // ===================================================== @@ -229,6 +234,7 @@ protected: virtual void UPNPInitStatus(bool result); BroadCastSocketThread *broadCastThread; void startBroadCastThread(); + void resumeBroadcast(); bool isBroadCastThreadRunning(); vector blockIPList; @@ -239,6 +245,8 @@ public: void listen(int connectionQueueSize= SOMAXCONN); Socket *accept(); void stopBroadCastThread(); + void pauseBroadcast(); + void addIPAddressToBlockedList(string value); bool isIPAddressBlocked(string value) const; @@ -275,6 +283,7 @@ public: static bool isUPNP; static bool enabledUPNP; + static Mutex mutexUPNP; static int upnp_init(void *param); diff --git a/source/shared_lib/include/platform/sdl/thread.h b/source/shared_lib/include/platform/sdl/thread.h index 7d55510e9..e611cac57 100644 --- a/source/shared_lib/include/platform/sdl/thread.h +++ b/source/shared_lib/include/platform/sdl/thread.h @@ -77,11 +77,14 @@ private: class Mutex { private: + SDL_mutex* mutex; int refCount; string ownerId; string deleteownerId; + SDL_mutex* mutexAccessor; + public: Mutex(string ownerId=""); ~Mutex(); diff --git a/source/shared_lib/sources/platform/common/simple_threads.cpp b/source/shared_lib/sources/platform/common/simple_threads.cpp index 49b72c42c..a9fd23da1 100644 --- a/source/shared_lib/sources/platform/common/simple_threads.cpp +++ b/source/shared_lib/sources/platform/common/simple_threads.cpp @@ -302,6 +302,12 @@ SimpleTaskThread::SimpleTaskThread( SimpleTaskCallbackInterface *simpleTaskInter MutexSafeWrapper safeMutex(&mutexLastExecuteTimestamp,mutexOwnerId); mutexLastExecuteTimestamp.setOwnerId(mutexOwnerId); lastExecuteTimestamp = time(NULL); + + this->simpleTaskInterface->setupTask(this); +} + +SimpleTaskThread::~SimpleTaskThread() { + this->simpleTaskInterface->shutdownTask(this); } bool SimpleTaskThread::isThreadExecutionLagging() { diff --git a/source/shared_lib/sources/platform/posix/socket.cpp b/source/shared_lib/sources/platform/posix/socket.cpp index f1467cd5c..db94842f0 100644 --- a/source/shared_lib/sources/platform/posix/socket.cpp +++ b/source/shared_lib/sources/platform/posix/socket.cpp @@ -78,6 +78,7 @@ static struct IGDdatas data; static char lanaddr[16] = ""; bool UPNP_Tools::isUPNP = true; bool UPNP_Tools::enabledUPNP = false; +Mutex UPNP_Tools::mutexUPNP; // UPnP - End #ifdef WIN32 @@ -172,7 +173,7 @@ bool UPNP_Tools::enabledUPNP = false; return rhs1.nID < rhs2.nID; } - const int kNumMessages = sizeof(gaErrorList) / sizeof(ErrorEntry); + const int kNumMessages = sizeof(gaErrorList) / sizeof(ErrorEntry[0]); //// WSAGetLastErrorMessage //////////////////////////////////////////// // A function similar in spirit to Unix's perror() that tacks a canned @@ -189,7 +190,7 @@ bool UPNP_Tools::enabledUPNP = false; { // Build basic error string static char acErrorBuffer[256]; - std::ostrstream outs(acErrorBuffer, sizeof(acErrorBuffer)); + std::ostrstream outs(acErrorBuffer, (sizeof(acErrorBuffer) / sizeof(acErrorBuffer[0]))); outs << pcMessagePrefix << ": "; // Tack appropriate canned message onto end of supplied message @@ -211,7 +212,7 @@ bool UPNP_Tools::enabledUPNP = false; // Finish error message off and return it. outs << std::ends; - acErrorBuffer[sizeof(acErrorBuffer) - 1] = '\0'; + acErrorBuffer[(sizeof(acErrorBuffer) / sizeof(acErrorBuffer[0])) - 1] = '\0'; return acErrorBuffer; } @@ -652,7 +653,9 @@ std::vector Socket::getLocalIPAddressList() { char myhostaddr[101] = ""; int ipIdx = 0; while (myhostent->h_addr_list[ipIdx] != 0) { - sprintf(myhostaddr, "%s",inet_ntoa(*(struct in_addr *)myhostent->h_addr_list[ipIdx])); + //sprintf(myhostaddr, "%s",inet_ntoa(*(struct in_addr *)myhostent->h_addr_list[ipIdx])); + Inet_NtoA(SockAddrToUint32((struct sockaddr *)&myhostent->h_addr_list[ipIdx]), myhostaddr); + //printf("%s\n",myhostaddr); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] myhostaddr = [%s]\n",__FILE__,__FUNCTION__,__LINE__,myhostaddr); @@ -706,7 +709,8 @@ std::vector Socket::getLocalIPAddressList() { if(result_ifaddrr >= 0) { struct sockaddr_in *pSockAddr = (struct sockaddr_in *)&ifr.ifr_addr; if(pSockAddr != NULL) { - sprintf(myhostaddr, "%s",inet_ntoa(pSockAddr->sin_addr)); + //sprintf(myhostaddr, "%s",inet_ntoa(pSockAddr->sin_addr)); + Inet_NtoA(SockAddrToUint32((struct sockaddr *)&pSockAddr->sin_addr), myhostaddr); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] szBuf [%s], myhostaddr = [%s], ifr.ifr_flags = %d, ifrA.ifr_flags = %d, ifr.ifr_name [%s]\n",__FILE__,__FUNCTION__,__LINE__,szBuf,myhostaddr,ifr.ifr_flags,ifrA.ifr_flags,ifr.ifr_name); // Now only include interfaces that are both UP and running @@ -753,15 +757,15 @@ bool Socket::isSocketValid(const PLATFORM_SOCKET *validateSocket) { } Socket::Socket(PLATFORM_SOCKET sock) { - MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); - inSocketDestructorSynchAccessor.setOwnerId(string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); + inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); this->inSocketDestructor = false; //safeMutexSocketDestructorFlag.ReleaseLock(); //this->pingThread = NULL; - pingThreadAccessor.setOwnerId(string(__FILE__) + "_" + intToStr(__LINE__)); - dataSynchAccessorRead.setOwnerId(string(__FILE__) + "_" + intToStr(__LINE__)); - dataSynchAccessorWrite.setOwnerId(string(__FILE__) + "_" + intToStr(__LINE__)); + pingThreadAccessor.setOwnerId(CODE_AT_LINE); + dataSynchAccessorRead.setOwnerId(CODE_AT_LINE); + dataSynchAccessorWrite.setOwnerId(CODE_AT_LINE); @@ -770,8 +774,8 @@ Socket::Socket(PLATFORM_SOCKET sock) { } Socket::Socket() { - MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); - inSocketDestructorSynchAccessor.setOwnerId(string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); + inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); this->inSocketDestructor = false; //safeMutexSocketDestructorFlag.ReleaseLock(); @@ -830,7 +834,7 @@ void Socket::simpleTask(BaseThread *callingThread) { for(std::map::iterator iterMap = pingCache.begin(); iterMap != pingCache.end(); iterMap++) { - MutexSafeWrapper safeMutex(&pingThreadAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutex(&pingThreadAccessor,CODE_AT_LINE); iterMap->second = getAveragePingMS(iterMap->first, 1); safeMutex.ReleaseLock(); } @@ -838,12 +842,12 @@ void Socket::simpleTask(BaseThread *callingThread) { */ Socket::~Socket() { - MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); if(this->inSocketDestructor == true) { SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); return; } - inSocketDestructorSynchAccessor.setOwnerId(string(__FILE__) + "_" + intToStr(__LINE__)); + inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); this->inSocketDestructor = true; if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START closing socket = %d...\n",__FILE__,__FUNCTION__,sock); @@ -864,6 +868,7 @@ Socket::~Socket() { //delete pingThread; //pingThread = NULL; + safeMutexSocketDestructorFlag.ReleaseLock(); } void Socket::disconnectSocket() { @@ -872,8 +877,8 @@ void Socket::disconnectSocket() { if(isSocketValid() == true) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] calling shutdown and close for socket = %d...\n",__FILE__,__FUNCTION__,sock); - MutexSafeWrapper safeMutex(&dataSynchAccessorRead,string(__FILE__) + "_" + intToStr(__LINE__)); - MutexSafeWrapper safeMutex1(&dataSynchAccessorWrite,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutex(&dataSynchAccessorRead,CODE_AT_LINE); + MutexSafeWrapper safeMutex1(&dataSynchAccessorWrite,CODE_AT_LINE); ::shutdown(sock,2); #ifndef WIN32 ::close(sock); @@ -1062,15 +1067,15 @@ int Socket::send(const void *data, int dataSize) { if(isSocketValid() == true) { errno = 0; - MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); if(this->inSocketDestructor == true) { SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); return -1; } - inSocketDestructorSynchAccessor.setOwnerId(string(__FILE__) + "_" + intToStr(__LINE__)); + inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); safeMutexSocketDestructorFlag.ReleaseLock(); - MutexSafeWrapper safeMutex(&dataSynchAccessorWrite,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutex(&dataSynchAccessorWrite,CODE_AT_LINE); #ifdef __APPLE__ bytesSent = ::send(sock, (const char *)data, dataSize, SO_NOSIGPIPE); @@ -1100,15 +1105,15 @@ int Socket::send(const void *data, int dataSize) { if(isConnected() == true) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d, sock = %d, dataSize = %d, data = %p\n",__FILE__,__FUNCTION__,__LINE__,attemptCount,sock,dataSize,data); - MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); if(this->inSocketDestructor == true) { SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); return -1; } - inSocketDestructorSynchAccessor.setOwnerId(string(__FILE__) + "_" + intToStr(__LINE__)); + inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); safeMutexSocketDestructorFlag.ReleaseLock(); - MutexSafeWrapper safeMutex(&dataSynchAccessorWrite,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutex(&dataSynchAccessorWrite,CODE_AT_LINE); #ifdef __APPLE__ bytesSent = ::send(sock, (const char *)data, dataSize, SO_NOSIGPIPE); #else @@ -1149,15 +1154,15 @@ int Socket::send(const void *data, int dataSize) { if(isConnected() == true) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d, sock = %d, dataSize = %d, data = %p\n",__FILE__,__FUNCTION__,__LINE__,attemptCount,sock,dataSize,data); - MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); if(this->inSocketDestructor == true) { SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); return -1; } - inSocketDestructorSynchAccessor.setOwnerId(string(__FILE__) + "_" + intToStr(__LINE__)); + inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); safeMutexSocketDestructorFlag.ReleaseLock(); - MutexSafeWrapper safeMutex(&dataSynchAccessorWrite,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutex(&dataSynchAccessorWrite,CODE_AT_LINE); const char *sendBuf = (const char *)data; #ifdef __APPLE__ bytesSent = ::send(sock, &sendBuf[totalBytesSent], dataSize - totalBytesSent, SO_NOSIGPIPE); @@ -1214,15 +1219,15 @@ int Socket::receive(void *data, int dataSize, bool tryReceiveUntilDataSizeMet) { ssize_t bytesReceived = 0; if(isSocketValid() == true) { - MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); if(this->inSocketDestructor == true) { SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); return -1; } - inSocketDestructorSynchAccessor.setOwnerId(string(__FILE__) + "_" + intToStr(__LINE__)); + inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); safeMutexSocketDestructorFlag.ReleaseLock(); - MutexSafeWrapper safeMutex(&dataSynchAccessorRead,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutex(&dataSynchAccessorRead,CODE_AT_LINE); bytesReceived = recv(sock, reinterpret_cast(data), dataSize, 0); safeMutex.ReleaseLock(); } @@ -1243,15 +1248,15 @@ int Socket::receive(void *data, int dataSize, bool tryReceiveUntilDataSizeMet) { break; } else if(Socket::isReadable() == true) { - MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); if(this->inSocketDestructor == true) { SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); return -1; } - inSocketDestructorSynchAccessor.setOwnerId(string(__FILE__) + "_" + intToStr(__LINE__)); + inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); safeMutexSocketDestructorFlag.ReleaseLock(); - MutexSafeWrapper safeMutex(&dataSynchAccessorRead,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutex(&dataSynchAccessorRead,CODE_AT_LINE); bytesReceived = recv(sock, reinterpret_cast(data), dataSize, 0); safeMutex.ReleaseLock(); @@ -1301,15 +1306,15 @@ int Socket::peek(void *data, int dataSize,bool mustGetData) { if(isSocketValid() == 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()); - MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); if(this->inSocketDestructor == true) { SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); return -1; } - inSocketDestructorSynchAccessor.setOwnerId(string(__FILE__) + "_" + intToStr(__LINE__)); + inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); safeMutexSocketDestructorFlag.ReleaseLock(); - //MutexSafeWrapper safeMutex(&dataSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(sock) + "_" + intToStr(dataSize)); + //MutexSafeWrapper safeMutex(&dataSynchAccessor,CODE_AT_LINE + "_" + intToStr(sock) + "_" + intToStr(dataSize)); static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); MutexSafeWrapper safeMutex(&dataSynchAccessorRead,mutexOwnerId); @@ -1341,15 +1346,15 @@ int Socket::peek(void *data, int dataSize,bool mustGetData) { */ if(Socket::isReadable() == true) { - MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); if(this->inSocketDestructor == true) { SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); return -1; } - inSocketDestructorSynchAccessor.setOwnerId(string(__FILE__) + "_" + intToStr(__LINE__)); + inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); safeMutexSocketDestructorFlag.ReleaseLock(); - //MutexSafeWrapper safeMutex(&dataSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__) + "_" + intToStr(sock) + "_" + intToStr(dataSize)); + //MutexSafeWrapper safeMutex(&dataSynchAccessor,CODE_AT_LINE + "_" + intToStr(sock) + "_" + intToStr(dataSize)); MutexSafeWrapper safeMutex(&dataSynchAccessorRead,string(__FILE__) + string("_") + intToStr(__LINE__)); err = recv(sock, reinterpret_cast(data), dataSize, MSG_PEEK); safeMutex.ReleaseLock(); @@ -1420,15 +1425,15 @@ bool Socket::isReadable() { int i = 0; { - //MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + //MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); //if(this->inSocketDestructor == true) { // SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); // return false; //} - //inSocketDestructorSynchAccessor.setOwnerId(string(__FILE__) + "_" + intToStr(__LINE__)); + //inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); //safeMutexSocketDestructorFlag.ReleaseLock(); - MutexSafeWrapper safeMutex(&dataSynchAccessorRead,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutex(&dataSynchAccessorRead,CODE_AT_LINE); i= select((int)sock + 1, &set, NULL, NULL, &tv); } if(i < 0) { @@ -1457,15 +1462,15 @@ bool Socket::isWritable() { int i = 0; { - //MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + //MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); //if(this->inSocketDestructor == true) { // SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); // return false; //} - //inSocketDestructorSynchAccessor.setOwnerId(string(__FILE__) + "_" + intToStr(__LINE__)); + //inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); //safeMutexSocketDestructorFlag.ReleaseLock(); - MutexSafeWrapper safeMutex(&dataSynchAccessorWrite,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutex(&dataSynchAccessorWrite,CODE_AT_LINE); i = select((int)sock + 1, NULL, &set, NULL, &tv); } bool result = false; @@ -1490,12 +1495,12 @@ bool Socket::isWritable() { bool Socket::isConnected() { if(isSocketValid() == false) return false; - MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); if(this->inSocketDestructor == true) { SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); return false; } - inSocketDestructorSynchAccessor.setOwnerId(string(__FILE__) + "_" + intToStr(__LINE__)); + inSocketDestructorSynchAccessor.setOwnerId(CODE_AT_LINE); //if the socket is not writable then it is not conencted if(isWritable() == false) { @@ -1645,7 +1650,7 @@ void ClientSocket::connect(const Ip &ip, int port) FD_SET(sock, &myset); { - MutexSafeWrapper safeMutex(&dataSynchAccessorRead,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutex(&dataSynchAccessorRead,CODE_AT_LINE); err = select((int)sock + 1, NULL, &myset, NULL, &tv); //safeMutex.ReleaseLock(); } @@ -1787,7 +1792,10 @@ void BroadCastClientSocketThread::execute() { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"recvfrom failed: %s\n", getLastSocketErrorFormattedText().c_str()); } else { - string fromIP = inet_ntoa(bcSender.sin_addr); + //string fromIP = inet_ntoa(bcSender.sin_addr); + char szHostFrom[100]=""; + Inet_NtoA(SockAddrToUint32((struct sockaddr *)&bcSender.sin_addr), szHostFrom); + string fromIP = szHostFrom; if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"broadcast message received: [%s] from: [%s]\n", buff,fromIP.c_str() ); if(std::find(foundServers.begin(),foundServers.end(),fromIP) == foundServers.end()) { @@ -1847,9 +1855,10 @@ void BroadCastClientSocketThread::execute() { ServerSocket::ServerSocket() : Socket() { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - MutexSafeWrapper safeMutexUPNP(&ServerSocket::mutexUpnpdiscoverThread,string(__FILE__) + "_" + intToStr(__LINE__)); - ServerSocket::upnpdiscoverThread = NULL; - safeMutexUPNP.ReleaseLock(); + //printf("SERVER SOCKET CONSTRUCTOR\n"); + //MutexSafeWrapper safeMutexUPNP(&ServerSocket::mutexUpnpdiscoverThread,CODE_AT_LINE); + //ServerSocket::upnpdiscoverThread = NULL; + //safeMutexUPNP.ReleaseLock(); portBound = false; broadCastThread = NULL; @@ -1866,7 +1875,8 @@ ServerSocket::~ServerSocket() { stopBroadCastThread(); //printf("In [%s::%s] Line: %d safeMutexUPNP\n",__FILE__,__FUNCTION__,__LINE__); - MutexSafeWrapper safeMutexUPNP(&ServerSocket::mutexUpnpdiscoverThread,string(__FILE__) + "_" + intToStr(__LINE__)); + //printf("SERVER SOCKET DESTRUCTOR\n"); + MutexSafeWrapper safeMutexUPNP(&ServerSocket::mutexUpnpdiscoverThread,CODE_AT_LINE); if(ServerSocket::upnpdiscoverThread != NULL) { SDL_WaitThread(ServerSocket::upnpdiscoverThread, NULL); ServerSocket::upnpdiscoverThread = NULL; @@ -1880,11 +1890,13 @@ ServerSocket::~ServerSocket() { //UPNP_Tools::enabledUPNP = false; } + MutexSafeWrapper safeMutexUPNP1(&UPNP_Tools::mutexUPNP,CODE_AT_LINE); if(urls.controlURL && urls.ipcondescURL && urls.controlURL_CIF) { FreeUPNPUrls(&urls); } if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + safeMutexUPNP1.ReleaseLock(); } void ServerSocket::stopBroadCastThread() { @@ -1933,6 +1945,17 @@ void ServerSocket::startBroadCastThread() { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } +void ServerSocket::resumeBroadcast() { + if(broadCastThread != NULL) { + broadCastThread->setPauseBroadcast(false); + } +} +void ServerSocket::pauseBroadcast() { + if(broadCastThread != NULL) { + broadCastThread->setPauseBroadcast(true); + } +} + bool ServerSocket::isBroadCastThreadRunning() { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); @@ -2024,9 +2047,12 @@ void ServerSocket::listen(int connectionQueueSize) { if(isBroadCastThreadRunning() == false) { startBroadCastThread(); } + else { + resumeBroadcast(); + } } else { - stopBroadCastThread(); + pauseBroadcast(); } } @@ -2038,7 +2064,7 @@ Socket *ServerSocket::accept() { struct sockaddr_in cli_addr; socklen_t clilen = sizeof(cli_addr); char client_host[100]=""; - MutexSafeWrapper safeMutex(&dataSynchAccessorRead,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutex(&dataSynchAccessorRead,CODE_AT_LINE); PLATFORM_SOCKET newSock= ::accept(sock, (struct sockaddr *) &cli_addr, &clilen); safeMutex.ReleaseLock(); @@ -2055,10 +2081,12 @@ Socket *ServerSocket::accept() { } else { - sprintf(client_host, "%s",inet_ntoa(cli_addr.sin_addr)); + Inet_NtoA(SockAddrToUint32((struct sockaddr *)&cli_addr), client_host); + //printf("client_host [%s]\n",client_host); + //sprintf(client_host, "%s",inet_ntoa(cli_addr.sin_addr)); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got connection, newSock = %d client_host [%s]\n",__FILE__,__FUNCTION__,__LINE__,newSock,client_host); } - if(isIPAddressBlocked(client_host) == true) { + if(isIPAddressBlocked((client_host[0] != '\0' ? client_host : "")) == true) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] BLOCKING connection, newSock = %d client_host [%s]\n",__FILE__,__FUNCTION__,__LINE__,newSock,client_host); #ifndef WIN32 @@ -2073,15 +2101,16 @@ Socket *ServerSocket::accept() { } Socket *result = new Socket(newSock); - result->setIpAddress(client_host); + result->setIpAddress((client_host[0] != '\0' ? client_host : "")); return result; } void ServerSocket::NETdiscoverUPnPDevices() { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] UPNP - Start\n",__FILE__,__FUNCTION__,__LINE__); + //printf("SERVER SOCKET NETdiscoverUPnPDevices - START\n"); //printf("In [%s::%s] Line: %d safeMutexUPNP\n",__FILE__,__FUNCTION__,__LINE__); - MutexSafeWrapper safeMutexUPNP(&ServerSocket::mutexUpnpdiscoverThread,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexUPNP(&ServerSocket::mutexUpnpdiscoverThread,CODE_AT_LINE); if(ServerSocket::upnpdiscoverThread != NULL) { SDL_WaitThread(ServerSocket::upnpdiscoverThread, NULL); ServerSocket::upnpdiscoverThread = NULL; @@ -2089,9 +2118,12 @@ void ServerSocket::NETdiscoverUPnPDevices() { // WATCH OUT! Because the thread takes void * as a parameter we MUST cast to the pointer type // used on the other side (inside the thread) + //printf("STARTING UPNP Thread\n"); ServerSocket::upnpdiscoverThread = SDL_CreateThread(&UPNP_Tools::upnp_init, dynamic_cast(this)); safeMutexUPNP.ReleaseLock(); //printf("In [%s::%s] Line: %d safeMutexUPNP\n",__FILE__,__FUNCTION__,__LINE__); + + //printf("SERVER SOCKET NETdiscoverUPnPDevices - END\n"); } void ServerSocket::UPNPInitStatus(bool result) { @@ -2147,6 +2179,7 @@ void UPNP_Tools::RemoveUPNPPortForward(int internalPort, int externalPort) { // This code below handles Universal Plug and Play Router Discovery // int UPNP_Tools::upnp_init(void *param) { + int result = -1; struct UPNPDev *devlist = NULL; struct UPNPDev *dev = NULL; char *descXML = NULL; @@ -2155,6 +2188,7 @@ int UPNP_Tools::upnp_init(void *param) { // Callers MUST pass in NULL or a UPNPInitInterface * UPNPInitInterface *callback = (UPNPInitInterface *)(param); + MutexSafeWrapper safeMutexUPNP(&UPNP_Tools::mutexUPNP,CODE_AT_LINE); memset(&urls, 0, sizeof(struct UPNPUrls)); memset(&data, 0, sizeof(struct IGDdatas)); @@ -2202,77 +2236,95 @@ int UPNP_Tools::upnp_init(void *param) { dev = devlist; /* defaulting to first device */ } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"UPnP device found: %s %s\n", dev->descURL, dev->st); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("UPnP device found: %s %s\n", dev->descURL, dev->st); + if(dev != NULL) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"UPnP device found: %s %s\n", dev->descURL, dev->st); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("UPnP device found: %s %s\n", dev->descURL, dev->st); - descXML = (char *)miniwget_getaddr(dev->descURL, &descXMLsize, lanaddr, sizeof(lanaddr)); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"LAN address: %s\n", lanaddr); + //printf("UPnP device found: [%s] [%s] lanaddr [%s]\n", dev->descURL, dev->st,lanaddr); + descXML = (char *)miniwget_getaddr(dev->descURL, &descXMLsize, lanaddr, (sizeof(lanaddr) / sizeof(lanaddr[0]))); + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"LAN address: %s\n", lanaddr); - if (descXML) { - parserootdesc (descXML, descXMLsize, &data); - free (descXML); descXML = 0; - GetUPNPUrls (&urls, &data, dev->descURL); + if (descXML) { + parserootdesc (descXML, descXMLsize, &data); + free (descXML); descXML = 0; + GetUPNPUrls (&urls, &data, dev->descURL); + } + sprintf(buf, "UPnP device found: %s %s LAN address %s", dev->descURL, dev->st, lanaddr); + + freeUPNPDevlist(devlist); + devlist = NULL; } - sprintf(buf, "UPnP device found: %s %s LAN address %s", dev->descURL, dev->st, lanaddr); - - freeUPNPDevlist(devlist); if (!urls.controlURL || urls.controlURL[0] == '\0') { sprintf(buf, "controlURL not available, UPnP disabled"); if(callback) { + safeMutexUPNP.ReleaseLock(); callback->UPNPInitStatus(false); } - return false; + result = 0; } - - char externalIP[16] = ""; + else { + char externalIP[16] = ""; #ifndef MINIUPNPC_VERSION_PRE1_5 - UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIP); + UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIP); #else - UPNP_GetExternalIPAddress(urls.controlURL, data.servicetype, externalIP); + UPNP_GetExternalIPAddress(urls.controlURL, data.servicetype, externalIP); #endif - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"UPnP device found at: [%s] callback [%p]\n",externalIP,callback); + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"UPnP device found at: [%s] callback [%p]\n",externalIP,callback); - //UPNP_Tools::NETaddRedirects(ports); - UPNP_Tools::enabledUPNP = true; - if(callback) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - callback->UPNPInitStatus(true); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - } - return true; + //UPNP_Tools::NETaddRedirects(ports); + UPNP_Tools::enabledUPNP = true; + if(callback) { + safeMutexUPNP.ReleaseLock(); + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + callback->UPNPInitStatus(true); + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + } + result = 1; + } } - sprintf(buf, "UPnP device not found."); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"No UPnP devices found.\n"); + if(result == -1) { + sprintf(buf, "UPnP device not found."); - if(callback) { - callback->UPNPInitStatus(false); - } - return false; + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"No UPnP devices found.\n"); + + if(callback) { + safeMutexUPNP.ReleaseLock(); + callback->UPNPInitStatus(false); + } + result = 0; + } } else { sprintf(buf, "UPnP detection routine disabled by user."); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"UPnP detection routine disabled by user.\n"); if(callback) { + safeMutexUPNP.ReleaseLock(); callback->UPNPInitStatus(false); } - return false; + result = 0; } + + //printf("ENDING UPNP Thread\n"); + + return result; } bool UPNP_Tools::upnp_add_redirect(int ports[2],bool mutexLock) { + bool result = true; char externalIP[16] = ""; char ext_port_str[16] = ""; char int_port_str[16] = ""; int r = 0; + //printf("SERVER SOCKET upnp_add_redirect - START\n"); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] upnp_add_redir(%d : %d)\n",__FILE__,__FUNCTION__,__LINE__,ports[0],ports[1]); if(mutexLock) { //printf("In [%s::%s] Line: %d safeMutexUPNP\n",__FILE__,__FUNCTION__,__LINE__); - MutexSafeWrapper safeMutexUPNP(&ServerSocket::mutexUpnpdiscoverThread,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexUPNP(&ServerSocket::mutexUpnpdiscoverThread,CODE_AT_LINE); if(ServerSocket::upnpdiscoverThread != NULL) { SDL_WaitThread(ServerSocket::upnpdiscoverThread, NULL); ServerSocket::upnpdiscoverThread = NULL; @@ -2281,17 +2333,19 @@ bool UPNP_Tools::upnp_add_redirect(int ports[2],bool mutexLock) { //printf("In [%s::%s] Line: %d safeMutexUPNP\n",__FILE__,__FUNCTION__,__LINE__); } + MutexSafeWrapper safeMutexUPNP(&UPNP_Tools::mutexUPNP,CODE_AT_LINE); if (!urls.controlURL || urls.controlURL[0] == '\0') { - return false; + result = false; } + else { #ifndef MINIUPNPC_VERSION_PRE1_5 - UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIP); + UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIP); #else - UPNP_GetExternalIPAddress(urls.controlURL, data.servicetype, externalIP); + UPNP_GetExternalIPAddress(urls.controlURL, data.servicetype, externalIP); #endif - sprintf(ext_port_str, "%d", ports[0]); - sprintf(int_port_str, "%d", ports[1]); + sprintf(ext_port_str, "%d", ports[0]); + sprintf(int_port_str, "%d", ports[1]); #ifndef MINIUPNPC_VERSION_PRE1_5 #ifndef MINIUPNPC_VERSION_PRE1_6 @@ -2300,22 +2354,27 @@ bool UPNP_Tools::upnp_add_redirect(int ports[2],bool mutexLock) { r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,ext_port_str, int_port_str, lanaddr, "MegaGlest - www.megaglest.org", "TCP", 0); #endif #else - r = UPNP_AddPortMapping(urls.controlURL, data.servicetype,ext_port_str, int_port_str, lanaddr, "MegaGlest - www.megaglest.org", "TCP", 0); + r = UPNP_AddPortMapping(urls.controlURL, data.servicetype,ext_port_str, int_port_str, lanaddr, "MegaGlest - www.megaglest.org", "TCP", 0); #endif - if (r != UPNPCOMMAND_SUCCESS) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] AddPortMapping(%s, %s, %s) failed\n",__FILE__,__FUNCTION__,__LINE__,ext_port_str, int_port_str, lanaddr); - return false; + if (r != UPNPCOMMAND_SUCCESS) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] AddPortMapping(%s, %s, %s) failed\n",__FILE__,__FUNCTION__,__LINE__,ext_port_str, int_port_str, lanaddr); + result = false; + } + + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] AddPortMapping(%s, %s, %s) success\n",__FILE__,__FUNCTION__,__LINE__,ext_port_str, int_port_str, lanaddr); } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] AddPortMapping(%s, %s, %s) success\n",__FILE__,__FUNCTION__,__LINE__,ext_port_str, int_port_str, lanaddr); - return true; + //printf("SERVER SOCKET upnp_add_redirect - END [%d]\n",result); + return result; } void UPNP_Tools::upnp_rem_redirect(int ext_port) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] upnp_rem_redir(%d)\n",__FILE__,__FUNCTION__,__LINE__,ext_port); + //printf("SERVER SOCKET upnp_rem_redirect - START\n"); + //printf("In [%s::%s] Line: %d safeMutexUPNP\n",__FILE__,__FUNCTION__,__LINE__); - MutexSafeWrapper safeMutexUPNP(&ServerSocket::mutexUpnpdiscoverThread,string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexUPNP(&ServerSocket::mutexUpnpdiscoverThread,CODE_AT_LINE); if(ServerSocket::upnpdiscoverThread != NULL) { SDL_WaitThread(ServerSocket::upnpdiscoverThread, NULL); ServerSocket::upnpdiscoverThread = NULL; @@ -2325,6 +2384,7 @@ void UPNP_Tools::upnp_rem_redirect(int ext_port) { //printf("In [%s::%s] Line: %d ext_port = %d urls.controlURL = [%s]\n",__FILE__,__FUNCTION__,__LINE__,ext_port,urls.controlURL); + MutexSafeWrapper safeMutexUPNP1(&UPNP_Tools::mutexUPNP,CODE_AT_LINE); if (urls.controlURL && urls.controlURL[0] != '\0') { char ext_port_str[16]=""; sprintf(ext_port_str, "%d", ext_port); @@ -2343,6 +2403,8 @@ void UPNP_Tools::upnp_rem_redirect(int ext_port) { //printf("\n\nresult = %d\n",result); } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n#2 DEBUGGING urls.controlURL [%s]\n",urls.controlURL); + + //printf("SERVER SOCKET upnp_rem_redirect - END\n"); } void UPNP_Tools::NETaddRedirects(std::vector UPNPPortForwardList,bool mutexLock) { @@ -2384,6 +2446,19 @@ BroadCastSocketThread::~BroadCastSocketThread() { //printf("delete broadcast thread [%p]\n",this); } +bool BroadCastSocketThread::getPauseBroadcast() { + MutexSafeWrapper safeMutexSocketDestructorFlag(&mutexPauseBroadcast,CODE_AT_LINE); + mutexPauseBroadcast.setOwnerId(CODE_AT_LINE); + return pauseBroadcast; +} + +void BroadCastSocketThread::setPauseBroadcast(bool value) { + MutexSafeWrapper safeMutexSocketDestructorFlag(&mutexPauseBroadcast,CODE_AT_LINE); + mutexPauseBroadcast.setOwnerId(CODE_AT_LINE); + pauseBroadcast = value; +} + + bool BroadCastSocketThread::canShutdown(bool deleteSelfIfShutdownDelayed) { bool ret = (getExecutingTask() == false); if(ret == false && deleteSelfIfShutdownDelayed == true) { @@ -2479,15 +2554,17 @@ void BroadCastSocketThread::execute() { if(difftime(time(NULL),elapsed) >= 1 && getQuitStatus() == false) { elapsed = time(NULL); - // Broadcast the packet to the subnet - //if( sendto( bcfd, buff, sizeof(buff) + 1, 0 , (struct sockaddr *)&bcaddr, sizeof(struct sockaddr_in) ) != sizeof(buff) + 1 ) - if( sendto( bcfd[idx], buff, buffMaxSize, 0 , (struct sockaddr *)&bcLocal[idx], sizeof(struct sockaddr_in) ) != buffMaxSize ) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Sendto error: %s\n", getLastSocketErrorFormattedText().c_str()); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcasting on port [%d] the message: [%s]\n",Socket::getBroadCastPort(),buff); - } + if(getPauseBroadcast() == false) { + // Broadcast the packet to the subnet + //if( sendto( bcfd, buff, sizeof(buff) + 1, 0 , (struct sockaddr *)&bcaddr, sizeof(struct sockaddr_in) ) != sizeof(buff) + 1 ) + if( sendto( bcfd[idx], buff, buffMaxSize, 0 , (struct sockaddr *)&bcLocal[idx], sizeof(struct sockaddr_in) ) != buffMaxSize ) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Sendto error: %s\n", getLastSocketErrorFormattedText().c_str()); + } + else { + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcasting on port [%d] the message: [%s]\n",Socket::getBroadCastPort(),buff); + } + } if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } @@ -2648,6 +2725,7 @@ std::string Socket::getIpAddress() { void ServerSocket::addIPAddressToBlockedList(string value) { if(isIPAddressBlocked(value) == false) { blockIPList.push_back(value); + if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Blocked IP Address [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,value.c_str()); } } bool ServerSocket::isIPAddressBlocked(string value) const { diff --git a/source/shared_lib/sources/platform/sdl/thread.cpp b/source/shared_lib/sources/platform/sdl/thread.cpp index ebd6d2ba4..89a3c3078 100644 --- a/source/shared_lib/sources/platform/sdl/thread.cpp +++ b/source/shared_lib/sources/platform/sdl/thread.cpp @@ -92,7 +92,39 @@ void Thread::resume() { // Mutex // ===================================== +class SDLMutexSafeWrapper { +protected: + SDL_mutex *mutex; + +public: + + SDLMutexSafeWrapper(SDL_mutex *mutex) { + this->mutex = mutex; + Lock(); + } + ~SDLMutexSafeWrapper() { + ReleaseLock(); + } + + void Lock() { + if(this->mutex != NULL) { + SDL_mutexP(this->mutex); + } + } + void ReleaseLock(bool keepMutex=false) { + if(this->mutex != NULL) { + SDL_mutexV(this->mutex); + + if(keepMutex == false) { + this->mutex = NULL; + } + } + } +}; + Mutex::Mutex(string ownerId) { + mutexAccessor = SDL_CreateMutex(); + SDLMutexSafeWrapper safeMutex(mutexAccessor); refCount=0; this->ownerId = ownerId; mutex = SDL_CreateMutex(); @@ -106,6 +138,7 @@ Mutex::Mutex(string ownerId) { } Mutex::~Mutex() { + SDLMutexSafeWrapper safeMutex(mutexAccessor); if(mutex == NULL) { char szBuf[1024]=""; snprintf(szBuf,1023,"In [%s::%s Line: %d] mutex == NULL refCount = %d owner [%s] deleteownerId [%s]",__FILE__,__FUNCTION__,__LINE__,refCount,ownerId.c_str(),deleteownerId.c_str()); diff --git a/source/shared_lib/sources/util/conversion.cpp b/source/shared_lib/sources/util/conversion.cpp index 11a33392e..aae5d787a 100644 --- a/source/shared_lib/sources/util/conversion.cpp +++ b/source/shared_lib/sources/util/conversion.cpp @@ -72,7 +72,7 @@ bool strToBool(const string &s, bool *b){ return false; } -bool strToInt(const string &s, int *i){ +bool strToInt(const string &s, int *i) { char *endChar; setlocale(LC_NUMERIC, "C"); @@ -84,7 +84,7 @@ bool strToInt(const string &s, int *i){ return true; } -bool strToFloat(const string &s, float *f){ +bool strToFloat(const string &s, float *f) { char *endChar; setlocale(LC_NUMERIC, "C"); *f= static_cast(strtod(s.c_str(), &endChar)); @@ -107,29 +107,28 @@ string boolToStr(bool b) { string intToStr(int64 i) { char str[strSize]=""; snprintf(str, strSize-1, "%lld", (long long int)i); - return str; + return (str[0] != '\0' ? str : ""); } string intToHex(int i){ char str[strSize]=""; snprintf(str, strSize-1, "%x", i); - return str; + return (str[0] != '\0' ? str : ""); } string floatToStr(float f,int precsion) { char str[strSize]=""; snprintf(str, strSize-1, "%.*f", precsion,f); - return str; + return (str[0] != '\0' ? str : ""); } string doubleToStr(double d,int precsion) { char str[strSize]=""; snprintf(str, strSize-1, "%.*f", precsion,d); - return str; + return (str[0] != '\0' ? str : ""); } -bool IsNumeric(const char *p, bool allowNegative) -{ +bool IsNumeric(const char *p, bool allowNegative) { int index = 0; for ( ; *p; p++) { if (*p < '0' || *p > '9') { diff --git a/source/shared_lib/sources/util/util.cpp b/source/shared_lib/sources/util/util.cpp index 29ffc4b81..68987daeb 100644 --- a/source/shared_lib/sources/util/util.cpp +++ b/source/shared_lib/sources/util/util.cpp @@ -415,12 +415,7 @@ void SystemFlags::handleDebug(DebugType type, const char *fmt, ...) { else { // Get the current time. time_t curtime = time (NULL); - // Convert it to local time representation. - struct tm *loctime = localtime (&curtime); - char szBuf2[100]=""; - strftime(szBuf2,100,"%Y-%m-%d %H:%M:%S",loctime); - - logDebugEntry(type, szBuf, curtime); + logDebugEntry(type, (szBuf[0] != '\0' ? szBuf : ""), curtime); } }