Selaa lähdekoodia

* moved CConsoleHandler to lib (update project files)
* using winapi for better console handling with MSVC (I hope I didn't break anything at GCC)
* new logging system (use log0 - log5 for different priorities and colors (at msvc))
* using lists for storing activated interface objects
* more proper closing of server

Michał W. Urbańczyk 17 vuotta sitten
vanhempi
sitoutus
629d934810

+ 68 - 150
CConsoleHandler.cpp

@@ -1,10 +1,9 @@
+#define VCMI_DLL
 #include "stdafx.h"
 #include "CConsoleHandler.h"
 #include "CAdvmapInterface.h"
 #include "CCastleInterface.h"
 #include "CPlayerInterface.h"
-#include "SDL.h"
-#include "SDL_thread.h"
 #include "CGameInfo.h"
 #include "global.h"
 #include "CGameState.h"
@@ -15,164 +14,83 @@
 #include "SDL_Extensions.h"
 #include "hch/CHeroHandler.h"
 #include "hch/CLodHandler.h"
-#include "boost/filesystem/operations.hpp"
 #include <boost/algorithm/string.hpp>
-#ifdef WIN32
-#include <conio.h>
-#else
+#include "boost/function.hpp"
+#include <boost/thread.hpp>
+#ifdef _MSC_VER
+#include <windows.h>
+HANDLE handleIn;
+HANDLE handleOut;
+WORD defColor;
 #endif
 
-bool continueReadingConsole = true;
+void CConsoleHandler::setColor(int level)
+{
+#ifdef _MSC_VER
+	WORD color;
+	switch(level)
+	{
+	case -1:
+		color = defColor;
+		break;
+	case 0:
+		color = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
+		break;
+	case 1:
+		color = FOREGROUND_RED | FOREGROUND_INTENSITY;
+		break;
+	case 2:
+		color = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
+		break;
+	case 3:
+		color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
+		break;
+	case 4:
+		color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
+		break;
+	case 5:
+		color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
+		break;
+	default:
+		color = defColor;
+		break;
+	}
+	SetConsoleTextAttribute(handleOut,color);
+#endif
+}
 
-int internalFunc(void * callback)
+int CConsoleHandler::run()
 {
-	CCallback * cb = (CCallback*)callback;
-	char * usersMessage = new char[500];
+	char buffer[500];
 	std::string readed;
 	while(true)
 	{
-#ifdef WIN32
-		if(continueReadingConsole && kbhit())
-#else
-#endif
-		{
-			std::cin.getline(usersMessage, 500);
-			std::istringstream readed;
-			std::string pom(usersMessage);
-			readed.str(pom);
-			std::string cn; //command name
-			readed >> cn;
-			int3 src, dst;
-
-			int heronum;
-			int3 dest;
-
-			if(pom==std::string("die, fool"))
-				exit(0);
-			if(cn==std::string("activate"))
-			{
-				int what;
-				readed >> what;
-				switch (what)
-				{
-				case 0:
-					LOCPLINT->curint->activate();
-					break;
-				case 1:
-					LOCPLINT->adventureInt->activate();
-					break;
-				case 2:
-					LOCPLINT->castleInt->activate();
-					break;
-				}
-			}
-			else if(pom==std::string("get txt"))
-			{
-				boost::filesystem::create_directory("Extracted_txts");
-				std::cout<<"Command accepted. Opening .lod file...\t";
-				CLodHandler * txth = new CLodHandler;
-				txth->init(std::string(DATA_DIR "Data" PATHSEPARATOR "H3bitmap.lod"),"data");
-				std::cout<<"done.\nScanning .lod file\n";
-				int curp=0;
-				std::string pattern = ".TXT";
-				for(int i=0;i<txth->entries.size(); i++)
-				{
-					std::string pom = txth->entries[i].nameStr;
-					if(boost::algorithm::find_last(pom,pattern))
-					{
-						txth->extractFile(std::string("Extracted_txts\\")+pom,pom);
-					}
-					int p2 = ((float)i/(float)txth->entries.size())*(float)100;
-					if(p2!=curp)
-					{
-						curp = p2;
-						std::cout<<"\r"<<curp<<"%";
-					}
-				}
-				std::cout<<"\rExtracting done :)\n";
-			}
-			vector<Coordinate>* p;
-			int heroX;
-			int heroY;
-			int heroZ;
-			switch (*cn.c_str())
-			{
-			//case 'P':
-			//	std::cout<<"Policzyc sciezke."<<std::endl;		
-			//	readed>>src>>dst;
-			//	
-			//	p = CGI->pathf->GetPath(Coordinate(src),Coordinate(dst),CGI->heroh->heroInstances[0]);
-			//	LOCPLINT->adventureInt->terrain.currentPath = CGI->pathf->ConvertToOldFormat(p);
-			//	//LOCPLINT->adventureInt->terrain.currentPath = CGI->pathf->getPath(src,dst,CGI->heroh->heroInstances[0]);
-			//	break;
-			//case 'm': //number of heroes
-			//	std::cout<<"Number of heroes: "<<CGI->heroh->heroInstances.size()<<std::endl;
-			//	break;
-			//case 'H': //position of hero
-			//	readed>>heronum;
-			//	std::cout<<"Position of hero "<<heronum<<": "<<CGI->heroh->heroInstances[heronum]->getPosition(false)<<std::endl;
-			//	break;
-			//case 'M': //move heroa
-			//	{
-			//		readed>>heronum>>dest;
-			//		const CGHeroInstance * hero = cb->getHeroInfo(0,heronum,0);
-			//		p = CGI->pathf->GetPath(Coordinate(hero->getPosition(false)),Coordinate(dest),hero);
-			//		cb->moveHero(heronum, CGI->pathf->ConvertToOldFormat(p), 0, 0);
-			//		//LOCPLINT->adventureInt->terrain.currentPath = CGI->pathf->getPath(src,dst,CGI->heroh->heroInstances[0]);
-			//		break;
-			//	}
-			//case 'D': //pos description
-			//	readed>>src;
-			//	CGI->mh->getObjDescriptions(src);
-			//	break;
-			//case 'I': 
-			//	{
-			//		SDL_Surface * temp = LOCPLINT->infoWin(NULL);
-			//		blitAtWR(temp,605,389);
-			//		SDL_FreeSurface(temp);
-			//		break;
-			//	}
-			//case 'T': //test rect
-			//	readed>>src;
-			//	for(int g=0; g<8; ++g)
-			//	{
-			//		for(int v=0; v<8; ++v)
-			//		{
-			//			int3 csrc = src;
-			//			csrc.y+=g;
-			//			csrc.x+=v;
-			//			if(CGI->mh->getObjDescriptions(csrc).size())
-			//				std::cout<<'x';
-			//			else
-			//				std::cout<<'o';
-			//		}
-			//		std::cout<<std::endl;
-			//	}
-			//	break;
-			//case 'A':  //hide everything from map
-			//	for(int c=0; c<CGI->objh->objInstances.size(); ++c)
-			//	{
-			//		CGI->mh->hideObject(CGI->objh->objInstances[c]);
-			//	}
-			//	break;
-			//case 'R': //restora all objects after A has been pressed
-			//	for(int c=0; c<CGI->objh->objInstances.size(); ++c)
-			//	{
-			//		CGI->mh->printObject(CGI->objh->objInstances[c]);
-			//	}
-			//	break;
-			}
-			//SDL_Delay(100);
-			//delete p;
-		}
-		SDL_Delay(100);
+		std::cin.getline(buffer, 500);
+		if(cb && *cb)
+			(*cb)(buffer);
 	}
 	return -1;
 }
-
-SDL_Thread * consoleReadingThread;
-
-void CConsoleHandler::runConsole()
+CConsoleHandler::CConsoleHandler()
 {
-	consoleReadingThread = SDL_CreateThread(&internalFunc, cb);
+#ifdef _MSC_VER
+	handleIn = GetStdHandle(STD_INPUT_HANDLE);
+	handleOut = GetStdHandle(STD_OUTPUT_HANDLE);
+	CONSOLE_SCREEN_BUFFER_INFO csbi;
+	GetConsoleScreenBufferInfo(handleOut,&csbi);
+	defColor = csbi.wAttributes;
+#endif
+	cb = new boost::function<void(const std::string &)>;
 }
+CConsoleHandler::~CConsoleHandler()
+{
+	delete cb;
+}
+void CConsoleHandler::killConsole(void *hThread)
+{
+#ifdef _MSC_VER
+	log3 << "Killing console... ";
+	TerminateThread(hThread,0);
+	log3 << "done!\n";
+#endif
+}

+ 19 - 12
CConsoleHandler.h

@@ -1,19 +1,26 @@
 #ifndef CCONSOLEHANDLER_H
 #define CCONSOLEHANDLER_H
-class CCallback;
-class CConsoleHandler
+namespace boost
+{
+	template<typename signature>
+	class function;
+}
+class DLL_EXPORT CConsoleHandler
 {
-	CCallback * cb;
 public:
-	void runConsole();
-
-	friend class CClient;
-
-#ifndef __GNUC__
-	friend int _tmain(int argc, _TCHAR* argv[]);
-#else
-	friend int main(int argc, char **argv);
-#endif
+	boost::function<void(const std::string &)> *cb;
+	int curLvl;
+	int run();
+	void setColor(int level);
+	CConsoleHandler();
+	~CConsoleHandler();
+	static void killConsole(void *hThread); //for windows only, use native handle to the thread
+	template<typename T> void print(const T &data, int level)
+	{
+		setColor(level);
+		std::cout << data << std::flush;
+		setColor(-1);
+	}
 };
 
 #endif //CCONSOLEHANDLER_H

+ 1 - 0
CGameState.cpp

@@ -927,6 +927,7 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
 			}
 			map->heroes.push_back(nnn);
 			map->objects.push_back(nnn);
+			map->addBlockVisTiles(nnn);
 		}
 	}
 

+ 4 - 2
CHeroWindow.cpp

@@ -687,7 +687,7 @@ void CArtPlace::clickLeft(boost::logic::tribool down)
 			LOCPLINT->objsToBlit.push_back(spellWindow);
 		}
 	}
-	if(!down && !clicked) //not clicked before
+	if(!down && !clicked && pressedL) //not clicked before
 	{
 		if(ourArt && ourArt->id == 0)
 			return; //this is handled separately
@@ -750,6 +750,7 @@ void CArtPlace::clickLeft(boost::logic::tribool down)
 		clicked = false;
 		ourWindow->activeArtPlace = NULL;
 	}
+	ClickableL::clickLeft(down);
 }
 void CArtPlace::clickRight(boost::logic::tribool down)
 {
@@ -840,10 +841,11 @@ void RClickableArea::clickRight(boost::logic::tribool down)
 
 void LRClickableAreaWText::clickLeft(boost::logic::tribool down)
 {
-	if(!down)
+	if(!down && pressedL)
 	{
 		LOCPLINT->showInfoDialog(text, std::vector<SComponent*>());
 	}
+	ClickableL::clickLeft(down);
 }
 void LRClickableAreaWText::clickRight(boost::logic::tribool down)
 {

+ 118 - 43
CMT.cpp

@@ -6,6 +6,8 @@
 #include <vector>
 #include <queue>
 #include <cmath>
+#include <boost/algorithm/string.hpp>
+#include "boost/filesystem/operations.hpp"
 #include <boost/interprocess/mapped_region.hpp>
 #include <boost/interprocess/shared_memory_object.hpp>
 #include <boost/thread.hpp>
@@ -17,6 +19,7 @@
 #include "mapHandler.h"
 #include "global.h"
 #include "CPreGame.h"
+#include "CCastleInterface.h"
 #include "CConsoleHandler.h"
 #include "CCursorHandler.h"
 #include "CPathfinder.h"
@@ -48,13 +51,35 @@ extern SDL_Surface * CSDL_Ext::std32bppSurface;
 std::queue<SDL_Event> events;
 boost::mutex eventsM;
 TTF_Font * TNRB16, *TNR, *GEOR13, *GEORXX, *GEORM, *GEOR16;
+CLogger<0> log0;
+CLogger<1> log1;
+CLogger<2> log2;
+CLogger<3> log3;
+CLogger<4> log4;
+CLogger<5> log5;
+CConsoleHandler *console = NULL;
+std::ostream *logfile = NULL;
 namespace intpr = boost::interprocess;
+void processCommand(const std::string &message);
 #ifndef __GNUC__
 int _tmain(int argc, _TCHAR* argv[])
 #else
 int main(int argc, char** argv)
 #endif
 { 
+	boost::thread *console = NULL;
+	if(argc>2)
+	{
+		std::cout << "Special mode without new support for console!" << std::endl;
+	}
+	else
+	{
+		logfile = new std::ofstream("VCMI_Client_log.txt");
+		::console = new CConsoleHandler;
+		*::console->cb = &processCommand;
+		console = new boost::thread(boost::bind(&CConsoleHandler::run,::console));
+	}
+	log0 << "\tConsole and logifle ready!" << std::endl;
 	int port;
 	if(argc > 1)
 	{
@@ -67,10 +92,10 @@ int main(int argc, char** argv)
 	else
 	{
 		port = 3030;
-		std::cout << "Port " << port << " will be used." << std::endl;
+		log0 << "Port " << port << " will be used." << std::endl;
 	}
 	std::cout.flags(ios::unitbuf);
-	std::cout << NAME << std::endl;
+	log0 << NAME << std::endl;
 	srand ( time(NULL) );
 	CPG=NULL;
 	atexit(SDL_Quit);
@@ -79,12 +104,13 @@ int main(int argc, char** argv)
 	//luatest.test(); 
 		//CBIKHandler cb;
 		//cb.open("CSECRET.BIK");
-	std::cout << "Starting... " << std::endl;
+	log0 << "Starting... " << std::endl;
 	THC timeHandler tmh, total, pomtime;
-	if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO/*|SDL_INIT_EVENTTHREAD*/)==0)
+	if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO)==0)
 	{
 		screen = SDL_SetVideoMode(800,600,24,SDL_SWSURFACE|SDL_DOUBLEBUF/*|SDL_FULLSCREEN*/);  //initializing important global surface
-		THC std::cout<<"\tInitializing screen: "<<pomtime.getDif()<<std::endl;
+		log0 <<"\tInitializing screen: "<<pomtime.getDif();
+			log0 << std::endl;
 		SDL_WM_SetCaption(NAME.c_str(),""); //set window title
 		#if SDL_BYTEORDER == SDL_BIG_ENDIAN
 			int rmask = 0xff000000;int gmask = 0x00ff0000;int bmask = 0x0000ff00;int amask = 0x000000ff;
@@ -92,7 +118,7 @@ int main(int argc, char** argv)
 			int rmask = 0x000000ff;	int gmask = 0x0000ff00;	int bmask = 0x00ff0000;	int amask = 0xff000000;
 		#endif
 		CSDL_Ext::std32bppSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, 1, 1, 32, rmask, gmask, bmask, amask);
-		THC std::cout<<"\tInitializing minors: "<<pomtime.getDif()<<std::endl;
+		log0 << "\tInitializing minors: " << pomtime.getDif() << std::endl;
 		TTF_Init();
 		TNRB16 = TTF_OpenFont("Fonts" PATHSEPARATOR "tnrb.ttf",16);
 		GEOR13 = TTF_OpenFont("Fonts" PATHSEPARATOR "georgia.ttf",13);
@@ -100,20 +126,19 @@ int main(int argc, char** argv)
 		GEORXX = TTF_OpenFont("Fonts" PATHSEPARATOR "tnrb.ttf",22);
 		GEORM = TTF_OpenFont("Fonts" PATHSEPARATOR "georgia.ttf",10);
 		atexit(TTF_Quit);
-		THC std::cout<<"\tInitializing fonts: "<<pomtime.getDif()<<std::endl;
+		THC log0<<"\tInitializing fonts: "<<pomtime.getDif()<<std::endl;
 		CMusicHandler * mush = new CMusicHandler;  //initializing audio
 		mush->initMusics();
 		//audio initialized 
-		cgi->consoleh = new CConsoleHandler;
 		cgi->mush = mush;
-		THC std::cout<<"\tInitializing sound: "<<pomtime.getDif()<<std::endl;
-		THC std::cout<<"Initializing screen, fonts and sound handling: "<<tmh.getDif()<<std::endl;
+		THC log0<<"\tInitializing sound: "<<pomtime.getDif()<<std::endl;
+		THC log0<<"Initializing screen, fonts and sound handling: "<<tmh.getDif()<<std::endl;
 		CDefHandler::Spriteh = cgi->spriteh = new CLodHandler();
 		cgi->spriteh->init("Data" PATHSEPARATOR "H3sprite.lod","Sprites");
 		BitmapHandler::bitmaph = cgi->bitmaph = new CLodHandler;
 		cgi->bitmaph->init("Data" PATHSEPARATOR "H3bitmap.lod","Data");
-		THC std::cout<<"Loading .lod files: "<<tmh.getDif()<<std::endl;
-		initDLL(cgi->bitmaph);
+		THC log0<<"Loading .lod files: "<<tmh.getDif()<<std::endl;
+		initDLL(cgi->bitmaph,::console,logfile);
 		CGI->arth = VLC->arth;
 		CGI->creh = VLC->creh;
 		CGI->townh = VLC->townh;
@@ -122,7 +147,7 @@ int main(int argc, char** argv)
 		CGI->spellh = VLC->spellh;
 		CGI->dobjinfo = VLC->dobjinfo;
 		CGI->buildh = VLC->buildh;
-		THC std::cout<<"Initializing VCMI_Lib: "<<tmh.getDif()<<std::endl;
+		log0<<"Initializing VCMI_Lib: "<<tmh.getDif()<<std::endl;
 		//cgi->curh->initCursor();
 		//cgi->curh->showGraphicCursor();
 		pomtime.getDif();
@@ -130,28 +155,28 @@ int main(int argc, char** argv)
 		cgi->curh->initCursor();
 		//cgi->screenh = new CScreenHandler;
 		//cgi->screenh->initScreen();
-		THC std::cout<<"\tScreen handler: "<<pomtime.getDif()<<std::endl;
+		log0<<"\tScreen handler: "<<pomtime.getDif()<<std::endl;
 		CAbilityHandler * abilh = new CAbilityHandler;
 		abilh->loadAbilities();
 		cgi->abilh = abilh;
-		THC std::cout<<"\tAbility handler: "<<pomtime.getDif()<<std::endl;
-		THC std::cout<<"Preparing first handlers: "<<tmh.getDif()<<std::endl;
+		log0<<"\tAbility handler: "<<pomtime.getDif()<<std::endl;
+		log0<<"Preparing first handlers: "<<tmh.getDif()<<std::endl;
 		pomtime.getDif();
 		graphics = new Graphics();
-		THC std::cout<<"\tMain graphics: "<<tmh.getDif()<<std::endl;
+		log0<<"\tMain graphics: "<<tmh.getDif()<<std::endl;
 		std::vector<CDefHandler **> animacje;
 		for(std::vector<CHeroClass *>::iterator i = cgi->heroh->heroClasses.begin();i!=cgi->heroh->heroClasses.end();i++)
 			animacje.push_back(&((*i)->*(&CHeroClass::moveAnim)));
 		graphics->loadHeroAnim(animacje);
-		THC std::cout<<"\tHero animations: "<<tmh.getDif()<<std::endl;
-		THC std::cout<<"Initializing game graphics: "<<tmh.getDif()<<std::endl;
+		log0<<"\tHero animations: "<<tmh.getDif()<<std::endl;
+		log0<<"Initializing game graphics: "<<tmh.getDif()<<std::endl;
 		CMessage::init();
 		cgi->generaltexth = new CGeneralTextHandler;
 		cgi->generaltexth->load();
-		THC std::cout<<"Preparing more handlers: "<<tmh.getDif()<<std::endl;
+		log0<<"Preparing more handlers: "<<tmh.getDif()<<std::endl;
 		CPreGame * cpg = new CPreGame(); //main menu and submenus
-		THC std::cout<<"Initialization CPreGame (together): "<<tmh.getDif()<<std::endl;
-		THC std::cout<<"Initialization of VCMI (togeter): "<<total.getDif()<<std::endl;
+		log0<<"Initialization CPreGame (together): "<<tmh.getDif()<<std::endl;
+		log0<<"Initialization of VCMI (togeter): "<<total.getDif()<<std::endl;
 		cpg->mush = mush;
 
 		StartInfo *options = new StartInfo(cpg->runLoop());
@@ -164,26 +189,17 @@ int main(int argc, char** argv)
 		ServerReady *sr = new(mr.get_address())ServerReady();
 		std::string comm = std::string(SERVER_NAME) + " " + portc + " > server_log.txt";
 		boost::thread servthr(boost::bind(system,comm.c_str())); //runs server executable; 	//TODO: will it work on non-windows platforms?
-		THC std::cout<<"Preparing shared memory and starting server: "<<tmh.getDif()<<std::endl;
+		log0<<"Preparing shared memory and starting server: "<<tmh.getDif()<<std::endl;
 	///////////////////////////////////////////////////////////////////////////////////////
-		THC tmh.getDif();pomtime.getDif();//reset timers
+		tmh.getDif();pomtime.getDif();//reset timers
 		cgi->pathf = new CPathfinder();
-		THC std::cout<<"\tPathfinder: "<<pomtime.getDif()<<std::endl;
-		if(argc>2)
-		{
-			std::cout << "Special mode without support for console!" << std::endl;
-		}
-		else
-		{
-			cgi->consoleh->runConsole();
-		}
-		THC std::cout<<"\tCallback and console: "<<pomtime.getDif()<<std::endl;
-		THC std::cout<<"Handlers initialization (together): "<<tmh.getDif()<<std::endl;
+		log0<<"\tPathfinder: "<<pomtime.getDif()<<std::endl;
+		log0<<"Handlers initialization (together): "<<tmh.getDif()<<std::endl;
 		std::ofstream lll("client_log.txt");
 
 		CConnection *c=NULL;
 		//wait until server is ready
-		std::cout<<"Waiting for server... " << std::flush;
+		log0<<"Waiting for server... ";
 		{
 			intpr::scoped_lock<intpr::interprocess_mutex> slock(sr->mutex);
 			while(!sr->ready)
@@ -192,22 +208,21 @@ int main(int argc, char** argv)
 			}
 		}
 		intpr::shared_memory_object::remove("vcmi_memory");
-		std::cout << tmh.getDif()<<std::endl;
+		log0 << tmh.getDif()<<std::endl;
 		while(!c)
 		{
 			try
 			{
-				std::cout << "Establishing connection...\t";
+				log0 << "Establishing connection...\n";
 				c = new CConnection("127.0.0.1",portc,NAME,lll);
-				std::cout << "done!" <<std::endl;
 			}
 			catch(...)
 			{
-				std::cout << "\nCannot establish connection! Retrying within 3 seconds" <<std::endl;
-				SDL_Delay(3000);
+				log1 << "\nCannot establish connection! Retrying within 2 seconds" <<std::endl;
+				SDL_Delay(2000);
 			}
 		}
-		THC std::cout<<"\tConnecting to the server: "<<tmh.getDif()<<std::endl;
+		THC log0<<"\tConnecting to the server: "<<tmh.getDif()<<std::endl;
 		CClient cl(c,options);
 		boost::thread t(boost::bind(&CClient::run,&cl));
 		SDL_Event ev;
@@ -217,7 +232,9 @@ int main(int argc, char** argv)
 			if(ev.type==SDL_QUIT) 
 			{
 				cl.close();
+				::console->killConsole(console->native_handle());
 				SDL_Delay(750);
+				log0 << "Ending...\n";
 				exit(0);
 			}
 			eventsM.lock();
@@ -227,7 +244,65 @@ int main(int argc, char** argv)
 	}
 	else
 	{
-		printf("Something was wrong: %s/n", SDL_GetError());
+		log1<<"Something was wrong: "<<SDL_GetError()<<std::endl;
 		return -1;
 	}
 }
+
+void processCommand(const std::string &message)
+{
+	std::istringstream readed;
+	readed.str(message);
+	std::string cn; //command name
+	readed >> cn;
+	int3 src, dst;
+
+	int heronum;
+	int3 dest;
+
+	if(message==std::string("die, fool"))
+		exit(0);
+	else if(cn==std::string("activate"))
+	{
+		int what;
+		readed >> what;
+		switch (what)
+		{
+		case 0:
+			LOCPLINT->curint->activate();
+			break;
+		case 1:
+			LOCPLINT->adventureInt->activate();
+			break;
+		case 2:
+			LOCPLINT->castleInt->activate();
+			break;
+		}
+	}
+	else if(message=="get txt")
+	{
+		boost::filesystem::create_directory("Extracted_txts");
+		log0<<"Command accepted. Opening .lod file...\t";
+		CLodHandler * txth = new CLodHandler;
+		txth->init(std::string(DATA_DIR "Data" PATHSEPARATOR "H3bitmap.lod"),"data");
+		log0<<"done.\nScanning .lod file\n";
+		int curp=0;
+		std::string pattern = ".TXT";
+		for(int i=0;i<txth->entries.size(); i++)
+		{
+			std::string pom = txth->entries[i].nameStr;
+			if(boost::algorithm::find_last(pom,pattern))
+			{
+				txth->extractFile(std::string("Extracted_txts\\")+pom,pom);
+			}
+			if(i%8) continue;
+			int p2 = ((float)i/(float)txth->entries.size())*(float)100;
+			if(p2!=curp)
+			{
+				curp = p2;
+				log0<<"\r"<<curp<<"%";
+			}
+		}
+		log0<<"\rExtracting done :)\n";
+	}
+}

+ 50 - 42
CPlayerInterface.cpp

@@ -40,7 +40,6 @@ using namespace boost::assign;
 using namespace CSDL_Ext;
 
 extern TTF_Font * GEOR16;
-extern bool continueReadingConsole;
 CPlayerInterface * LOCPLINT;
 extern std::queue<SDL_Event> events;
 extern boost::mutex eventsM;
@@ -887,7 +886,7 @@ void ClickableL::clickLeft(tribool down)
 }
 void ClickableL::activate()
 {
-	LOCPLINT->lclickable.push_back(this);
+	LOCPLINT->lclickable.push_front(this);
 }
 void ClickableL::deactivate()
 {
@@ -907,7 +906,7 @@ void ClickableR::clickRight(tribool down)
 }
 void ClickableR::activate()
 {
-	LOCPLINT->rclickable.push_back(this);
+	LOCPLINT->rclickable.push_front(this);
 }
 void ClickableR::deactivate()
 {
@@ -915,7 +914,7 @@ void ClickableR::deactivate()
 }
 void Hoverable::activate()
 {
-	LOCPLINT->hoverable.push_back(this);
+	LOCPLINT->hoverable.push_front(this);
 }
 void Hoverable::deactivate()
 {
@@ -927,7 +926,7 @@ void Hoverable::hover(bool on)
 }
 void KeyInterested::activate()
 {
-	LOCPLINT->keyinterested.push_back(this);
+	LOCPLINT->keyinterested.push_front(this);
 }
 void KeyInterested::deactivate()
 {
@@ -936,7 +935,7 @@ void KeyInterested::deactivate()
 }
 void MotionInterested::activate()
 {
-	LOCPLINT->motioninterested.push_back(this);
+	LOCPLINT->motioninterested.push_front(this);
 }
 void MotionInterested::deactivate()
 {
@@ -1008,12 +1007,14 @@ void CPlayerInterface::yourTurn()
 		updateWater();
 		pim->lock();
 		int tv = th.getDif();
-		for (int i=0;i<timeinterested.size();i++)
+		std::list<TimeInterested*> hlp = timeinterested;
+		for (std::list<TimeInterested*>::iterator i=hlp.begin(); i != hlp.end();i++)
 		{
-			if (timeinterested[i]->toNextTick>=0)
-				timeinterested[i]->toNextTick-=tv;
-			if (timeinterested[i]->toNextTick<0)
-				timeinterested[i]->tick();
+			if(!vstd::contains(timeinterested,*i)) continue;
+			if ((*i)->toNextTick>=0)
+				(*i)->toNextTick-=tv;
+			if ((*i)->toNextTick<0)
+				(*i)->tick();
 		}
 		LOCPLINT->adventureInt->updateScreen = false;
 		eventsM.lock();
@@ -1582,26 +1583,26 @@ SDL_Surface * CPlayerInterface::infoWin(const CGObjectInstance * specific) //spe
 
 void CPlayerInterface::handleMouseMotion(SDL_Event *sEvent)
 {
-	std::vector<int> hlp;
-	for (int i=0; i<hoverable.size();i++)
+	std::vector<Hoverable*> hlp;
+	for(std::list<Hoverable*>::iterator i=hoverable.begin(); i != hoverable.end();i++)
 	{
-		if (isItIn(&hoverable[i]->pos,sEvent->motion.x,sEvent->motion.y))
+		if (isItIn(&(*i)->pos,sEvent->motion.x,sEvent->motion.y))
 		{
-			if (!hoverable[i]->hovered)
-				hlp.push_back(i);
+			if (!(*i)->hovered)
+				hlp.push_back((*i));
 		}
-		else if (hoverable[i]->hovered)
+		else if ((*i)->hovered)
 		{
-			hoverable[i]->hover(false);
+			(*i)->hover(false);
 		}
 	}
 	for(int i=0; i<hlp.size();i++)
-		hoverable[hlp[i]]->hover(true);
-	for(int i=0; i<motioninterested.size();i++)
+		hlp[i]->hover(true);
+	for(std::list<MotionInterested*>::iterator i=motioninterested.begin(); i != motioninterested.end();i++)
 	{
-		if (motioninterested[i]->strongInterest || isItIn(&motioninterested[i]->pos,sEvent->motion.x,sEvent->motion.y))
+		if ((*i)->strongInterest || isItIn(&(*i)->pos,sEvent->motion.x,sEvent->motion.y))
 		{
-			motioninterested[i]->mouseMoved(sEvent->motion);
+			(*i)->mouseMoved(sEvent->motion);
 		}
 	}
 	if(sEvent->motion.x<15)
@@ -1710,12 +1711,11 @@ void CPlayerInterface::handleKeyDown(SDL_Event *sEvent)
 			LOCPLINT->adventureInt->scrollingDown = true;
 			break;
 		}
-	case (SDLK_q):
-		{
-			continueReadingConsole = false;
-			exit(0);
-			break;
-		}
+	//case (SDLK_q):
+	//	{
+	//		exit(0);
+	//		break;
+	//	}
 	case (SDLK_u):
 		{
 			adventureInt->underground.clickLeft(true);
@@ -1767,46 +1767,54 @@ void CPlayerInterface::handleEvent(SDL_Event *sEvent)
 
 	else if ((sEvent->type==SDL_MOUSEBUTTONDOWN) && (sEvent->button.button == SDL_BUTTON_LEFT))
 	{
-		for(int i=0; i<lclickable.size();i++)
+		std::list<ClickableL*> hlp = lclickable;
+		for(std::list<ClickableL*>::iterator i=hlp.begin(); i != hlp.end();i++)
 		{
-			if (isItIn(&lclickable[i]->pos,sEvent->motion.x,sEvent->motion.y))
+			if(!vstd::contains(lclickable,*i)) continue;
+			if (isItIn(&(*i)->pos,sEvent->motion.x,sEvent->motion.y))
 			{
-				lclickable[i]->clickLeft(true);
+				(*i)->clickLeft(true);
 			}
 		}
 	}
 	else if ((sEvent->type==SDL_MOUSEBUTTONUP) && (sEvent->button.button == SDL_BUTTON_LEFT))
 	{
-		for(int i=0; i<lclickable.size();i++)
+		std::list<ClickableL*> hlp = lclickable;
+		for(std::list<ClickableL*>::iterator i=hlp.begin(); i != hlp.end();i++)
 		{
-			if (isItIn(&lclickable[i]->pos,sEvent->motion.x,sEvent->motion.y))
+			if(!vstd::contains(lclickable,*i)) continue;
+			if (isItIn(&(*i)->pos,sEvent->motion.x,sEvent->motion.y))
 			{
-				lclickable[i]->clickLeft(false);
+				(*i)->clickLeft(false);
 			}
 			else
-				lclickable[i]->clickLeft(boost::logic::indeterminate);
+				(*i)->clickLeft(boost::logic::indeterminate);
 		}
 	}
 	else if ((sEvent->type==SDL_MOUSEBUTTONDOWN) && (sEvent->button.button == SDL_BUTTON_RIGHT))
 	{
-		for(int i=0; i<rclickable.size();i++)
+		std::list<ClickableR*> hlp = rclickable;
+		for(std::list<ClickableR*>::iterator i=hlp.begin(); i != hlp.end();i++)
 		{
-			if (isItIn(&rclickable[i]->pos,sEvent->motion.x,sEvent->motion.y))
+			if(!vstd::contains(rclickable,*i)) continue;
+			if (isItIn(&(*i)->pos,sEvent->motion.x,sEvent->motion.y))
 			{
-				rclickable[i]->clickRight(true);
+				(*i)->clickRight(true);
 			}
 		}
 	}
 	else if ((sEvent->type==SDL_MOUSEBUTTONUP) && (sEvent->button.button == SDL_BUTTON_RIGHT))
 	{
-		for(int i=0; i<rclickable.size();i++)
+		std::list<ClickableR*> hlp = rclickable;
+		for(std::list<ClickableR*>::iterator i=hlp.begin(); i != hlp.end();i++)
 		{
-			if (isItIn(&rclickable[i]->pos,sEvent->motion.x,sEvent->motion.y))
+			if(!vstd::contains(rclickable,*i)) continue;
+			if (isItIn(&(*i)->pos,sEvent->motion.x,sEvent->motion.y))
 			{
-				rclickable[i]->clickRight(false);
+				(*i)->clickRight(false);
 			}
 			else
-				rclickable[i]->clickRight(boost::logic::indeterminate);
+				(*i)->clickRight(boost::logic::indeterminate);
 		}
 	}
 	current = NULL;

+ 7 - 6
CPlayerInterface.h

@@ -4,6 +4,7 @@
 #include "CGameInterface.h"
 #include "SDL_framerate.h"
 #include <map>
+#include <list>
 
 class CDefEssential;
 class AdventureMapButton;
@@ -327,12 +328,12 @@ public:
 	CCallback * cb;
 
 	//GUI elements
-	std::vector<ClickableL*> lclickable;
-	std::vector<ClickableR*> rclickable;
-	std::vector<Hoverable*> hoverable;
-	std::vector<KeyInterested*> keyinterested;
-	std::vector<MotionInterested*> motioninterested;
-	std::vector<TimeInterested*> timeinterested;
+	std::list<ClickableL*> lclickable;
+	std::list<ClickableR*> rclickable;
+	std::list<Hoverable*> hoverable;
+	std::list<KeyInterested*> keyinterested;
+	std::list<MotionInterested*> motioninterested;
+	std::list<TimeInterested*> timeinterested;
 	std::vector<IShowable*> objsToBlit;
 
 	//overloaded funcs from CGameInterface

+ 7 - 7
CPreGame.cpp

@@ -1009,7 +1009,7 @@ void MapSel::processMaps(std::vector<std::string> &pliczkiTemp, int &index)
 			else break;
 		}
 		gzclose(tempf);
-		if(iii<50) {std::cout<<"\t\tWarning: corrupted map file: "<<pliczkiTemp[pom]<<std::endl; continue;}
+		if(iii<50) {log3<<"\t\tWarning: corrupted map file: "<<pliczkiTemp[pom]<<std::endl; continue;}
 		if (!sss[4]) continue; //nie ma graczy? mapa niegrywalna //ju¿ to kiedyœ komentowa³em- - to bzdura //tu calkiem pasuje...
 		CMapInfo mi(pliczkiTemp[pom],sss);
 		mx.lock();
@@ -1393,19 +1393,19 @@ CPreGame::CPreGame()
 	preth = new CPreGameTextHandler;
 	preth->loadTexts();
 	CGI->preth=preth;
-	THC std::cout<<"\tCPreGame: loading txts: "<<tmh.getDif()<<std::endl;
+	log0<<"\tCPreGame: loading txts: "<<tmh.getDif()<<std::endl;
 	currentMessage=NULL;
 	behindCurMes=NULL;
 	initMainMenu();
-	THC std::cout<<"\tCPreGame: main menu initialization: "<<tmh.getDif()<<std::endl;
+	log0<<"\tCPreGame: main menu initialization: "<<tmh.getDif()<<std::endl;
 	initNewMenu();
-	THC std::cout<<"\tCPreGame: newgame menu initialization: "<<tmh.getDif()<<std::endl;
+	log0<<"\tCPreGame: newgame menu initialization: "<<tmh.getDif()<<std::endl;
 	initScenSel();
-	THC std::cout<<"\tCPreGame: scenario choice initialization: "<<tmh.getDif()<<std::endl;
+	log0<<"\tCPreGame: scenario choice initialization: "<<tmh.getDif()<<std::endl;
 	initOptions();
-	THC std::cout<<"\tCPreGame: scenario options initialization: "<<tmh.getDif()<<std::endl;
+	log0<<"\tCPreGame: scenario options initialization: "<<tmh.getDif()<<std::endl;
 	showMainMenu();
-	THC std::cout<<"\tCPreGame: displaying main menu: "<<tmh.getDif()<<std::endl;
+	log0<<"\tCPreGame: displaying main menu: "<<tmh.getDif()<<std::endl;
 	CPG=this;
 	playerName="Player";
 }

+ 41 - 38
client/Client.cpp

@@ -101,7 +101,7 @@ CClient::CClient(CConnection *con, StartInfo *si)
 {		
 	timeHandler tmh;
 	CGI->state = new CGameState();
-	THC std::cout<<"\tGamestate: "<<tmh.getDif()<<std::endl;
+	log0 <<"\tGamestate: "<<tmh.getDif()<<std::endl;
 	CConnection &c(*con);
 ////////////////////////////////////////////////////
 	ui8 pom8;
@@ -116,34 +116,34 @@ CClient::CClient(CConnection *con, StartInfo *si)
 	ui32 seed, sum;
 	std::string mapname;
 	c >> mapname >> sum >> seed;
-	THC std::cout<<"\tSending/Getting info to/from the server: "<<tmh.getDif()<<std::endl;
+	log0 <<"\tSending/Getting info to/from the server: "<<tmh.getDif()<<std::endl;
 
 	Mapa * mapa = new Mapa(mapname);
-	THC std::cout<<"Reading and detecting map file (together): "<<tmh.getDif()<<std::endl;
-	std::cout << "\tServer checksum for "<<mapname <<": "<<sum << std::endl;
-	std::cout << "\tOur checksum for the map: "<< mapa->checksum << std::endl;
+	log0 <<"Reading and detecting map file (together): "<<tmh.getDif()<<std::endl;
+	log0 << "\tServer checksum for "<<mapname <<": "<<sum << std::endl;
+	log0 << "\tOur checksum for the map: "<< mapa->checksum << std::endl;
 
 	if(mapa->checksum != sum)
 	{
+		log1 << "Wrong map checksum!!!" << std::endl;
 #ifndef __GNUC__
 		throw std::exception("Wrong checksum");
 #else
 		throw std::exception();
 #endif
-		exit(-1);
 	}
-	std::cout << "\tUsing random seed: "<<seed << std::endl;
+	log0 << "\tUsing random seed: "<<seed << std::endl;
 
 	gs = CGI->state;
 	gs->scenarioOps = si;
 	gs->init(si,mapa,seed);
 
 	CGI->mh = new CMapHandler();
-	THC std::cout<<"Initializing GameState (together): "<<tmh.getDif()<<std::endl;
+	log0 <<"Initializing GameState (together): "<<tmh.getDif()<<std::endl;
 	CGI->mh->map = mapa;
-	THC std::cout<<"Creating mapHandler: "<<tmh.getDif()<<std::endl;
+	log0 <<"Creating mapHandler: "<<tmh.getDif()<<std::endl;
 	CGI->mh->init();
-	THC std::cout<<"Initializing mapHandler (together): "<<tmh.getDif()<<std::endl;
+	log0 <<"Initializing mapHandler (together): "<<tmh.getDif()<<std::endl;
 
 	for (int i=0; i<CGI->state->scenarioOps->playerInfos.size();i++) //initializing interfaces
 	{ 
@@ -160,7 +160,7 @@ CClient::CClient(CConnection *con, StartInfo *si)
 			playerint[color]->init(cb);
 		}
 	}
-	cb = CGI->consoleh->cb = new CCallback(gs,-1,this);
+	//cb = CGI->consoleh->cb = new CCallback(gs,-1,this);
 }
 CClient::~CClient(void)
 {
@@ -173,7 +173,7 @@ void CClient::process(int what)
 		{
 			ui8 player;
 			*serv >> player;//who?
-			std::cout << "It's turn of "<<(unsigned)player<<" player."<<std::endl;
+			log5 << "It's turn of "<<(unsigned)player<<" player."<<std::endl;
 			boost::thread(boost::bind(&CGameInterface::yourTurn,playerint[player]));
 			break;
 		}
@@ -181,16 +181,16 @@ void CClient::process(int what)
 		{
 			NewTurn n;
 			*serv >> n;
-			std::cout << "New day: "<<(unsigned)n.day<<". Applying changes... ";
+			log5 << "New day: "<<(unsigned)n.day<<". Applying changes... ";
 			gs->apply(&n);
-			std::cout << "done!"<<std::endl;
+			log5 << "done!"<<std::endl;
 			break;
 		}
 	case 102: //set resource amount
 		{
 			SetResource sr;
 			*serv >> sr;
-			std::cout << "Set amount of "<<CGI->objh->restypes[sr.resid] 
+			log5 << "Set amount of "<<CGI->objh->restypes[sr.resid] 
 			  << " of player "<<(unsigned)sr.player <<" to "<<sr.val<<std::endl;
 			gs->apply(&sr);
 			playerint[sr.player]->receivedResource(sr.resid,sr.val);
@@ -211,7 +211,7 @@ void CClient::process(int what)
 		{
 			SetResources sr;
 			*serv >> sr;
-			std::cout << "Set amount of resources of player "<<(unsigned)sr.player<<std::endl;
+			log5 << "Set amount of resources of player "<<(unsigned)sr.player<<std::endl;
 			gs->apply(&sr);
 			playerint[sr.player]->receivedResource(-1,-1);
 			break;
@@ -220,7 +220,7 @@ void CClient::process(int what)
 		{
 			SetPrimSkill sps;
 			*serv >> sps;
-			std::cout << "Changing hero primary skill"<<std::endl;
+			log5 << "Changing hero primary skill"<<std::endl;
 			gs->apply(&sps);
 			playerint[gs->getHero(sps.id)->tempOwner]->heroPrimarySkillChanged(gs->getHero(sps.id),sps.which,sps.val);
 			break;
@@ -229,7 +229,7 @@ void CClient::process(int what)
 		{
 			SetSecSkill sr;
 			*serv >> sr;
-			std::cout << "Changing hero secondary skill"<<std::endl;
+			log5 << "Changing hero secondary skill"<<std::endl;
 			gs->apply(&sr);
 			//TODO? - maybe inform interfaces
 			break;
@@ -259,7 +259,7 @@ void CClient::process(int what)
 		{
 			ChangeSpells vc;
 			*serv >> vc;
-			std::cout << "Changing spells of hero "<<vc.hid<<std::endl;
+			log5 << "Changing spells of hero "<<vc.hid<<std::endl;
 			gs->apply(&vc);
 			break;
 		}
@@ -273,7 +273,7 @@ void CClient::process(int what)
 			if(obj->ID == 34)
 			{
 				CGHeroInstance *h = static_cast<CGHeroInstance*>(obj);
-				std::cout << "Removing hero with id = "<<(unsigned)rh.id<<std::endl;
+				log5 << "Removing hero with id = "<<(unsigned)rh.id<<std::endl;
 				playerint[h->tempOwner]->heroKilled(h);
 			}
 			break;
@@ -282,7 +282,7 @@ void CClient::process(int what)
 		{
 			TryMoveHero *th = new TryMoveHero; //will be deleted by callback after processing
 			*serv >> *th;
-			std::cout << "HeroMove: id="<<th->id<<"\tResult: "<<(unsigned)th->result<<"\tPosition "<<th->end<<std::endl;
+			log5 << "HeroMove: id="<<th->id<<"\tResult: "<<(unsigned)th->result<<"\tPosition "<<th->end<<std::endl;
 
 			gs->apply(th);
 			int player = gs->map->objects[th->id]->getOwner();
@@ -317,7 +317,7 @@ void CClient::process(int what)
 		{
 			SetGarrisons sg;
 			*serv >> sg;
-			std::cout << "Setting garrisons." << std::endl;
+			log5 << "Setting garrisons." << std::endl;
 			gs->apply(&sg);
 			for(std::map<ui32,CCreatureSet>::iterator i = sg.garrs.begin(); i!=sg.garrs.end(); i++)
 				playerint[gs->map->objects[i->first]->tempOwner]->garrisonChanged(gs->map->objects[i->first]);
@@ -336,7 +336,7 @@ void CClient::process(int what)
 			NewStructures ns;
 			*serv >> ns;
 			CGTownInstance *town = static_cast<CGTownInstance*>(gs->map->objects[ns.tid]);
-			std::cout << "New structure(s) in " << ns.tid <<" " << town->name << " - " << *ns.bid.begin() << std::endl;
+			log5 << "New structure(s) in " << ns.tid <<" " << town->name << " - " << *ns.bid.begin() << std::endl;
 			gs->apply(&ns);
 			BOOST_FOREACH(si32 bid, ns.bid)
 			{
@@ -356,7 +356,7 @@ void CClient::process(int what)
 		{
 			SetAvailableCreatures ns;
 			*serv >> ns;
-			std::cout << "Setting available creatures in " << ns.tid << std::endl;
+			log5 << "Setting available creatures in " << ns.tid << std::endl;
 			gs->apply(&ns);
 			CGTownInstance *t = gs->getTown(ns.tid);
 			if(vstd::contains(playerint,t->tempOwner))
@@ -367,7 +367,7 @@ void CClient::process(int what)
 		{
 			SetHeroesInTown inTown;
 			*serv >> inTown;
-			std::cout << "Setting heroes in town " << inTown.tid << std::endl;
+			log5 << "Setting heroes in town " << inTown.tid << std::endl;
 			gs->apply(&inTown);
 			CGTownInstance *t = gs->getTown(inTown.tid);
 			if(vstd::contains(playerint,t->tempOwner))
@@ -378,7 +378,7 @@ void CClient::process(int what)
 		{
 			SetHeroArtifacts sha;
 			*serv >> sha;
-			std::cout << "Setting artifacts of hero " << sha.hid << std::endl;
+			log5 << "Setting artifacts of hero " << sha.hid << std::endl;
 			gs->apply(&sha);
 			CGHeroInstance *t = gs->getHero(sha.hid);
 			if(vstd::contains(playerint,t->tempOwner))
@@ -389,7 +389,7 @@ void CClient::process(int what)
 		{
 			SetObjectProperty sop;
 			*serv >> sop;
-			std::cout << "Setting " << (unsigned)sop.what << " property of " << sop.id <<" object to "<<sop.val<<std::endl;
+			log5 << "Setting " << (unsigned)sop.what << " property of " << sop.id <<" object to "<<sop.val<<std::endl;
 			gs->apply(&sop);
 			break;
 		}
@@ -397,7 +397,7 @@ void CClient::process(int what)
 		{
 			SetHoverName shn;
 			*serv >> shn;
-			std::cout << "Setting a name of " << shn.id <<" object to "<< toString(shn.name) <<std::endl;
+			log5 << "Setting a name of " << shn.id <<" object to "<< toString(shn.name) <<std::endl;
 			gs->mx->lock();
 			gs->map->objects[shn.id]->hoverName = toString(shn.name);
 			gs->mx->unlock();
@@ -407,7 +407,7 @@ void CClient::process(int what)
 		{
 			HeroLevelUp  bs;
 			*serv >> bs;
-			std::cout << "Hero levels up!" <<std::endl;
+			log5 << "Hero levels up!" <<std::endl;
 			gs->apply(&bs);
 			CGHeroInstance *h = gs->getHero(bs.heroid);
 			if(vstd::contains(playerint,h->tempOwner))
@@ -421,7 +421,7 @@ void CClient::process(int what)
 		{
 			SelectionDialog sd;
 			*serv >> sd;
-			std::cout << "Showing selection dialog " <<std::endl;
+			log5 << "Showing selection dialog " <<std::endl;
 			std::vector<Component*> comps;
 			for(int i=0;i<sd.components.size();i++)
 				comps.push_back(&sd.components[i]);
@@ -433,7 +433,7 @@ void CClient::process(int what)
 		{
 			YesNoDialog ynd;
 			*serv >> ynd;
-			std::cout << "Showing yes/no dialog " <<std::endl;
+			log5 << "Showing yes/no dialog " <<std::endl;
 			std::vector<Component*> comps;
 			for(int i=0;i<ynd.components.size();i++)
 				comps.push_back(&ynd.components[i]);
@@ -445,7 +445,7 @@ void CClient::process(int what)
 		{
 			BattleStart bs;
 			*serv >> bs; //uses new to allocate memory for battleInfo - must be deleted when battle is over
-			std::cout << "Starting battle!" <<std::endl;
+			log5 << "Starting battle!" <<std::endl;
 			gs->apply(&bs);
 
 			if(playerint.find(gs->curB->side1) != playerint.end())
@@ -459,7 +459,7 @@ void CClient::process(int what)
 		{
 			BattleNextRound bnr;
 			*serv >> bnr;
-			std::cout << "Round nr " << bnr.round <<std::endl;
+			log5 << "Round nr " << bnr.round <<std::endl;
 			gs->apply(&bnr);
 
 			//tell players about next round
@@ -473,7 +473,7 @@ void CClient::process(int what)
 		{
 			BattleSetActiveStack sas;
 			*serv >> sas;
-			std::cout << "Active stack: " << sas.stack <<std::endl;
+			log5 << "Active stack: " << sas.stack <<std::endl;
 			gs->apply(&sas);
 			int owner = gs->curB->getStack(sas.stack)->owner;
 			if(owner >= PLAYER_LIMIT) //ugly workaround to skip neutral creatures - should be replaced with AI
@@ -493,7 +493,7 @@ void CClient::process(int what)
 		{
 			BattleResult br;
 			*serv >> br;
-			std::cout << "Battle ends. Winner: " << (unsigned)br.winner<< ". Type of end: "<< (unsigned)br.result <<std::endl;
+			log5 << "Battle ends. Winner: " << (unsigned)br.winner<< ". Type of end: "<< (unsigned)br.result <<std::endl;
 
 			if(playerint.find(gs->curB->side1) != playerint.end())
 				playerint[gs->curB->side1]->battleEnd(&br);
@@ -507,7 +507,7 @@ void CClient::process(int what)
 		{
 			BattleStackMoved br;
 			*serv >> br;
-			std::cout << "Stack "<<br.stack <<" moves to the tile "<<br.tile<<std::endl;
+			log5 << "Stack "<<br.stack <<" moves to the tile "<<br.tile<<std::endl;
 			if(playerint.find(gs->curB->side1) != playerint.end())
 				playerint[gs->curB->side1]->battleStackMoved(br.stack,br.tile,br.flags&1,br.flags&2);
 			if(playerint.find(gs->curB->side2) != playerint.end())
@@ -519,7 +519,7 @@ void CClient::process(int what)
 		{
 			BattleAttack ba;
 			*serv >> ba;
-			std::cout << "Stack: " << ba.stackAttacking << " is attacking stack "<< ba.bsa.stackAttacked <<std::endl;
+			log5 << "Stack: " << ba.stackAttacking << " is attacking stack "<< ba.bsa.stackAttacked <<std::endl;
 			gs->apply(&ba);
 			LOCPLINT->battleAttack(&ba);
 			break;
@@ -543,7 +543,7 @@ void CClient::waitForMoveAndSend(int color)
 		*serv << ui16(3002) << ba;
 		return;
 	}HANDLE_EXCEPTION
-	std::cout << "We should not be here!" << std::endl;
+	log1 << "We should not be here!" << std::endl;
 }
 void CClient::run()
 {
@@ -560,7 +560,10 @@ void CClient::run()
 
 void CClient::close()
 {
+	log3 << "Connection has been requested to be closed.\n";
 	boost::unique_lock<boost::mutex>(*serv->wmx);
 	*serv << ui16(99);
+	log3 << "Sended closing signal to the server\n";
 	serv->close();
+	log3 << "Our socket has been closed.\n";
 }

+ 1 - 1
client/Graphics.cpp

@@ -396,7 +396,7 @@ void Graphics::loadHeroFlags()
 	grupa.create_thread(boost::bind(&Graphics::loadHeroFlags,this,boost::ref(pr[1]),false));
 	grupa.create_thread(boost::bind(&Graphics::loadHeroFlags,this,boost::ref(pr[0]),false));
 	grupa.join_all();
-	std::cout << "Loading and transforming heroes' flags: "<<th.getDif()<<std::endl;
+	log0 << "Loading and transforming heroes' flags: "<<th.getDif()<<std::endl;
 }
 SDL_Surface * Graphics::getPic(int ID, bool fort, bool builded)
 {

+ 0 - 8
client/VCMI_client.vcproj

@@ -293,10 +293,6 @@
 				RelativePath="..\CCastleInterface.cpp"
 				>
 			</File>
-			<File
-				RelativePath="..\CConsoleHandler.cpp"
-				>
-			</File>
 			<File
 				RelativePath=".\CCreatureAnimation.cpp"
 				>
@@ -439,10 +435,6 @@
 				RelativePath="..\CCastleInterface.h"
 				>
 			</File>
-			<File
-				RelativePath="..\CConsoleHandler.h"
-				>
-			</File>
 			<File
 				RelativePath=".\CCreatureAnimation.h"
 				>

+ 61 - 23
global.h

@@ -17,7 +17,8 @@ typedef boost::int8_t si8; //signed int 8 bits (1 byte)
 #endif
 
 #define NAME_VER ("VCMI 0.63")
-
+#define CONSOLE_LOGGING_LEVEL 5
+#define FILE_LOGGING_LEVEL 6
 
 #ifdef _WIN32
 #define PATHSEPARATOR "\\"
@@ -88,28 +89,6 @@ const int SPELL_LEVELS = 5;
 	#endif
 #endif
 
-#define HANDLE_EXCEPTION  \
-	catch (const std::exception& e) {	\
-	std::cerr << e.what() << std::endl;	\
-	}									\
-	catch (const std::exception * e)	\
-	{									\
-		std::cerr << e->what()<< std::endl;	\
-		delete e;						\
-	}
-
-#define HANDLE_EXCEPTIONC(COMMAND)  \
-	catch (const std::exception& e) {	\
-	COMMAND;							\
-	std::cerr << e.what() << std::endl;	\
-	}									\
-	catch (const std::exception * e)	\
-	{									\
-		COMMAND;						\
-		std::cerr << e->what()<< std::endl;	\
-		delete e;						\
-	}
-
 namespace vstd
 {
 	template <typename Container, typename Item>
@@ -190,4 +169,63 @@ namespace vstd
 	}
 }
 using vstd::operator-=;
+
+#include "CConsoleHandler.h"
+extern std::ostream *logfile;
+extern CConsoleHandler *console;
+template <int lvl> class CLogger
+{
+public:
+	CLogger<lvl>& operator<<(std::ostream& (*fun)(std::ostream&))
+	{
+		if(lvl < CONSOLE_LOGGING_LEVEL)
+			std::cout << fun;
+		if((lvl < FILE_LOGGING_LEVEL) && logfile)
+			*logfile << fun;
+		return *this;
+	}
+
+	template<typename T> 
+	CLogger<lvl> & operator<<(const T & data)
+	{
+		if(lvl < CONSOLE_LOGGING_LEVEL)
+			if(console)
+				console->print(data,lvl);
+			else
+				std::cout << data << std::flush;
+		if((lvl < FILE_LOGGING_LEVEL) && logfile)
+			*logfile << data << std::flush;
+		return *this;
+	}
+};
+
+extern CLogger<0> log0; //green - standard progress info
+extern CLogger<1> log1; //red - big errors
+extern CLogger<2> log2; //magenta - major warnings
+extern CLogger<3> log3; //yellow - minor warnings
+extern CLogger<4> log4; //white - detailed log info
+extern CLogger<5> log5; //gray - minor log info
+
+#define HANDLE_EXCEPTION  \
+	catch (const std::exception& e) {	\
+	log1 << e.what() << std::endl;	\
+	}									\
+	catch (const std::exception * e)	\
+	{									\
+		log1 << e->what()<< std::endl;	\
+		delete e;						\
+	}
+
+#define HANDLE_EXCEPTIONC(COMMAND)  \
+	catch (const std::exception& e) {	\
+	COMMAND;							\
+	log1 << e.what() << std::endl;	\
+	}									\
+	catch (const std::exception * e)	\
+	{									\
+		COMMAND;						\
+		log1 << e->what()<< std::endl;	\
+		delete e;						\
+	}
+
 #endif //GLOBAL_H

+ 7 - 7
hch/CLodHandler.cpp

@@ -31,7 +31,7 @@ unsigned char * CLodHandler::giveFile(std::string defName, int * length)
 	Entry * ourEntry = entries.znajdz(Entry(defName));
 	if(!ourEntry) //nothing's been found
 	{
-		std::cerr<<"Cannot find file: "<<defName;
+		log1<<"Cannot find file: "<<defName;
 		return NULL;
 	}
 	if(length) *length = ourEntry->realSize;
@@ -47,7 +47,7 @@ unsigned char * CLodHandler::giveFile(std::string defName, int * length)
 		FILE * f = fopen(name,"rb");
 		int result = fread(outp,1,ourEntry->realSize,f);
 		mutex->unlock();
-		if(result<0) {std::cout<<"Error in file reading: "<<name<<std::endl;delete[] outp; return NULL;}
+		if(result<0) {log1<<"Error in file reading: "<<name<<std::endl;delete[] outp; return NULL;}
 		else
 			return outp;
 	}
@@ -228,7 +228,7 @@ void CLodHandler::extract(std::string FName)
 			out.open(bufff.c_str(), std::ios::binary);
 			if(!out.is_open())
 			{
-				std::cout<<"Unable to create "<<bufff;
+				log1<<"Unable to create "<<bufff;
 			}
 			else
 			{
@@ -251,7 +251,7 @@ void CLodHandler::extract(std::string FName)
 			destin.close();
 			if(decRes!=0)
 			{
-				std::cout<<"LOD Extraction error"<<"  "<<decRes<<" while extracting to "<<bufff<<std::endl;
+				log1<<"LOD Extraction error"<<"  "<<decRes<<" while extracting to "<<bufff<<std::endl;
 			}
 		}
 		delete[] outp;
@@ -279,7 +279,7 @@ void CLodHandler::extractFile(std::string FName, std::string name)
 			out.open(bufff.c_str(), std::ios::binary);
 			if(!out.is_open())
 			{
-				std::cout<<"Unable to create "<<bufff;
+				log1<<"Unable to create "<<bufff;
 			}
 			else
 			{
@@ -302,7 +302,7 @@ void CLodHandler::extractFile(std::string FName, std::string name)
 			destin.close();
 			if(decRes!=0)
 			{
-				std::cout<<"LOD Extraction error"<<"  "<<decRes<<" while extracting to "<<bufff<<std::endl;
+				log1<<"LOD Extraction error"<<"  "<<decRes<<" while extracting to "<<bufff<<std::endl;
 			}
 		}
 		delete[] outp;
@@ -391,7 +391,7 @@ void CLodHandler::init(std::string lodFile, std::string dirName)
 		}
 	}
 	else
-		std::cout<<"Warning: No "+dirName+"/ folder!"<<std::endl;
+		log1<<"Warning: No "+dirName+"/ folder!"<<std::endl;
 }
 std::string CLodHandler::getTextFile(std::string name)
 {

+ 10 - 10
lib/Connection.cpp

@@ -46,27 +46,27 @@ CConnection::CConnection(std::string host, std::string port, std::string Name, s
     tcp::resolver::iterator end, pom, endpoint_iterator = resolver.resolve(tcp::resolver::query(host,port),error);
 	if(error)
 	{
-		std::cout << "Problem with resolving: " << std::endl << error <<std::endl;
+		log1 << "Problem with resolving: " << std::endl << error <<std::endl;
 		goto connerror1;
 	}
 	pom = endpoint_iterator;
 	if(pom != end)
-		std::cout<<"Found endpoints:" << std::endl;
+		log0<<"Found endpoints:" << std::endl;
 	else
 	{
-		std::cout<< "Critical problem: No endpoints found!" << std::endl;
+		log1 << "Critical problem: No endpoints found!" << std::endl;
 		goto connerror1;
 	}
 	i=0;
 	while(pom != end)
 	{
-		std::cout << "\t" << i << ": " << (boost::asio::ip::tcp::endpoint&)*pom << std::endl;
+		log0 << "\t" << i << ": " << (boost::asio::ip::tcp::endpoint&)*pom << std::endl;
 		pom++;
 	}
 	i=0;
 	while(endpoint_iterator != end)
 	{
-		std::cout << "Trying connection to " << (boost::asio::ip::tcp::endpoint&)*endpoint_iterator << "  (" << i++ << ")" << std::endl;
+		log0 << "Trying connection to " << (boost::asio::ip::tcp::endpoint&)*endpoint_iterator << "  (" << i++ << ")" << std::endl;
 		socket->connect(*endpoint_iterator, error);
 		if(!error)
 		{
@@ -75,18 +75,18 @@ CConnection::CConnection(std::string host, std::string port, std::string Name, s
 		}
 		else
 		{
-			std::cout << "Problem with connecting: " << std::endl <<  error << std::endl;
+			log1 << "Problem with connecting: " << std::endl <<  error << std::endl;
 		}
 		endpoint_iterator++;
 	}
 
 	//we shouldn't be here - error handling
 connerror1:
-	std::cout << "Something went wrong... checking for error info" << std::endl;
+	log1 << "Something went wrong... checking for error info" << std::endl;
 	if(error)
 		std::cout << error <<std::endl;
 	else
-		std::cout << "No error info. " << std::endl;
+		log1 << "No error info. " << std::endl;
 	delete io_service;
 	//delete socket;	
 	throw std::string("Can't establish connection :(");
@@ -115,14 +115,14 @@ CConnection::CConnection(boost::asio::basic_socket_acceptor<boost::asio::ip::tcp
 }
 int CConnection::write(const void * data, unsigned size)
 {
-	LOG("Sending " << size << " byte(s) of data" <<std::endl);
+	//LOG("Sending " << size << " byte(s) of data" <<std::endl);
 	int ret;
 	ret = asio::write(*socket,asio::const_buffers_1(asio::const_buffer(data,size)));
 	return ret;
 }
 int CConnection::read(void * data, unsigned size)
 {
-	LOG("Receiving " << size << " byte(s) of data" <<std::endl);
+	//LOG("Receiving " << size << " byte(s) of data" <<std::endl);
 	int ret = asio::read(*socket,asio::mutable_buffers_1(asio::mutable_buffer(data,size)));
 	return ret;
 }

+ 19 - 10
lib/VCMI_Lib.cpp

@@ -12,9 +12,18 @@
 class CLodHandler;
 LibClasses * VLC = NULL;
 CLodHandler * bitmaph=NULL;
-
-DLL_EXPORT void initDLL(CLodHandler *b)
+CLogger<0> log0;
+CLogger<1> log1;
+CLogger<2> log2;
+CLogger<3> log3;
+CLogger<4> log4;
+CLogger<5> log5;
+CConsoleHandler *console = NULL;
+std::ostream *logfile = NULL;
+DLL_EXPORT void initDLL(CLodHandler *b, CConsoleHandler *Console, std::ostream *Logfile)
 {
+	console = Console;
+	logfile = Logfile;
 	timeHandler pomtime;
 	bitmaph=b;
 	VLC = new LibClasses;
@@ -23,39 +32,39 @@ DLL_EXPORT void initDLL(CLodHandler *b)
 	heroh->loadHeroes();
 	heroh->loadPortraits();
 	VLC->heroh = heroh;
-	THC std::cout<<"\tHero handler: "<<pomtime.getDif()<<std::endl;
+	log0 <<"\tHero handler: "<<pomtime.getDif()<<std::endl;
 
 	CArtHandler * arth = new CArtHandler;
 	arth->loadArtifacts();
 	VLC->arth = arth;
-	THC std::cout<<"\tArtifact handler: "<<pomtime.getDif()<<std::endl;
+	log0<<"\tArtifact handler: "<<pomtime.getDif()<<std::endl;
 
 	CCreatureHandler * creh = new CCreatureHandler();
 	creh->loadCreatures();
 	VLC->creh = creh;
-	THC std::cout<<"\tCreature handler: "<<pomtime.getDif()<<std::endl;
+	log0<<"\tCreature handler: "<<pomtime.getDif()<<std::endl;
 
 	VLC->townh = new CTownHandler;
 	VLC->townh->loadNames();
-	THC std::cout<<"\tTown handler: "<<pomtime.getDif()<<std::endl;
+	log0<<"\tTown handler: "<<pomtime.getDif()<<std::endl;
 
 	CObjectHandler * objh = new CObjectHandler;
 	objh->loadObjects();
 	VLC->objh = objh;
-	THC std::cout<<"\tObject handler: "<<pomtime.getDif()<<std::endl;
+	log0<<"\tObject handler: "<<pomtime.getDif()<<std::endl;
 
 	VLC->dobjinfo = new CDefObjInfoHandler;
 	VLC->dobjinfo->load();
-	THC std::cout<<"\tDef information handler: "<<pomtime.getDif()<<std::endl;
+	log0<<"\tDef information handler: "<<pomtime.getDif()<<std::endl;
 
 	VLC->buildh = new CBuildingHandler;
 	VLC->buildh->loadBuildings();
-	THC std::cout<<"\tBuilding handler: "<<pomtime.getDif()<<std::endl;
+	log0<<"\tBuilding handler: "<<pomtime.getDif()<<std::endl;
 
 	CSpellHandler * spellh = new CSpellHandler;
 	spellh->loadSpells();
 	VLC->spellh = spellh;		
-	THC std::cout<<"\tSpell handler: "<<pomtime.getDif()<<std::endl;
+	log0<<"\tSpell handler: "<<pomtime.getDif()<<std::endl;
 }
 
 DLL_EXPORT void loadToIt(std::string &dest, std::string &src, int &iter, int mode)

+ 1 - 1
lib/VCMI_Lib.h

@@ -44,6 +44,6 @@ extern DLL_EXPORT LibClasses * VLC;
 DLL_EXPORT void loadToIt(std::string &dest, std::string &src, int &iter, int mode);
 DLL_EXPORT void loadToIt(si32 &dest, std::string &src, int &iter, int mode);
 
-DLL_EXPORT void initDLL(CLodHandler *b);
+DLL_EXPORT void initDLL(CLodHandler *b, CConsoleHandler *Console, std::ostream *Logfile);
 
 #endif //VCMI_LIB_H

+ 8 - 0
lib/VCMI_lib.vcproj

@@ -266,6 +266,10 @@
 				RelativePath="..\hch\CBuildingHandler.cpp"
 				>
 			</File>
+			<File
+				RelativePath="..\CConsoleHandler.cpp"
+				>
+			</File>
 			<File
 				RelativePath="..\hch\CCreatureHandler.cpp"
 				>
@@ -332,6 +336,10 @@
 				RelativePath="..\hch\CBuildingHandler.h"
 				>
 			</File>
+			<File
+				RelativePath="..\CConsoleHandler.h"
+				>
+			</File>
 			<File
 				RelativePath="..\hch\CCreatureHandler.h"
 				>

+ 11 - 11
map.cpp

@@ -448,25 +448,25 @@ void Mapa::initFromBytes(unsigned char * bufor)
 	th.getDif();
 	int i=0;
 	readHeader(bufor, i);
-	std::cout<<"\tReading header: "<<th.getDif()<<std::endl;
+	log0<<"\tReading header: "<<th.getDif()<<std::endl;
 
 	readRumors(bufor, i);
-	std::cout<<"\tReading rumors: "<<th.getDif()<<std::endl;
+	log0<<"\tReading rumors: "<<th.getDif()<<std::endl;
 
 	readPredefinedHeroes(bufor, i);
-	std::cout<<"\tReading predefined heroes: "<<th.getDif()<<std::endl;
+	log0<<"\tReading predefined heroes: "<<th.getDif()<<std::endl;
 
 	readTerrain(bufor, i);
-	std::cout<<"\tReading terrain: "<<th.getDif()<<std::endl;
+	log0<<"\tReading terrain: "<<th.getDif()<<std::endl;
 
 	readDefInfo(bufor, i);
-	std::cout<<"\tReading defs info: "<<th.getDif()<<std::endl;
+	log0<<"\tReading defs info: "<<th.getDif()<<std::endl;
 
 	readObjects(bufor, i);
-	std::cout<<"\tReading objects: "<<th.getDif()<<std::endl;
+	log0<<"\tReading objects: "<<th.getDif()<<std::endl;
 	
 	readEvents(bufor, i);
-	std::cout<<"\tReading events: "<<th.getDif()<<std::endl;
+	log0<<"\tReading events: "<<th.getDif()<<std::endl;
 
 	//map readed, bufor no longer needed
 	delete[] bufor; bufor=NULL;
@@ -478,7 +478,7 @@ void Mapa::initFromBytes(unsigned char * bufor)
 			continue;
 		addBlockVisTiles(objects[f]);
 	}
-	std::cout<<"\tCalculating blocked/visitable tiles: "<<th.getDif()<<std::endl;
+	log0<<"\tCalculating blocked/visitable tiles: "<<th.getDif()<<std::endl;
 }	
 void Mapa::removeBlockVisTiles(CGObjectInstance * obj)
 {
@@ -534,7 +534,7 @@ void Mapa::addBlockVisTiles(CGObjectInstance * obj)
 }
 Mapa::Mapa(std::string filename)
 {
-	std::cout<<"Opening map file: "<<filename<<"\t "<<std::flush;
+	log0<<"Opening map file: "<<filename<<"\t "<<std::flush;
 	gzFile map = gzopen(filename.c_str(),"rb");
 	std::vector<unsigned char> mapstr; int pom;
 	while((pom=gzgetc(map))>=0)
@@ -547,11 +547,11 @@ Mapa::Mapa(std::string filename)
 	{
 		initTable[ss] = mapstr[ss];
 	}
-	std::cout<<"done."<<std::endl;
+	log0<<"done."<<std::endl;
 	boost::crc_32_type  result;
 	result.process_bytes(initTable,mapstr.size());
 	checksum = result.checksum();
-	std::cout << "\tOur map checksum: "<<result.checksum() << std::endl;
+	log0 << "\tOur map checksum: "<<result.checksum() << std::endl;
 	initFromBytes(initTable);
 }
 

+ 9 - 35
mapHandler.cpp

@@ -456,32 +456,6 @@ void CMapHandler::initObjectRects()
 		}
 	}
 }
-void CMapHandler::calculateBlockedPos()
-{
-	//for(int f=0; f<map->objects.size(); ++f) //calculationg blocked / visitable positions
-	//{
-	//	if(!map->objects[f]->defInfo)
-	//		continue;
-	//	CDefHandler * curd = map->objects[f]->defInfo->handler;
-	//	for(int fx=0; fx<8; ++fx)
-	//	{
-	//		for(int fy=0; fy<6; ++fy)
-	//		{
-	//			int xVal = map->objects[f]->pos.x + fx - 7;
-	//			int yVal = map->objects[f]->pos.y + fy - 5;
-	//			int zVal = map->objects[f]->pos.z;
-	//			if(xVal>=0 && xVal<ttiles.size()-Woff && yVal>=0 && yVal<ttiles[0].size()-Hoff)
-	//			{
-	//				TerrainTile2 & curt = ttiles[xVal][yVal][zVal];
-	//				if(((map->objects[f]->defInfo->visitMap[fy] >> (7 - fx)) & 1))
-	//					curt.tileInfo->visitable = true;
-	//				if(!((map->objects[f]->defInfo->blockMap[fy] >> (7 - fx)) & 1))
-	//					curt.tileInfo->blocked = true;
-	//			}
-	//		}
-	//	}
-	//}
-}
 void processDef (CGDefInfo* def)
 {
 	def->handler=CDefHandler::giveDef(def->name);
@@ -495,7 +469,7 @@ void processDef (CGDefInfo* def)
 		pom->height = pom->handler->ourImages[0].bitmap->h/32;
 	}
 	else if(def->id != 34 && def->id != 98)
-		std::cout << "\t\tMinor warning: lacking def info for " << def->id << " " << def->subid <<" " << def->name << std::endl;
+		log3 << "\t\tMinor warning: lacking def info for " << def->id << " " << def->subid <<" " << def->name << std::endl;
 	if(!def->handler->alphaTransformed)
 	{
 		for(int yy=0; yy<def->handler->ourImages.size(); ++yy)
@@ -510,7 +484,7 @@ void CMapHandler::init()
 	timeHandler th;
 	th.getDif();
 	loadDefs();	//loading castles' defs
-	THC std::cout<<"Reading terrain defs: "<<th.getDif()<<std::endl;
+	log0<<"Reading terrain defs: "<<th.getDif()<<std::endl;
 
 	std::ifstream ifs("config/townsDefs.txt");
 	int ccc;
@@ -527,10 +501,10 @@ void CMapHandler::init()
 			n = CGI->state->capitols[i%ccc];
 		ifs >> n->name;
 		if(!n)
-			std::cout << "*HUGE* Warning - missing town def for " << i << std::endl;
+			log1 << "*HUGE* Warning - missing town def for " << i << std::endl;
 		map->defs.insert(n);
 	} 
-	std::cout<<"\tLoading town def info: "<<th.getDif()<<std::endl;
+	log0<<"\tLoading town def info: "<<th.getDif()<<std::endl;
 
 	for(int i=0;i<map->heroes.size();i++)
 	{
@@ -544,7 +518,7 @@ void CMapHandler::init()
 
 	std::for_each(map->defy.begin(),map->defy.end(),processDef); //load h3m defs
 	std::for_each(map->defs.begin(),map->defs.end(),processDef); //and non-h3m defs
-	THC std::cout<<"\tUnpacking and handling defs: "<<th.getDif()<<std::endl;
+	log0<<"\tUnpacking and handling defs: "<<th.getDif()<<std::endl;
 
 	for(int i=0;i<PLAYER_LIMIT;i++)
 	{
@@ -553,20 +527,20 @@ void CMapHandler::init()
 			usedHeroes.insert(map->players[i].heroesNames[j].heroID);
 		}
 	}
-	std::cout<<"\tChecking used heroes: "<<th.getDif()<<std::endl;
+	log0<<"\tChecking used heroes: "<<th.getDif()<<std::endl;
 
 
 
 	for(int h=0; h<map->defy.size(); ++h) //initializing loaded def handler's info	{
 		CGI->mh->loadedDefs.insert(std::make_pair(map->defy[h]->name, map->defy[h]->handler));
-	std::cout<<"\tCollecting loaded def's handlers: "<<th.getDif()<<std::endl;
+	log0<<"\tCollecting loaded def's handlers: "<<th.getDif()<<std::endl;
 
 	prepareFOWDefs();
 	roadsRiverTerrainInit();	//road's and river's DefHandlers; and simple values initialization
 	borderAndTerrainBitmapInit();
-	std::cout<<"\tPreparing FoW, roads, rivers,borders: "<<th.getDif()<<std::endl;
+	log0<<"\tPreparing FoW, roads, rivers,borders: "<<th.getDif()<<std::endl;
 	initObjectRects();
-	std::cout<<"\tMaking object rects: "<<th.getDif()<<std::endl;
+	log0<<"\tMaking object rects: "<<th.getDif()<<std::endl;
 }
 
 SDL_Surface * CMapHandler::terrainRect(int x, int y, int dx, int dy, int level, unsigned char anim, std::vector< std::vector< std::vector<unsigned char> > > * visibilityMap, bool otherHeroAnim, unsigned char heroAnim, SDL_Surface * extSurf, SDL_Rect * extRect)

+ 7 - 2
server/CGameHandler.cpp

@@ -338,6 +338,11 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
 			bool blockvis = false;
 			switch(pom)
 			{
+			case 99: //end!
+				{
+					log0 << "We have been requested to close.\n";
+					exit(0);
+				}
 			case 100: //my interface ended its turn
 				{
 					states.setFlag(gs->currentPlayer,&PlayerStatus::makingTurn,false);
@@ -953,12 +958,12 @@ upgend:
 	}
 	catch (const std::exception& e)
 	{
-		std::cerr << e.what() << std::endl;
+		log1 << e.what() << std::endl;
 		end2 = true;
 	}
 	catch (const std::exception * e)
 	{
-		std::cerr << e->what()<< std::endl;	
+		log1 << e->what()<< std::endl;	
 		end2 = true;
 		delete e;
 	}

+ 12 - 2
server/CVCMIServer.cpp

@@ -22,7 +22,14 @@ using namespace boost;
 using namespace boost::asio;
 using namespace boost::asio::ip;
 namespace intpr = boost::interprocess;
-
+CLogger<0> log0;
+CLogger<1> log1;
+CLogger<2> log2;
+CLogger<3> log3;
+CLogger<4> log4;
+CLogger<5> log5;
+CConsoleHandler *console = NULL;
+std::ostream *logfile = NULL;
 bool end2 = false;
 int port = 3030;
 
@@ -155,6 +162,9 @@ int _tmain(int argc, _TCHAR* argv[])
 int main(int argc, char** argv)
 #endif
 {
+	logfile = new std::ofstream("VCMI_Server_log.txt");
+	console = new CConsoleHandler;
+	boost::thread t(boost::bind(&CConsoleHandler::run,::console));
 	if(argc > 1)
 	{
 #ifdef _MSC_VER
@@ -166,7 +176,7 @@ int main(int argc, char** argv)
 	std::cout << "Port " << port << " will be used." << std::endl;
 	CLodHandler h3bmp;
 	h3bmp.init("Data" PATHSEPARATOR "H3bitmap.lod","Data");
-	initDLL(&h3bmp);
+	initDLL(&h3bmp,console,logfile);
 	srand ( (unsigned int)time(NULL) );
 	try
 	{