Quellcode durchsuchen

* 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 vor 17 Jahren
Ursprung
Commit
629d934810
21 geänderte Dateien mit 461 neuen und 410 gelöschten Zeilen
  1. 68 150
      CConsoleHandler.cpp
  2. 19 12
      CConsoleHandler.h
  3. 1 0
      CGameState.cpp
  4. 4 2
      CHeroWindow.cpp
  5. 118 43
      CMT.cpp
  6. 50 42
      CPlayerInterface.cpp
  7. 7 6
      CPlayerInterface.h
  8. 7 7
      CPreGame.cpp
  9. 41 38
      client/Client.cpp
  10. 1 1
      client/Graphics.cpp
  11. 0 8
      client/VCMI_client.vcproj
  12. 61 23
      global.h
  13. 7 7
      hch/CLodHandler.cpp
  14. 10 10
      lib/Connection.cpp
  15. 19 10
      lib/VCMI_Lib.cpp
  16. 1 1
      lib/VCMI_Lib.h
  17. 8 0
      lib/VCMI_lib.vcproj
  18. 11 11
      map.cpp
  19. 9 35
      mapHandler.cpp
  20. 7 2
      server/CGameHandler.cpp
  21. 12 2
      server/CVCMIServer.cpp

+ 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
 	{