ソースを参照

- Integrated the logging API into the client and the lib - Remove some more comments and switched to /// style - Fixed recursive locks - Added Global.h to CMakeLists(now visible in qt-creator) - Removed usage of shared_mutex - Added unique_ptr to CLogger targets

beegee1 12 年 前
コミット
c7c2686379
62 ファイル変更718 行追加1024 行削除
  1. 4 4
      CCallback.cpp
  2. 2 2
      Global.h
  3. 1 1
      client/AdventureMapClasses.cpp
  4. 9 10
      client/CAnimation.cpp
  5. 1 1
      client/CAnimation.h
  6. 4 4
      client/CBitmapHandler.cpp
  7. 4 4
      client/CCastleInterface.cpp
  8. 1 1
      client/CCreatureWindow.cpp
  9. 2 2
      client/CHeroWindow.cpp
  10. 88 154
      client/CMT.cpp
  11. 17 17
      client/CMusicHandler.cpp
  12. 10 10
      client/CPlayerInterface.cpp
  13. 12 16
      client/CPreGame.cpp
  14. 13 13
      client/CVideoHandler.cpp
  15. 45 45
      client/Client.cpp
  16. 6 7
      client/GUIClasses.cpp
  17. 2 2
      client/Graphics.cpp
  18. 10 13
      client/NetPacksClient.cpp
  19. 2 2
      client/battle/CBattleAnimations.cpp
  20. 6 6
      client/battle/CBattleInterface.cpp
  21. 1 1
      client/battle/CCreatureAnimation.cpp
  22. 1 2
      client/gui/CGuiHandler.cpp
  23. 1 3
      client/gui/CIntObject.cpp
  24. 1 1
      client/gui/CIntObjectClasses.cpp
  25. 6 6
      client/gui/SDL_Extensions.cpp
  26. 6 6
      client/mapHandler.cpp
  27. 13 7
      config/schemas/settings.json
  28. 1 1
      lib/BattleState.cpp
  29. 1 1
      lib/BattleState.h
  30. 11 13
      lib/CArtHandler.cpp
  31. 13 14
      lib/CBattleCallback.cpp
  32. 4 4
      lib/CBonusTypeHandler.cpp
  33. 14 12
      lib/CConsoleHandler.cpp
  34. 25 5
      lib/CConsoleHandler.h
  35. 10 10
      lib/CCreatureHandler.cpp
  36. 4 4
      lib/CCreatureSet.cpp
  37. 6 6
      lib/CGameInterface.cpp
  38. 46 47
      lib/CGameState.cpp
  39. 6 6
      lib/CHeroHandler.cpp
  40. 1 1
      lib/CLogger.h
  41. 2 8
      lib/CMakeLists.txt
  42. 14 15
      lib/CModHandler.cpp
  43. 35 36
      lib/CObjectHandler.cpp
  44. 2 2
      lib/CSpellHandler.cpp
  45. 1 1
      lib/CTownHandler.cpp
  46. 29 29
      lib/Connection.cpp
  47. 6 6
      lib/Connection.h
  48. 5 6
      lib/HeroBonus.cpp
  49. 18 18
      lib/IGameCallback.cpp
  50. 13 13
      lib/JsonNode.cpp
  51. 1 1
      lib/NetPacks.h
  52. 12 12
      lib/NetPacksLib.cpp
  53. 1 1
      lib/StartInfo.h
  54. 7 7
      lib/VCMI_Lib.cpp
  55. 3 3
      lib/filesystem/CResourceLoader.cpp
  56. 27 22
      lib/logging/CBasicLogConfigurator.cpp
  57. 15 14
      lib/logging/CBasicLogConfigurator.h
  58. 59 57
      lib/logging/CLogger.cpp
  59. 43 294
      lib/logging/CLogger.h
  60. 3 3
      lib/mapping/CCampaignHandler.cpp
  61. 3 3
      lib/mapping/CMapEditManager.cpp
  62. 9 9
      lib/mapping/MapFormatH3M.cpp

+ 4 - 4
CCallback.cpp

@@ -61,7 +61,7 @@ int CCallback::selectionMade(int selection, int queryID)
 	ASSERT_IF_CALLED_WITH_PLAYER
 	if(queryID == -1)
 	{
-		tlog1 << "Cannot answer the query -1!\n";
+        logGlobal->errorStream() << "Cannot answer the query -1!";
 		return false;
 	}
 
@@ -98,7 +98,7 @@ bool CCallback::upgradeCreature(const CArmedInstance *obj, SlotID stackPos, Crea
 
 void CCallback::endTurn()
 {
-	tlog5 << "Player " << *player << " ended his turn." << std::endl;
+    logGlobal->traceStream() << "Player " << *player << " ended his turn.";
 	EndTurn pack;
 	sendRequest(&pack); //report that we ended turn
 }
@@ -190,7 +190,7 @@ int CBattleCallback::sendRequest(const CPack *request)
 	int requestID = cl->sendRequest(request, *player);
 	if(waitTillRealize)
 	{
-		tlog5 << boost::format("We'll wait till request %d is answered.\n") % requestID;
+        logGlobal->traceStream() << boost::format("We'll wait till request %d is answered.\n") % requestID;
 		auto gsUnlocker = vstd::makeUnlockSharedGuardIf(getGsMutex(), unlockGsWhenWaiting);
 		cl->waitingRequest.waitWhileContains(requestID);
 	}
@@ -390,4 +390,4 @@ bool CBattleCallback::battleMakeTacticAction( BattleAction * action )
 	ma.ba = *action;
 	sendRequest(&ma);
 	return true;
-}
+}

+ 2 - 2
Global.h

@@ -149,9 +149,8 @@ typedef boost::int16_t si16; //signed int 16 bits (2 bytes)
 typedef boost::int8_t si8; //signed int 8 bits (1 byte)
 
 // Lock typedefs
-typedef boost::unique_lock<boost::shared_mutex> TWriteLock;
-typedef boost::shared_lock<boost::shared_mutex> TReadLock;
 typedef boost::lock_guard<boost::mutex> TLockGuard;
+typedef boost::lock_guard<boost::recursive_mutex> TLockGuardRec;
 
 /* ---------------------------------------------------------------------------- */
 /* Macros */
@@ -576,3 +575,4 @@ using vstd::make_unique;
 /* VCMI headers */
 /* ---------------------------------------------------------------------------- */
 #include "lib/CLogger.h"
+#include "lib/logging/CLogger.h"

+ 1 - 1
client/AdventureMapClasses.cpp

@@ -485,7 +485,7 @@ std::map<int, std::pair<SDL_Color, SDL_Color> > CMinimap::loadColors(std::string
 		auto index = boost::find(GameConstants::TERRAIN_NAMES, m.first);
 		if (index == boost::end(GameConstants::TERRAIN_NAMES))
 		{
-			tlog1 << "Error: unknown terrain in terrains.json: " << m.first << "\n";
+            logGlobal->errorStream() << "Error: unknown terrain in terrains.json: " << m.first;
 			continue;
 		}
 		int terrainID = index - boost::begin(GameConstants::TERRAIN_NAMES);

+ 9 - 10
client/CAnimation.cpp

@@ -314,7 +314,7 @@ void CDefFile::loadFrame(size_t frame, size_t group, ImageLoader &loader) const
 			break;
 		}
 	default:
-		tlog0<<"Error: unsupported format of def file: "<<sprite.format<<"\n";
+        logGlobal->errorStream()<<"Error: unsupported format of def file: "<<sprite.format;
 		break;
 	}
 };
@@ -609,7 +609,7 @@ SDLImage::SDLImage(std::string filename, bool compressed):
 
 	if (surf == NULL)
 	{
-		tlog1 << "Error: failed to load image "<<filename<<"\n";
+        logGlobal->errorStream() << "Error: failed to load image "<<filename;
 	}
 	else
 	{
@@ -1035,8 +1035,8 @@ CDefFile * CAnimation::getFile() const
 
 void CAnimation::printError(size_t frame, size_t group, std::string type) const
 {
-	tlog0 << type <<" error: Request for frame not present in CAnimation!\n"
-	      <<"\tFile name: "<<name<<" Group: "<<group<<" Frame: "<<frame<<"\n";
+    logGlobal->errorStream() << type <<" error: Request for frame not present in CAnimation! "
+          <<"\tFile name: "<<name<<" Group: "<<group<<" Frame: "<<frame;
 }
 
 CAnimation::CAnimation(std::string Name, bool Compressed):
@@ -1065,7 +1065,7 @@ CAnimation::~CAnimation()
 {
 	if (!images.empty())
 	{
-		tlog2<<"Warning: not all frames were unloaded from "<<name<<"\n";
+        logGlobal->warnStream()<<"Warning: not all frames were unloaded from "<<name;
 		for (group_map::iterator group = images.begin(); group != images.end(); ++group )
 			for (image_map::iterator image = group->second.begin(); image != group->second.end(); ++image )
 				delete image->second;
@@ -1156,14 +1156,13 @@ std::set<CAnimation*> CAnimation::loadedAnims;
 
 void CAnimation::getAnimInfo()
 {
-	tlog1<<"Animation stats: Loaded "<<loadedAnims.size()<<" total\n";
+    logGlobal->errorStream()<<"Animation stats: Loaded "<<loadedAnims.size()<<" total";
 	for (std::set<CAnimation*>::iterator it = loadedAnims.begin(); it != loadedAnims.end(); it++)
 	{
 		CAnimation * anim = *it;
-		tlog1<<"Name: "<<anim->name<<" Groups: "<<anim->images.size();
+        logGlobal->errorStream()<<"Name: "<<anim->name<<" Groups: "<<anim->images.size();
 		if (!anim->images.empty())
-			tlog1<<", "<<anim->images.begin()->second.size()<<" image loaded in group "<< anim->images.begin()->first;
-		tlog1<<"\n";
+            logGlobal->errorStream()<<", "<<anim->images.begin()->second.size()<<" image loaded in group "<< anim->images.begin()->first;
 	}
 }
 
@@ -1250,7 +1249,7 @@ void CAnimImage::setFrame(size_t Frame, size_t Group)
 		}
 	}
 	else
-		tlog1 << "Error: accessing unavailable frame " << Group << ":" << Frame << " in CAnimation!\n";
+        logGlobal->errorStream() << "Error: accessing unavailable frame " << Group << ":" << Frame << " in CAnimation!";
 }
 
 void CAnimImage::playerColored(PlayerColor currPlayer)

+ 1 - 1
client/CAnimation.h

@@ -193,7 +193,7 @@ public:
 	CAnimation();
 	~CAnimation();
 
-	//static method for debugging - print info about loaded animations in tlog1
+    //static method for debugging - print info about loaded animations
 	static void getAnimInfo();
 	static std::set<CAnimation*> loadedAnims;
 

+ 4 - 4
client/CBitmapHandler.cpp

@@ -102,7 +102,7 @@ SDL_Surface * BitmapHandler::loadBitmapFromDir(std::string path, std::string fna
 {
 	if(!fname.size())
 	{
-		tlog2 << "Call to loadBitmap with void fname!\n";
+        logGlobal->warnStream() << "Call to loadBitmap with void fname!";
 		return NULL;
 	}
 	if (!CResourceHandler::get()->existsResource(ResourceID(path + fname, EResType::IMAGE)))
@@ -128,7 +128,7 @@ SDL_Surface * BitmapHandler::loadBitmapFromDir(std::string path, std::string fna
 			}
 		}
 		else
-			tlog1<<"Failed to open "<<fname<<" as H3 PCX!\n";
+            logGlobal->errorStream()<<"Failed to open "<<fname<<" as H3 PCX!";
 	}
 	else
 	{ //loading via SDL_Image
@@ -150,7 +150,7 @@ SDL_Surface * BitmapHandler::loadBitmapFromDir(std::string path, std::string fna
 		}
 		else
 		{
-			tlog1<<"Failed to open "<<fname<<" via SDL_Image\n";
+            logGlobal->errorStream()<<"Failed to open "<<fname<<" via SDL_Image";
 		}
 	}
 	SDL_SetColorKey(ret, SDL_SRCCOLORKEY, SDL_MapRGB(ret->format, 0, 255, 255));
@@ -163,7 +163,7 @@ SDL_Surface * BitmapHandler::loadBitmap(std::string fname, bool setKey)
 
 	if (!(bitmap = loadBitmapFromDir("DATA/", fname, setKey)) &&
 		!(bitmap = loadBitmapFromDir("SPRITES/", fname, setKey)))
-		tlog1<<"Error: Failed to find file "<<fname<<"\n";
+        logGlobal->errorStream()<<"Error: Failed to find file "<<fname;
 
 	return bitmap;
 }

+ 4 - 4
client/CCastleInterface.cpp

@@ -213,7 +213,7 @@ std::string getBuildingSubtitle(const CStructure * structure)//hover text for bu
 		}
 		else
 		{
-			tlog2 << "Problem: dwelling with id " << bid << " offers no creatures!\n";
+            logGlobal->warnStream() << "Problem: dwelling with id " << bid << " offers no creatures!";
 			return "#ERROR#";
 		}
 	}
@@ -570,7 +570,7 @@ const CGHeroInstance* CCastleBuildings::getHero()
 
 void CCastleBuildings::buildingClicked(BuildingID building)
 {
-	tlog5<<"You've clicked on "<<building<<std::endl;
+    logGlobal->traceStream()<<"You've clicked on "<<building;
 	const CBuilding *b = town->town->buildings.find(building)->second;
 
 	if(building >= BuildingID::DWELL_FIRST)
@@ -1143,7 +1143,7 @@ void CCastleInterface::keyPressed( const SDL_KeyboardEvent & key )
 			BOOST_FOREACH(const CStructure * str, town->town->clientInfo.structures)
 			{
 				if (str->building)
-					tlog1 << int(str->building->bid) << " -> " << int(str->pos.z) << "\n";
+                    logGlobal->errorStream() << int(str->building->bid) << " -> " << int(str->pos.z);
 			}
 		}
 		break;
@@ -1159,7 +1159,7 @@ void CCastleInterface::keyPressed( const SDL_KeyboardEvent & key )
 			BOOST_FOREACH(const CStructure * str, town->town->clientInfo.structures)
 			{
 				if (str->building)
-					tlog1 << int(str->building->bid) << " -> " << int(str->pos.z) << "\n";
+                    logGlobal->errorStream() << int(str->building->bid) << " -> " << int(str->pos.z);
 			}
 
 		}

+ 1 - 1
client/CCreatureWindow.cpp

@@ -652,7 +652,7 @@ void CCreatureWindow::passArtifactToHero()
 		LOCPLINT->cb->swapArtifacts (ArtifactLocation (stack, displayedArtifact), ArtifactLocation(h, creatureArtifact->firstBackpackSlot(h)));
 	}
 	else
-		tlog2 << "Pass artifact to hero should be disabled, no hero or no artifact!\n";
+        logGlobal->warnStream() << "Pass artifact to hero should be disabled, no hero or no artifact!";
 
 	//redraw is handled via CArtifactHolder interface
 }

+ 2 - 2
client/CHeroWindow.cpp

@@ -173,7 +173,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded /*= fals
 {	
 	if(!hero) //something strange... no hero? it shouldn't happen
 	{
-		tlog1 << "Set NULL hero? no way...\n";
+        logGlobal->errorStream() << "Set NULL hero? no way...";
 		return;
 	}
 
@@ -370,4 +370,4 @@ void CHeroWindow::showAll(SDL_Surface * to)
 	std::ostringstream manastr;
 	manastr << curHero->mana << '/' << heroWArt.manaLimit();
 	printAtLoc(manastr.str(), 211, 252, FONT_SMALL, Colors::WHITE, to);
-}
+}

+ 88 - 154
client/CMT.cpp

@@ -39,6 +39,7 @@
 #include "../lib/CScriptingModule.h"
 #include "../lib/GameConstants.h"
 #include "gui/CGuiHandler.h"
+#include "../lib/logging/CBasicLogConfigurator.h"
 
 #ifdef _WIN32
 #include "SDL_syswm.h"
@@ -101,7 +102,7 @@ void startGameFromFile(const std::string &fname)
 		CLoadFile out(fname);
 		if(!out.sfile || !*out.sfile)
 		{
-			tlog1 << "Failed to open startfile, falling back to the main menu!\n";
+            logGlobal->errorStream() << "Failed to open startfile, falling back to the main menu!";
 			GH.curInt = CGPreGame::create();
 			return;
 		}
@@ -116,7 +117,7 @@ void startGameFromFile(const std::string &fname)
 void init()
 {
 	CStopWatch tmh, pomtime;
-	tlog0 << "\tInitializing minors: " << pomtime.getDiff() << std::endl;
+    logGlobal->infoStream() << "\tInitializing minors: " << pomtime.getDiff();
 
 	//initializing audio
 	// Note: because of interface button range, volume can only be a
@@ -127,29 +128,27 @@ void init()
 	CCS->musich = new CMusicHandler;
 	CCS->musich->init();
 	CCS->musich->setVolume(settings["general"]["music"].Float());
-	tlog0<<"\tInitializing sound: "<<pomtime.getDiff()<<std::endl;
-	tlog0<<"Initializing screen and sound handling: "<<tmh.getDiff()<<std::endl;
+    logGlobal->infoStream()<<"\tInitializing sound: "<<pomtime.getDiff();
+    logGlobal->infoStream()<<"Initializing screen and sound handling: "<<tmh.getDiff();
 
 	loadDLLClasses();
 	const_cast<CGameInfo*>(CGI)->setFromLib();
 	CCS->soundh->initSpellsSounds(CGI->spellh->spells);
-	tlog0<<"Initializing VCMI_Lib: "<<tmh.getDiff()<<std::endl;
+    logGlobal->infoStream()<<"Initializing VCMI_Lib: "<<tmh.getDiff();
 
 	pomtime.getDiff();
 	CCS->curh = new CCursorHandler;
 	CCS->curh->initCursor();
 	CCS->curh->show();
-	tlog0<<"Screen handler: "<<pomtime.getDiff()<<std::endl;
+    logGlobal->infoStream()<<"Screen handler: "<<pomtime.getDiff();
 	pomtime.getDiff();
 	graphics = new Graphics();
 	graphics->loadHeroAnims();
-	tlog0<<"\tMain graphics: "<<tmh.getDiff()<<std::endl;
-	tlog0<<"Initializing game graphics: "<<tmh.getDiff()<<std::endl;
+    logGlobal->infoStream()<<"\tMain graphics: "<<tmh.getDiff();
+    logGlobal->infoStream()<<"Initializing game graphics: "<<tmh.getDiff();
 
 	CMessage::init();
-	tlog0<<"Message handler: "<<tmh.getDiff()<<std::endl;
-	//CPG = new CPreGame(); //main menu and submenus
-	//tlog0<<"Initialization CPreGame (together): "<<tmh.getDif()<<std::endl;
+    logGlobal->infoStream()<<"Message handler: "<<tmh.getDiff();
 }
 
 static void prog_version(void)
@@ -203,7 +202,7 @@ int main(int argc, char** argv)
     fclose(check);
 #endif
     
-	tlog0 << "Starting... " << std::endl;
+    std::cout << "Starting... " << std::endl;
 	po::options_description opts("Allowed options");
 	opts.add_options()
 		("help,h", "display help and exit")
@@ -225,7 +224,7 @@ int main(int argc, char** argv)
 		}
 		catch(std::exception &e) 
 		{
-			tlog1 << "Failure during parsing command-line options:\n" << e.what() << std::endl;
+            std::cerr << "Failure during parsing command-line options:\n" << e.what() << std::endl;
 		}
 	}
 
@@ -251,16 +250,33 @@ int main(int argc, char** argv)
 	// it may result in very small \ very fast mouse when game in fullscreen mode
 	putenv((char*)"SDL_VIDEO_X11_DGAMOUSE=0");
 
+    // Init old logging system and new (temporary) logging system
 	CStopWatch total, pomtime;
 	std::cout.flags(std::ios::unitbuf);
-	logfile = new std::ofstream((VCMIDirs::get().localPath() + "/VCMI_Client_log.txt").c_str());
+    logfile = new std::ofstream((VCMIDirs::get().localPath() + "/VCMI_Client_log.txt").c_str());
 	console = new CConsoleHandler;
 	*console->cb = boost::bind(&processCommand, _1);
 	console->start();
 	atexit(dispose);
-	tlog0 <<"Creating console and logfile: "<<pomtime.getDiff() << std::endl;
 
+    CBasicLogConfigurator logConfig(VCMIDirs::get().localPath() + "/VCMI_Client_log2.txt", console);
+    logConfig.configureDefault(false);
+    logGlobal->infoStream() <<"Creating console and logfile: "<<pomtime.getDiff();
+
+    // Init filesystem and settings
 	preinitDLL(::console, logfile);
+    settings.init();
+
+    // Initialize logging based on settings
+    try
+    {
+        logConfig.configure();
+        logGlobal->infoStream() << "Initialized logging system successfully.";
+    }
+    catch(const std::exception & e)
+    {
+        std::cout << "Could not initialize the logging system due to configuration error/s. " << e.what() << std::endl;
+    }
 
 	// Some basic data validation to produce better error messages in cases of incorrect install
 	auto testFile = [](std::string filename, std::string message) -> bool
@@ -268,7 +284,7 @@ int main(int argc, char** argv)
 		if (CResourceHandler::get()->existsResource(ResourceID(filename)))
 			return true;
 
-		tlog1 << "Error: " << message << " was not found!\n";
+        logGlobal->errorStream() << "Error: " << message << " was not found!";
 		return false;
 	};
 
@@ -282,10 +298,9 @@ int main(int argc, char** argv)
 	testFile("VIDEO/GOOD1A.SMK", "campaign movies");
 	testFile("SOUNDS/G1A.WAV", "campaign music"); //technically not a music but voiced intro sounds
 
-	settings.init();
 	conf.init();
-	tlog0 <<"Loading settings: "<<pomtime.getDiff() << std::endl;
-	tlog0 << NAME << std::endl;
+    logGlobal->infoStream() <<"Loading settings: "<<pomtime.getDiff();
+    logGlobal->infoStream() << NAME;
 
 	srand ( time(NULL) );
 
@@ -294,7 +309,7 @@ int main(int argc, char** argv)
 
 	if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO))
 	{
-		tlog1<<"Something was wrong: "<< SDL_GetError() << std::endl;
+        logGlobal->errorStream()<<"Something was wrong: "<< SDL_GetError();
 		exit(-1);
 	}
 	atexit(SDL_Quit);
@@ -305,17 +320,17 @@ int main(int argc, char** argv)
 	//something is really wrong...
 	if (res["width"].Float() < 100 || res["height"].Float() < 100)
 	{
-		tlog0 << "Fatal error: failed to load settings!\n";
-		tlog0 << "Possible reasons:\n";
-		tlog0 << "\tCorrupted local configuration file at " << VCMIDirs::get().localPath() << "/config/settings.json\n";
-		tlog0 << "\tMissing or corrupted global configuration file at " << VCMIDirs::get().dataPath() << "/config/schemas/settings.json\n";
-		tlog0 << "VCMI will now exit...\n";
+        logGlobal->errorStream() << "Fatal error: failed to load settings!";
+        logGlobal->errorStream() << "Possible reasons:";
+        logGlobal->errorStream() << "\tCorrupted local configuration file at " << VCMIDirs::get().localPath() << "/config/settings.json";
+        logGlobal->errorStream() << "\tMissing or corrupted global configuration file at " << VCMIDirs::get().dataPath() << "/config/schemas/settings.json";
+        logGlobal->errorStream() << "VCMI will now exit...";
 		exit(EXIT_FAILURE);
 	}
 
 	setScreenRes(res["width"].Float(), res["height"].Float(), video["bitsPerPixel"].Float(), video["fullscreen"].Bool());
 
-	tlog0 <<"\tInitializing screen: "<<pomtime.getDiff() << std::endl;
+    logGlobal->infoStream() <<"\tInitializing screen: "<<pomtime.getDiff();
 
 	// Initialize video
 #if DISABLE_VIDEO
@@ -327,7 +342,7 @@ int main(int argc, char** argv)
 		CCS->videoh = new CEmptyVideoPlayer;
 #endif
 
-	tlog0<<"\tInitializing video: "<<pomtime.getDiff()<<std::endl;
+    logGlobal->infoStream()<<"\tInitializing video: "<<pomtime.getDiff();
 
 	//we can properly play intro only in the main thread, so we have to move loading to the separate thread
 	boost::thread loading(init);
@@ -338,7 +353,7 @@ int main(int argc, char** argv)
 	SDL_FillRect(screen,NULL,0);
 	CSDL_Ext::update(screen);
 	loading.join();
-	tlog0<<"Initialization of VCMI (together): "<<total.getDiff()<<std::endl;
+    logGlobal->infoStream()<<"Initialization of VCMI (together): "<<total.getDiff();
 
 	if(!vm.count("battle"))
 	{
@@ -357,8 +372,8 @@ int main(int argc, char** argv)
 		{
 			if(fileToStartFrom.size())
 			{
-				tlog3 << "Warning: cannot find given file to start from (" << fileToStartFrom
-					<< "). Falling back to main menu.\n";
+                logGlobal->warnStream() << "Warning: cannot find given file to start from (" << fileToStartFrom
+                    << "). Falling back to main menu.";
 			}
 			GH.curInt = CGPreGame::create(); //will set CGP pointer to itself
 		}
@@ -380,12 +395,13 @@ int main(int argc, char** argv)
 
 void printInfoAboutIntObject(const CIntObject *obj, int level)
 {
-	tlog4 << std::string(level, '\t');
+    std::stringstream sbuffer;
+    sbuffer << std::string(level, '\t');
 
-	tlog4 << typeid(*obj).name() << " *** ";
+    sbuffer << typeid(*obj).name() << " *** ";
 	if (obj->active)
 	{
-#define PRINT(check, text) if (obj->active & CIntObject::check) tlog4 << text
+#define PRINT(check, text) if (obj->active & CIntObject::check) sbuffer << text
 		PRINT(LCLICK, 'L');
 		PRINT(RCLICK, 'R');
 		PRINT(HOVER, 'H');
@@ -398,9 +414,10 @@ void printInfoAboutIntObject(const CIntObject *obj, int level)
 #undef  PRINT
 	}
 	else
-		tlog4 << "inactive";
-	tlog4 << " at " << obj->pos.x <<"x"<< obj->pos.y;
-	tlog4 << " (" << obj->pos.w <<"x"<< obj->pos.h << ")\n";
+        sbuffer << "inactive";
+    sbuffer << " at " << obj->pos.x <<"x"<< obj->pos.y;
+    sbuffer << " (" << obj->pos.w <<"x"<< obj->pos.h << ")";
+    logGlobal->debugStream() << sbuffer.str();
 
 	BOOST_FOREACH(const CIntObject *child, obj->children)
 		printInfoAboutIntObject(child, level+1);
@@ -427,7 +444,7 @@ void processCommand(const std::string &message)
 		{
 			if(client && client->erm)
 				client->erm->executeUserCommand(message);
-			tlog0 << "erm>";
+            std::cout << "erm>";
 		}
 	}
 	else if(message==std::string("die, fool"))
@@ -437,7 +454,7 @@ void processCommand(const std::string &message)
 	else if(cn == "erm")
 	{
 		ermInteractiveMode = true;
-		tlog0 << "erm>";
+        std::cout << "erm>";
 	}
 	else if(cn==std::string("activate"))
 	{
@@ -462,16 +479,14 @@ void processCommand(const std::string &message)
 	}
 	else if(cn=="screen")
 	{
-		tlog0 << "Screenbuf points to ";
+        std::cout << "Screenbuf points to ";
 
 		if(screenBuf == screen)
-			tlog1 << "screen";
+            logGlobal->errorStream() << "screen";
 		else if(screenBuf == screen2)
-			tlog1 << "screen2";
+            logGlobal->errorStream() << "screen2";
 		else
-			tlog1 << "?!?";
-
-		tlog1 << std::endl;
+            logGlobal->errorStream() << "?!?";
 
 		SDL_SaveBMP(screen, "Screen_c.bmp");
 		SDL_SaveBMP(screen2, "Screen2_c.bmp");
@@ -488,46 +503,10 @@ void processCommand(const std::string &message)
 		std::string fname;
 		readed >> fname;
 		client->loadGame(fname);
-	}/*
-	else if(cn=="resolution" || cn == "r")
-	{
-		if(LOCPLINT)
-		{
-			tlog1 << "Resolution can be set only before starting the game.\n";
-			return;
-		}
-		std::map<std::pair<int,int>, config::GUIOptions >::iterator j;
-		int i=1;
-		tlog4 << "Available screen resolutions:\n";
-		for(j=conf.guiOptions.begin(); j!=conf.guiOptions.end(); j++)
-			tlog4 << i++ <<". " << j->first.first << " x " << j->first.second << std::endl;
-		tlog4 << "Type number from 1 to " << i-1 << " to set appropriate resolution or 0 to cancel.\n";
-		std::cin >> i;
-		if(i < 0  ||  i > conf.guiOptions.size() || std::cin.bad() || std::cin.fail())
-		{
-			std::cin.clear();
-			tlog1 << "Invalid resolution ID! Not a number between 0 and  " << conf.guiOptions.size() << ". No settings changed.\n";
-		}
-		else if(!i)
-		{
-			return;
-		}
-		else
-		{
-			auto j = conf.guiOptions.begin();
-			std::advance(j, i - 1); //move j to the i-th resolution info
-			const int w = j->first.first, h = j->first.second;
-			Settings screen = settings.write["video"]["screenRes"];
-			screen["width"].Float()  = w;
-			screen["height"].Float() = h;
-			conf.SetResolution(screen["width"].Float(), screen["height"].Float());
-			tlog0 << "Screen resolution set to " << (int)screen["width"].Float() << " x "
-												 << (int)screen["height"].Float() <<". It will be applied afters game restart.\n";
-		}
-	}*/
+    }
 	else if(message=="get txt")
 	{
-		tlog0<<"Command accepted.\t";
+        std::cout<<"Command accepted.\t";
 		boost::filesystem::create_directory("Extracted_txts");
 		auto iterator = CResourceHandler::get()->getIterator([](const ResourceID & ident)
 		{
@@ -544,8 +523,8 @@ void processCommand(const std::string &message)
 			++iterator;
 		}
 
-		tlog0 << "\rExtracting done :)\n";
-		tlog0 << " Extracted files can be found in " << basePath << " directory\n";
+        std::cout << "\rExtracting done :)\n";
+        std::cout << " Extracted files can be found in " << basePath << " directory\n";
 	}
 	else if(cn=="crash")
 	{
@@ -560,24 +539,24 @@ void processCommand(const std::string &message)
 	else if (cn == "ai")
 	{
 		VLC->IS_AI_ENABLED = !VLC->IS_AI_ENABLED;
-		tlog4 << "Current AI status: " << (VLC->IS_AI_ENABLED ? "enabled" : "disabled") << std::endl;
+        std::cout << "Current AI status: " << (VLC->IS_AI_ENABLED ? "enabled" : "disabled") << std::endl;
 	}
 	else if(cn == "mp" && adventureInt)
 	{
 		if(const CGHeroInstance *h = dynamic_cast<const CGHeroInstance *>(adventureInt->selection))
-			tlog0 << h->movement << "; max: " << h->maxMovePoints(true) << "/" << h->maxMovePoints(false) << std::endl;
+            std::cout << h->movement << "; max: " << h->maxMovePoints(true) << "/" << h->maxMovePoints(false) << std::endl;
 	}
 	else if(cn == "bonuses")
 	{
-		tlog0 << "Bonuses of " << adventureInt->selection->getHoverText() << std::endl
+        std::cout << "Bonuses of " << adventureInt->selection->getHoverText() << std::endl
 			<< adventureInt->selection->getBonusList() << std::endl;
 
-		tlog0 << "\nInherited bonuses:\n";
+        std::cout << "\nInherited bonuses:\n";
 		TCNodes parents;
 		adventureInt->selection->getParents(parents);
 		BOOST_FOREACH(const CBonusSystemNode *parent, parents)
 		{
-			tlog0 << "\nBonuses from " << typeid(*parent).name() << std::endl << parent->getBonusList() << std::endl;
+            std::cout << "\nBonuses from " << typeid(*parent).name() << std::endl << parent->getBonusList() << std::endl;
 		}
 	}
 	else if(cn == "not dialog")
@@ -591,7 +570,7 @@ void processCommand(const std::string &message)
 			if(const CIntObject *obj = dynamic_cast<const CIntObject *>(child))
 				printInfoAboutIntObject(obj, 0);
 			else
-				tlog4 << typeid(*obj).name() << std::endl;
+                std::cout << typeid(*obj).name() << std::endl;
 		}
 	}
 	else if(cn=="tell")
@@ -604,7 +583,7 @@ void processCommand(const std::string &message)
 			BOOST_FOREACH(const CGHeroInstance *h, LOCPLINT->cb->getHeroesInfo())
 				if(h->type->ID == id1)
 					if(const CArtifactInstance *a = h->getArt(ArtifactPosition(id2)))
-						tlog4 << a->nodeName();
+                        std::cout << a->nodeName();
 		}
 	}
 	else if (cn == "set")
@@ -647,7 +626,7 @@ void processCommand(const std::string &message)
 	{
 		std::string fname;
 		readed >> fname;
-		tlog0 << "Will try loading that AI to see if it is correct name...\n";
+        std::cout << "Will try loading that AI to see if it is correct name...\n";
 		try
 		{
 			if(auto ai = CDynLibHandler::getNewBattleAI(fname)) //test that given AI is indeed available... heavy but it is easy to make a typo and break the game
@@ -655,13 +634,13 @@ void processCommand(const std::string &message)
 				delete ai;
 				Settings neutralAI = settings.write["server"]["neutralAI"];
 				neutralAI->String() = fname;
-				tlog0 << "Setting changed, from now the battle ai will be " << fname << "!\n";
+                std::cout << "Setting changed, from now the battle ai will be " << fname << "!\n";
 			}
 		}
 		catch(std::exception &e)
 		{
-			tlog3 << "Failed opening " << fname << ": " << e.what() << std::endl;
-			tlog3 << "Setting not changes, AI not found or invalid!\n";
+            logGlobal->warnStream() << "Failed opening " << fname << ": " << e.what();
+            logGlobal->warnStream() << "Setting not changes, AI not found or invalid!";
 		}
 	}
 	else if(client && client->serv && client->serv->connected && LOCPLINT) //send to server
@@ -698,7 +677,7 @@ static void setScreenRes(int w, int h, int bpp, bool fullscreen, bool resetVideo
 	int suggestedBpp = SDL_VideoModeOK(w, h, bpp, SDL_SWSURFACE|(fullscreen?SDL_FULLSCREEN:0));
 	if(suggestedBpp == 0)
 	{
-		tlog1 << "Error: SDL says that " << w << "x" << h << " resolution is not available!\n";
+        logGlobal->errorStream() << "Error: SDL says that " << w << "x" << h << " resolution is not available!";
 		return;
 	}
 
@@ -706,7 +685,7 @@ static void setScreenRes(int w, int h, int bpp, bool fullscreen, bool resetVideo
 	
 	if(suggestedBpp != bpp)
 	{
-		tlog2 << "Note: SDL suggests to use " << suggestedBpp << " bpp instead of"  << bpp << " bpp "  << std::endl;
+        logGlobal->warnStream() << "Note: SDL suggests to use " << suggestedBpp << " bpp instead of"  << bpp << " bpp ";
 	}
 
 	//For some reason changing fullscreen via config window checkbox result in SDL_Quit event
@@ -719,11 +698,11 @@ static void setScreenRes(int w, int h, int bpp, bool fullscreen, bool resetVideo
 	
 	if((screen = SDL_SetVideoMode(w, h, suggestedBpp, SDL_SWSURFACE|(fullscreen?SDL_FULLSCREEN:0))) == NULL)
 	{
-		tlog1 << "Requested screen resolution is not available (" << w << "x" << h << "x" << suggestedBpp << "bpp)\n";
+        logGlobal->errorStream() << "Requested screen resolution is not available (" << w << "x" << h << "x" << suggestedBpp << "bpp)";
 		throw std::runtime_error("Requested screen resolution is not available\n");
 	}
 
-	tlog0 << "New screen flags: " << screen->flags << std::endl;
+    logGlobal->infoStream() << "New screen flags: " << screen->flags;
 
 	if(screen2)
 		SDL_FreeSurface(screen2);
@@ -749,9 +728,9 @@ static void setScreenRes(int w, int h, int bpp, bool fullscreen, bool resetVideo
 	}
 	else
 	{
-		tlog3 << "Something went wrong, getwm=" << getwm << std::endl;
-		tlog3 << "SDL says: " << SDL_GetError() << std::endl;
-		tlog3 << "Window won't be centered.\n";
+        logGlobal->warnStream() << "Something went wrong, getwm=" << getwm;
+        logGlobal->warnStream() << "SDL says: " << SDL_GetError();
+        logGlobal->warnStream() << "Window won't be centered.";
 	}
 #endif
 	//TODO: centering game window on other platforms (or does the environment do their job correctly there?)
@@ -772,7 +751,7 @@ static void fullScreenChanged()
 	bitsPerPixel = SDL_VideoModeOK(screen->w, screen->h, bitsPerPixel, SDL_SWSURFACE|(toFullscreen?SDL_FULLSCREEN:0));
 	if(bitsPerPixel == 0)
 	{
-		tlog1 << "Error: SDL says that " << screen->w << "x" << screen->h << " resolution is not available!\n";
+        logGlobal->errorStream() << "Error: SDL says that " << screen->w << "x" << screen->h << " resolution is not available!";
 		return;
 	}
 
@@ -792,9 +771,7 @@ static void listenForEvents()
 	{
 		SDL_Event ev;
 
-		//tlog0 << "Waiting... ";
 		int ret = SDL_WaitEvent(&ev);
-		//tlog0 << "got " << (int)ev.type;
 		if (ret == 0 || (ev.type==SDL_QUIT) ||
 			(ev.type == SDL_KEYDOWN && ev.key.keysym.sym==SDLK_F4 && (ev.key.keysym.mod & KMOD_ALT)))
 		{
@@ -811,7 +788,7 @@ static void listenForEvents()
 			console = NULL;
 			SDL_Delay(750);
 			SDL_Quit();
-			tlog0 << "Ending...\n";
+            std::cout << "Ending...";
 			break;
 		}
 		else if(LOCPLINT && ev.type == SDL_KEYDOWN && ev.key.keysym.sym==SDLK_F4)
@@ -838,25 +815,11 @@ static void listenForEvents()
 
 			switch(ev.user.code)
 			{
-		/*	case CHANGE_SCREEN_RESOLUTION:
-			{
-				tlog0 << "Changing resolution has been requested\n";
-				const JsonNode& video = settings["video"];
-				const JsonNode& res = video["gameRes"];
-				setScreenRes(res["width"].Float(), res["height"].Float(), video["bitsPerPixel"].Float(), video["fullscreen"].Bool());
-				break;
-			}*/
 			case RETURN_TO_MAIN_MENU:
 				{
-// 					StartInfo si = *client->getStartInfo();
-// 					if(si.mode == StartInfo::CAMPAIGN)
-// 						GH.pushInt( new CBonusSelection(si.campState) );
-// 					else
-					{
-						endGame();
-						GH.curInt = CGPreGame::create();;
-						GH.defActionsDef = 63;
-					}
+                    endGame();
+                    GH.curInt = CGPreGame::create();;
+                    GH.defActionsDef = 63;
 				}
 				break;
 			case STOP_CLIENT:
@@ -881,19 +844,16 @@ static void listenForEvents()
 				fullScreenChanged();
 				break;
 			default:
-				tlog1 << "Error: unknown user event. Code " << ev.user.code << std::endl;
+                logGlobal->errorStream() << "Error: unknown user event. Code " << ev.user.code;
 				assert(0);
 			}
 
 			continue;
 		} 
-
-		//tlog0 << " pushing ";
 		{
 			boost::unique_lock<boost::mutex> lock(eventsM); 
 			events.push(ev);
 		}
-		//tlog0 << " done\n";
 	}
 }
 
@@ -906,21 +866,8 @@ void startGame(StartInfo * options, CConnection *serv/* = NULL*/)
 			it->second.playerID = PlayerSettings::PLAYER_AI;
 		}
 	}
-/*	const JsonNode& res = settings["video"]["screenRes"];
-
-	if(screen->w != res["width"].Float()   ||   screen->h != res["height"].Float())
-	{
-		requestChangingResolution();
-
-		//allow event handling thread change resolution
-		auto unlock = vstd::makeUnlockGuard(eventsM);
-		while(!setResolution) boost::this_thread::sleep(boost::posix_time::milliseconds(50));
-	}
-	else
-		setResolution = true;*/
-
-		client = new CClient;
 
+    client = new CClient;
 	CPlayerInterface::howManyPeople = 0;
 	switch(options->mode) //new game
 	{
@@ -938,16 +885,3 @@ void startGame(StartInfo * options, CConnection *serv/* = NULL*/)
 
 		client->connectionHandler = new boost::thread(&CClient::run, client);
 }
-/*
-void requestChangingResolution()
-{
-	//mark that we are going to change resolution
-	setResolution = false;
-
-	//push special event to order event reading thread to change resolution
-	SDL_Event ev;
-	ev.type = SDL_USEREVENT;
-	ev.user.code = CHANGE_SCREEN_RESOLUTION;
-	SDL_PushEvent(&ev);
-}
-*/

+ 17 - 17
client/CMusicHandler.cpp

@@ -51,7 +51,7 @@ void CAudioBase::init()
 
 	if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024)==-1)
 	{
-		tlog1 << "Mix_OpenAudio error: " << Mix_GetError() << std::endl;
+        logGlobal->errorStream() << "Mix_OpenAudio error: " << Mix_GetError();
 		return;
 	}
 
@@ -149,7 +149,7 @@ Mix_Chunk *CSoundHandler::GetSoundChunk(soundBase::soundID soundID)
 	}
 	catch(std::exception &e)
 	{
-		tlog3 << "Cannot get sound " << soundID << " chunk: " << e.what() << "\n";
+        logGlobal->warnStream() << "Cannot get sound " << soundID << " chunk: " << e.what();
 		return nullptr;
 	}
 }
@@ -171,7 +171,7 @@ Mix_Chunk *CSoundHandler::GetSoundChunk(std::string &sound)
 	}
 	catch(std::exception &e)
 	{
-		tlog3 << "Cannot get sound " << sound << " chunk: " << e.what() << "\n";
+        logGlobal->warnStream() << "Cannot get sound " << sound << " chunk: " << e.what();
 		return nullptr;
 	}
 }
@@ -188,11 +188,11 @@ void CSoundHandler::initSpellsSounds(const std::vector< ConstTransitivePtr<CSpel
 			const CSpell *s = CGI->spellh->spells[spellid];
 
 			if (vstd::contains(spellSounds, s))
-				tlog1 << "Spell << " << spellid << " already has a sound" << std::endl;
+                logGlobal->errorStream() << "Spell << " << spellid << " already has a sound";
 
 			std::string sound = node["soundfile"].String();
 			if (sound.empty())
-				tlog0 << "Error: invalid sound for id "<< spellid << "\n";
+                logGlobal->errorStream() << "Error: invalid sound for id "<< spellid;
 			spellSounds[s] = sound;
 		}
 	}
@@ -212,7 +212,7 @@ int CSoundHandler::playSound(soundBase::soundID soundID, int repeats)
 	{
 		channel = Mix_PlayChannel(-1, chunk, repeats);
 		if (channel == -1)
-			tlog1 << "Unable to play sound file " << soundID << " , error " << Mix_GetError() << std::endl;
+            logGlobal->errorStream() << "Unable to play sound file " << soundID << " , error " << Mix_GetError();
 		else
 			callbacks[channel];//insert empty callback
 	}
@@ -236,7 +236,7 @@ int CSoundHandler::playSound(std::string sound, int repeats)
 	{
 		channel = Mix_PlayChannel(-1, chunk, repeats);
 		if (channel == -1)
-			tlog1 << "Unable to play sound file " << sound << " , error " << Mix_GetError() << std::endl;
+            logGlobal->errorStream() << "Unable to play sound file " << sound << " , error " << Mix_GetError();
 		else
 			callbacks[channel];//insert empty callback
 	}
@@ -360,7 +360,7 @@ void CMusicHandler::playMusicFromSet(std::string whichSet, bool loop)
 	auto selectedSet = musicsSet.find(whichSet);
 	if (selectedSet == musicsSet.end())
 	{
-		tlog0 << "Error: playing music from non-existing set: " << whichSet << "\n";
+        logGlobal->errorStream() << "Error: playing music from non-existing set: " << whichSet;
 		return;
 	}
 
@@ -376,14 +376,14 @@ void CMusicHandler::playMusicFromSet(std::string whichSet, int entryID, bool loo
 	auto selectedSet = musicsSet.find(whichSet);
 	if (selectedSet == musicsSet.end())
 	{
-		tlog0 << "Error: playing music from non-existing set: " << whichSet << "\n";
+        logGlobal->errorStream() << "Error: playing music from non-existing set: " << whichSet;
 		return;
 	}
 
 	auto selectedEntry = selectedSet->second.find(entryID);
 	if (selectedEntry == selectedSet->second.end())
 	{
-		tlog0 << "Error: playing non-existing entry " << entryID << " from set: " << whichSet << "\n";
+        logGlobal->errorStream() << "Error: playing non-existing entry " << entryID << " from set: " << whichSet;
 		return;
 	}
 
@@ -460,7 +460,7 @@ MusicEntry::MusicEntry(CMusicHandler *owner, std::string setName, std::string mu
 }
 MusicEntry::~MusicEntry()
 {
-	tlog5<<"Del-ing music file "<<currentName<<"\n";
+    logGlobal->traceStream()<<"Del-ing music file "<<currentName;
 	if (music)
 		Mix_FreeMusic(music);
 }
@@ -469,19 +469,19 @@ void MusicEntry::load(std::string musicURI)
 {
 	if (music)
 	{
-		tlog5<<"Del-ing music file "<<currentName<<"\n";
+        logGlobal->traceStream()<<"Del-ing music file "<<currentName;
 		Mix_FreeMusic(music);
 	}
 
 	currentName = musicURI;
 
-	tlog5<<"Loading music file "<<musicURI<<"\n";
+    logGlobal->traceStream()<<"Loading music file "<<musicURI;
 
 	music = Mix_LoadMUS(CResourceHandler::get()->getResourceName(ResourceID(musicURI, EResType::MUSIC)).c_str());
 
 	if(!music)
 	{
-		tlog3 << "Warning: Cannot open " << currentName << ": " << Mix_GetError() << std::endl;
+        logGlobal->warnStream() << "Warning: Cannot open " << currentName << ": " << Mix_GetError();
 		return;
 	}
 
@@ -505,10 +505,10 @@ bool MusicEntry::play()
 		load(iterator->second);
 	}
 
-	tlog5<<"Playing music file "<<currentName<<"\n";
+    logGlobal->traceStream()<<"Playing music file "<<currentName;
 	if(Mix_PlayMusic(music, 1) == -1)
 	{
-		tlog1 << "Unable to play music (" << Mix_GetError() << ")" << std::endl;
+        logGlobal->errorStream() << "Unable to play music (" << Mix_GetError() << ")";
 		return false;
 	}
 	return true;
@@ -518,7 +518,7 @@ bool MusicEntry::stop(int fade_ms)
 {
 	if (Mix_PlayingMusic())
 	{
-		tlog5<<"Stoping music file "<<currentName<<"\n";
+        logGlobal->traceStream()<<"Stoping music file "<<currentName;
 		loop = 0;
 		Mix_FadeOutMusic(fade_ms);
 		return true;

+ 10 - 10
client/CPlayerInterface.cpp

@@ -98,7 +98,7 @@ struct OCM_HLP_CGIN
 
 CPlayerInterface::CPlayerInterface(PlayerColor Player)
 {
-	tlog5 << "\tHuman player interface for player " << Player << " being constructed\n";
+    logGlobal->traceStream() << "\tHuman player interface for player " << Player << " being constructed";
 	observerInDuelMode = false;
 	howManyPeople++;
 	GH.defActionsDef = 0;
@@ -759,7 +759,7 @@ void CPlayerInterface::actionFinished(const BattleAction* action)
 BattleAction CPlayerInterface::activeStack(const CStack * stack) //called when it's turn of that stack
 {
 	THREAD_CREATED_BY_CLIENT;
-	tlog5 << "Awaiting command for " << stack->nodeName() << std::endl;
+    logGlobal->traceStream() << "Awaiting command for " << stack->nodeName();
 	CBattleInterface *b = battleInt;
 
 	assert(!b->givenCommand->get()); //command buffer must be clean (we don't want to use old command)
@@ -783,7 +783,7 @@ BattleAction CPlayerInterface::activeStack(const CStack * stack) //called when i
 	b->givenCommand->data = NULL;
 
 	//return command
-	tlog5 << "Giving command for " << stack->nodeName() << std::endl;
+    logGlobal->traceStream() << "Giving command for " << stack->nodeName();
 	return ret;
 }
 
@@ -1207,7 +1207,7 @@ void CPlayerInterface::serialize( CISer<CLoadFile> &h, const int version )
 
 bool CPlayerInterface::moveHero( const CGHeroInstance *h, CGPath path )
 {
-	tlog5 << __FUNCTION__ << std::endl;
+    logGlobal->traceStream() << __FUNCTION__;
 	if(!LOCPLINT->makingTurn)
 		return false;
 	if (!h)
@@ -1232,11 +1232,11 @@ bool CPlayerInterface::moveHero( const CGHeroInstance *h, CGPath path )
 	{
 		//evil...
 
-		tlog5 << "before [un]locks in " << __FUNCTION__ << std::endl;
+        logGlobal->traceStream() << "before [un]locks in " << __FUNCTION__;
 		auto unlockEvents = vstd::makeUnlockGuard(eventsM);
 		auto unlockGs = vstd::makeUnlockSharedGuard(cb->getGsMutex()); //GS mutex is above PIM because CClient::run thread first locks PIM and then GS -> so this way we avoid deadlocks
 		auto unlockPim = vstd::makeUnlockGuard(*pim);
-		tlog5 << "after [un]locks in " << __FUNCTION__ << std::endl;
+        logGlobal->traceStream() << "after [un]locks in " << __FUNCTION__;
 		//TODO the above combination works... but it should all be atomic (unlock all three or none)
 
 		{
@@ -1285,13 +1285,13 @@ bool CPlayerInterface::moveHero( const CGHeroInstance *h, CGPath path )
 				int3 endpos(path.nodes[i-1].coord.x, path.nodes[i-1].coord.y, h->pos.z);
 				bool guarded = CGI->mh->map->isInTheMap(cb->guardingCreaturePosition(endpos - int3(1, 0, 0)));
 
-				tlog5 << "Requesting hero movement to " << endpos << std::endl;
+                logGlobal->traceStream() << "Requesting hero movement to " << endpos;
 				cb->moveHero(h,endpos);
 
 				while(stillMoveHero.data != STOP_MOVE  &&  stillMoveHero.data != CONTINUE_MOVE)
 					stillMoveHero.cond.wait(un);
 
-				tlog5 << "Resuming " << __FUNCTION__ << std::endl;
+                logGlobal->traceStream() << "Resuming " << __FUNCTION__;
 				if (guarded || showingDialog->get() == true) // Abort movement if a guard was fought or there is a dialog to display (Mantis #1136)
 					break;
 			}
@@ -1475,7 +1475,7 @@ void CPlayerInterface::waitWhileDialog(bool unlockPim /*= true*/)
 {
 	if(GH.amIGuiThread())
 	{
-		tlog3 << "Cannot wait for dialogs in gui thread (deadlock risk)!\n";
+        logGlobal->warnStream() << "Cannot wait for dialogs in gui thread (deadlock risk)!";
 		return;
 	}
 
@@ -2142,7 +2142,7 @@ CGPath * CPlayerInterface::getAndVerifyPath(const CGHeroInstance * h)
 		CGPath &path = paths[h];
 		if(!path.nodes.size())
 		{
-			tlog3 << "Warning: empty path found...\n";
+            logGlobal->warnStream() << "Warning: empty path found...";
 			paths.erase(h);
 		}
 		else

+ 12 - 16
client/CPreGame.cpp

@@ -363,7 +363,7 @@ static boost::function<void()> genCommand(CMenuScreen* menu, std::vector<std::st
 			}
 		}
 	}
-	tlog0<<"Failed to parse command: "<<string<<"\n";
+    logGlobal->errorStream()<<"Failed to parse command: "<<string;
 	return boost::function<void()>();
 }
 
@@ -544,7 +544,7 @@ void CGPreGame::openCampaignScreen(std::string name)
 			return;
 		}
 	}
-	tlog1<<"Unknown campaign set: "<<name<<"\n";
+    logGlobal->errorStream()<<"Unknown campaign set: "<<name;
 }
 
 CGPreGame *CGPreGame::create()
@@ -934,7 +934,7 @@ void CSelectionScreen::handleConnection()
 		{
 			CPackForSelectionScreen *pack = NULL;
 			*serv >> pack;
-			tlog5 << "Received a pack of type " << typeid(*pack).name()  << std::endl;
+            logNetwork->traceStream() << "Received a pack of type " << typeid(*pack).name();
 			assert(pack);
 			if(QuitMenuWithoutStarting *endingPack = dynamic_cast<QuitMenuWithoutStarting *>(pack))
 			{
@@ -1112,7 +1112,7 @@ void SelectionTab::parseMaps(const std::vector<ResourceID> & files)
 		}
 		catch(std::exception & e)
 		{
-			tlog2 << "Map " << files[i].getName() << " is invalid. Message: " << e.what() << std::endl;
+            logGlobal->errorStream() << "Map " << files[i].getName() << " is invalid. Message: " << e.what();
 		}
 	}
 }
@@ -1152,7 +1152,7 @@ void SelectionTab::parseGames(const std::vector<ResourceID> &files, bool multi)
 		}
 		catch(const std::exception & e)
 		{
-			tlog3 << "Error: Failed to process " << files[i].getName() <<": " << e.what() << std::endl;
+            logGlobal->errorStream() << "Error: Failed to process " << files[i].getName() <<": " << e.what();
 		}
 	}
 }
@@ -1435,7 +1435,7 @@ void SelectionTab::printMaps(SDL_Surface *to)
 				break;
 			default:
 				// Unknown version. Be safe and ignore that map
-				tlog2 << "Warning: " << currentItem->fileURI << " has wrong version!\n";
+                logGlobal->warnStream() << "Warning: " << currentItem->fileURI << " has wrong version!";
 				continue;
 			}
 			blitAtLoc(format->ourImages[temp].bitmap, 88, 117 + line * 25, to);
@@ -3535,7 +3535,7 @@ void CBonusSelection::updateBonusSelection()
 			case CScenarioTravel::STravelBonus::PLAYER_PREV_SCENARIO:
 				{
 					auto superhero = ourCampaign->camp->scenarios[bonDescs[i].info2].strongestHero(PlayerColor(bonDescs[i].info1));
-					if (!superhero) tlog5 << "No superhero! How could it be transfered?\n";
+                    if (!superhero) logGlobal->warnStream() << "No superhero! How could it be transfered?";
 					picNumber = superhero ? superhero->portrait : 0;
 					desc = CGI->generaltexth->allTexts[719];
 
@@ -3579,13 +3579,9 @@ void CBonusSelection::startMap()
 {
 	StartInfo *si = new StartInfo(sInfo);
 
-	/*if (ourCampaign->mapsConquered.size())
-	{
-		GH.popInts(1);
-	}*/
 	const CCampaignScenario & scenario = ourCampaign->camp->scenarios[ourCampaign->currentMap];
 
-	tlog1 << "Starting scenario " << int(ourCampaign->currentMap) << "\n";
+    logGlobal->infoStream() << "Starting scenario " << int(ourCampaign->currentMap);
 
 	auto exitCb = [si]()
 	{
@@ -3595,13 +3591,13 @@ void CBonusSelection::startMap()
 	if (scenario.prolog.hasPrologEpilog)
 	{
 		GH.pushInt(new CPrologEpilogVideo(scenario.prolog, exitCb));
-		tlog1 << "Video: " << scenario.prolog.prologVideo <<"\n";
-		tlog1 << "Audio: " << scenario.prolog.prologMusic <<"\n";
-		tlog1 << "Text:  " << scenario.prolog.prologText <<"\n";
+        logGlobal->infoStream() << "Video: " << scenario.prolog.prologVideo;
+        logGlobal->infoStream() << "Audio: " << scenario.prolog.prologMusic;
+        logGlobal->infoStream() << "Text:  " << scenario.prolog.prologText;
 	}
 	else
 	{
-		tlog1 << "Without prolog\n";
+        logGlobal->infoStream() << "Without prolog";
 		exitCb();
 	}
 }

+ 13 - 13
client/CVideoHandler.cpp

@@ -32,12 +32,12 @@ void checkForError(bool throwing = true)
 	if(!error)
 		return;
 
-	tlog1 << "Error " << error << " encountered!\n";
+    logGlobal->errorStream() << "Error " << error << " encountered!";
 	std::string msg;
 	char* pTemp = NULL;
 	FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
 		NULL, error,  MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), (LPSTR)&pTemp, 1, NULL );
-	tlog1 << "Error: " << pTemp << std::endl;
+    logGlobal->errorStream() << "Error: " << pTemp;
 	msg = pTemp;
 	LocalFree( pTemp );
 	pTemp = NULL;
@@ -63,7 +63,7 @@ void DLLHandler::Instantiate(const char *filename)
 	dll = LoadLibraryA(filename);
 	if(!dll)
 	{
-		tlog1 << "Failed loading " << filename << std::endl;
+        logGlobal->errorStream() << "Failed loading " << filename;
 		checkForError(true);
 	}
 }
@@ -74,13 +74,13 @@ void *DLLHandler::FindAddress(const char *symbol)
 
 	if(!dll)
 	{
-		tlog1 << "Cannot look for " << symbol << " because DLL hasn't been appropriately loaded!\n";
+        logGlobal->errorStream() << "Cannot look for " << symbol << " because DLL hasn't been appropriately loaded!";
 		return NULL;
 	}
 	ret = (void*) GetProcAddress(dll,symbol);
 	if(!ret)
 	{
-		tlog1 << "Failed to find " << symbol << " in " << name << std::endl;
+        logGlobal->errorStream() << "Failed to find " << symbol << " in " << name;
 		checkForError();
 	}
 	return ret;
@@ -92,7 +92,7 @@ DLLHandler::~DLLHandler()
 	{
 		if(!FreeLibrary(dll))
 		{
-			tlog1 << "Failed to free " << name << std::endl;
+            logGlobal->errorStream() << "Failed to free " << name;
 			checkForError();
 		}
 	}
@@ -139,7 +139,7 @@ bool CBIKHandler::open(std::string name)
 
 	if(hBinkFile == INVALID_HANDLE_VALUE)
 	{
-		tlog1 << "BIK handler: failed to open " << name << std::endl;
+        logGlobal->errorStream() << "BIK handler: failed to open " << name;
 		goto checkErrorAndClean;
 	}
 	//GCC wants scope of waveout to dont cross labels/swith/goto
@@ -153,7 +153,7 @@ bool CBIKHandler::open(std::string name)
 	hBink = binkOpen(hBinkFile, 0x8a800000);
 	if(!hBink)
 	{
-		tlog1 << "bink failed to open " << name << std::endl;
+        logGlobal->errorStream() << "bink failed to open " << name;
 		goto checkErrorAndClean;
 	}
 
@@ -303,7 +303,7 @@ bool CSmackPlayer::open( std::string name )
 	data = ptrSmackOpen( (void*)name.c_str(), flags[1], -1);
 	if (!data)
 	{
-		tlog1 << "Smack cannot open " << name << std::endl;
+        logGlobal->errorStream() << "Smack cannot open " << name;
 		checkForError();
 		throw std::runtime_error("SMACK failed opening video");
 	}
@@ -437,7 +437,7 @@ bool CVideoPlayer::open(std::string name)
 	catch(std::exception &e)
 	{
 		current = nullptr;
-		tlog3 << "Failed to open video file " << name << ": " << e.what() << std::endl;
+        logGlobal->warnStream() << "Failed to open video file " << name << ": " << e.what();
 	}
 
 	return false;
@@ -447,7 +447,7 @@ void CVideoPlayer::close()
 {
 	if(!current)
 	{
-		tlog2 << "Closing no opened player...?" << std::endl;
+        logGlobal->warnStream() << "Closing no opened player...?";
 		return;
 	}
 
@@ -455,7 +455,7 @@ void CVideoPlayer::close()
 	current = NULL;
 	if(!DeleteFileA(fname.c_str()))
 	{
-		tlog1 << "Cannot remove temporarily extracted video file: " << fname;
+        logGlobal->errorStream() << "Cannot remove temporarily extracted video file: " << fname;
 		checkForError(false);
 	}
 	fname.clear();
@@ -628,7 +628,7 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay)
 
 	if (!CResourceHandler::get()->existsResource(resource))
 	{
-		tlog0 << "Error: video " << resource.getName() << " was not found\n";
+        logGlobal->errorStream() << "Error: video " << resource.getName() << " was not found";
 		return false;
 	}
 

+ 45 - 45
client/Client.cpp

@@ -125,11 +125,11 @@ void CClient::waitForMoveAndSend(PlayerColor color)
 	}
 	catch(boost::thread_interrupted&)
 	{
-		tlog5 << "Wait for move thread was interrupted and no action will be send. Was a battle ended by spell?\n";
+        logNetwork->debugStream() << "Wait for move thread was interrupted and no action will be send. Was a battle ended by spell?";
 		return;
 	}
 	HANDLE_EXCEPTION
-	tlog1 << "We should not be here!" << std::endl;
+    logNetwork->errorStream() << "We should not be here!";
 }
 
 void CClient::run()
@@ -156,11 +156,11 @@ void CClient::run()
 	//catch only asio exceptions
 	catch (const boost::system::system_error& e)
 	{	
-		tlog3 << "Lost connection to server, ending listening thread!\n";
-		tlog1 << e.what() << std::endl;
+        logNetwork->errorStream() << "Lost connection to server, ending listening thread!";
+        logNetwork->errorStream() << e.what();
 		if(!terminate) //rethrow (-> boom!) only if closing connection was unexpected
 		{
-			tlog1 << "Something wrong, lost connection while game is still ongoing...\n";
+            logNetwork->errorStream() << "Something wrong, lost connection while game is still ongoing...";
 			throw;
 		}
 	}
@@ -170,7 +170,7 @@ void CClient::save(const std::string & fname)
 {
 	if(gs->curB)
 	{
-		tlog1 << "Game cannot be saved during battle!\n";
+        logNetwork->errorStream() << "Game cannot be saved during battle!";
 		return;
 	}
 
@@ -188,26 +188,26 @@ void CClient::endGame( bool closeConnection /*= true*/ )
 	// Tell the network thread to reach a stable state
 	if(closeConnection)
 		stopConnection();
-	tlog0 << "Closed connection." << std::endl;
+    logNetwork->infoStream() << "Closed connection.";
 
 	GH.curInt = NULL;
 	LOCPLINT->terminate_cond.setn(true);
 	{
 		boost::unique_lock<boost::recursive_mutex> un(*LOCPLINT->pim);
-		tlog0 << "\n\nEnding current game!" << std::endl;
+        logNetwork->infoStream() << "Ending current game!";
 		if(GH.topInt())
 			GH.topInt()->deactivate();
 		GH.listInt.clear();
 		GH.objsToBlit.clear();
 		GH.statusbar = NULL;
-		tlog0 << "Removed GUI." << std::endl;
+        logNetwork->infoStream() << "Removed GUI.";
 
 
 		delete CGI->mh;
 		const_cast<CGameInfo*>(CGI)->mh = NULL;
 
 		const_cast<CGameInfo*>(CGI)->state.dellNull();
-		tlog0 << "Deleted mapHandler and gameState." << std::endl;
+        logNetwork->infoStream() << "Deleted mapHandler and gameState.";
 		LOCPLINT = NULL;
 	}
 	while (!playerint.empty())
@@ -218,14 +218,14 @@ void CClient::endGame( bool closeConnection /*= true*/ )
 	}
 
 	callbacks.clear();
-	tlog0 << "Deleted playerInts." << std::endl;
+    logNetwork->infoStream() << "Deleted playerInts.";
 
-	tlog0 << "Client stopped." << std::endl;
+    logNetwork->infoStream() << "Client stopped.";
 }
 
 void CClient::loadGame( const std::string & fname )
 {
-	tlog0 <<"\n\nLoading procedure started!\n\n";
+    logNetwork->infoStream() <<"Loading procedure started!";
 
 	CServerHandler sh;
 	sh.startServer();
@@ -241,16 +241,16 @@ void CClient::loadGame( const std::string & fname )
 			loadCommonState(checkingLoader);
 			loader = checkingLoader.decay();
 		}
-		tlog0 << "Loaded common part of save " << tmh.getDiff()<<std::endl;
+        logNetwork->infoStream() << "Loaded common part of save " << tmh.getDiff();
 		const_cast<CGameInfo*>(CGI)->state = gs;
 		const_cast<CGameInfo*>(CGI)->mh = new CMapHandler();
 		const_cast<CGameInfo*>(CGI)->mh->map = gs->map;
 		pathInfo = new CPathsInfo(int3(gs->map->width, gs->map->height, gs->map->twoLevel ? 2 : 1));
 		CGI->mh->init();
-		tlog0 <<"Initing maphandler: "<<tmh.getDiff()<<std::endl;
+        logNetwork->infoStream() <<"Initing maphandler: "<<tmh.getDiff();
 
 		*loader >> *this;
-		tlog0 << "Loaded client part of save " << tmh.getDiff()<<std::endl;
+        logNetwork->infoStream() << "Loaded client part of save " << tmh.getDiff();
 	}
 
 	serv = sh.connectToServer();
@@ -264,7 +264,7 @@ void CClient::loadGame( const std::string & fname )
 	if(pom8) 
 		throw std::runtime_error("Server cannot open the savegame!");
 	else
-		tlog0 << "Server opened savegame properly.\n";
+        logNetwork->infoStream() << "Server opened savegame properly.";
 
 	*serv << ui32(gs->scenarioOps->playerInfos.size()+1); //number of players + neutral
 	for(auto it = gs->scenarioOps->playerInfos.begin(); 
@@ -273,7 +273,7 @@ void CClient::loadGame( const std::string & fname )
 		*serv << ui8(it->first.getNum()); //players
 	}
 	*serv << ui8(PlayerColor::NEUTRAL.getNum());
-	tlog0 <<"Sent info to server: "<<tmh.getDiff()<<std::endl;
+    logNetwork->infoStream() <<"Sent info to server: "<<tmh.getDiff();
 
 	serv->enableStackSendingByID();
 	serv->disableSmartPointerSerialization();
@@ -297,7 +297,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
 
 	CStopWatch tmh;
 	const_cast<CGameInfo*>(CGI)->state = new CGameState();
-	tlog0 <<"\tGamestate: "<<tmh.getDiff()<<std::endl;
+    logNetwork->infoStream() <<"\tGamestate: "<<tmh.getDiff();
 	CConnection &c(*serv);
 	////////////////////////////////////////////////////
 
@@ -310,11 +310,11 @@ void CClient::newGame( CConnection *con, StartInfo *si )
 		if(pom8) 
 			throw std::runtime_error("Server cannot open the map!");
 		else
-			tlog0 << "Server opened map properly.\n";
+            logNetwork->infoStream() << "Server opened map properly.";
 	}
 
 	c >> si;
-	tlog0 <<"\tSending/Getting info to/from the server: "<<tmh.getDiff()<<std::endl;
+    logNetwork->infoStream() <<"\tSending/Getting info to/from the server: "<<tmh.getDiff();
 	c.enableStackSendingByID();
 	c.disableSmartPointerSerialization();
 
@@ -322,7 +322,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
 	gs = const_cast<CGameInfo*>(CGI)->state;
 	gs->scenarioOps = si;
 	gs->init(si);
-	tlog0 <<"Initializing GameState (together): "<<tmh.getDiff()<<std::endl;
+    logNetwork->infoStream() <<"Initializing GameState (together): "<<tmh.getDiff();
 
 	// Now after possible random map gen, we know exact player count.
 	// Inform server about how many players client handles
@@ -345,10 +345,10 @@ void CClient::newGame( CConnection *con, StartInfo *si )
 	{
 		const_cast<CGameInfo*>(CGI)->mh = new CMapHandler();
 		CGI->mh->map = gs->map;
-		tlog0 <<"Creating mapHandler: "<<tmh.getDiff()<<std::endl;
+        logNetwork->infoStream() <<"Creating mapHandler: "<<tmh.getDiff();
 		CGI->mh->init();
 		pathInfo = new CPathsInfo(int3(gs->map->width, gs->map->height, gs->map->twoLevel ? 2 : 1));
-		tlog0 <<"Initializing mapHandler (together): "<<tmh.getDiff()<<std::endl;
+        logNetwork->infoStream() <<"Initializing mapHandler (together): "<<tmh.getDiff();
 	}
 
 	int humanPlayers = 0;
@@ -361,7 +361,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
 		if(!vstd::contains(myPlayers, color))
 			continue;
 
-		tlog5 << "Preparing interface for player " << color << std::endl;
+        logNetwork->traceStream() << "Preparing interface for player " << color;
 		if(si->mode != StartInfo::DUEL)
 		{
 			auto cb = make_shared<CCallback>(gs,color,this);
@@ -373,7 +373,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
 				else
 					sensibleAILimit--;
 				playerint[color] = static_cast<CGameInterface*>(CDynLibHandler::getNewAI(AItoGive));
-				tlog1 << "Player " << static_cast<int>(color.getNum()) << " will be lead by " << AItoGive << std::endl;
+                logNetwork->infoStream() << "Player " << static_cast<int>(color.getNum()) << " will be lead by " << AItoGive;
 			}
 			else 
 			{
@@ -382,7 +382,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
 			}
 			battleints[color] = playerint[color];
 
-			tlog5 << "\tInitializing the interface\n";
+            logNetwork->traceStream() << "\tInitializing the interface";
 			playerint[color]->init(cb.get());
 			battleCallbacks[color] = callbacks[color] = cb;
 		}
@@ -497,15 +497,15 @@ void CClient::handlePack( CPack * pack )
 	{
 		boost::unique_lock<boost::recursive_mutex> guiLock(*LOCPLINT->pim);
 		apply->applyOnClBefore(this,pack);
-		tlog5 << "\tMade first apply on cl\n";
+        logNetwork->traceStream() << "\tMade first apply on cl";
 		gs->apply(pack);
-		tlog5 << "\tApplied on gs\n";
+        logNetwork->traceStream() << "\tApplied on gs";
 		apply->applyOnClAfter(this,pack);
-		tlog5 << "\tMade second apply on cl\n";
+        logNetwork->traceStream() << "\tMade second apply on cl";
 	}
 	else
 	{
-		tlog1 << "Message cannot be applied, cannot find applier! TypeID " << typeList.getTypeID(pack) << std::endl;
+        logNetwork->errorStream() << "Message cannot be applied, cannot find applier! TypeID " << typeList.getTypeID(pack);
 	}
 	delete pack;
 }
@@ -533,11 +533,11 @@ void CClient::stopConnection()
 
 	if (serv) //request closing connection
 	{
-		tlog0 << "Connection has been requested to be closed.\n";
+        logNetwork->infoStream() << "Connection has been requested to be closed.";
 		boost::unique_lock<boost::mutex>(*serv->wmx);
 		CloseServer close_server;
 		sendRequest(&close_server, PlayerColor::NEUTRAL);
-		tlog0 << "Sent closing signal to the server\n";
+        logNetwork->infoStream() << "Sent closing signal to the server";
 	}
 
 	if(connectionHandler)//end connection handler
@@ -545,7 +545,7 @@ void CClient::stopConnection()
 		if(connectionHandler->get_id() != boost::this_thread::get_id())
 			connectionHandler->join();
 
-		tlog0 << "Connection handler thread joined" << std::endl;
+        logNetwork->infoStream() << "Connection handler thread joined";
 
 		delete connectionHandler;
 		connectionHandler = NULL;
@@ -556,7 +556,7 @@ void CClient::stopConnection()
 		serv->close();
 		delete serv;
 		serv = NULL;
-		tlog3 << "Our socket has been closed." << std::endl;
+        logNetwork->warnStream() << "Our socket has been closed.";
 	}
 }
 
@@ -665,7 +665,7 @@ int CClient::sendRequest(const CPack *request, PlayerColor player)
 	static ui32 requestCounter = 0;
 
 	ui32 requestID = requestCounter++;
-	tlog5 << boost::format("Sending a request \"%s\". It'll have an ID=%d.\n") 
+    logNetwork->traceStream() << boost::format("Sending a request \"%s\". It'll have an ID=%d.")
 				% typeid(*request).name() % requestID;
 
 	waitingRequest.pushBack(requestID);
@@ -708,7 +708,7 @@ void CServerHandler::startServer()
 	th.update();
 	serverThread = new boost::thread(&CServerHandler::callServer, this); //runs server executable;
 	if(verbose)
-		tlog0 << "Setting up thread calling server: " << th.getDiff() << std::endl;
+        logNetwork->infoStream() << "Setting up thread calling server: " << th.getDiff();
 }
 
 void CServerHandler::waitForServer()
@@ -723,7 +723,7 @@ void CServerHandler::waitForServer()
 		shared->sr->cond.wait(slock);
 	}
 	if(verbose)
-		tlog0 << "Waiting for server: " << th.getDiff() << std::endl;
+        logNetwork->infoStream() << "Waiting for server: " << th.getDiff();
 }
 
 CConnection * CServerHandler::connectToServer()
@@ -735,7 +735,7 @@ CConnection * CServerHandler::connectToServer()
 	CConnection *ret = justConnectToServer(settings["server"]["server"].String(), port);
 
 	if(verbose)
-		tlog0<<"\tConnecting to the server: "<<th.getDiff()<<std::endl;
+        logNetwork->infoStream()<<"\tConnecting to the server: "<<th.getDiff();
 
 	return ret;
 }
@@ -751,7 +751,7 @@ CServerHandler::CServerHandler(bool runServer /*= false*/)
 	try
 	{
 		shared = new SharedMem();
-	} HANDLE_EXCEPTIONC(tlog1 << "Cannot open interprocess memory: ";)
+    } HANDLE_EXCEPTIONC(logNetwork->errorStream() << "Cannot open interprocess memory: ";)
 }
 
 CServerHandler::~CServerHandler()
@@ -767,11 +767,11 @@ void CServerHandler::callServer()
 	std::string comm = VCMIDirs::get().serverPath() + " " + port + " > " + logName;
 	int result = std::system(comm.c_str());
 	if (result == 0)
-		tlog1 << "Server closed correctly\n";
+        logNetwork->infoStream() << "Server closed correctly";
 	else
 	{
-		tlog0 << "Error: server failed to close correctly or crashed!\n";
-		tlog0 << "Check " << logName << " for more info\n";
+        logNetwork->errorStream() << "Error: server failed to close correctly or crashed!";
+        logNetwork->errorStream() << "Check " << logName << " for more info";
 		exit(1);// exit in case of error. Othervice without working server VCMI will hang
 	}
 }
@@ -783,14 +783,14 @@ CConnection * CServerHandler::justConnectToServer(const std::string &host, const
 	{
 		try
 		{
-			tlog0 << "Establishing connection...\n";
+            logNetwork->infoStream() << "Establishing connection...";
 			ret = new CConnection(	host.size() ? host : settings["server"]["server"].String(), 
 									port.size() ? port : boost::lexical_cast<std::string>(settings["server"]["port"].Float()), 
 									NAME);
 		}
 		catch(...)
 		{
-			tlog1 << "\nCannot establish connection! Retrying within 2 seconds" << std::endl;
+            logNetwork->errorStream() << "\nCannot establish connection! Retrying within 2 seconds";
 			SDL_Delay(2000);
 		}
 	}

+ 6 - 7
client/GUIClasses.cpp

@@ -84,7 +84,7 @@ void CArmyTooltip::init(const InfoAboutArmy &army)
 	{
 		if(slot.first.getNum() >= GameConstants::ARMY_SIZE)
 		{
-			tlog3 << "Warning: " << army.name << " has stack in slot " << slot.first << std::endl;
+            logGlobal->warnStream() << "Warning: " << army.name << " has stack in slot " << slot.first;
 			continue;
 		}
 
@@ -236,8 +236,8 @@ void CGarrisonSlot::hover (bool on)
 				}
 				else
 				{
-					tlog2 << "Warning - shouldn't be - highlighted void slot "<<owner->getSelection()<<std::endl;
-					tlog2 << "Highlighted set to NULL"<<std::endl;
+                    logGlobal->warnStream() << "Warning - shouldn't be - highlighted void slot "<<owner->getSelection();
+                    logGlobal->warnStream() << "Highlighted set to NULL";
 					owner->selectSlot(nullptr);
 				}
 			}
@@ -3359,7 +3359,7 @@ bool CAltarWindow::putOnAltar(CTradeableItem* altarSlot, const CArtifactInstance
 	int artID = art->artType->id;
 	if(artID != 1 && artID < 7) //special art
 	{
-		tlog2 << "Cannot put special artifact on altar!\n";
+        logGlobal->warnStream() << "Cannot put special artifact on altar!";
 		return false;
 	}
 
@@ -3368,7 +3368,7 @@ bool CAltarWindow::putOnAltar(CTradeableItem* altarSlot, const CArtifactInstance
 		int slotIndex = firstFreeSlot();
 		if(slotIndex < 0)
 		{
-			tlog2 << "No free slots on altar!\n";
+            logGlobal->warnStream() << "No free slots on altar!";
 			return false;
 		}
 		altarSlot = items[0][slotIndex];
@@ -4254,7 +4254,7 @@ void CArtPlace::clickRight(tribool down, bool previousState)
 
 					if(assemblyPossibilities.size() > 2)
 					{
-						tlog3 << "More than one possibility of assembling... taking only first\n";
+                        logGlobal->warnStream() << "More than one possibility of assembling... taking only first";
 						break;
 					}
 					return;
@@ -4941,7 +4941,6 @@ void CArtifactsOfHero::artifactMoved(const ArtifactLocation &src, const Artifact
 		//when moving one artifact onto another it leads to two art movements: dst->backapck; src->dst
 		// however after first movement we pick the art from backpack and the second movement coming when
 		// we have a different artifact may look surprising... but it's valid.
-		//tlog1 << "Unexpected artifact movement...\n";
 	}
 
 	updateParentWindow();

+ 2 - 2
client/Graphics.cpp

@@ -275,7 +275,7 @@ void Graphics::loadHeroFlags()
 		grupa.create_thread(boost::bind(&Graphics::loadHeroFlags,this,boost::ref(pr[g]),true));
 	}
 	grupa.join_all();
-	tlog0 << "Loading and transforming heroes' flags: "<<th.getDiff()<<std::endl;
+    logGlobal->infoStream() << "Loading and transforming heroes' flags: "<<th.getDiff();
 }
 
 void Graphics::blueToPlayersAdv(SDL_Surface * sur, PlayerColor player)
@@ -295,7 +295,7 @@ void Graphics::blueToPlayersAdv(SDL_Surface * sur, PlayerColor player)
 		}
 		else
 		{
-			tlog1 << "Wrong player id in blueToPlayersAdv (" << player << ")!\n";
+            logGlobal->errorStream() << "Wrong player id in blueToPlayersAdv (" << player << ")!";
 			return;
 		}
 

+ 10 - 13
client/NetPacksClient.cpp

@@ -111,7 +111,7 @@ void SetPrimSkill::applyCl( CClient *cl )
 	const CGHeroInstance *h = cl->getHero(id);
 	if(!h)
 	{
-		tlog1 << "Cannot find hero with ID " << id.getNum() << std::endl;
+        logNetwork->errorStream() << "Cannot find hero with ID " << id.getNum();
 		return;
 	}
 	INTERFACE_CALL_IF_PRESENT(h->tempOwner,heroPrimarySkillChanged,h,which,val);
@@ -122,7 +122,7 @@ void SetSecSkill::applyCl( CClient *cl )
 	const CGHeroInstance *h = cl->getHero(id);
 	if(!h)
 	{
-		tlog1 << "Cannot find hero with ID " << id << std::endl;
+        logNetwork->errorStream() << "Cannot find hero with ID " << id;
 		return;
 	}
 	INTERFACE_CALL_IF_PRESENT(h->tempOwner,heroSecondarySkillChanged,h,which,val);
@@ -467,8 +467,6 @@ void SetHeroesInTown::applyCl( CClient *cl )
 
 // void SetHeroArtifacts::applyCl( CClient *cl )
 // {
-// 	tlog1 << "SetHeroArtifacts :(\n";
-// //
 // // 	CGHeroInstance *h = GS(cl)->getHero(hid);
 // // 	CGameInterface *player = (vstd::contains(cl->playerint,h->tempOwner) ? cl->playerint[h->tempOwner] : NULL);
 // // 	if(!player)
@@ -492,7 +490,7 @@ void HeroRecruited::applyCl( CClient *cl )
 	CGHeroInstance *h = GS(cl)->map->heroes.back();
 	if(h->subID != hid)
 	{
-		tlog1 << "Something wrong with hero recruited!\n";
+        logNetwork->errorStream() << "Something wrong with hero recruited!";
 	}
 
 	CGI->mh->initHeroDef(h);
@@ -532,7 +530,7 @@ void InfoWindow::applyCl( CClient *cl )
 	if(vstd::contains(cl->playerint,player))
 		cl->playerint[player]->showInfoDialog(str,comps,(soundBase::soundID)soundID);
 	else
-		tlog2 << "We received InfoWindow for not our player...\n";
+        logNetwork->warnStream() << "We received InfoWindow for not our player...";
 }
 
 void SetObjectProperty::applyCl( CClient *cl )
@@ -576,7 +574,7 @@ void BlockingDialog::applyCl( CClient *cl )
 	if(vstd::contains(cl->playerint,player))
 		cl->playerint[player]->showBlockingDialog(str,components,queryID,(soundBase::soundID)soundID,selection(),cancel());
 	else
-		tlog2 << "We received YesNoDialog for not our player...\n";
+        logNetwork->warnStream() << "We received YesNoDialog for not our player...";
 }
 
 void GarrisonDialog::applyCl(CClient *cl)
@@ -757,7 +755,7 @@ void PackageApplied::applyCl( CClient *cl )
 {
 	INTERFACE_CALL_IF_PRESENT(player, requestRealized, this);
 	if(!cl->waitingRequest.tryRemovingElement(requestID))
-		tlog3 << "Surprising server message!\n";
+        logNetwork->warnStream() << "Surprising server message!";
 }
 
 void SystemMessage::applyCl( CClient *cl )
@@ -765,7 +763,7 @@ void SystemMessage::applyCl( CClient *cl )
 	std::ostringstream str;
 	str << "System message: " << text;
 
-	tlog4 << str.str() << std::endl;
+    logNetwork->debugStream() << str.str();
 	if(LOCPLINT)
 		LOCPLINT->cingconsole->print(str.str());
 }
@@ -797,7 +795,7 @@ void SaveGame::applyCl(CClient *cl)
 	}
 	catch(std::exception &e)
 	{
-		tlog1 << "Failed to save game:" << e.what() << std::endl;
+        logNetwork->errorStream() << "Failed to save game:" << e.what();
 	}
 
 // 	try
@@ -816,7 +814,6 @@ void SaveGame::applyCl(CClient *cl)
 // 	}
 // 	catch(...)
 // 	{
-// 		tlog1 << "Desync!!!\n";
 // 	}
 }
 
@@ -825,7 +822,7 @@ void PlayerMessage::applyCl(CClient *cl)
 	std::ostringstream str;
 	str << "Player "<< player <<" sends a message: " << text;
 
-	tlog4 << str.str() << std::endl;
+    logNetwork->debugStream() << str.str();
 	if(LOCPLINT)
 		LOCPLINT->cingconsole->print(str.str());
 }
@@ -970,6 +967,6 @@ void TradeComponents::applyCl(CClient *cl)
 	case Obj::TRADING_POST_SNOW:
 		break;
 	default:
-		tlog2 << "Shop type not supported! \n";
+        logNetwork->warnStream() << "Shop type not supported!";
 	}
 }

+ 2 - 2
client/battle/CBattleAnimations.cpp

@@ -312,7 +312,7 @@ bool CMeleeAttackAnimation::init()
 		group = mutPosToGroup[mutPos];
 		break;
 	default:
-		tlog1<<"Critical Error! Wrong dest in stackAttacking! dest: "<<dest<<" attacking stack pos: "<<attackingStackPosBeforeReturn<<" mutual pos: "<<mutPos<<std::endl;
+        logGlobal->errorStream()<<"Critical Error! Wrong dest in stackAttacking! dest: "<<dest<<" attacking stack pos: "<<attackingStackPosBeforeReturn<<" mutual pos: "<<mutPos;
 		group = CCreatureAnim::ATTACK_FRONT;
 		break;
 	}
@@ -1038,4 +1038,4 @@ void CSpellEffectAnimation::endAnim()
 	}
 
 	delete this;
-}
+}

+ 6 - 6
client/battle/CBattleInterface.cpp

@@ -1125,7 +1125,7 @@ void CBattleInterface::setBattleCursor(const int myNumber)
 	// Generally should NEVER happen, but to avoid the possibility of having endless loop below... [#1016]
 	if(!vstd::contains_if(sectorCursor, [](int sc) { return sc != -1; }))
 	{
-		tlog1 << "Error: for hex " << myNumber << " cannot find a hex to attack from!\n";
+        logGlobal->errorStream() << "Error: for hex " << myNumber << " cannot find a hex to attack from!";
 		attackingHex = -1;
 		return;
 	}
@@ -1473,7 +1473,7 @@ void CBattleInterface::giveCommand(Battle::ActionType action, BattleHex tile, ui
 	}
 
 	if(stack && stack != activeStack)
-		tlog3 << "Warning: giving an order to a non-active stack?\n";
+        logGlobal->warnStream() << "Warning: giving an order to a non-active stack?";
 
 	BattleAction * ba = new BattleAction(); //is deleted in CPlayerInterface::activeStack()
 	ba->side = defendingHeroInstance ? (curInt->playerID == defendingHeroInstance->tempOwner) : false;
@@ -1497,7 +1497,7 @@ void CBattleInterface::giveCommand(Battle::ActionType action, BattleHex tile, ui
 
 	if(!tacticsMode)
 	{
-		tlog5 << "Setting command for " << (stack ? stack->nodeName() : "hero") << std::endl;
+        logGlobal->traceStream() << "Setting command for " << (stack ? stack->nodeName() : "hero");
 		myTurn = false;
 		activeStack = NULL;
 		givenCommand->setn(ba);
@@ -2627,7 +2627,7 @@ void CBattleInterface::startAction(const BattleAction* action)
 	}
 	if(!stack)
 	{
-		tlog1<<"Something wrong with stackNumber in actionStarted. Stack number: "<<action->stackNumber<<std::endl;
+        logGlobal->errorStream()<<"Something wrong with stackNumber in actionStarted. Stack number: "<<action->stackNumber;
 		return;
 	}
 
@@ -3477,13 +3477,13 @@ void CBattleInterface::obstaclePlaced(const CObstacleInstance & oi)
 		sound = soundBase::fireWall;
 		break;
 	default:
-		tlog1 << "I don't know how to animate appearing obstacle of type " << (int)oi.obstacleType << std::endl;
+        logGlobal->errorStream() << "I don't know how to animate appearing obstacle of type " << (int)oi.obstacleType;
 		return;
 	}
 
 	if(graphics->battleACToDef[effectID].empty())
 	{
-		tlog1 << "Cannot find def for effect type " << effectID << std::endl;
+        logGlobal->errorStream() << "Cannot find def for effect type " << effectID;
 		return;
 	}
 

+ 1 - 1
client/battle/CCreatureAnimation.cpp

@@ -277,7 +277,7 @@ int CCreatureAnimation::nextFrame(SDL_Surface *dest, int x, int y, bool attacker
 	case 3: return nextFrameT<3>(dest, x, y, attacker, animCount, IncrementFrame, yellowBorder, blueBorder, destRect);
 	case 4: return nextFrameT<4>(dest, x, y, attacker, animCount, IncrementFrame, yellowBorder, blueBorder, destRect);
 	default:
-		tlog1 << (int)dest->format->BitsPerPixel << " bpp is not supported!!!\n";
+        logGlobal->errorStream() << (int)dest->format->BitsPerPixel << " bpp is not supported!!!";
 		return -1;
 	}
 }

+ 1 - 2
client/gui/CGuiHandler.cpp

@@ -389,7 +389,7 @@ void CGuiHandler::run()
 	}
 	catch(const std::exception & e)
 	{
-		tlog1 << "Error: " << e.what() << std::endl;
+        logGlobal->errorStream() << "Error: " << e.what();
 		exit(EXIT_FAILURE);
 	}
 }
@@ -465,7 +465,6 @@ SDLKey CGuiHandler::numToDigit( SDLKey key )
 	case SDLK_KP_ENTER:
 		return SDLK_RETURN;
 	default:
-		//tlog3 << "Illegal numkey conversion!" << std::endl;
 		return SDLK_UNKNOWN;
 	}
 #undef REMOVE_KP

+ 1 - 3
client/gui/CIntObject.cpp

@@ -70,7 +70,7 @@ void CIntObject::activate()
 			return;
 		else
 		{
-			tlog1 << "Warning: IntObject re-activated with mismatching used and active\n";
+            logGlobal->warnStream() << "Warning: IntObject re-activated with mismatching used and active";
 			deactivate(); //FIXME: better to avoid such possibility at all
 		}
 	}
@@ -232,12 +232,10 @@ void CIntObject::addChild(CIntObject *child, bool adjustPosition /*= false*/)
 {
 	if (vstd::contains(children, child))
 	{
-//		tlog4<< "Warning: object already assigned to this parent!\n";
 		return;
 	}
 	if (child->parent_m)
 	{
-//		tlog4<< "Warning: object already has parent!\n";
 		child->parent_m->removeChild(child, adjustPosition);
 	}
 	children.push_back(child);

+ 1 - 1
client/gui/CIntObjectClasses.cpp

@@ -1626,7 +1626,7 @@ void CTextInput::numberFilter(std::string & text, const std::string & oldText, i
 	catch(boost::bad_lexical_cast &)
 	{
 		//Should never happen. Unless I missed some cases
-		tlog0 << "Warning: failed to convert "<< text << " to number!\n";
+        logGlobal->warnStream() << "Warning: failed to convert "<< text << " to number!";
 		text = oldText;
 	}
 }

+ 6 - 6
client/gui/SDL_Extensions.cpp

@@ -513,7 +513,7 @@ int CSDL_Ext::blit8bppAlphaTo24bpp(const SDL_Surface * src, const SDL_Rect * src
 	case 3: return blit8bppAlphaTo24bppT<3>(src, srcRect, dst, dstRect);
 	case 4: return blit8bppAlphaTo24bppT<4>(src, srcRect, dst, dstRect);
 	default:
-		tlog1 << (int)dst->format->BitsPerPixel << " bpp is not supported!!!\n";
+        logGlobal->errorStream() << (int)dst->format->BitsPerPixel << " bpp is not supported!!!";
 		return -1;
 	}
 }
@@ -592,7 +592,7 @@ void CSDL_Ext::setPlayerColor(SDL_Surface * sur, PlayerColor player)
 		SDL_SetColors(sur, color, 5, 1);
 	}
 	else
-		tlog3 << "Warning, setPlayerColor called on not 8bpp surface!\n";
+        logGlobal->warnStream() << "Warning, setPlayerColor called on not 8bpp surface!";
 }
 
 TColorPutter CSDL_Ext::getPutterFor(SDL_Surface * const &dest, int incrementing)
@@ -613,7 +613,7 @@ case BytesPerPixel:									\
 		CASE_BPP(3)
 		CASE_BPP(4)
 	default:
-		tlog1 << (int)dest->format->BitsPerPixel << "bpp is not supported!\n";
+        logGlobal->errorStream() << (int)dest->format->BitsPerPixel << "bpp is not supported!";
 		return NULL;
 	}
 
@@ -627,7 +627,7 @@ TColorPutterAlpha CSDL_Ext::getPutterAlphaFor(SDL_Surface * const &dest, int inc
 		CASE_BPP(3)
 		CASE_BPP(4)
 	default:
-		tlog1 << (int)dest->format->BitsPerPixel << "bpp is not supported!\n";
+        logGlobal->errorStream() << (int)dest->format->BitsPerPixel << "bpp is not supported!";
 		return NULL;
 	}
 #undef CASE_BPP
@@ -711,7 +711,7 @@ BlitterWithRotationVal CSDL_Ext::getBlitterWithRotation(SDL_Surface *dest)
 	case 3: return blitWithRotateClipVal<3>;
 	case 4: return blitWithRotateClipVal<4>;
 	default:
-		tlog1 << (int)dest->format->BitsPerPixel << " bpp is not supported!!!\n";
+        logGlobal->errorStream() << (int)dest->format->BitsPerPixel << " bpp is not supported!!!";
 		break;
 	}
 
@@ -727,7 +727,7 @@ BlitterWithRotationVal CSDL_Ext::getBlitterWithRotationAndAlpha(SDL_Surface *des
 	case 3: return blitWithRotateClipValWithAlpha<3>;
 	case 4: return blitWithRotateClipValWithAlpha<4>;
 	default:
-		tlog1 << (int)dest->format->BitsPerPixel << " bpp is not supported!!!\n";
+        logGlobal->errorStream() << (int)dest->format->BitsPerPixel << " bpp is not supported!!!";
 		break;
 	}
 

+ 6 - 6
client/mapHandler.cpp

@@ -257,7 +257,7 @@ static void processDef (const CGDefInfo* def)
 		}
 		else
 		{
-			tlog2 << "No def name for " << def->id << "  " << def->subid << std::endl;
+            logGlobal->warnStream() << "No def name for " << def->id << "  " << def->subid;
 			return;
 		}
 		ourDef = graphics->getDef(def);
@@ -380,14 +380,14 @@ void CMapHandler::init()
 	}
 
     std::for_each(map->customDefs.begin(),map->customDefs.end(),processDef); //load h3m defs
-	tlog0<<"\tUnpacking and handling defs: "<<th.getDiff()<<std::endl;
+    logGlobal->infoStream()<<"\tUnpacking and handling defs: "<<th.getDiff();
 
 	prepareFOWDefs();
 	roadsRiverTerrainInit();	//road's and river's DefHandlers; and simple values initialization
 	borderAndTerrainBitmapInit();
-	tlog0<<"\tPreparing FoW, roads, rivers,borders: "<<th.getDiff()<<std::endl;
+    logGlobal->infoStream()<<"\tPreparing FoW, roads, rivers,borders: "<<th.getDiff();
 	initObjectRects();
-	tlog0<<"\tMaking object rects: "<<th.getDiff()<<std::endl;
+    logGlobal->infoStream()<<"\tMaking object rects: "<<th.getDiff();
 
 }
 
@@ -559,7 +559,7 @@ void CMapHandler::terrainRect( int3 top_tile, ui8 anim, const std::vector< std::
 					{
 						if(themp->tempOwner >= PlayerColor::PLAYER_LIMIT) //Neutral hero?
 						{
-							tlog1 << "A neutral hero (" << themp->name << ") at " << themp->pos << ". Should not happen!\n";
+                            logGlobal->errorStream() << "A neutral hero (" << themp->name << ") at " << themp->pos << ". Should not happen!";
 							continue;
 						}
 
@@ -581,7 +581,7 @@ void CMapHandler::terrainRect( int3 top_tile, ui8 anim, const std::vector< std::
 							case 0: flg = &Graphics::flags1; break;
 							case 1: flg = &Graphics::flags2; break;
 							case 2: flg = &Graphics::flags3; break;
-							default: tlog1 << "Not supported boat subtype: " << themp->boat->subID << std::endl;
+                            default: logGlobal->errorStream() << "Not supported boat subtype: " << themp->boat->subID;
 							}
 						}
 						else

+ 13 - 7
config/schemas/settings.json

@@ -143,9 +143,12 @@
 		"logging" : {
 			"type" : "object",
 			"default" : {},
+			"required" : [ "console", "file", "loggers" ],
 			"properties" : {
 				"console" : {
 					"type" : "object",
+					"default" : {},
+					"required" : [ "format", "threshold", "coloredOutputEnabled", "colorMapping" ],
 					"properties" : {
 						"format" : {
 							"type" : "string",
@@ -170,6 +173,7 @@
 							],
 							"items" : {
 								"type" : "object",
+								"default" : {},
 								"required" : [ "domain", "level", "color" ],
 								"properties" : {
 									"domain" : { "type" : "string" },
@@ -182,6 +186,8 @@
 				},
 				"file" : {
 					"type" : "object",
+					"default" : {},
+					"required" : [ "format" ],
 					"properties" : {
 						"format" : {
 							"type" : "string",
@@ -190,14 +196,14 @@
 					}
 				},
 				"loggers" : {
-					"type" : "object",
-					"additionalProperties" : {
-						"type":"object",
-						"required" : [ "level" ],
+					"type" : "array",
+					"default" : [ { "domain" : "global", "level" : "info" } ],
+					"items" : {
+						"type" : "object",
+						"required" : [ "level", "domain" ],
 						"properties" : {
-							"level" : {
-								"$ref" : "#/definitions/logLevelEnum"
-							}
+							"domain" : { "type" : "string" },
+							"level" : { "$ref" : "#/definitions/logLevelEnum" }
 						}
 
 					}

+ 1 - 1
lib/BattleState.cpp

@@ -777,7 +777,7 @@ ui8 BattleInfo::whatSide(PlayerColor player) const
 		if(sides[i] == player)
 			return i;
 
-	tlog1 << "BattleInfo::whatSide: Player " << player << " is not in battle!\n";
+    logGlobal->warnStream() << "BattleInfo::whatSide: Player " << player << " is not in battle!";
 	return -1;
 }
 

+ 1 - 1
lib/BattleState.h

@@ -222,7 +222,7 @@ public:
 			else if(!army || slot == SlotID() || !army->hasStackAtSlot(slot))
 			{
 				base = NULL;
-				tlog3 << type->nameSing << " doesn't have a base stack!\n";
+                logGlobal->warnStream() << type->nameSing << " doesn't have a base stack!";
 			}
 			else
 			{

+ 11 - 13
lib/CArtHandler.cpp

@@ -214,7 +214,7 @@ void CArtHandler::load(bool onlyTxt)
 	for (size_t i=0; i < artifacts.size(); i++)
 	{
 		if (artifacts[i] == nullptr)
-			tlog0 << "Warning: artifact with id " << i << " is missing!\n";
+            logGlobal->warnStream() << "Warning: artifact with id " << i << " is missing!";
 	}
 }
 
@@ -224,7 +224,7 @@ void CArtHandler::load(std::string objectID, const JsonNode & node)
 	art->id = ArtifactID(artifacts.size());
 
 	artifacts.push_back(art);
-	tlog5 << "Added artifact: " << objectID << "\n";
+    logGlobal->traceStream() << "Added artifact: " << objectID;
 	VLC->modh->identifiers.registerObject ("artifact." + objectID, art->id);
 }
 
@@ -296,7 +296,7 @@ void CArtHandler::addSlot(CArtifact * art, const std::string & slotID)
 			art->possibleSlots[ArtBearer::HERO].push_back (slot);
 		}
 		else
-			tlog2 << "Warning! Artifact slot " << slotID << " not recognized!";
+            logGlobal->warnStream() << "Warning! Artifact slot " << slotID << " not recognized!";
 	}
 }
 
@@ -330,7 +330,7 @@ void CArtHandler::loadClass(CArtifact * art, const JsonNode & node)
 	}
 	else
 	{
-		tlog2 << "Warning! Artifact rarity " << node["class"].String() << " not recognized!";
+        logGlobal->warnStream() << "Warning! Artifact rarity " << node["class"].String() << " not recognized!";
 		art->aClass = CArtifact::ART_SPECIAL;
 	}
 }
@@ -360,7 +360,7 @@ void CArtHandler::loadType(CArtifact * art, const JsonNode & node)
 			}
 		}
 		else
-			tlog2 << "Warning! Artifact type " << b.String() << " not recognized!";
+            logGlobal->warnStream() << "Warning! Artifact type " << b.String() << " not recognized!";
 	}
 }
 
@@ -466,8 +466,6 @@ ArtifactID CArtHandler::getArtSync (ui32 rand, int flags, bool erasePicked)
 			out.resize (64);
 			std::fill_n (out.begin(), 64, artifacts[2]); //Give Grail - this can't be banned (hopefully)
 		}
-
-		//tlog0 << "Treasure count: " << treasures.size() << std::endl;
 	};
 
 	std::vector<ConstTransitivePtr<CArtifact> > out;
@@ -611,11 +609,11 @@ void CArtHandler::erasePickedArt(ArtifactID id)
 			artifactList->erase(itr);
 		}
 		else
-			tlog2 << "Problem: cannot erase artifact " << art->Name() << " from list, it was not present\n";
+            logGlobal->warnStream() << "Problem: cannot erase artifact " << art->Name() << " from list, it was not present";
 
 	}
 	else
-		tlog2 << "Problem: cannot find list for artifact " << art->Name() << ", strange class. (special?)\n";
+        logGlobal->warnStream() << "Problem: cannot find list for artifact " << art->Name() << ", strange class. (special?)";
 }
 
 boost::optional<std::vector<CArtifact*>&> CArtHandler::listFromClass( CArtifact::EartClass artifactClass )
@@ -725,8 +723,8 @@ bool CArtifactInstance::canBePutAt(const CArtifactSet *artSet, ArtifactPosition
  	auto possibleSlots = artType->possibleSlots.find(artSet->bearerType());
  	if(possibleSlots == artType->possibleSlots.end())
  	{
-		tlog3 << "Warning: artifact " << artType->Name() << " doesn't have defined allowed slots for bearer of type "
-			<< artSet->bearerType() << std::endl;
+        logGlobal->warnStream() << "Warning: artifact " << artType->Name() << " doesn't have defined allowed slots for bearer of type "
+            << artSet->bearerType();
 		return false;
 	}
 
@@ -830,7 +828,7 @@ SpellID CArtifactInstance::getGivenSpellID() const
 	const Bonus * b = getBonusLocalFirst(Selector::type(Bonus::SPELL));
 	if(!b)
 	{
-		tlog3 << "Warning: " << nodeName() << " doesn't bear any spell!\n";
+        logGlobal->warnStream() << "Warning: " << nodeName() << " doesn't bear any spell!";
 		return SpellID::NONE;
 	}
 	return SpellID(b->subtype);
@@ -1116,7 +1114,7 @@ si32 CArtifactSet::getArtTypeId(ArtifactPosition pos) const
 	const CArtifactInstance * const a = getArt(pos);
 	if(!a)
 	{
-		tlog2 << (dynamic_cast<const CGHeroInstance*>(this))->name << " has no artifact at " << pos << " (getArtTypeId)\n";
+        logGlobal->warnStream() << (dynamic_cast<const CGHeroInstance*>(this))->name << " has no artifact at " << pos << " (getArtTypeId)";
 		return -1;
 	}
 	return a->artType->id;

+ 13 - 14
lib/CBattleCallback.cpp

@@ -17,7 +17,7 @@
  *
  */
 
-#define RETURN_IF_NOT_BATTLE(X) if(!duringBattle()) {tlog1 << __FUNCTION__ << " called when no battle!\n"; return X; }
+#define RETURN_IF_NOT_BATTLE(X) if(!duringBattle()) {logGlobal->errorStream() << __FUNCTION__ << " called when no battle!"; return X; }
 
 namespace SiegeStuffThatShouldBeMovedToHandlers //  <=== TODO
 {
@@ -36,7 +36,7 @@ namespace SiegeStuffThatShouldBeMovedToHandlers //  <=== TODO
 			outMaxDmg = 7.5;
 			break;
 		default:
-			tlog1 << "Unknown turret type!" << std::endl;
+            logGlobal->warnStream() << "Unknown turret type!";
 			outMaxDmg = outMinDmg = 1;
 		}
 	}
@@ -138,7 +138,7 @@ std::vector<shared_ptr<const CObstacleInstance> > CBattleInfoEssentials::battleG
 	{
 		if(!!player && *perspective != battleGetMySide())
 		{
-			tlog1 << "Unauthorized access attempt!\n";
+            logGlobal->errorStream() << "Unauthorized access attempt!";
 			assert(0); //I want to notice if that happens
 			//perspective = battleGetMySide();
 		}
@@ -226,8 +226,8 @@ BattlePerspective::BattlePerspective CBattleInfoEssentials::battleGetMySide() co
 	if(*player == getBattle()->sides[1])
 		return BattlePerspective::RIGHT_SIDE;
 
-	tlog1 << "Cannot find player " << *player << " in battle!\n";
-	return BattlePerspective::INVALID;
+    logGlobal->errorStream() << "Cannot find player " << *player << " in battle!";
+    return BattlePerspective::INVALID;
 }
 
 const CStack * CBattleInfoEssentials::battleActiveStack() const
@@ -271,13 +271,13 @@ const CGHeroInstance * CBattleInfoEssentials::battleGetFightingHero(ui8 side) co
 	RETURN_IF_NOT_BATTLE(nullptr);
 	if(side > 1)
 	{
-		tlog1 << "FIXME: " <<  __FUNCTION__ << " wrong argument!" << std::endl;
+        logGlobal->errorStream() << "FIXME: " <<  __FUNCTION__ << " wrong argument!";
 		return nullptr;
 	}
 
 	if(!battleDoWeKnowAbout(side))
 	{
-		tlog1 << "FIXME: " <<  __FUNCTION__ << " access check " << std::endl;
+        logGlobal->errorStream() << "FIXME: " <<  __FUNCTION__ << " access check ";
 		return nullptr;
 	}
 
@@ -288,7 +288,7 @@ InfoAboutHero CBattleInfoEssentials::battleGetHeroInfo( ui8 side ) const
 {
 	auto hero = getBattle()->heroes[side];
 	if(!hero)
-		tlog3 << __FUNCTION__ << ": side " << (int)side << " does not have hero!\n";
+        logGlobal->warnStream() << __FUNCTION__ << ": side " << (int)side << " does not have hero!";
 
 	return InfoAboutHero(hero, battleDoWeKnowAbout(side));
 }
@@ -305,7 +305,7 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastSpell(Pla
 	const ui8 side = playerToSide(player);
 	if(!battleDoWeKnowAbout(side))
 	{
-		tlog3 << "You can't check if enemy can cast given spell!\n";
+        logGlobal->warnStream() << "You can't check if enemy can cast given spell!";
 		return ESpellCastProblem::INVALID;
 	}
 
@@ -365,7 +365,7 @@ ui8 CBattleInfoEssentials::playerToSide(PlayerColor player) const
 	RETURN_IF_NOT_BATTLE(-1);
 	int ret = vstd::find_pos(getBattle()->sides, player);
 	if(ret < 0)
-		tlog3 << "Cannot find side for player " << player << std::endl;
+        logGlobal->warnStream() << "Cannot find side for player " << player;
 
 	return ret;
 }
@@ -478,7 +478,7 @@ SpellID CBattleInfoCallback::battleGetRandomStackSpell(const CStack * stack, ERa
 		return getRandomCastedSpell(stack); //caster
 		break;
 	default:
-		tlog1 << "Incorrect mode of battleGetRandomSpell (" << mode <<")\n";
+        logGlobal->errorStream() << "Incorrect mode of battleGetRandomSpell (" << mode <<")";
 		return SpellID::NONE;
 	}
 }
@@ -1242,7 +1242,6 @@ ReachabilityInfo CBattleInfoCallback::getReachability(const CStack *stack) const
 	{
 		//Stack is held by enemy, we can't use his perspective to check for reachability.
 		// Happens ie. when hovering enemy stack for its range. The arg could be set properly, but it's easier to fix it here.
-		//tlog3 << "Falling back to our perspective for reachability lookup for " << stack->nodeName() << std::endl;
 		params.perspective = battleGetMySide();
 	}
 
@@ -1390,7 +1389,7 @@ bool CBattleInfoCallback::isToReverseHlp (BattleHex hexFrom, BattleHex hexTo, bo
 	{
 		return fromDiv % 2 == 1;
 	}
-	tlog1 << "Catastrope in CBattleInfoCallback::isToReverse!" << std::endl;
+    logGlobal->errorStream() << "Catastrope in CBattleInfoCallback::isToReverse!";
 	return false; //should never happen
 }
 
@@ -1716,7 +1715,7 @@ std::vector<BattleHex> CBattleInfoCallback::battleGetPossibleTargets(PlayerColor
 		}
 		break;
 	default:
-		tlog1 << "FIXME " << __FUNCTION__ << " doesn't work with target type " << spell->getTargetType() << std::endl;
+        logGlobal->errorStream() << "FIXME " << __FUNCTION__ << " doesn't work with target type " << spell->getTargetType();
 	}
 
 	return ret;

+ 4 - 4
lib/CBonusTypeHandler.cpp

@@ -45,7 +45,7 @@ MacroString::MacroString(const std::string &format)
 			
 			if (end_pos == std::string::npos)
 			{
-				tlog2 << "Format error in: " << format <<std::endl;
+                logBonus->warnStream() << "Format error in: " << format;
 				end_pos = start_pos;
 				break;
 			}
@@ -148,7 +148,7 @@ std::string CBonusTypeHandler::bonusToString(Bonus *bonus, const IBonusBearer *b
 		}			
 		else
 		{
-			tlog2 << "Unknown macro in bonus config: " << name << std::endl;
+            logBonus->warnStream() << "Unknown macro in bonus config: " << name;
 			return "[error]";
 		}
 	};
@@ -282,14 +282,14 @@ void CBonusTypeHandler::load(const JsonNode& config)
 //			
 //			bonusTypes.push_back(bt);
 			
-			tlog2 << "Adding new bonuses not implemented (" << node.first << ")" << std::endl;
+            logBonus->warnStream() << "Adding new bonuses not implemented (" << node.first << ")";
 		}
 		else
 		{
 			CBonusType& bt = bonusTypes[it->second];
 			
 			loadItem(node.second, bt);
-			tlog5 << "Loaded bonus type " << node.first << std::endl;
+            logBonus->traceStream() << "Loaded bonus type " << node.first;
 		}	
 	}		
 }

+ 14 - 12
lib/CConsoleHandler.cpp

@@ -13,6 +13,8 @@
 *
 */
 
+boost::mutex CConsoleHandler::smx;
+
 #ifndef _WIN32
 	typedef std::string TColor;
 	#define CONSOLE_GREEN "\x1b[1;32m"
@@ -51,16 +53,16 @@ void printWinError()
 	int error = GetLastError();
 	if(!error)
 	{
-		tlog0 << "No Win error information set.\n";
+        logGlobal->errorStream() << "No Win error information set.";
 		return;
 	}
-	tlog1 << "Error " << error << " encountered:\n";
+    logGlobal->errorStream() << "Error " << error << " encountered:";
 
 	//Get error description
 	char* pTemp = NULL;
 	FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
 		NULL, error,  MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), (LPSTR)&pTemp, 1, NULL);
-	tlog1 << pTemp << std::endl;
+    logGlobal->errorStream() << pTemp;
 	LocalFree( pTemp );
 }
 
@@ -101,19 +103,19 @@ const char* exceptionName(DWORD exc)
 
 LONG WINAPI onUnhandledException(EXCEPTION_POINTERS* exception)
 {
-	tlog1 << "Disaster happened.\n";
+    logGlobal->errorStream() << "Disaster happened.";
 
 	PEXCEPTION_RECORD einfo = exception->ExceptionRecord;
-	tlog1 << "Reason: 0x" << std::hex << einfo->ExceptionCode << " - " << exceptionName(einfo->ExceptionCode);
-	tlog1 << " at " << std::setfill('0') << std::setw(4) << exception->ContextRecord->SegCs << ":" << (void*)einfo->ExceptionAddress << std::endl;;
+    logGlobal->errorStream() << "Reason: 0x" << std::hex << einfo->ExceptionCode << " - " << exceptionName(einfo->ExceptionCode)
+        << " at " << std::setfill('0') << std::setw(4) << exception->ContextRecord->SegCs << ":" << (void*)einfo->ExceptionAddress;
 
 	if (einfo->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
 	{
-		tlog1 << "Attempt to " << (einfo->ExceptionInformation[0] == 1 ? "write to " : "read from ")
-			<< "0x" <<  std::setw(8) << (void*)einfo->ExceptionInformation[1] << std::endl;;
+        logGlobal->errorStream() << "Attempt to " << (einfo->ExceptionInformation[0] == 1 ? "write to " : "read from ")
+            << "0x" <<  std::setw(8) << (void*)einfo->ExceptionInformation[1];
 	}
 	const DWORD threadId = ::GetCurrentThreadId();
-	tlog1 << "Thread ID: " << threadId << " [" << std::dec << std::setw(0) << threadId << "]\n";
+    logGlobal->errorStream() << "Thread ID: " << threadId << " [" << std::dec << std::setw(0) << threadId << "]";
 
 #ifndef __MINGW32__
 	//exception info to be placed in the dump
@@ -132,7 +134,7 @@ LONG WINAPI onUnhandledException(EXCEPTION_POINTERS* exception)
 
 	strcat(mname, "_crashinfo.dmp");
 	HANDLE dfile = CreateFileA(mname, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
-	tlog1 << "Crash info will be put in " << mname << std::endl;
+    logGlobal->errorStream() << "Crash info will be put in " << mname;
 	MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), dfile, MiniDumpWithDataSegs, &meinfo, 0, 0);
 #endif
 	MessageBoxA(0, "VCMI has crashed. We are sorry. File with information about encountered problem has been created.", "VCMI Crashhandler", MB_OK | MB_ICONERROR);
@@ -228,10 +230,10 @@ CConsoleHandler::CConsoleHandler() : thread(nullptr)
 }
 CConsoleHandler::~CConsoleHandler()
 {
-	tlog3 << "Killing console... ";
+    logGlobal->infoStream() << "Killing console...";
 	end();
 	delete cb;
-	tlog3 << "done!\n";
+    logGlobal->infoStream() << "Killing console... done!";
 }
 void CConsoleHandler::end()
 {

+ 25 - 5
lib/CConsoleHandler.h

@@ -35,9 +35,9 @@ public:
     ~CConsoleHandler(); //d-tor
     void start(); //starts listening thread
 
-    template<typename T> void print(const T &data, EConsoleTextColor::EConsoleTextColor color = EConsoleTextColor::DEFAULT, bool printToStdErr = false)
+    template<typename T> void print(const T &data, bool addNewLine = false, EConsoleTextColor::EConsoleTextColor color = EConsoleTextColor::DEFAULT, bool printToStdErr = false)
 	{
-        TLockGuard _(mx);
+        TLockGuard _(smx);
 #ifndef _WIN32
 		// with love from ffmpeg - library is trying to print some warnings from separate thread
 		// this results in broken console on Linux. Lock stdout to print all our data at once
@@ -46,12 +46,29 @@ public:
         if(color != EConsoleTextColor::DEFAULT) setColor(color);
         if(printToStdErr)
         {
-            std::cerr << data << std::flush;
+            std::cerr << data;
+            if(addNewLine)
+            {
+                std::cerr << std::endl;
+            }
+            else
+            {
+                std::cerr << std::flush;
+            }
         }
         else
         {
-            std::cout << data << std::flush;
+            std::cout << data;
+            if(addNewLine)
+            {
+                std::cout << std::endl;
+            }
+            else
+            {
+                std::cout << std::flush;
+            }
         }
+
         if(color != EConsoleTextColor::DEFAULT) setColor(EConsoleTextColor::DEFAULT);
 #ifndef _WIN32
 		funlockfile(stdout);
@@ -67,7 +84,10 @@ private:
 
     void setColor(EConsoleTextColor::EConsoleTextColor color); //sets color of text appropriate for given logging level
 
-    mutable boost::mutex mx;
+    /// FIXME: Implement CConsoleHandler as singleton, move some logic into CLogConsoleTarget, etc... needs to be disussed:)
+    /// Without static, application will crash complaining about mutex deleted. In short: CConsoleHandler gets deleted before
+    /// the logging system.
+    static boost::mutex smx;
 
     boost::thread * thread;
 };

+ 10 - 10
lib/CCreatureHandler.cpp

@@ -167,7 +167,7 @@ static void AddAbility(CCreature *cre, const JsonVector &ability_vec)
 			cre->addBonus(-1, Bonus::LUCK);
 			cre->getBonusList().back()->effectRange = Bonus::ONLY_ENEMY_ARMY;
 		} else
-			tlog1 << "Error: invalid ability type " << type << " in creatures config" << std::endl;
+            logGlobal->errorStream() << "Error: invalid ability type " << type << " in creatures config";
 
 		return;
 	}
@@ -192,7 +192,7 @@ static void RemoveAbility(CCreature *cre, const JsonNode &ability)
 		if (type == "DOUBLE_WIDE")
 			cre->doubleWide = false;
 		else
-			tlog1 << "Error: invalid ability type " << type << " in creatures config" << std::endl;
+            logGlobal->errorStream() << "Error: invalid ability type " << type << " in creatures config";
 
 		return;
 	}
@@ -251,7 +251,7 @@ void CCreatureHandler::loadBonuses(CCreature & ncre, std::string bonuses)
 
 void CCreatureHandler::load()
 {
-	tlog5 << "\t\tReading ZCRTRAIT.TXT" << std::endl;
+    logGlobal->traceStream() << "\t\tReading ZCRTRAIT.TXT";
 
 	////////////reading ZCRTRAIT.TXT ///////////////////
 	CLegacyConfigParser parser("DATA/ZCRTRAIT.TXT");
@@ -304,7 +304,7 @@ void CCreatureHandler::load()
 	while (parser.endLine());
 
 	// loading creatures properties
-	tlog5 << "\t\tReading creatures json configs" << std::endl;
+    logGlobal->traceStream() << "\t\tReading creatures json configs";
 
 	const JsonNode gameConf(ResourceID("config/gameConfig.json"));
 	const JsonNode config(JsonUtils::assembleFromFiles(gameConf["creatures"].convertTo<std::vector<std::string> >()));
@@ -430,7 +430,7 @@ void CCreatureHandler::load()
 
 	}//end of Stack Experience
 
-	tlog5 << "\t\tReading config/commanders.json" << std::endl;
+    logGlobal->traceStream() << "\t\tReading config/commanders.json";
 	const JsonNode config3(ResourceID("config/commanders.json"));
 
 	BOOST_FOREACH (auto bonus, config3["bonusPerLevel"].Vector())
@@ -508,7 +508,7 @@ void CCreatureHandler::load(std::string creatureID, const JsonNode & node)
 	creature->idNumber = CreatureID(creatures.size());
 
 	creatures.push_back(creature);
-	tlog5 << "Added creature: " << creatureID << "\n";
+    logGlobal->traceStream() << "Added creature: " << creatureID;
 	registerCreature(creature->nameRef, creature->idNumber);
 }
 
@@ -778,7 +778,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigPars
 			case 'U':
 				b.type = Bonus::UNDEAD; break;
 			default:
-				tlog5 << "Not parsed bonus " << buf << mod << "\n";
+                logGlobal->traceStream() << "Not parsed bonus " << buf << mod;
 				return;
 				break;
 		}
@@ -880,7 +880,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigPars
 				b.type = Bonus::MIND_IMMUNITY;
 				break;
 			default:
-				tlog5 << "Not parsed bonus " << buf << mod << "\n";
+                logGlobal->traceStream() << "Not parsed bonus " << buf << mod;
 				return;
 		}
 		break;
@@ -921,7 +921,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigPars
 		b.valType = Bonus::INDEPENDENT_MAX;
 		break;
 	default:
-		tlog5 << "Not parsed bonus " << buf << mod << "\n";
+        logGlobal->traceStream() << "Not parsed bonus " << buf << mod;
 		return;
 		break;
 	}
@@ -1011,7 +1011,7 @@ CreatureID CCreatureHandler::pickRandomMonster(const boost::function<int()> &ran
 
 		if(!allowed.size())
 		{
-			tlog2 << "Cannot pick a random creature of tier " << tier << "!\n";
+            logGlobal->warnStream() << "Cannot pick a random creature of tier " << tier << "!";
 			return CreatureID::NONE;
 		}
 

+ 4 - 4
lib/CCreatureSet.cpp

@@ -44,12 +44,12 @@ bool CCreatureSet::setCreature(SlotID slot, CreatureID type, TQuantity quantity)
 {
 	if(!slot.validSlot())
 	{
-		tlog1 << "Cannot set slot " << slot << std::endl;
+        logGlobal->errorStream() << "Cannot set slot " << slot;
 		return false;
 	}
 	if(!quantity)
 	{
-		tlog2 << "Using set creature to delete stack?\n";
+        logGlobal->warnStream() << "Using set creature to delete stack?";
 		eraseStack(slot);
 		return true;
 	}
@@ -170,7 +170,7 @@ void CCreatureSet::addToSlot(SlotID slot, CreatureID cre, TQuantity count, bool
 	}
 	else
 	{
-		tlog1 << "Failed adding to slot!\n";
+        logGlobal->errorStream() << "Failed adding to slot!";
 	}
 }
 
@@ -188,7 +188,7 @@ void CCreatureSet::addToSlot(SlotID slot, CStackInstance *stack, bool allowMergi
 	}
 	else
 	{
-		tlog1 << "Cannot add to slot " << slot << " stack " << *stack << std::endl;
+        logGlobal->errorStream() << "Cannot add to slot " << slot << " stack " << *stack;
 	}
 }
 

+ 6 - 6
lib/CGameInterface.cpp

@@ -44,16 +44,16 @@ rett * createAny(std::string dllname, std::string methodName)
 		getAI = (rett*(*)())dlsym(dll,methodName.c_str());
 	}
 	else
-		tlog0 << "Error: " << dlerror() <<"\n";
+        logGlobal->errorStream() << "Error: " << dlerror();
 #endif
 	if (!dll)
 	{
-		tlog1 << "Cannot open dynamic library ("<<dllname<<"). Throwing..."<<std::endl;
+        logGlobal->errorStream() << "Cannot open dynamic library ("<<dllname<<"). Throwing...";
 		throw std::runtime_error("Cannot open dynamic library");
 	}
 	else if(!getName || !getAI)
 	{
-		tlog1 << dllname << " does not export method " << methodName << std::endl;
+        logGlobal->errorStream() << dllname << " does not export method " << methodName;
 #ifdef _WIN32
 		FreeLibrary(dll);
 #else
@@ -63,11 +63,11 @@ rett * createAny(std::string dllname, std::string methodName)
 	}
 
 	getName(temp);
-	tlog0 << "Loaded " << temp << std::endl;
+    logGlobal->infoStream() << "Loaded " << temp;
 	ret = getAI();
 
 	if(!ret)
-		tlog1 << "Cannot get AI!\n";
+        logGlobal->errorStream() << "Cannot get AI!";
 
 	return ret;
 }
@@ -75,7 +75,7 @@ rett * createAny(std::string dllname, std::string methodName)
 template<typename rett>
 rett * createAnyAI(std::string dllname, std::string methodName)
 {
-	tlog1<<"Opening "<<dllname<<"\n";
+    logGlobal->infoStream() << "Opening " << dllname;
 	std::string filename = VCMIDirs::get().libraryName(dllname);
 	rett* ret = createAny<rett>(VCMIDirs::get().libraryPath() + "/AI/" + filename, methodName);
 	ret->dllName = dllname;

+ 46 - 47
lib/CGameState.cpp

@@ -203,13 +203,13 @@ void MetaString::getLocalString(const std::pair<ui8,ui32> &txt, std::string &dst
 			vec = &VLC->generaltexth->capColors;
 			break;
 		default:
-			tlog1 << "Failed string substitution because type is " << type << std::endl;
+            logGlobal->errorStream() << "Failed string substitution because type is " << type;
 			dst = "#@#";
 			return;
 		}
 		if(vec->size() <= ser)
 		{
-			tlog1 << "Failed string substitution with type " << type << " because index " << ser << " is out of bounds!\n";
+            logGlobal->errorStream() << "Failed string substitution with type " << type << " because index " << ser << " is out of bounds!";
 			dst = "#!#";
 		}
 		else
@@ -256,7 +256,7 @@ DLL_LINKAGE void MetaString::toString(std::string &dst) const
 			boost::replace_first(dst, "%+d", '+' + boost::lexical_cast<std::string>(numbers[nums++]));
 			break;
 		default:
-			tlog1 << "MetaString processing error!\n";
+            logGlobal->errorStream() << "MetaString processing error!";
 			break;
 		}
 	}
@@ -313,7 +313,7 @@ DLL_LINKAGE std::string MetaString::buildList () const
 				lista.replace (lista.find("%d"), 2, boost::lexical_cast<std::string>(numbers[nums++]));
 				break;
 			default:
-				tlog1 << "MetaString processing error!\n";
+                logGlobal->errorStream() << "MetaString processing error!";
 		}
 
 	}
@@ -362,7 +362,7 @@ static CGObjectInstance * createObject(Obj id, int subid, int3 pos, PlayerColor
 	nobj->ID = id;
 	nobj->subID = subid;
 	if(!nobj->defInfo)
-		tlog3 <<"No def declaration for " <<id <<" "<<subid<<std::endl;
+        logGlobal->warnStream() <<"No def declaration for " <<id <<" "<<subid;
 	nobj->pos = pos;
 	//nobj->state = NULL;//new CLuaObjectScript();
 	nobj->tempOwner = owner;
@@ -382,7 +382,7 @@ CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, PlayerColor pl
 
 	if(player>=PlayerColor::PLAYER_LIMIT)
 	{
-		tlog1 << "Cannot pick hero for " << town->typeID << ". Wrong owner!\n";
+        logGlobal->errorStream() << "Cannot pick hero for " << town->typeID << ". Wrong owner!";
 		return NULL;
 	}
 
@@ -400,7 +400,7 @@ CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, PlayerColor pl
 		}
 		if(!pool.size())
 		{
-			tlog1 << "Cannot pick native hero for " << player << ". Picking any...\n";
+            logGlobal->errorStream() << "Cannot pick native hero for " << player << ". Picking any...";
 			return pickHeroFor(false, player, town, available);
 		}
 		else
@@ -423,7 +423,7 @@ CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, PlayerColor pl
 		}
 		if(!pool.size() || sum == 0)
 		{
-			tlog1 << "There are no heroes available for player " << player<<"!\n";
+            logGlobal->errorStream() << "There are no heroes available for player " << player<<"!";
 			return nullptr;
 		}
 
@@ -495,7 +495,7 @@ int CGameState::pickHero(PlayerColor owner)
 			return factionHeroes[i];
 	}
 
-	tlog3 << "Warning: cannot find free hero - trying to get first available..."<<std::endl;
+    logGlobal->warnStream() << "Warning: cannot find free hero - trying to get first available...";
 	for(int j=0; j<VLC->heroh->heroes.size(); j++)
 		if(!map->getHero(j))
 			return j;
@@ -637,7 +637,7 @@ std::pair<Obj,int> CGameState::pickObject (CGObjectInstance *obj)
 
 			if (result.first == Obj::NO_OBJ)
 			{
-				tlog0 << "Error: failed to find creature for dwelling of "<< int(faction) << " of level " << int(level) << "\n";
+                logGlobal->errorStream() << "Error: failed to find creature for dwelling of "<< int(faction) << " of level " << int(level);
 				auto iter = VLC->objh->cregens.begin();
 				std::advance(iter, ran() % VLC->objh->cregens.size() );
 				result = std::make_pair(Obj::CREATURE_GENERATOR1, iter->first);
@@ -670,7 +670,7 @@ void CGameState::randomizeObject(CGObjectInstance *cur)
 	else if(ran.first==Obj::HERO)//special code for hero
 	{
 		CGHeroInstance *h = dynamic_cast<CGHeroInstance *>(cur);
-		if(!h) {tlog2<<"Wrong random hero at "<<cur->pos<<std::endl; return;}
+        if(!h) {logGlobal->warnStream()<<"Wrong random hero at "<<cur->pos; return;}
 		cur->ID = ran.first;
 		cur->subID = ran.second;
 		h->type = VLC->heroh->heroes[ran.second];
@@ -682,7 +682,7 @@ void CGameState::randomizeObject(CGObjectInstance *cur)
 	else if(ran.first==Obj::TOWN)//special code for town
 	{
 		CGTownInstance *t = dynamic_cast<CGTownInstance*>(cur);
-		if(!t) {tlog2<<"Wrong random town at "<<cur->pos<<std::endl; return;}
+        if(!t) {logGlobal->warnStream()<<"Wrong random town at "<<cur->pos; return;}
 		cur->ID = ran.first;
 		cur->subID = ran.second;
 		//FIXME: copy-pasted from above
@@ -704,7 +704,7 @@ void CGameState::randomizeObject(CGObjectInstance *cur)
 	map->customDefs.push_back(cur->defInfo = ran.first.toDefObjInfo()[ran.second]);
 	if(!cur->defInfo)
 	{
-		tlog1<<"*BIG* WARNING: Missing def declaration for "<<cur->ID<<" "<<cur->subID<<std::endl;
+        logGlobal->errorStream()<<"*BIG* WARNING: Missing def declaration for "<<cur->ID<<" "<<cur->subID;
 		return;
 	}
 
@@ -847,7 +847,7 @@ void CGameState::init(StartInfo * si)
 		return ret;
 	};
 
-	tlog0 << "\tUsing random seed: "<< si->seedToBeUsed << std::endl;
+    logGlobal->infoStream() << "\tUsing random seed: "<< si->seedToBeUsed;
 	ran.seed((boost::int32_t)si->seedToBeUsed);
 	scenarioOps = new StartInfo(*si);
 	initialOpts = new StartInfo(*si);
@@ -859,7 +859,7 @@ void CGameState::init(StartInfo * si)
 		{
 			if(scenarioOps->createRandomMap)
 			{
-				tlog0 << "Create random map." << std::endl;
+                logGlobal->infoStream() << "Create random map.";
 
 				// Create player settings for RMG
 				std::map<PlayerColor, CMapGenerator::CPlayerSettings> players;
@@ -909,14 +909,14 @@ void CGameState::init(StartInfo * si)
 			}
 			else
 			{
-				tlog0 << "Open map file: " << scenarioOps->mapname << std::endl;
+                logGlobal->infoStream() << "Open map file: " << scenarioOps->mapname;
 				map = CMapService::loadMap(scenarioOps->mapname).release();
 			}
 		}
 		break;
 	case StartInfo::CAMPAIGN:
 		{
-			tlog0 << "Open campaign map file: " << scenarioOps->campState->currentMap << std::endl;
+            logGlobal->infoStream() << "Open campaign map file: " << scenarioOps->campState->currentMap;
 			auto campaign = scenarioOps->campState;
 			assert(vstd::contains(campaign->camp->mapPieces, scenarioOps->campState->currentMap));
 
@@ -929,20 +929,19 @@ void CGameState::init(StartInfo * si)
 		initDuel();
 		return;
 	default:
-		tlog1 << "Wrong mode: " << (int)scenarioOps->mode << std::endl;
+        logGlobal->errorStream() << "Wrong mode: " << (int)scenarioOps->mode;
 		return;
 	}
 	VLC->arth->initAllowedArtifactsList(map->allowedArtifact);
-	tlog0 << "Map loaded!" << std::endl;
+    logGlobal->infoStream() << "Map loaded!";
 
-	//tlog0 <<"Reading and detecting map file (together): "<<tmh.getDif()<<std::endl;
-	tlog0 << "\tOur checksum for the map: "<< map->checksum << std::endl;
+    logGlobal->infoStream() << "\tOur checksum for the map: "<< map->checksum;
 	if(scenarioOps->mapfileChecksum)
 	{
-		tlog0 << "\tServer checksum for " << scenarioOps->mapname <<": "<< scenarioOps->mapfileChecksum << std::endl;
+        logGlobal->infoStream() << "\tServer checksum for " << scenarioOps->mapname <<": "<< scenarioOps->mapfileChecksum;
 		if(map->checksum != scenarioOps->mapfileChecksum)
 		{
-			tlog1 << "Wrong map checksum!!!" << std::endl;
+            logGlobal->errorStream() << "Wrong map checksum!!!";
 			throw std::runtime_error("Wrong checksum");
 		}
 	}
@@ -951,8 +950,8 @@ void CGameState::init(StartInfo * si)
 
 	day = 0;
 
-	tlog4 << "Initialization:\n";
-	tlog4 << "\tPicking grail position\n";
+    logGlobal->debugStream() << "Initialization:";
+    logGlobal->debugStream() << "\tPicking grail position";
  	//pick grail location
  	if(map->grailPos.x < 0 || map->grailRadious) //grail not set or set within a radius around some place
  	{
@@ -988,11 +987,11 @@ void CGameState::init(StartInfo * si)
 		if(allowedPos.size())
 			map->grailPos = allowedPos[ran() % allowedPos.size()];
 		else
-			tlog2 << "Warning: Grail cannot be placed, no appropriate tile found!\n";
+            logGlobal->warnStream() << "Warning: Grail cannot be placed, no appropriate tile found!";
 	}
 
 	//picking random factions for players
-	tlog4 << "\tPicking random factions for players\n";
+    logGlobal->debugStream() << "\tPicking random factions for players";
 	for(auto it = scenarioOps->playerInfos.begin();
 		it != scenarioOps->playerInfos.end(); ++it)
 	{
@@ -1007,7 +1006,7 @@ void CGameState::init(StartInfo * si)
 	}
 
 	//randomizing objects
-	tlog4 << "\tRandomizing objects\n";
+    logGlobal->debugStream() << "\tRandomizing objects";
 	BOOST_FOREACH(CGObjectInstance *obj, map->objects)
 	{
 		if(!obj)
@@ -1029,7 +1028,7 @@ void CGameState::init(StartInfo * si)
 	//std::cout<<"\tRandomizing objects: "<<th.getDif()<<std::endl;
 
 	/*********creating players entries in gs****************************************/
-	tlog4 << "\tCreating player entries in gs\n";
+    logGlobal->debugStream() << "\tCreating player entries in gs";
 	for(auto it = scenarioOps->playerInfos.begin();
 		it != scenarioOps->playerInfos.end(); ++it)
 	{
@@ -1043,7 +1042,7 @@ void CGameState::init(StartInfo * si)
 	}
 
 	/*********give starting hero****************************************/
-	tlog4 << "\tGiving starting hero\n";
+    logGlobal->debugStream() << "\tGiving starting hero";
 	{
 		bool campaignGiveHero = false;
 		if(scenarioOps->campState)
@@ -1082,7 +1081,7 @@ void CGameState::init(StartInfo * si)
 	}
 
 	/*************************replace hero placeholders*****************************/
-	tlog4 << "\tReplacing hero placeholders\n";
+    logGlobal->debugStream() << "\tReplacing hero placeholders";
 	std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > campHeroReplacements; //instance, id in vector
 	if (scenarioOps->campState)
 	{
@@ -1162,7 +1161,7 @@ void CGameState::init(StartInfo * si)
 						replaceHero(gid, Xheroes[hp->power - 1]);
 					else
 					{
-						tlog3 << "Warning, no hero to replace!\n";
+                        logGlobal->warnStream() << "Warning, no hero to replace!";
 						map->removeBlockVisTiles(hp, true);
 						delete hp;
 						map->objects[g] = NULL;
@@ -1175,7 +1174,7 @@ void CGameState::init(StartInfo * si)
 	}
 
 	/******************RESOURCES****************************************************/
-	tlog4 << "\tSetting up resources\n";
+    logGlobal->debugStream() << "\tSetting up resources";
 	const JsonNode config(ResourceID("config/startres.json"));
 	const JsonVector &vector = config["difficulty"].Vector();
 	const JsonNode &level = vector[scenarioOps->difficulty];
@@ -1229,7 +1228,7 @@ void CGameState::init(StartInfo * si)
 
 
 	/*************************HEROES************************************************/
-	tlog4 << "\tSetting up heroes\n";
+    logGlobal->debugStream() << "\tSetting up heroes";
 	//Replace placeholders with heroes from previous missions
 	BOOST_FOREACH(auto obj, campHeroReplacements)
 	{
@@ -1274,7 +1273,7 @@ void CGameState::init(StartInfo * si)
 	{
 		if (map->heroes[i]->getOwner() == PlayerColor::UNFLAGGABLE)
 		{
-			tlog2 << "Warning - hero with uninitialized owner!\n";
+            logGlobal->warnStream() << "Warning - hero with uninitialized owner!";
 			continue;
 		}
 		CGHeroInstance * vhi = map->heroes[i];
@@ -1344,7 +1343,7 @@ void CGameState::init(StartInfo * si)
 					}
 				}
 				if(maxB < 0)
-					tlog2 << "Warning - cannot give bonus to hero cause there are no heroes!\n";
+                    logGlobal->warnStream() << "Warning - cannot give bonus to hero cause there are no heroes!";
 				else
 					giveCampaignBonusToHero(heroes[maxB]);
 			}
@@ -1363,7 +1362,7 @@ void CGameState::init(StartInfo * si)
 	}
 
 	/*************************FOG**OF**WAR******************************************/
-	tlog4 << "\tFog of war\n"; //FIXME: should be initialized after all bonuses are set
+    logGlobal->debugStream() << "\tFog of war"; //FIXME: should be initialized after all bonuses are set
 	for(auto k=teams.begin(); k!=teams.end(); ++k)
 	{
 		k->second.fogOfWarMap.resize(map->width);
@@ -1392,7 +1391,7 @@ void CGameState::init(StartInfo * si)
 		}
 	}
 
-	tlog4 << "\tStarting bonuses\n";
+    logGlobal->debugStream() << "\tStarting bonuses";
 	for(auto k=players.begin(); k!=players.end(); ++k)
 	{
 		//starting bonus
@@ -1421,7 +1420,7 @@ void CGameState::init(StartInfo * si)
 			{
  				if(!k->second.heroes.size())
 				{
-					tlog5 << "Cannot give starting artifact - no heroes!" << std::endl;
+                    logGlobal->debugStream() << "Cannot give starting artifact - no heroes!";
 					break;
 				}
  				CArtifact *toGive;
@@ -1434,7 +1433,7 @@ void CGameState::init(StartInfo * si)
 		}
 	}
 	/****************************TOWNS************************************************/
-	tlog4 << "\tTowns\n";
+    logGlobal->debugStream() << "\tTowns";
 
 	//campaign bonuses for towns
 	if (scenarioOps->mode == StartInfo::CAMPAIGN)
@@ -1562,7 +1561,7 @@ void CGameState::init(StartInfo * si)
 			getPlayer(vti->getOwner())->towns.push_back(vti);
 	}
 
-	tlog4 << "\tObject initialization\n";
+    logGlobal->debugStream() << "\tObject initialization";
 	objCaller->preInit();
 	BOOST_FOREACH(CGObjectInstance *obj, map->objects)
 	{
@@ -1616,11 +1615,11 @@ void CGameState::init(StartInfo * si)
 	}
 
 
-	tlog4 << "\tChecking objectives\n";
+    logGlobal->debugStream() << "\tChecking objectives";
 	map->checkForObjectives(); //needs to be run when all objects are properly placed
 
 	int seedAfterInit = ran();
-	tlog0 << "Seed after init is " << seedAfterInit << " (before was " << scenarioOps->seedToBeUsed << ")" << std::endl;
+    logGlobal->infoStream() << "Seed after init is " << seedAfterInit << " (before was " << scenarioOps->seedToBeUsed << ")";
 	if(scenarioOps->seedPostInit > 0)
 	{
 		//RNG must be in the same state on all machines when initialization is done (otherwise we have desync)
@@ -1639,9 +1638,9 @@ void CGameState::initDuel()
 	{
 		if(boost::algorithm::ends_with(scenarioOps->mapname, ".json"))
 		{
-			tlog0 << "Loading duel settings from JSON file: " << scenarioOps->mapname << std::endl;
+            logGlobal->infoStream() << "Loading duel settings from JSON file: " << scenarioOps->mapname;
 			dp = DuelParameters::fromJSON(scenarioOps->mapname);
-			tlog0 << "JSON file has been successfully read!\n";
+            logGlobal->infoStream() << "JSON file has been successfully read!";
 		}
 		else
 		{
@@ -1651,7 +1650,7 @@ void CGameState::initDuel()
 	}
 	catch(...)
 	{
-		tlog1 << "Cannot load duel settings from " << scenarioOps->mapname << std::endl;
+        logGlobal->errorStream() << "Cannot load duel settings from " << scenarioOps->mapname;
 		throw;
 	}
 
@@ -3049,7 +3048,7 @@ void CPathfinder::calculatePaths(int3 src /*= int3(-1,-1,-1)*/, int movement /*=
 
 	if(!gs->map->isInTheMap(src)/* || !gs->map->isInTheMap(dest)*/) //check input
 	{
-		tlog1 << "CGameState::calculatePaths: Hero outside the gs->map? How dare you...\n";
+        logGlobal->errorStream() << "CGameState::calculatePaths: Hero outside the gs->map? How dare you...";
 		return;
 	}
 

+ 6 - 6
lib/CHeroHandler.cpp

@@ -62,7 +62,7 @@ std::vector<BattleHex> CObstacleInfo::getBlocked(BattleHex hex) const
 			toBlock += BattleHex::LEFT;
 
 		if(!toBlock.isValid())
-			tlog1 << "Misplaced obstacle!\n";
+            logGlobal->errorStream() << "Misplaced obstacle!";
 		else
 			ret.push_back(toBlock);
 	}
@@ -132,7 +132,7 @@ void CHeroClassHandler::load()
 	for (size_t i=0; i < heroClasses.size(); i++)
 	{
 		if (heroClasses[i] == nullptr)
-			tlog0 << "Warning: class with id " << i << " is missing!\n";
+            logGlobal->warnStream() << "Warning: class with id " << i << " is missing!";
 	}
 }
 
@@ -143,7 +143,7 @@ void CHeroClassHandler::load(std::string objectID, const JsonNode & input)
 	heroClass->id = heroClasses.size();
 
 	heroClasses.push_back(heroClass);
-	tlog5 << "Added hero class: " << objectID << "\n";
+    logGlobal->traceStream() << "Added hero class: " << objectID;
 	VLC->modh->identifiers.registerObject("heroClass." + heroClass->identifier, heroClass->id);
 }
 
@@ -214,7 +214,7 @@ void CHeroHandler::load(std::string objectID, const JsonNode & input)
 	hero->ID = heroes.size();
 
 	heroes.push_back(hero);
-	tlog5 << "Added hero: " << objectID << "\n";
+    logGlobal->traceStream() << "Added hero: " << objectID;
 	VLC->modh->identifiers.registerObject("hero." + objectID, hero->ID);
 }
 
@@ -467,7 +467,7 @@ void CHeroHandler::loadHeroes()
 	for (size_t i=0; i < heroes.size(); i++)
 	{
 		if (heroes[i] == nullptr)
-			tlog0 << "Warning: hero with id " << i << " is missing!\n";
+            logGlobal->warnStream() << "Warning: hero with id " << i << " is missing!";
 	}
 }
 
@@ -514,7 +514,7 @@ ui64 CHeroHandler::reqExp (ui32 level) const
 	}
 	else
 	{
-		tlog3 << "A hero has reached unsupported amount of experience\n";
+        logGlobal->warnStream() << "A hero has reached unsupported amount of experience";
 		return expPerLevel[expPerLevel.size()-1];
 	}
 }

+ 1 - 1
lib/CLogger.h

@@ -41,7 +41,7 @@ public:
 		if(lvl < CLogger::CONSOLE_LOGGING_LEVEL)
 		{
 			if(console)
-                console->print(data, static_cast<EConsoleTextColor::EConsoleTextColor>(lvl));
+                console->print(data, false, static_cast<EConsoleTextColor::EConsoleTextColor>(lvl));
 			else
 				std::cout << data << std::flush;
 		}

+ 2 - 8
lib/CMakeLists.txt

@@ -59,16 +59,10 @@ set(lib_SRCS
 )
 
 set(lib_HEADERS
+		../Global.h
+		../tchar_amigaos4.h
 		filesystem/CInputStream.h
 		filesystem/ISimpleResourceLoader.h
-		logging/CBasicLogConfigurator.h
-		logging/CLogger.h
-		mapping/CCampaignHandler.h
-		mapping/CMap.h
-		mapping/CMapEditManager.h
-		mapping/CMapInfo.h
-		mapping/CMapService.h
-		mapping/MapFormatH3M.h
 		AI_Base.h
 		CondSh.h
 		ConstTransitivePtr.h

+ 14 - 15
lib/CModHandler.cpp

@@ -25,7 +25,7 @@
 void CIdentifierStorage::checkIdentifier(std::string & ID)
 {
 	if (boost::algorithm::ends_with(ID, "."))
-		tlog3 << "BIG WARNING: identifier " << ID << " seems to be broken!\n";
+        logGlobal->warnStream() << "BIG WARNING: identifier " << ID << " seems to be broken!";
 	else
 	{
 		size_t pos = 0;
@@ -33,7 +33,7 @@ void CIdentifierStorage::checkIdentifier(std::string & ID)
 		{
 			if (std::tolower(ID[pos]) != ID[pos] ) //Not in camelCase
 			{
-				tlog3 << "Warning: identifier " << ID << " is not in camelCase!\n";
+                logGlobal->warnStream() << "Warning: identifier " << ID << " is not in camelCase!";
 				ID[pos] = std::tolower(ID[pos]);// Try to fix the ID
 			}
 			pos = ID.find('.', pos);
@@ -53,7 +53,7 @@ void CIdentifierStorage::requestIdentifier(std::string name, const boost::functi
 	else
 	{
 		if(boost::algorithm::starts_with(name, "primSkill."))
-			tlog3 << "incorrect primSkill name requested\n";
+            logGlobal->warnStream() << "incorrect primSkill name requested";
 
 		missingObjects[name].push_back(callback); // queue callback
 	}
@@ -88,13 +88,13 @@ void CIdentifierStorage::finalize() const
 	{
 		BOOST_FOREACH(auto object, missingObjects)
 		{
-			tlog1 << "Error: object " << object.first << " was not found!\n";
+            logGlobal->errorStream() << "Error: object " << object.first << " was not found!";
 		}
 		BOOST_FOREACH(auto object, registeredObjects)
 		{
-			tlog5 << object.first << " -> " << object.second << "\n";
+            logGlobal->traceStream() << object.first << " -> " << object.second;
 		}
-		tlog1 << "All known identifiers were dumped into log file\n";
+        logGlobal->errorStream() << "All known identifiers were dumped into log file";
 	}
 	assert(missingObjects.empty());
 }
@@ -139,8 +139,8 @@ bool CModHandler::hasCircularDependency(TModID modID, std::set <TModID> currentL
 	// Mod already present? We found a loop
 	if (vstd::contains(currentList, modID))
 	{
-		tlog0 << "Error: Circular dependency detected! Printing dependency list:\n";
-		tlog0 << "\t" << mod.name << " -> \n";
+        logGlobal->errorStream() << "Error: Circular dependency detected! Printing dependency list:";
+        logGlobal->errorStream() << "\t" << mod.name << " -> ";
 		return true;
 	}
 
@@ -151,7 +151,7 @@ bool CModHandler::hasCircularDependency(TModID modID, std::set <TModID> currentL
 	{
 		if (hasCircularDependency(dependency, currentList))
 		{
-			tlog0 << "\t" << mod.name << " ->\n"; // conflict detected, print dependency list
+            logGlobal->errorStream() << "\t" << mod.name << " ->\n"; // conflict detected, print dependency list
 			return true;
 		}
 	}
@@ -168,7 +168,7 @@ bool CModHandler::checkDependencies(const std::vector <TModID> & input) const
 		{
 			if (!vstd::contains(input, dep))
 			{
-				tlog1 << "Error: Mod " << mod.name << " requires missing " << dep << "!\n";
+                logGlobal->errorStream() << "Error: Mod " << mod.name << " requires missing " << dep << "!";
 				return false;
 			}
 		}
@@ -177,7 +177,7 @@ bool CModHandler::checkDependencies(const std::vector <TModID> & input) const
 		{
 			if (vstd::contains(input, conflicting))
 			{
-				tlog1 << "Error: Mod " << mod.name << " conflicts with " << allMods.at(conflicting).name << "!\n";
+                logGlobal->errorStream() << "Error: Mod " << mod.name << " conflicts with " << allMods.at(conflicting).name << "!";
 				return false;
 			}
 		}
@@ -274,12 +274,12 @@ void CModHandler::initialize(std::vector<std::string> availableMods)
 			detectedMods.push_back(name);
 		}
 		else
-			tlog3 << "\t\t Directory " << name << " does not contains VCMI mod\n";
+            logGlobal->warnStream() << "\t\t Directory " << name << " does not contains VCMI mod";
 	}
 
 	if (!checkDependencies(detectedMods))
 	{
-		tlog1 << "Critical error: failed to load mods! Exiting...\n";
+        logGlobal->errorStream() << "Critical error: failed to load mods! Exiting...";
 		exit(1);
 	}
 
@@ -316,8 +316,7 @@ void CModHandler::loadActiveMods()
 {
 	BOOST_FOREACH(const TModID & modName, activeMods)
 	{
-		tlog0 << "\t\tLoading mod ";
-		tlog2 << allMods[modName].name << "\n";
+        logGlobal->infoStream() << "\t\tLoading mod " << allMods[modName].name;
 
 		std::string modFileName = "mods/" + modName + "/mod.json";
 

+ 35 - 36
lib/CObjectHandler.cpp

@@ -200,24 +200,24 @@ static void readBankLevel(const JsonNode &level, BankConfig &bc)
 
 void CObjectHandler::load()
 {
-	tlog5 << "\t\tReading cregens \n";
+    logGlobal->traceStream() << "\t\tReading cregens ";
 
 	const JsonNode config(ResourceID("config/dwellings.json"));
 	BOOST_FOREACH(const JsonNode &dwelling, config["dwellings"].Vector())
 	{
 		cregens[dwelling["dwelling"].Float()] = CreatureID((si32)dwelling["creature"].Float());
 	}
-	tlog5 << "\t\tDone loading cregens!\n";
+    logGlobal->traceStream() << "\t\tDone loading cregens!";
 
-	tlog5 << "\t\tReading resources prices \n";
+    logGlobal->traceStream() << "\t\tReading resources prices ";
 	const JsonNode config2(ResourceID("config/resources.json"));
 	BOOST_FOREACH(const JsonNode &price, config2["resources_prices"].Vector())
 	{
 		resVals.push_back(price.Float());
 	}
-	tlog5 << "\t\tDone loading resource prices!\n";
+    logGlobal->traceStream() << "\t\tDone loading resource prices!";
 
-	tlog5 << "\t\tReading banks configs \n";
+    logGlobal->traceStream() << "\t\tReading banks configs";
 	const JsonNode config3(ResourceID("config/bankconfig.json"));
 	int bank_num = 0;
 	BOOST_FOREACH(const JsonNode &bank, config3["banks"].Vector())
@@ -237,7 +237,7 @@ void CObjectHandler::load()
 
 		bank_num ++;
 	}
-	tlog5 << "\t\tDone loading banks configs \n";
+    logGlobal->traceStream() << "\t\tDone loading banks configs";
 }
 
 int CObjectHandler::bankObjToIndex (const CGObjectInstance * obj)
@@ -255,7 +255,7 @@ int CObjectHandler::bankObjToIndex (const CGObjectInstance * obj)
 	case Obj::SHIPWRECK:
 		return 7;
 	default:
-		tlog2 << "Unrecognized Bank indetifier!\n";
+        logGlobal->warnStream() << "Unrecognized Bank indetifier!";
 		return 0;
 	}
 }
@@ -309,7 +309,7 @@ bool CGObjectInstance::visitableAt(int x, int y) const //returns true if object
 {
 	if(defInfo==NULL)
 	{
-		tlog2 << "Warning: VisitableAt for obj "<< id.getNum() <<": NULL defInfo!\n";
+        logGlobal->warnStream() << "Warning: VisitableAt for obj "<< id.getNum() <<": NULL defInfo!";
 		return false;
 	}
 
@@ -471,7 +471,7 @@ int3 CGObjectInstance::getVisitableOffset() const
 			if((defInfo->visitMap[5-y] >> x) & 1)
 				return int3(x,y,0);
 
-	tlog2 << "Warning: getVisitableOffset called on non-visitable obj!\n";
+    logGlobal->warnStream() << "Warning: getVisitableOffset called on non-visitable obj!";
 	return int3(-1,-1,-1);
 }
 
@@ -546,7 +546,7 @@ static int lowestSpeed(const CGHeroInstance * chi)
 {
 	if(!chi->Slots().size())
 	{
-		tlog1 << "Error! Hero " << chi->id.getNum() << " ("<<chi->name<<") has no army!\n";
+        logGlobal->errorStream() << "Error! Hero " << chi->id.getNum() << " ("<<chi->name<<") has no army!";
 		return 20;
 	}
 	TSlots::const_iterator i = chi->Slots().begin();
@@ -580,7 +580,7 @@ ui32 CGHeroInstance::getTileCost(const TerrainTile &dest, const TerrainTile &fro
 			ret = 50;
 			break;
 		default:
-			tlog1 << "Unknown road type: " << road << "... Something wrong!\n";
+            logGlobal->errorStream() << "Unknown road type: " << road << "... Something wrong!";
 			break;
 		}
 	}
@@ -668,7 +668,7 @@ void CGHeroInstance::setSecSkillLevel(SecondarySkill which, int val, bool abs)
 
 				if(secSkills[i].second > 3) //workaround to avoid crashes when same sec skill is given more than once
 				{
-					tlog1 << "Warning: Skill " << which << " increased over limit! Decreasing to Expert.\n";
+                    logGlobal->warnStream() << "Warning: Skill " << which << " increased over limit! Decreasing to Expert.";
 					secSkills[i].second = 3;
 				}
 				updateSkill(which, secSkills[i].second); //when we know final value
@@ -857,7 +857,7 @@ void CGHeroInstance::initArmy(IArmyDescriptor *dst /*= NULL*/)
 			if(!getArt(convSlot))
 				putArtifact(convSlot, CArtifactInstance::createNewArtifactInstance(aid));
 			else
-				tlog3 << "Hero " << name << " already has artifact at " << slot << ", omitting giving " << aid << std::endl;
+                logGlobal->warnStream() << "Hero " << name << " already has artifact at " << slot << ", omitting giving " << aid;
 		}
 		else
 			dst->setCreature(SlotID(stackNo-warMachinesGiven), stack.creature, count);
@@ -977,7 +977,7 @@ void CGHeroInstance::initObj() //TODO: use bonus system
 							creLevel = 5; //treat ballista as 5-level
 						else
 						{
-							tlog2 << "Warning: unknown level of " << specCreature.namePl << std::endl;
+                            logGlobal->warnStream() << "Warning: unknown level of " << specCreature.namePl;
 							continue;
 						}
 					}
@@ -1125,7 +1125,7 @@ void CGHeroInstance::initObj() //TODO: use bonus system
 				hs->addNewBonus(bonus);
 				break;
 			default:
-				tlog2 << "Unexpected hero specialty " << type <<'\n';
+                logGlobal->warnStream() << "Unexpected hero specialty " << type;
 		}
 	}
 	specialty.push_back(hs); //will it work?
@@ -1183,7 +1183,7 @@ void CGHeroInstance::Updatespecialty() //TODO: calculate special value of bonuse
 						}
 						else //no creature found, can't calculate value
 						{
-							tlog2 << "Primary skill specialty growth supported only with creature type limiters\n";
+                            logGlobal->warnStream() << "Primary skill specialty growth supported only with creature type limiters";
 							break;
 						}
 
@@ -2549,7 +2549,7 @@ void CGTownInstance::addHeroToStructureVisitors( const CGHeroInstance *h, si32 s
 	else
 	{
 		//should never ever happen
-		tlog1 << "Cannot add hero " << h->name << " to visitors of structure #" << structureInstanceID << std::endl;
+        logGlobal->errorStream() << "Cannot add hero " << h->name << " to visitors of structure #" << structureInstanceID;
 		assert(0);
 	}
 }
@@ -3155,7 +3155,7 @@ void CGCreature::initObj()
 
 		if(!amount) //armies with 0 creatures are illegal
 		{
-			tlog2 << "Problem: stack " << nodeName() << " cannot have 0 creatures. Check properties of " << c.nodeName() << std::endl;
+            logGlobal->warnStream() << "Problem: stack " << nodeName() << " cannot have 0 creatures. Check properties of " << c.nodeName();
 			amount = 1;
 		}
 	}
@@ -3355,7 +3355,7 @@ void CGCreature::fight( const CGHeroInstance *h ) const
 				cb->moveStack(StackLocation(this, sourceSlot), StackLocation(this, destSlot), stackSize);
 			else
 			{
-				tlog2 <<"Warning! Not enough empty slots to split stack!";
+                logGlobal->warnStream() <<"Warning! Not enough empty slots to split stack!";
 				break;
 			}
 		}
@@ -3693,7 +3693,7 @@ void CGTeleport::onHeroVisit( const CGHeroInstance * h ) const
 		if(vstd::contains(objs,Obj::MONOLITH2) && vstd::contains(objs[Obj::MONOLITH2],subID) && objs[Obj::MONOLITH2][subID].size())
 			destinationid = objs[Obj::MONOLITH2][subID][rand()%objs[Obj::MONOLITH2][subID].size()];
 		else
-			tlog2 << "Cannot find corresponding exit monolith for "<< id << std::endl;
+            logGlobal->warnStream() << "Cannot find corresponding exit monolith for "<< id;
 		break;
 	case Obj::MONOLITH3://two way monolith - pick any other one
 	case Obj::WHIRLPOOL: //Whirlpool
@@ -3730,7 +3730,7 @@ void CGTeleport::onHeroVisit( const CGHeroInstance * h ) const
 			}
 		}
 		else
-			tlog2 << "Cannot find corresponding exit monolith for "<< id << std::endl;
+            logGlobal->warnStream() << "Cannot find corresponding exit monolith for "<< id;
 		break;
 	case Obj::SUBTERRANEAN_GATE: //find nearest subterranean gate on the other level
 		{
@@ -3744,7 +3744,7 @@ void CGTeleport::onHeroVisit( const CGHeroInstance * h ) const
 	}
 	if(destinationid == ObjectInstanceID())
 	{
-		tlog2 << "Cannot find exit... (obj at " << pos << ") :( \n";
+        logGlobal->warnStream() << "Cannot find exit... (obj at " << pos << ") :( ";
 		return;
 	}
 	if (ID == Obj::WHIRLPOOL)
@@ -4087,7 +4087,7 @@ void CGPickable::onHeroVisit( const CGHeroInstance * h ) const
 		{
 			if (subID) //not OH3 treasure chest
 			{
-				tlog2 << "Not supported WoG treasure chest!\n";
+                logGlobal->warnStream() << "Not supported WoG treasure chest!";
 				return;
 			}
 
@@ -4531,7 +4531,7 @@ const std::string & CGSeerHut::getHoverText() const
 		hoverName = VLC->generaltexth->names[ID];
 		break;
 	default:
-		tlog5 << "unrecognized quest object\n";
+        logGlobal->debugStream() << "unrecognized quest object";
 	}
 	if (quest->progress & quest->missionType) //rollover when the quest is active
 	{
@@ -5479,7 +5479,7 @@ void CGShrine::onHeroVisit( const CGHeroInstance * h ) const
 {
 	if(spell == SpellID::NONE)
 	{
-		tlog1 << "Not initialized shrine visited!\n";
+        logGlobal->errorStream() << "Not initialized shrine visited!";
 		return;
 	}
 
@@ -5527,7 +5527,7 @@ void CGShrine::initObj()
 
 		if(!possibilities.size())
 		{
-			tlog1 << "Error: cannot init shrine, no allowed spells!\n";
+            logGlobal->errorStream() << "Error: cannot init shrine, no allowed spells!";
 			return;
 		}
 
@@ -5621,7 +5621,7 @@ void CGScholar::onHeroVisit( const CGHeroInstance * h ) const
 		}
 		break;
 	default:
-		tlog1 << "Error: wrong bonustype (" << (int)type << ") for Scholar!\n";
+        logGlobal->errorStream() << "Error: wrong bonustype (" << (int)type << ") for Scholar!";
 		return;
 	}
 
@@ -5721,7 +5721,7 @@ void CGOnceVisitable::onHeroVisit( const CGHeroInstance * h ) const
 		}
 		break;
 	default:
-		tlog1 << "Error: Unknown object (" << ID <<") treated as CGOnceVisitable!\n";
+        logGlobal->errorStream() << "Error: Unknown object (" << ID <<") treated as CGOnceVisitable!";
 		return;
 	}
 
@@ -6002,7 +6002,7 @@ void CBank::setPropertyDer (ui8 what, ui32 val)
 					}
 						break;
 					default:
-						tlog2 << "Error: Unexpected army data: " << bc->guards.size() <<" items found";
+                        logGlobal->warnStream() << "Error: Unexpected army data: " << bc->guards.size() <<" items found";
 						return;
 				}
 			}
@@ -6244,7 +6244,7 @@ void CGPyramid::initObj()
 	}
 	else
 	{
-		tlog1 <<"No spells available for Pyramid! Object set to empty.\n";
+        logGlobal->errorStream() <<"No spells available for Pyramid! Object set to empty.";
 	}
 	setPropertyDer (ObjProperty::BANK_INIT_ARMY,ran()); //set guards at game start
 }
@@ -6589,7 +6589,7 @@ void IBoatGenerator::getProblemText(MetaString &out, const CGHeroInstance *visit
 			out.addTxt(MetaString::ADVOB_TXT, 189);
 		break;
 	case NO_WATER:
-		tlog1 << "Shipyard without water!!! " << o->pos << "\t" << o->id << std::endl;
+        logGlobal->errorStream() << "Shipyard without water!!! " << o->pos << "\t" << o->id;
 		return;
 	}
 }
@@ -6621,7 +6621,6 @@ IShipyard * IShipyard::castFrom( CGObjectInstance *obj )
 	}
 	else
 	{
-		//tlog1 << "Cannot cast to IShipyard object with ID " << obj->ID << std::endl;
 		return NULL;
 	}
 }
@@ -6685,7 +6684,7 @@ void CCartographer::onHeroVisit( const CGHeroInstance * h ) const
 					text = 27;
 					break;
 				default:
-					tlog2 << "Unrecognized subtype of cartographer" << std::endl;
+                    logGlobal->warnStream() << "Unrecognized subtype of cartographer";
 			}
 			assert(text);
 			BlockingDialog bd (true, false);
@@ -6777,7 +6776,7 @@ void CGObelisk::setPropertyDer( ui8 what, ui32 val )
 
 		if(visited[TeamID(val)] > obeliskCount)
 		{
-			tlog0 << "Error: Visited " << visited[TeamID(val)] << "\t\t" << obeliskCount << std::endl;
+            logGlobal->errorStream() << "Error: Visited " << visited[TeamID(val)] << "\t\t" << obeliskCount;
 			assert(0);
 		}
 
@@ -7099,7 +7098,7 @@ const IMarket * IMarket::castFrom(const CGObjectInstance *obj, bool verbose /*=
 		return static_cast<const CGUniversity*>(obj);
 	default:
 		if(verbose)
-			tlog1 << "Cannot cast to IMarket object with ID " << obj->ID << std::endl;
+            logGlobal->errorStream() << "Cannot cast to IMarket object with ID " << obj->ID;
 		return NULL;
 	}
 }
@@ -7221,7 +7220,7 @@ void CGUniversity::initObj()
 			toChoose.push_back(i);
 	if (toChoose.size() < 4)
 	{
-		tlog0<<"Warning: less then 4 available skills was found by University initializer!\n";
+        logGlobal->warnStream()<<"Warning: less then 4 available skills was found by University initializer!";
 		return;
 	}
 

+ 2 - 2
lib/CSpellHandler.cpp

@@ -241,7 +241,7 @@ void CSpell::getEffects(std::vector<Bonus>& lst, const int level) const
 {
 	if (level < 0 || level>3)
 	{
-		tlog1 << __FUNCTION__ << " invalid school level " << level;
+        logGlobal->errorStream() << __FUNCTION__ << " invalid school level " << level;
 		return;
 	}
 	lst.reserve(lst.size() + effects[level].size());
@@ -506,7 +506,7 @@ void CSpellHandler::load()
 			auto it = bonusNameMap.find(name);
 			if (it == bonusNameMap.end())
 			{
-				tlog1 << "Error: invalid bonus name" << name << std::endl;
+                logGlobal->errorStream() << "Error: invalid bonus name" << name;
 			}
 			else
 			{

+ 1 - 1
lib/CTownHandler.cpp

@@ -543,7 +543,7 @@ void CTownHandler::load(std::string townID, const JsonNode &source)
 	if (!source["puzzleMap"].isNull())
 		loadPuzzle(faction, source["puzzleMap"]);
 
-	tlog5 << "Added faction: " << townID << "\n";
+    logGlobal->traceStream() << "Added faction: " << townID;
 	VLC->modh->identifiers.registerObject(std::string("faction.") + townID, faction.factionID);
 }
 

+ 29 - 29
lib/Connection.cpp

@@ -56,7 +56,7 @@ void CConnection::init()
 	//we got connection
 	(*this) << std::string("Aiya!\n") << name << myEndianess; //identify ourselves
 	(*this) >> pom >> pom >> contactEndianess;
-	tlog0 << "Established connection with "<<pom<<std::endl;
+    logNetwork->infoStream() << "Established connection with "<<pom;
 	wmx = new boost::mutex;
 	rmx = new boost::mutex;
 
@@ -76,27 +76,27 @@ CConnection::CConnection(std::string host, std::string port, std::string Name)
     tcp::resolver::iterator end, pom, endpoint_iterator = resolver.resolve(tcp::resolver::query(host,port),error);
 	if(error)
 	{
-		tlog1 << "Problem with resolving: " << std::endl << error <<std::endl;
+        logNetwork->errorStream() << "Problem with resolving: \n" << error;
 		goto connerror1;
 	}
 	pom = endpoint_iterator;
 	if(pom != end)
-		tlog0<<"Found endpoints:" << std::endl;
+        logNetwork->infoStream()<<"Found endpoints:";
 	else
 	{
-		tlog1 << "Critical problem: No endpoints found!" << std::endl;
+        logNetwork->errorStream() << "Critical problem: No endpoints found!";
 		goto connerror1;
 	}
 	i=0;
 	while(pom != end)
 	{
-		tlog0 << "\t" << i << ": " << (boost::asio::ip::tcp::endpoint&)*pom << std::endl;
+        logNetwork->infoStream() << "\t" << i << ": " << (boost::asio::ip::tcp::endpoint&)*pom;
 		pom++;
 	}
 	i=0;
 	while(endpoint_iterator != end)
 	{
-		tlog0 << "Trying connection to " << (boost::asio::ip::tcp::endpoint&)*endpoint_iterator << "  (" << i++ << ")" << std::endl;
+        logNetwork->infoStream() << "Trying connection to " << (boost::asio::ip::tcp::endpoint&)*endpoint_iterator << "  (" << i++ << ")";
 		socket->connect(*endpoint_iterator, error);
 		if(!error)
 		{
@@ -105,18 +105,18 @@ CConnection::CConnection(std::string host, std::string port, std::string Name)
 		}
 		else
 		{
-			tlog1 << "Problem with connecting: " << std::endl <<  error << std::endl;
+            logNetwork->errorStream() << "Problem with connecting: " <<  error;
 		}
 		endpoint_iterator++;
 	}
 
 	//we shouldn't be here - error handling
 connerror1:
-	tlog1 << "Something went wrong... checking for error info" << std::endl;
+    logNetwork->errorStream() << "Something went wrong... checking for error info";
 	if(error)
-		tlog1 << error <<std::endl;
+        logNetwork->errorStream() << error;
 	else
-		tlog1 << "No error info. " << std::endl;
+        logNetwork->errorStream() << "No error info. ";
 	delete io_service;
 	//delete socket;	
 	throw std::runtime_error("Can't establish connection :(");
@@ -134,7 +134,7 @@ CConnection::CConnection(TAcceptor * acceptor, boost::asio::io_service *Io_servi
 	acceptor->accept(*socket,error);
 	if (error)
 	{ 
-		tlog1 << "Error on accepting: " << std::endl << error << std::endl;
+        logNetwork->errorStream() << "Error on accepting: " << error;
 		delete socket;	
 		throw std::runtime_error("Can't establish connection :("); 
 	}
@@ -208,13 +208,13 @@ bool CConnection::isOpen() const
 	return socket && connected;
 }
 
-void CConnection::reportState(CLogger &out)
+void CConnection::reportState(CGLogger * out)
 {
-	out << "CConnection\n";
+    out->debugStream() << "CConnection";
 	if(socket && socket->is_open())
 	{
-		out << "\tWe have an open and valid socket\n";
-		out << "\t" << socket->available() <<" bytes awaiting\n";
+        out->debugStream() << "\tWe have an open and valid socket";
+        out->debugStream() << "\t" << socket->available() <<" bytes awaiting";
 	}
 }
 
@@ -222,16 +222,16 @@ CPack * CConnection::retreivePack()
 {
 	CPack *ret = NULL;
 	boost::unique_lock<boost::mutex> lock(*rmx);
-	tlog5 << "Listening... ";
+    logNetwork->traceStream() << "Listening... ";
 	*this >> ret;
-	tlog5 << "\treceived server message of type " << typeid(*ret).name() << std::endl;
+    logNetwork->traceStream() << "\treceived server message of type " << typeid(*ret).name();
 	return ret;
 }
 
 void CConnection::sendPackToServer(const CPack &pack, PlayerColor player, ui32 requestID)
 {
 	boost::unique_lock<boost::mutex> lock(*wmx);
-	tlog5 << "Sending to server a pack of type " << typeid(pack).name() << std::endl;
+    logNetwork->traceStream() << "Sending to server a pack of type " << typeid(pack).name();
 	*this << player << requestID << &pack; //packs has to be sent as polymorphic pointers!
 }
 
@@ -309,18 +309,18 @@ void CSaveFile::openNextFile(const std::string &fname)
 	}
 	catch(...)
 	{
-		tlog1 << "Failed to save to " << fname << std::endl;
+        logGlobal->errorStream() << "Failed to save to " << fname;
 		clear();
 		throw;
 	}
 }
 
-void CSaveFile::reportState(CLogger &out)
+void CSaveFile::reportState(CGLogger * out)
 {
-	out << "CSaveFile" << std::endl;
+    out->debugStream() << "CSaveFile";
 	if(sfile.get() && *sfile)
 	{
-		out << "\tOpened " << fName << "\n\tPosition: " << sfile->tellp() << std::endl;
+        out->debugStream() << "\tOpened " << fName << "\n\tPosition: " << sfile->tellp();
 	}
 }
 
@@ -377,15 +377,15 @@ void CLoadFile::openNextFile(const std::string &fname, int minimalVersion)
 
 		if(fileVersion > version)
 		{
-			tlog3 << boost::format("Warning format version mismatch: found %d when current is %d! (file %s)\n") % fileVersion % version % fname;
+            logGlobal->warnStream() << boost::format("Warning format version mismatch: found %d when current is %d! (file %s)\n") % fileVersion % version % fname;
 
 			auto versionptr = (char*)&fileVersion;
 			std::reverse(versionptr, versionptr + 4);
-			tlog3 << "Version number reversed is " << fileVersion << ", checking...\n";
+            logGlobal->warnStream() << "Version number reversed is " << fileVersion << ", checking...";
 
 			if(fileVersion == version)
 			{
-				tlog3 << fname << " seems to have different endianess! Entering reversing mode.\n";
+                logGlobal->warnStream() << fname << " seems to have different endianess! Entering reversing mode.";
 				reverseEndianess = true;
 			}
 			else
@@ -399,12 +399,12 @@ void CLoadFile::openNextFile(const std::string &fname, int minimalVersion)
 	}
 }
 
-void CLoadFile::reportState(CLogger &out)
+void CLoadFile::reportState(CGLogger * out)
 {
-	out << "CLoadFile" << std::endl;
+    out->debugStream() << "CLoadFile";
 	if(!!sfile && *sfile)
 	{
-		out << "\tOpened " << fName << "\n\tPosition: " << sfile->tellg() << std::endl;
+        out->debugStream() << "\tOpened " << fName << "\n\tPosition: " << sfile->tellg();
 	}
 }
 
@@ -501,7 +501,7 @@ int CLoadIntegrityValidator::read( const void * data, unsigned size )
 		controlFile->read(controlData.data(), size);
 		if(std::memcmp(data, controlData.data(), size))
 		{
-			tlog1 << "Desync found! Position: " << primaryFile->sfile->tellg() << std::endl;
+            logGlobal->errorStream() << "Desync found! Position: " << primaryFile->sfile->tellg();
 			foundDesync = true;
 			//throw std::runtime_error("Savegame dsynchronized!");
 		}

+ 6 - 6
lib/Connection.h

@@ -333,7 +333,7 @@ public:
 	CSerializer();
 	~CSerializer();
 
-	virtual void reportState(CLogger &out){};
+    virtual void reportState(CGLogger * out){};
 
 	template <typename T, typename U>
 	void registerVectoredType(const std::vector<T*> *Vector, const U T::*IdPtr)
@@ -1039,8 +1039,8 @@ public:
 	*this >> length;				\
 	if(length > 500000)				\
 	{								\
-		tlog2 << "Warning: very big length: " << length << "\n" ;\
-		reportState(tlog2);			\
+        logGlobal->warnStream() << "Warning: very big length: " << length;\
+        reportState(logGlobal);			\
 	};
 
 
@@ -1211,7 +1211,7 @@ public:
 
 	void openNextFile(const std::string &fname); //throws!
 	void clear();
-	void reportState(CLogger &out);
+    void reportState(CGLogger * out);
 
 	void putMagicBytes(const std::string &text);
 };
@@ -1234,7 +1234,7 @@ public:
 
 	void openNextFile(const std::string &fname, int minimalVersion); //throws!
 	void clear();
-	void reportState(CLogger &out);
+    void reportState(CGLogger * out);
 
 	void checkMagicBytes(const std::string &text);
 };
@@ -1263,7 +1263,7 @@ class DLL_LINKAGE CConnection
 	CConnection(void);
 
 	void init();
-	void reportState(CLogger &out);
+    void reportState(CGLogger * out);
 public:
 	boost::mutex *rmx, *wmx; // read/write mutexes
 	TSocket * socket;

+ 5 - 6
lib/HeroBonus.cpp

@@ -69,7 +69,7 @@ const bmap<std::string, TPropagatorPtr> bonusPropagatorMap = boost::assign::map_
 	("PLAYER_PROPAGATOR", make_shared<CPropagatorNodeType>(CBonusSystemNode::PLAYER));
 
 
-#define BONUS_LOG_LINE(x) tlog5 << x << std::endl
+#define BONUS_LOG_LINE(x) logBonus->traceStream() << x
 
 int CBonusSystemNode::treeChanged = 1;
 const bool CBonusSystemNode::cachingEnabled = true;
@@ -705,7 +705,7 @@ CBonusSystemNode::~CBonusSystemNode()
 
 	if(children.size())
 	{
-		tlog2 << "Warning: an orphaned child!\n";
+        logBonus->warnStream() << "Warning: an orphaned child!";
 		while(children.size())
 			children.front()->detachFrom(this);
 	}
@@ -818,7 +818,7 @@ void CBonusSystemNode::unpropagateBonus(Bonus * b)
 		bonuses -= b;
 		while(vstd::contains(bonuses, b))
 		{
-			tlog1 << "Bonus was duplicated (" << b->Description() << ") at " << nodeName() << std::endl;
+            logBonus->errorStream() << "Bonus was duplicated (" << b->Description() << ") at " << nodeName();
 			bonuses -= b;
 		}
 		BONUS_LOG_LINE("#$#" << b->Description() << " #is no longer propagated to# " << nodeName());
@@ -1399,7 +1399,6 @@ IPropagator::~IPropagator()
 
 // CBonusSystemNode * IPropagator::getDestNode(CBonusSystemNode *source, CBonusSystemNode *redParent, CBonusSystemNode *redChild)
 // {
-// 	tlog1 << "IPropagator::getDestNode called!\n";
 // 	return source;
 // }
 
@@ -1483,8 +1482,8 @@ int CreatureAlignmentLimiter::limit(const BonusLimitationContext &context) const
 	case EAlignment::EVIL:
 		return !c->isEvil();
 	default:
-		tlog1 << "Warning: illegal alignment in limiter!\n";
-		return true;
+        logBonus->warnStream() << "Warning: illegal alignment in limiter!";
+        return true;
 	}
 }
 

+ 18 - 18
lib/IGameCallback.cpp

@@ -34,9 +34,9 @@
 
 //TODO make clean
 #define ERROR_SILENT_RET_VAL_IF(cond, txt, retVal) do {if(cond){return retVal;}} while(0)
-#define ERROR_VERBOSE_OR_NOT_RET_VAL_IF(cond, verbose, txt, retVal) do {if(cond){if(verbose)tlog1 << BOOST_CURRENT_FUNCTION << ": " << txt << std::endl; return retVal;}} while(0)
-#define ERROR_RET_IF(cond, txt) do {if(cond){tlog1 << BOOST_CURRENT_FUNCTION << ": " << txt << std::endl; return;}} while(0)
-#define ERROR_RET_VAL_IF(cond, txt, retVal) do {if(cond){tlog1 << BOOST_CURRENT_FUNCTION << ": " << txt << std::endl; return retVal;}} while(0)
+#define ERROR_VERBOSE_OR_NOT_RET_VAL_IF(cond, verbose, txt, retVal) do {if(cond){if(verbose)logGlobal->errorStream() << BOOST_CURRENT_FUNCTION << ": " << txt; return retVal;}} while(0)
+#define ERROR_RET_IF(cond, txt) do {if(cond){logGlobal->errorStream() << BOOST_CURRENT_FUNCTION << ": " << txt; return;}} while(0)
+#define ERROR_RET_VAL_IF(cond, txt, retVal) do {if(cond){logGlobal->errorStream() << BOOST_CURRENT_FUNCTION << ": " << txt; return retVal;}} while(0)
 
 extern boost::rand48 ran;
 
@@ -81,7 +81,7 @@ void CPrivilagedInfoCallback::getTilesInRange( boost::unordered_set<int3, ShashI
 {
 	if(!!player && *player >= PlayerColor::PLAYER_LIMIT)
 	{
-		tlog1 << "Illegal call to getTilesInRange!\n";
+        logGlobal->errorStream() << "Illegal call to getTilesInRange!";
 		return;
 	}
 	if (radious == -1) //reveal entire map
@@ -111,7 +111,7 @@ void CPrivilagedInfoCallback::getAllTiles (boost::unordered_set<int3, ShashInt3>
 {
 	if(!!Player && *Player >= PlayerColor::PLAYER_LIMIT)
 	{
-		tlog1 << "Illegal call to getAllTiles !\n";
+        logGlobal->errorStream() << "Illegal call to getAllTiles !";
 		return;
 	}
 	bool water = surface == 0 || surface == 2,
@@ -218,37 +218,37 @@ void CPrivilagedInfoCallback::getAllowedSpells(std::vector<SpellID> &out, ui16 l
 template<typename Loader>
 void CPrivilagedInfoCallback::loadCommonState(Loader &in)
 {
-	tlog0 << "Loading lib part of game...\n";
+    logGlobal->infoStream() << "Loading lib part of game...";
 	in.checkMagicBytes(SAVEGAME_MAGIC);
 
 	CMapHeader dum;
 	StartInfo *si;
 
-	tlog0 <<"\tReading header"<<std::endl;
+    logGlobal->infoStream() <<"\tReading header";
 	in >> dum;
 
-	tlog0 << "\tReading options"<<std::endl;
+    logGlobal->infoStream() << "\tReading options";
 	in >> si;
 
-	tlog0 <<"\tReading handlers"<<std::endl;
+    logGlobal->infoStream() <<"\tReading handlers";
 	in >> *VLC;
 
-	tlog0 <<"\tReading gamestate"<<std::endl;
+    logGlobal->infoStream() <<"\tReading gamestate";
 	in >> gs;
 }
 
 template<typename Saver>
 void CPrivilagedInfoCallback::saveCommonState(Saver &out) const
 {
-	tlog0 << "Saving lib part of game...";
+    logGlobal->infoStream() << "Saving lib part of game...";
 	out.putMagicBytes(SAVEGAME_MAGIC);
-	tlog0 <<"\tSaving header"<<std::endl;
+    logGlobal->infoStream() <<"\tSaving header";
 	out << static_cast<CMapHeader&>(*gs->map);
-	tlog0 << "\tSaving options"<<std::endl;
+    logGlobal->infoStream() << "\tSaving options";
 	out << gs->scenarioOps;
-	tlog0 << "\tSaving handlers"<<std::endl;
+    logGlobal->infoStream() << "\tSaving handlers";
 	out << *VLC;
-	tlog0 << "\tSaving gamestate"<<std::endl;
+    logGlobal->infoStream() << "\tSaving gamestate";
 	out << gs;
 }
 
@@ -293,7 +293,7 @@ const CGObjectInstance* CGameInfoCallback::getObj(ObjectInstanceID objid, bool v
 	if(oid < 0  ||  oid >= gs->map->objects.size())
 	{
 		if(verbose)
-			tlog1 << "Cannot get object with id " << oid << std::endl;
+            logGlobal->errorStream() << "Cannot get object with id " << oid;
 		return NULL;
 	}
 
@@ -301,14 +301,14 @@ const CGObjectInstance* CGameInfoCallback::getObj(ObjectInstanceID objid, bool v
 	if(!ret)
 	{
 		if(verbose)
-			tlog1 << "Cannot get object with id " << oid << ". Object was removed.\n";
+            logGlobal->errorStream() << "Cannot get object with id " << oid << ". Object was removed.";
 		return NULL;
 	}
 
 	if(!isVisible(ret, player))
 	{
 		if(verbose)
-			tlog1 << "Cannot get object with id " << oid << ". Object is not visible.\n";
+            logGlobal->errorStream() << "Cannot get object with id " << oid << ". Object is not visible.";
 		return NULL;
 	}
 

+ 13 - 13
lib/JsonNode.cpp

@@ -397,8 +397,8 @@ JsonNode JsonParser::parse(std::string fileName)
 
 	if (!errors.empty())
 	{
-		tlog3<<"File " << fileName << " is not a valid JSON file!\n";
-		tlog3<<errors;
+        logGlobal->warnStream()<<"File " << fileName << " is not a valid JSON file!";
+        logGlobal->warnStream()<<errors;
 	}
 	return root;
 }
@@ -1103,8 +1103,8 @@ bool JsonValidator::validate(const JsonNode &root, std::string schemaName, std::
 
 	if (!errors.empty())
 	{
-		tlog3 << "Data in " << name << " is invalid!\n";
-		tlog3 << errors;
+        logGlobal->warnStream() << "Data in " << name << " is invalid!";
+        logGlobal->warnStream() << errors;
 	}
 
 	return errors.empty();
@@ -1129,7 +1129,7 @@ Bonus * JsonUtils::parseBonus (const JsonVector &ability_vec) //TODO: merge with
 	auto it = bonusNameMap.find(type);
 	if (it == bonusNameMap.end())
 	{
-		tlog1 << "Error: invalid ability type " << type << std::endl;
+        logGlobal->errorStream() << "Error: invalid ability type " << type;
 		return b;
 	}
 	b->type = it->second;
@@ -1147,7 +1147,7 @@ const T & parseByMap(const std::map<std::string, T> & map, const JsonNode * val,
 		auto it = map.find(type);
 		if (it == map.end())
 		{
-			tlog1 << "Error: invalid " << err << type << std::endl;
+            logGlobal->errorStream() << "Error: invalid " << err << type;
 			return defaultValue;
 		}
 		else
@@ -1177,7 +1177,7 @@ void JsonUtils::resolveIdentifier (si32 &var, const JsonNode &node, std::string
 				});
 				break;
 			default:
-				tlog2 << "Error! Wrong indentifier used for value of " << name;
+                logGlobal->errorStream() << "Error! Wrong indentifier used for value of " << name;
 		}
 	}
 }
@@ -1196,7 +1196,7 @@ void JsonUtils::resolveIdentifier (const JsonNode &node, si32 &var)
 			});
 			break;
 		default:
-			tlog2 << "Error! Wrong indentifier used for identifier!";
+            logGlobal->errorStream() << "Error! Wrong indentifier used for identifier!";
 	}
 }
 
@@ -1210,7 +1210,7 @@ Bonus * JsonUtils::parseBonus (const JsonNode &ability)
 	auto it = bonusNameMap.find(type);
 	if (it == bonusNameMap.end())
 	{
-		tlog1 << "Error: invalid ability type " << type << std::endl;
+        logGlobal->errorStream() << "Error: invalid ability type " << type;
 		return b;
 	}
 	b->type = it->second;
@@ -1254,7 +1254,7 @@ Bonus * JsonUtils::parseBonus (const JsonNode &ability)
 			}
 			break;
 		default:
-			tlog2 << "Error! Wrong bonus duration format.";
+            logGlobal->errorStream() << "Error! Wrong bonus duration format.";
 		}
 	}
 
@@ -1301,7 +1301,7 @@ Bonus * JsonUtils::parseBonus (const JsonNode &ability)
 							auto it = bonusNameMap.find (anotherBonusType);
 							if (it == bonusNameMap.end())
 							{
-								tlog1 << "Error: invalid ability type " << anotherBonusType << std::endl;
+                                logGlobal->errorStream() << "Error: invalid ability type " << anotherBonusType;
 								continue;
 							}
 							l2->type = it->second;
@@ -1461,7 +1461,7 @@ const JsonNode & getSchemaByName(std::string name)
 		return loadedSchemas[name];
 	}
 
-	tlog1 << "Error: missing schema with name " << name << "!\n";
+    logGlobal->errorStream() << "Error: missing schema with name " << name << "!";
 	assert(0);
 	return nullNode;
 }
@@ -1476,7 +1476,7 @@ const JsonNode & JsonUtils::getSchema(std::string URI)
 
 	if (segments[0] != "vcmi")
 	{
-		tlog1 << "Error: unsupported URI protocol for schema: " << segments[0] << "\n";
+        logGlobal->errorStream() << "Error: unsupported URI protocol for schema: " << segments[0];
 		return nullNode;
 	}
 

+ 1 - 1
lib/NetPacks.h

@@ -46,7 +46,7 @@ struct CPack
 	ui16 getType() const{return type;}
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
-		tlog1 << "CPack serialized... this should not happen!\n";
+        logNetwork->errorStream() << "CPack serialized... this should not happen!";
 	}
 	void applyGs(CGameState *gs)
 	{};

+ 12 - 12
lib/NetPacksLib.cpp

@@ -113,7 +113,7 @@ DLL_LINKAGE void AddQuest::applyGs(CGameState *gs)
 	if (!vstd::contains(*vec, quest))
 		vec->push_back (quest);
 	else
-		tlog2 << "Warning! Attempt to add duplicated quest\n";
+        logNetwork->warnStream() << "Warning! Attempt to add duplicated quest";
 }
 
 DLL_LINKAGE void UpdateArtHandlerLists::applyGs(CGameState *gs)
@@ -257,7 +257,7 @@ DLL_LINKAGE void ChangeObjPos::applyGs( CGameState *gs )
 	CGObjectInstance *obj = gs->getObjInstance(objid);
 	if(!obj)
 	{
-		tlog1 << "Wrong ChangeObjPos: object " << objid.getNum() << " doesn't exist!\n";
+        logNetwork->errorStream() << "Wrong ChangeObjPos: object " << objid.getNum() << " doesn't exist!";
 		return;
 	}
 	gs->map->removeBlockVisTiles(obj);
@@ -604,7 +604,7 @@ DLL_LINKAGE const CStackInstance * StackLocation::getStack()
 {
 	if(!army->hasStackAtSlot(slot))
 	{
-		tlog2 << "Warning: " << army->nodeName() << " dont have a stack at slot " << slot << std::endl;
+        logNetwork->warnStream() << "Warning: " << army->nodeName() << " dont have a stack at slot " << slot;
 		return NULL;
 	}
 	return &army->getStack(slot);
@@ -661,7 +661,7 @@ DLL_LINKAGE const CArtifactInstance *ArtifactLocation::getArt() const
 			return s->artifact;
 		else
 		{
-			tlog3 << "ArtifactLocation::getArt: That location is locked!\n";
+            logNetwork->warnStream() << "ArtifactLocation::getArt: That location is locked!";
 			return NULL;
 		}
 	}
@@ -751,7 +751,7 @@ DLL_LINKAGE void RebalanceStacks::applyGs( CGameState *gs )
 					//else - artifact cna be lost :/
 					else
 					{
-						tlog2 << "Artifact is present at destination slot!";
+                        logNetwork->warnStream() << "Artifact is present at destination slot!";
 					}
 					artHere->move (alHere, alDest);
 					//TODO: choose from dialog
@@ -908,7 +908,7 @@ DLL_LINKAGE void SetAvailableArtifacts::applyGs( CGameState *gs )
 		}
 		else
 		{
-			tlog1 << "Wrong black market id!" << std::endl;
+            logNetwork->errorStream() << "Wrong black market id!";
 		}
 	}
 	else
@@ -960,7 +960,7 @@ DLL_LINKAGE void SetObjectProperty::applyGs( CGameState *gs )
 	CGObjectInstance *obj = gs->getObjInstance(id);
 	if(!obj)
 	{
-		tlog1 << "Wrong object ID - property cannot be set!\n";
+        logNetwork->errorStream() << "Wrong object ID - property cannot be set!";
 		return;
 	}
 
@@ -1082,7 +1082,7 @@ DLL_LINKAGE void BattleTriggerEffect::applyGs( CGameState *gs )
 			st->state.insert(EBattleStackState::FEAR);
 			break;
 		default:
-			tlog2 << "Unrecognized trigger effect type "<< type <<"\n";
+            logNetwork->warnStream() << "Unrecognized trigger effect type "<< type;
 	}
 }
 
@@ -1358,7 +1358,7 @@ DLL_LINKAGE void SetStackEffect::applyGs( CGameState *gs )
 			}
 		}
 		else
-			tlog1 << "Cannot find stack " << id << std::endl;
+            logNetwork->errorStream() << "Cannot find stack " << id;
 	}
 	typedef std::pair<ui32, Bonus> p;
 	BOOST_FOREACH(p para, uniqueBonuses)
@@ -1372,7 +1372,7 @@ DLL_LINKAGE void SetStackEffect::applyGs( CGameState *gs )
 				actualizeEffect(s, effect);
 		}
 		else
-			tlog1 << "Cannot find stack " << para.first << std::endl;
+            logNetwork->errorStream() << "Cannot find stack " << para.first;
 	}
 }
 
@@ -1393,7 +1393,7 @@ DLL_LINKAGE void StacksHealedOrResurrected::applyGs( CGameState *gs )
 
 		if(!changedStack->alive() && !accessibility.accessible(changedStack->position, changedStack))
 		{
-			tlog1 << "Cannot resurrect " << changedStack->nodeName() << " because hex " << changedStack->position << " is occupied!\n";
+            logNetwork->errorStream() << "Cannot resurrect " << changedStack->nodeName() << " because hex " << changedStack->position << " is occupied!";
 			return; //position is already occupied
 		}
 
@@ -1501,7 +1501,7 @@ DLL_LINKAGE void BattleStackAdded::applyGs(CGameState *gs)
 {
 	if (!BattleHex(pos).isValid())
 	{
-		tlog2 << "No place found for new stack!\n";
+        logNetwork->warnStream() << "No place found for new stack!";
 		return;
 	}
 

+ 1 - 1
lib/StartInfo.h

@@ -91,7 +91,7 @@ struct StartInfo
 	{
 		if(playerInfos.find(no) != playerInfos.end())
 			return playerInfos[no];
-		tlog1 << "Cannot find info about player " << no <<". Throwing...\n";
+        logGlobal->errorStream() << "Cannot find info about player " << no <<". Throwing...";
 		throw std::runtime_error("Cannot find info about player");
 	}
 

+ 7 - 7
lib/VCMI_Lib.cpp

@@ -62,24 +62,24 @@ void LibClasses::loadFilesystem()
 	CStopWatch loadTime;
 
 	CResourceHandler::initialize();
-	tlog0<<"\t Initialization: "<<loadTime.getDiff()<<std::endl;
+    logGlobal->infoStream()<<"\t Initialization: "<<loadTime.getDiff();
 
 	CResourceHandler::loadFileSystem("", "ALL/config/filesystem.json");
-	tlog0<<"\t Data loading: "<<loadTime.getDiff()<<std::endl;
+    logGlobal->infoStream()<<"\t Data loading: "<<loadTime.getDiff();
 
 	modh = new CModHandler;
-	tlog0<<"\tMod handler: "<<loadTime.getDiff()<<std::endl;
+    logGlobal->infoStream()<<"\tMod handler: "<<loadTime.getDiff();
 
 	modh->initialize(CResourceHandler::getAvailableMods());
 	CResourceHandler::setActiveMods(modh->getActiveMods());
-	tlog0<<"\t Mod filesystems: "<<loadTime.getDiff()<<std::endl;
+    logGlobal->infoStream()<<"\t Mod filesystems: "<<loadTime.getDiff();
 
-	tlog0<<"Basic initialization: "<<totalTime.getDiff()<<std::endl;
+    logGlobal->infoStream()<<"Basic initialization: "<<totalTime.getDiff();
 }
 
 static void logHandlerLoaded(const std::string& name, CStopWatch &timer)
 {
-   tlog0<<"\t" << name << " handler: "<<timer.getDiff()<<std::endl;
+   logGlobal->infoStream()<<"\t" << name << " handler: "<<timer.getDiff();
 };
 
 template <class Handler> void createHandler(Handler *&handler, const std::string &name, CStopWatch &timer)
@@ -166,4 +166,4 @@ void LibClasses::callWhenDeserializing()
 LibClasses::~LibClasses()
 {
 	clear();
-}
+}

+ 3 - 3
lib/filesystem/CResourceLoader.cpp

@@ -175,7 +175,7 @@ void CResourceLoader::addLoader(std::string mountPoint, shared_ptr<ISimpleResour
 		ResourceLocator locator(loader.get(), entry.second);
 
 		if (ident.getType() == EResType::OTHER)
-			tlog5 << "Warning: unknown file type: " << entry.second << "\n";
+            logGlobal->warnStream() << "Warning: unknown file type: " << entry.second;
 
 		resources[ident].push_back(locator);
 	}
@@ -385,7 +385,7 @@ void CResourceHandler::loadFileSystem(const std::string & prefix, const JsonNode
 		BOOST_FOREACH(auto & entry, mountPoint.second.Vector())
 		{
 			CStopWatch timer;
-			tlog5 << "\t\tLoading resource at " << prefix + entry["path"].String() << "\n";
+            logGlobal->debugStream() << "\t\tLoading resource at " << prefix + entry["path"].String();
 
 			if (entry["type"].String() == "dir")
 				loadDirectory(prefix, mountPoint.first, entry);
@@ -396,7 +396,7 @@ void CResourceHandler::loadFileSystem(const std::string & prefix, const JsonNode
 			if (entry["type"].String() == "vid")
 				loadArchive(prefix, mountPoint.first, entry, EResType::ARCHIVE_VID);
 
-			tlog5 << "Resource loaded in " << timer.getDiff() << " ms.\n";
+            logGlobal->debugStream() << "Resource loaded in " << timer.getDiff() << " ms.";
 		}
 	}
 }

+ 27 - 22
lib/logging/CBasicLogConfigurator.cpp

@@ -3,33 +3,41 @@
 
 #include "../CConfigHandler.h"
 
-CBasicLogConfigurator::CBasicLogConfigurator(const std::string & filePath, CConsoleHandler * console)
+CBasicLogConfigurator::CBasicLogConfigurator(const std::string & filePath, CConsoleHandler * console) : filePath(filePath), console(console)
 {
-    const JsonNode & logging = settings["logging"];
+
+}
+
+void CBasicLogConfigurator::configureDefault(bool appendToLogFile /*= true*/)
+{
+    CGLogger::getGlobalLogger()->addTarget(make_unique<CLogConsoleTarget>(console));
+    CGLogger::getGlobalLogger()->addTarget(make_unique<CLogFileTarget>(filePath, appendToLogFile));
+}
+
+void CBasicLogConfigurator::configure(bool appendToLogFile /*= true*/)
+{
+    const JsonNode & loggingNode = settings["logging"];
+    if(loggingNode.isNull()) throw std::runtime_error("Settings haven't been loaded.");
 
     // Configure loggers
-    const JsonNode & loggers = logging["loggers"];
+    const JsonNode & loggers = loggingNode["loggers"];
     if(!loggers.isNull())
     {
-        BOOST_FOREACH(auto & loggerPair, loggers.Struct())
+        BOOST_FOREACH(auto & loggerNode, loggers.Vector())
         {
             // Get logger
-            std::string name = loggerPair.first;
-            CGLogger * logger = CGLogger::getLogger(name);
+            std::string name = loggerNode["domain"].String();
+            CGLogger * logger = CGLogger::getLogger(CLoggerDomain(name));
 
             // Set log level
-            const JsonNode & loggerNode = loggerPair.second;
-            const JsonNode & levelNode = loggerNode["level"];
-            if(!levelNode.isNull())
-            {
-                logger->setLevel(getLogLevel(levelNode.String()));
-            }
+            logger->setLevel(getLogLevel(loggerNode["level"].String()));
         }
     }
+    CGLogger::getGlobalLogger()->clearTargets();
 
     // Add console target
-    CLogConsoleTarget * consoleTarget = new CLogConsoleTarget(console);
-    const JsonNode & consoleNode = logging["console"];
+    auto consoleTarget = make_unique<CLogConsoleTarget>(console);
+    const JsonNode & consoleNode = loggingNode["console"];
     if(!consoleNode.isNull())
     {
         const JsonNode & consoleFormatNode = consoleNode["format"];
@@ -48,25 +56,22 @@ CBasicLogConfigurator::CBasicLogConfigurator(const std::string & filePath, CCons
                 std::string domain = mappingNode["domain"].String();
                 std::string level = mappingNode["level"].String();
                 std::string color = mappingNode["color"].String();
-                colorMapping.setColorFor(domain, getLogLevel(level), getConsoleColor(color));
+                colorMapping.setColorFor(CLoggerDomain(domain), getLogLevel(level), getConsoleColor(color));
             }
         }
         consoleTarget->setColorMapping(colorMapping);
     }
-    CGLogger::getGlobalLogger()->addTarget(consoleTarget);
+    CGLogger::getGlobalLogger()->addTarget(std::move(consoleTarget));
 
     // Add file target
-    CLogFileTarget * fileTarget = new CLogFileTarget(filePath);
-    const JsonNode & fileNode = logging["file"];
+    auto fileTarget = make_unique<CLogFileTarget>(filePath, appendToLogFile);
+    const JsonNode & fileNode = loggingNode["file"];
     if(!fileNode.isNull())
     {
         const JsonNode & fileFormatNode = fileNode["format"];
         if(!fileFormatNode.isNull()) fileTarget->setFormatter(CLogFormatter(fileFormatNode.String()));
     }
-
-    // Add targets to the root logger by default
-    CGLogger::getGlobalLogger()->addTarget(consoleTarget);
-    CGLogger::getGlobalLogger()->addTarget(fileTarget);
+    CGLogger::getGlobalLogger()->addTarget(std::move(fileTarget));
 }
 
 ELogLevel::ELogLevel CBasicLogConfigurator::getLogLevel(const std::string & level) const

+ 15 - 14
lib/logging/CBasicLogConfigurator.h

@@ -14,27 +14,28 @@
 #include "CLogger.h"
 
 class CConsoleHandler;
+class JsonNode;
 
-/**
- * The basic log configurator reads log properties from settings.json and
- * sets up the logging system.
- */
+/// The class CBasicLogConfigurator reads log properties from settings.json and
+/// sets up the logging system.
 class DLL_LINKAGE CBasicLogConfigurator
 {
 public:
-    /**
-     * Constructor.
-     *
-     * @param filePath The file path of the log file.
-     * @param console The console handler to log messages to the console. The handler should be initialized.
-     *
-     * @throws std::runtime_error if the configuration has errors
-     */
     CBasicLogConfigurator(const std::string & filePath, CConsoleHandler * console);
 
-private:
-    // Methods
+    /// Configures the logging system by parsing the logging settings. It adds the console target and the file target to the global logger.
+    /// If the append parameter is true, the log file will be appended to. Otherwise the log file will be truncated.
+    /// Throws std::runtime_error if the configuration has errors.
+    void configure(bool appendToLogFile = true);
+
+    /// Configures a default logging system by adding the console target and the file target to the global logger.
+    /// If the append parameter is true, the log file will be appended to. Otherwise the log file will be truncated.
+    void configureDefault(bool appendToLogFile = true);
 
+private:
     ELogLevel::ELogLevel getLogLevel(const std::string & level) const;
     EConsoleTextColor::EConsoleTextColor getConsoleColor(const std::string & colorName) const;
+
+    std::string filePath;
+    CConsoleHandler * console;
 };

+ 59 - 57
lib/logging/CLogger.cpp

@@ -33,12 +33,34 @@ std::string CLoggerDomain::getName() const
     return name;
 }
 
-boost::mutex CGLogger::smx;
+CLoggerStream::CLoggerStream(const CGLogger & logger, ELogLevel::ELogLevel level) : logger(logger), level(level), sbuffer(nullptr)
+{
+
+}
+
+CLoggerStream::~CLoggerStream()
+{
+    if(sbuffer)
+    {
+        logger.log(level, sbuffer->str());
+        delete sbuffer;
+        sbuffer = nullptr;
+    }
+}
+
+boost::recursive_mutex CGLogger::smx;
+
+CGLogger * logGlobal = CGLogger::getGlobalLogger();
+
+CGLogger * logBonus = CGLogger::getLogger(CLoggerDomain("bonus"));
+
+CGLogger * logNetwork = CGLogger::getLogger(CLoggerDomain("network"));
 
 CGLogger * CGLogger::getLogger(const CLoggerDomain & domain)
 {
-    TLockGuard _(smx);
-    CGLogger * logger = CLogManager::get()->getLogger(domain);
+    boost::lock_guard<boost::recursive_mutex> _(smx);
+
+    CGLogger * logger = CLogManager::get().getLogger(domain);
     if(logger)
     {
         return logger;
@@ -50,29 +72,27 @@ CGLogger * CGLogger::getLogger(const CLoggerDomain & domain)
         {
             logger->setLevel(ELogLevel::INFO);
         }
-        CLogManager::get()->addLogger(logger);
+        CLogManager::get().addLogger(logger);
         return logger;
     }
 }
 
 CGLogger * CGLogger::getGlobalLogger()
 {
-    return getLogger(CLoggerDomain::DOMAIN_GLOBAL);
+    return getLogger(CLoggerDomain(CLoggerDomain::DOMAIN_GLOBAL));
 }
 
-CGLogger::CGLogger(const CLoggerDomain & domain) : domain(domain), level(ELogLevel::INFO)
+CGLogger::CGLogger(const CLoggerDomain & domain) : domain(domain)
 {
-    if(!domain.isGlobalDomain())
+    if(domain.isGlobalDomain())
     {
-        parent = getLogger(domain.getParent());
+        level = ELogLevel::INFO;
+        parent = nullptr;
     }
-}
-
-CGLogger::~CGLogger()
-{
-    BOOST_FOREACH(ILogTarget * target, targets)
+    else
     {
-        delete target;
+        level = ELogLevel::NOT_SET;
+        parent = getLogger(domain.getParent());
     }
 }
 
@@ -136,13 +156,13 @@ void CGLogger::log(ELogLevel::ELogLevel level, const std::string & message) cons
 
 ELogLevel::ELogLevel CGLogger::getLevel() const
 {
-    TReadLock _(mx);
+    TLockGuard _(mx);
     return level;
 }
 
 void CGLogger::setLevel(ELogLevel::ELogLevel level)
 {
-    TWriteLock _(mx);
+    TLockGuard _(mx);
     if(domain.isGlobalDomain() && level == ELogLevel::NOT_SET) return;
     this->level = level;
 }
@@ -152,16 +172,10 @@ const CLoggerDomain & CGLogger::getDomain() const
     return domain;
 }
 
-void CGLogger::addTarget(ILogTarget * target)
-{
-    TWriteLock _(mx);
-    targets.push_back(target);
-}
-
-std::list<ILogTarget *> CGLogger::getTargets() const
+void CGLogger::addTarget(unique_ptr<ILogTarget> && target)
 {
-    TReadLock _(mx);
-    return targets;
+    TLockGuard _(mx);
+    targets.push_back(std::move(target));
 }
 
 ELogLevel::ELogLevel CGLogger::getEffectiveLevel() const
@@ -177,41 +191,28 @@ ELogLevel::ELogLevel CGLogger::getEffectiveLevel() const
 
 void CGLogger::callTargets(const LogRecord & record) const
 {
+    TLockGuard _(mx);
     for(const CGLogger * logger = this; logger != nullptr; logger = logger->parent)
     {
-        BOOST_FOREACH(ILogTarget * target, logger->getTargets())
+        BOOST_FOREACH(auto & target, logger->targets)
         {
             target->write(record);
         }
     }
 }
 
-CLoggerStream::CLoggerStream(const CGLogger & logger, ELogLevel::ELogLevel level) : logger(logger), level(level), sbuffer(nullptr)
+void CGLogger::clearTargets()
 {
-
-}
-
-CLoggerStream::~CLoggerStream()
-{
-    if(sbuffer)
-    {
-        logger.log(level, sbuffer->str());
-        delete sbuffer;
-        sbuffer = nullptr;
-    }
+    TLockGuard _(mx);
+    targets.clear();
 }
 
-CLogManager * CLogManager::instance = nullptr;
-
-boost::mutex CLogManager::smx;
+boost::recursive_mutex CLogManager::smx;
 
-CLogManager * CLogManager::get()
+CLogManager & CLogManager::get()
 {
-    TLockGuard _(smx);
-    if(!instance)
-    {
-        instance = new CLogManager();
-    }
+    TLockGuardRec _(smx);
+    static CLogManager instance;
     return instance;
 }
 
@@ -230,13 +231,13 @@ CLogManager::~CLogManager()
 
 void CLogManager::addLogger(CGLogger * logger)
 {
-    TWriteLock _(mx);
+    TLockGuard _(mx);
     loggers[logger->getDomain().getName()] = logger;
 }
 
 CGLogger * CLogManager::getLogger(const CLoggerDomain & domain)
 {
-    TReadLock _(mx);
+    TLockGuard _(mx);
     auto it = loggers.find(domain.getName());
     if(it != loggers.end())
     {
@@ -312,7 +313,7 @@ const std::string & CLogFormatter::getPattern() const
 CColorMapping::CColorMapping()
 {
     // Set default mappings
-    auto & levelMap = map[""];
+    auto & levelMap = map[CLoggerDomain::DOMAIN_GLOBAL];
     levelMap[ELogLevel::TRACE] = EConsoleTextColor::GRAY;
     levelMap[ELogLevel::DEBUG] = EConsoleTextColor::WHITE;
     levelMap[ELogLevel::INFO] = EConsoleTextColor::GREEN;
@@ -357,7 +358,7 @@ EConsoleTextColor::EConsoleTextColor CColorMapping::getColorFor(const CLoggerDom
 
 CLogConsoleTarget::CLogConsoleTarget(CConsoleHandler * console) : console(console), threshold(ELogLevel::INFO), coloredOutputEnabled(true)
 {
-
+    formatter.setPattern("%l %n [%t] - %m");
 }
 
 void CLogConsoleTarget::write(const LogRecord & record)
@@ -370,11 +371,11 @@ void CLogConsoleTarget::write(const LogRecord & record)
     {
         if(coloredOutputEnabled)
         {
-            console->print(message, colorMapping.getColorFor(record.domain, record.level));
+            console->print(message, true, colorMapping.getColorFor(record.domain, record.level));
         }
         else
         {
-            console->print(message, EConsoleTextColor::DEFAULT, printToStdErr);
+            console->print(message, true, EConsoleTextColor::DEFAULT, printToStdErr);
         }
     }
     else
@@ -382,11 +383,11 @@ void CLogConsoleTarget::write(const LogRecord & record)
         TLockGuard _(mx);
         if(printToStdErr)
         {
-            std::cerr << message << std::flush;
+            std::cerr << message << std::endl;
         }
         else
         {
-            std::cout << message << std::flush;
+            std::cout << message << std::endl;
         }
     }
 }
@@ -431,9 +432,10 @@ void CLogConsoleTarget::setColorMapping(const CColorMapping & colorMapping)
     this->colorMapping = colorMapping;
 }
 
-CLogFileTarget::CLogFileTarget(const std::string & filePath) : file(filePath)
+CLogFileTarget::CLogFileTarget(const std::string & filePath, bool append /*= true*/)
+    : file(filePath, append ? std::ios_base::app : std::ios_base::out)
 {
-
+    formatter.setPattern("%d %l %n [%t] - %m");
 }
 
 CLogFileTarget::~CLogFileTarget()

+ 43 - 294
lib/logging/CLogger.h

@@ -28,70 +28,31 @@ namespace ELogLevel
     };
 }
 
-/**
- * The logger domain provides convenient access to super domains from a sub domain.
- */
+/// The class CLoggerDomain provides convenient access to super domains from a sub domain.
 class DLL_LINKAGE CLoggerDomain
 {
 public:
-    /**
-     * Constructor.
-     *
-     * @param name The domain name. Sub-domains can be specified by separating domains by a dot, e.g. "ai.battle". The global domain is named "global".
-     */
-    CLoggerDomain(const std::string & name);
-
-    // Accessors
+    /// Constructs a CLoggerDomain with the domain designated by name.
+    /// Sub-domains can be specified by separating domains by a dot, e.g. "ai.battle". The global domain is named "global".
+    explicit CLoggerDomain(const std::string & name);
 
     std::string getName() const;
-
-    // Methods
-
-    /**
-     * Gets the parent logger domain.
-     *
-     * @return the parent logger domain or the same domain logger if this method has been called on the global domain
-     */
     CLoggerDomain getParent() const;
-
-    /**
-     * Returns true if this domain is the global domain.
-     *
-     * @return true if this is the global domain or false if not
-     */
     bool isGlobalDomain() const;
 
-    // Constants
-
-    /** Constant to the global domain name. */
     static const std::string DOMAIN_GLOBAL;
 
 private:
     std::string name;
 };
 
-/**
- * The logger stream provides a stream-like way of logging messages.
- */
+/// The class CLoggerStream provides a stream-like way of logging messages.
 class DLL_LINKAGE CLoggerStream
 {
 public:
-    /**
-     * Constructs a new logger stream.
-     *
-     * @param logger The logger which should be used to log the generated message to.
-     * @param level The log level of the generated message.
-     */
     CLoggerStream(const CGLogger & logger, ELogLevel::ELogLevel level);
     ~CLoggerStream();
 
-    // Methods
-
-    /**
-     * Writes data to the logger stream.
-     *
-     * @param data Any data can be written to the stream.
-     */
     template<typename T>
     CLoggerStream & operator<<(const T & data)
     {
@@ -101,203 +62,86 @@ public:
     }
 
 private:
-    // Data members
-
     const CGLogger & logger;
     ELogLevel::ELogLevel level;
     std::stringstream * sbuffer;
 };
 
-/**
- * The logger is used to log messages to certain targets of a specific domain/name. Temporary name is
- * CGLogger, should be renamed to CLogger after refactoring.
- */
-class DLL_LINKAGE CGLogger : public boost::noncopyable
+/// The class CGLogger is used to log messages to certain targets of a specific domain/name.
+/// Temporary name is CGLogger, should be renamed to CLogger after refactoring.
+class DLL_LINKAGE CGLogger
 {
 public:
-    ~CGLogger();
-
-    // Accessors
-
     inline ELogLevel::ELogLevel getLevel() const;
     void setLevel(ELogLevel::ELogLevel level);
-
     const CLoggerDomain & getDomain() const;
 
-    // Methods
-
-    /**
-     * Gets a logger by domain.
-     *
-     * @param domain The logger domain.
-     * @return the logger object
-     */
+    /// Logger access methods
     static CGLogger * getLogger(const CLoggerDomain & domain);
-
-    /**
-     * Gets the global logger which is the parent of all domain-specific loggers.
-     *
-     * @return the global logger object
-     */
     static CGLogger * getGlobalLogger();
 
-    /**
-     * Logs a message with the trace level.
-     *
-     * @param message The message to log.
-     */
+    /// Log methods for various log levels
     void trace(const std::string & message) const;
-
-    /**
-     * Returns a logger stream with the trace level.
-     *
-     * @return the logger stream
-     */
     CLoggerStream traceStream() const;
 
-    /**
-     * Logs a message with the debug level.
-     *
-     * @param message The message to log.
-     */
     void debug(const std::string & message) const;
-
-    /**
-     * Returns a logger stream with the debug level.
-     *
-     * @return the logger stream
-     */
     CLoggerStream debugStream() const;
 
-    /**
-     * Logs a message with the info level.
-     *
-     * @param message The message to log.
-     */
     void info(const std::string & message) const;
-
-    /**
-     * Returns a logger stream with the info level.
-     *
-     * @return the logger stream
-     */
     CLoggerStream infoStream() const;
 
-    /**
-     * Logs a message with the warn level.
-     *
-     * @param message The message to log.
-     */
     void warn(const std::string & message) const;
-
-    /**
-     * Returns a logger stream with the warn level.
-     *
-     * @return the logger stream
-     */
     CLoggerStream warnStream() const;
 
-    /**
-     * Logs a message with the error level.
-     *
-     * @param message The message to log.
-     */
     void error(const std::string & message) const;
-
-    /**
-     * Returns a logger stream with the error level.
-     *
-     * @return the logger stream
-     */
     CLoggerStream errorStream() const;
 
-    /**
-     * Logs a message of the given log level.
-     *
-     * @param level The log level of the message to log.
-     * @param message The message to log.
-     */
     inline void log(ELogLevel::ELogLevel level, const std::string & message) const;
 
-    /**
-     * Adds a target to this logger and indirectly to all loggers which derive from this logger.
-     * The logger holds strong-ownership of the target object.
-     *
-     * @param target The log target to add.
-     */
-    void addTarget(ILogTarget * target);
+    void addTarget(unique_ptr<ILogTarget> && target);
+    void clearTargets();
 
 private:
-    // Methods
-
     explicit CGLogger(const CLoggerDomain & domain);
     CGLogger * getParent() const;
-    inline ELogLevel::ELogLevel getEffectiveLevel() const;
+    inline ELogLevel::ELogLevel getEffectiveLevel() const; /// Returns the log level applied on this logger whether directly or indirectly.
     inline void callTargets(const LogRecord & record) const;
-    inline std::list<ILogTarget *> getTargets() const;
-
-    // Data members
 
     CLoggerDomain domain;
     CGLogger * parent;
     ELogLevel::ELogLevel level;
-    std::list<ILogTarget *> targets;
-    mutable boost::shared_mutex mx;
-    static boost::mutex smx;
+    std::list<unique_ptr<ILogTarget> > targets;
+    mutable boost::mutex mx;
+    static boost::recursive_mutex smx;
 };
 
+extern DLL_LINKAGE CGLogger * logGlobal;
+extern DLL_LINKAGE CGLogger * logBonus;
+extern DLL_LINKAGE CGLogger * logNetwork;
+
 /* ---------------------------------------------------------------------------- */
 /* Implementation/Detail classes, Private API */
 /* ---------------------------------------------------------------------------- */
 
-/**
- * The log manager is a global storage of all logger objects.
- */
+/// The class CLogManager is a global storage for logger objects.
 class DLL_LINKAGE CLogManager : public boost::noncopyable
 {
 public:
-    ~CLogManager();
+    static CLogManager & get();
 
-    // Methods
-
-    /**
-     * Gets an instance of the log manager.
-     *
-     * @return an instance of the log manager
-     */
-    static CLogManager * get();
-
-    /**
-     * Adds a logger. The log manager holds strong ownership of the logger object.
-     *
-     * @param logger The logger to add.
-     */
     void addLogger(CGLogger * logger);
-
-    /**
-     * Gets a logger by domain.
-     *
-     * @param domain The domain of the logger.
-     * @return a logger by domain or nullptr if the logger was not found
-     */
-    CGLogger * getLogger(const CLoggerDomain & domain);
+    CGLogger * getLogger(const CLoggerDomain & domain); /// Returns a logger or nullptr if no one is registered for the given domain.
 
 private:
-    // Methods
-
     CLogManager();
+    ~CLogManager();
 
-    // Data members
-
-    static CLogManager * instance;
     std::map<std::string, CGLogger *> loggers;
-    mutable boost::shared_mutex mx;
-    static boost::mutex smx;
+    mutable boost::mutex mx;
+    static boost::recursive_mutex smx;
 };
 
-/**
- * The log records holds the log message and additional logging information.
- */
+/// The struct LogRecord holds the log message and additional logging information.
 struct DLL_LINKAGE LogRecord
 {
     LogRecord(const CLoggerDomain & domain, ELogLevel::ELogLevel level, const std::string & message)
@@ -306,134 +150,64 @@ struct DLL_LINKAGE LogRecord
 
     }
 
-    /** The logger domain. */
     CLoggerDomain domain;
-
-    /** The log level. */
     ELogLevel::ELogLevel level;
-
-    /** The message. */
     std::string message;
-
-    /** The time when the message was created. */
     boost::posix_time::ptime timeStamp;
-
-    /** The thread id. */
     boost::thread::id threadId;
 };
 
-/**
- * The log formatter formats log records.
- *
- * There are several pattern characters which can be used to format a log record:
- * %d = Date/Time
- * %l = Log level
- * %n = Logger name
- * %t = Thread ID
- * %m = Message
- */
+/// The class CLogFormatter formats log records.
+///
+/// There are several pattern characters which can be used to format a log record:
+/// %d = Date/Time
+/// %l = Log level
+/// %n = Logger name
+/// %t = Thread ID
+/// %m = Message
 class DLL_LINKAGE CLogFormatter
 {
 public:
     CLogFormatter();
-
-    /**
-     * Constructor.
-     *
-     * @param pattern The pattern to format the log record with.
-     */
     CLogFormatter(const std::string & pattern);
 
-    // Accessors
-
     void setPattern(const std::string & pattern);
     const std::string & getPattern() const;
 
-    // Methods
-
-    /**
-     * Formats a log record.
-     *
-     * @param record The log record to format.
-     * @return the formatted log record as a string
-     */
     std::string format(const LogRecord & record) const;
 
 private:
-    // Data members
-
     std::string pattern;
 };
 
-/**
- * The interface log target is used by all log target implementations. It holds
- * the abstract method write which sub-classes should implement.
- */
+/// The interface ILogTarget is used by all log target implementations. It holds
+/// the abstract method write which sub-classes should implement.
 class DLL_LINKAGE ILogTarget : public boost::noncopyable
 {
 public:
     virtual ~ILogTarget() { };
-
-    /**
-     * Writes a log record.
-     *
-     * @param record The log record to write.
-     */
     virtual void write(const LogRecord & record) = 0;
 };
 
-/**
- * The color mapping maps a logger name and a level to a specific color.
- */
+/// The class CColorMapping maps a logger name and a level to a specific color. Supports domain inheritance.
 class DLL_LINKAGE CColorMapping
 {
 public:
-    /**
-     * Constructor. There are default color mappings for the root logger, which child loggers inherit if not overriden.
-     */
     CColorMapping();
 
-    // Methods
-
-    /**
-     * Sets a console text color for a logger name and a level.
-     *
-     * @param domain The domain of the logger.
-     * @param level The logger level.
-     * @param color The console text color to use as the mapping.
-     */
     void setColorFor(const CLoggerDomain & domain, ELogLevel::ELogLevel level, EConsoleTextColor::EConsoleTextColor color);
-
-    /**
-     * Gets a console text color for a logger name and a level.
-     *
-     * @param domain The domain of the logger.
-     * @param level The logger level.
-     * @return the console text color which has been applied for the mapping
-     */
     EConsoleTextColor::EConsoleTextColor getColorFor(const CLoggerDomain & domain, ELogLevel::ELogLevel level) const;
 
 private:
-    // Data members
-
     std::map<std::string, std::map<ELogLevel::ELogLevel, EConsoleTextColor::EConsoleTextColor> > map;
 };
 
-/**
- * The console target is a logging target which writes message to the console.
- */
+/// The class CLogConsoleTarget is a logging target which writes message to the console.
 class DLL_LINKAGE CLogConsoleTarget : public ILogTarget
 {
 public:
-    /**
-     * Constructor.
-     *
-     * @param console Optional. The console handler which is used to output messages to the console.
-     */
     explicit CLogConsoleTarget(CConsoleHandler * console);
 
-    // Accessors
-
     bool isColoredOutputEnabled() const;
     void setColoredOutputEnabled(bool coloredOutputEnabled);
 
@@ -446,18 +220,9 @@ public:
     const CColorMapping & getColorMapping() const;
     void setColorMapping(const CColorMapping & colorMapping);
 
-    // Methods
-
-    /**
-     * Writes a log record to the console.
-     *
-     * @param record The log record to write.
-     */
     void write(const LogRecord & record);
 
 private:
-    // Data members
-
     CConsoleHandler * console;
     ELogLevel::ELogLevel threshold;
     bool coloredOutputEnabled;
@@ -466,37 +231,21 @@ private:
     mutable boost::mutex mx;
 };
 
-/**
- * The log file target is a logging target which writes messages to a log file.
- */
+/// The class CLogFileTarget is a logging target which writes messages to a log file.
 class DLL_LINKAGE CLogFileTarget : public ILogTarget
 {
 public:
-    /**
-     * Constructor.
-     *
-     * @param filePath The file path of the log file.
-     */
-    explicit CLogFileTarget(const std::string & filePath);
+    /// Constructs a CLogFileTarget and opens the file designated by filePath. If the append parameter is true, the file will be appended to. Otherwise the file designated by filePath
+    /// will be truncated before being opened.
+    explicit CLogFileTarget(const std::string & filePath, bool append = true);
     ~CLogFileTarget();
 
-    // Accessors
-
     const CLogFormatter & getFormatter() const;
     void setFormatter(const CLogFormatter & formatter);
 
-    // Methods
-
-    /**
-     * Writes a log record to the log file.
-     *
-     * @param record The log record to write.
-     */
     void write(const LogRecord & record);
 
 private:
-    // Data members
-
     std::ofstream file;
     CLogFormatter formatter;
     mutable boost::mutex mx;

+ 3 - 3
lib/mapping/CCampaignHandler.cpp

@@ -229,7 +229,7 @@ CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory( const ui8 * buff
 						break;
 					}
 				default:
-					tlog1<<"Corrupted h3c file"<<std::endl;
+                    logGlobal->warnStream() << "Corrupted h3c file";
 					break;
 				}
 				ret.bonusesToChoose.push_back(bonus);
@@ -266,8 +266,8 @@ CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory( const ui8 * buff
 		}
 	default:
 		{
-			tlog1<<"Corrupted h3c file"<<std::endl;
-			break;
+            logGlobal->warnStream() << "Corrupted h3c file";
+            break;
 		}
 	}
 

+ 3 - 3
lib/mapping/CMapEditManager.cpp

@@ -178,8 +178,8 @@ void CMapEditManager::updateTerrainViews(int posx, int posy, int width, int heig
 					ValidationResult valRslt = validateTerrainView(i, j, mapLevel, flip > 0 ? getFlippedPattern(pattern, flip) : pattern);
 					if(valRslt.result)
 					{
-						tlog5 << "Pattern detected at pos " << i << "x" << j << "x" << mapLevel << ": P-Nr. " << k
-							  << ", Flip " << flip << ", Repl. " << valRslt.transitionReplacement << std::endl;
+                        logGlobal->debugStream() << "Pattern detected at pos " << i << "x" << j << "x" << mapLevel << ": P-Nr. " << k
+                              << ", Flip " << flip << ", Repl. " << valRslt.transitionReplacement;
 
 						bestPattern = k;
 						bestFlip = flip;
@@ -191,7 +191,7 @@ void CMapEditManager::updateTerrainViews(int posx, int posy, int width, int heig
 			if(bestPattern == -1)
 			{
 				// This shouldn't be the case
-				tlog2 << "No pattern detected at pos " << i << "x" << j << "x" << mapLevel << std::endl;
+                logGlobal->warnStream() << "No pattern detected at pos " << i << "x" << j << "x" << mapLevel;
 				continue;
 			}
 

+ 9 - 9
lib/mapping/MapFormatH3M.cpp

@@ -132,7 +132,7 @@ void CMapLoaderH3M::init()
 	{
 		BOOST_FOREACH(MapLoadingTime & mlt, times)
 		{
-			tlog0 << "\tReading " << mlt.name << " took " << mlt.time << " ms." << std::endl;
+            logGlobal->debugStream() << "\tReading " << mlt.name << " took " << mlt.time << " ms.";
 		}
 	}
 }
@@ -644,14 +644,14 @@ bool CMapLoaderH3M::loadArtifactToSlot(CGHeroInstance * hero, int slot)
 	{
 		if(vstd::contains(VLC->arth->bigArtifacts, aid) && slot >= GameConstants::BACKPACK_START)
 		{
-			tlog3 << "Warning: A big artifact (war machine) in hero's backpack, ignoring..." << std::endl;
+            logGlobal->warnStream() << "Warning: A big artifact (war machine) in hero's backpack, ignoring...";
 			return false;
 		}
 		if(aid == 0 && slot == ArtifactPosition::MISC5)
 		{
 			//TODO: check how H3 handles it -> art 0 in slot 18 in AB map
-			tlog3 << "Spellbook to MISC5 slot? Putting it spellbook place. AB format peculiarity ? (format "
-				  << static_cast<int>(map->version) << ")" << std::endl;
+            logGlobal->warnStream() << "Spellbook to MISC5 slot? Putting it spellbook place. AB format peculiarity ? (format "
+                  << static_cast<int>(map->version) << ")";
 			slot = ArtifactPosition::SPELLBOOK;
 		}
 
@@ -773,8 +773,8 @@ void CMapLoaderH3M::readDefInfo()
 				{
 					VLC->dobjinfo->gobjs.erase(defInfo->id);
 				}
-				tlog2 << "\t\tWarning: no defobjinfo entry for object ID="
-					  << defInfo->id << " subID=" << defInfo->subid << std::endl;
+                logGlobal->warnStream() << "\t\tWarning: no defobjinfo entry for object ID="
+                      << defInfo->id << " subID=" << defInfo->subid;
 			}
 			else
 			{
@@ -1539,7 +1539,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(ObjectInstanceID idToBeGiven)
 	{
 		if(map->predefinedHeroes[j]->subID == nhi->subID)
 		{
-			tlog0 << "Hero " << nhi->subID << " will be taken from the predefined heroes list." << std::endl;
+            logGlobal->debugStream() << "Hero " << nhi->subID << " will be taken from the predefined heroes list.";
 			delete nhi;
 			nhi = map->predefinedHeroes[j];
 			break;
@@ -2040,8 +2040,8 @@ std::set<BuildingID> CMapLoaderH3M::convertBuildings(const std::set<BuildingID>
 		}
 		else
 		{
-			tlog3 << "Conversion warning: unknown building " << *i << " in castle "
-				  << castleID << std::endl;
+            logGlobal->warnStream() << "Conversion warning: unknown building " << *i << " in castle "
+                  << castleID;
 		}
 	}