Pārlūkot izejas kodu

Split Process console commands code into individual functions

Extracted functions for each if branch, added one line doc for each function, rearranged the commands to be groupped more logically.
krs 2 gadi atpakaļ
vecāks
revīzija
14cbdf7ab0
2 mainītis faili ar 485 papildinājumiem un 261 dzēšanām
  1. 409 255
      client/ClientCommandManager.cpp
  2. 76 6
      client/ClientCommandManager.h

+ 409 - 255
client/ClientCommandManager.cpp

@@ -42,7 +42,34 @@
 
 #include <SDL_surface.h>
 
-void ClientCommandManager::handleGoSolo()
+void ClientCommandManager::handleQuitCommand()
+{
+		exit(EXIT_SUCCESS);
+}
+
+void ClientCommandManager::handleSaveCommand(std::istringstream & singleWordBuffer)
+{
+	if(!CSH->client)
+	{
+		printCommandMessage("Game is not in playing state");
+		return;
+	}
+
+	std::string saveFilename;
+	singleWordBuffer >> saveFilename;
+	CSH->client->save(saveFilename);
+	printCommandMessage("Game saved as: " + saveFilename);
+}
+
+void ClientCommandManager::handleLoadCommand(std::istringstream& singleWordBuffer)
+{
+	// TODO: this code should end the running game and manage to call startGame instead
+	//std::string fname;
+	//singleWordBuffer >> fname;
+	//CSH->client->loadGame(fname);
+}
+
+void ClientCommandManager::handleGoSoloCommand()
 {
 	Settings session = settings.write["session"];
 
@@ -80,21 +107,33 @@ void ClientCommandManager::handleGoSolo()
 	session["aiSolo"].Bool() = !session["aiSolo"].Bool();
 }
 
-void ClientCommandManager::handleControlAi(const std::string &colorName)
+void ClientCommandManager::handleAutoskipCommand()
 {
+		Settings session = settings.write["session"];
+		session["autoSkip"].Bool() = !session["autoSkip"].Bool();
+}
+
+void ClientCommandManager::handleControlaiCommand(std::istringstream& singleWordBuffer)
+{
+	std::string colorName;
+	singleWordBuffer >> colorName;
+	boost::to_lower(colorName);
+
 	boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
 	if(!CSH->client)
 	{
 		printCommandMessage("Game is not in playing state");
 		return;
 	}
+
 	PlayerColor color;
 	if(LOCPLINT)
 		color = LOCPLINT->playerID;
+
 	for(auto & elem : CSH->client->gameState()->players)
 	{
-		if(elem.second.human || (colorName.length() &&
-								 elem.first.getNum() != vstd::find_pos(GameConstants::PLAYER_COLOR_NAMES, colorName)))
+		if(elem.second.human || 
+			(colorName.length() && elem.first.getNum() != vstd::find_pos(GameConstants::PLAYER_COLOR_NAMES, colorName)))
 		{
 			continue;
 		}
@@ -102,290 +141,313 @@ void ClientCommandManager::handleControlAi(const std::string &colorName)
 		CSH->client->removeGUI();
 		CSH->client->installNewPlayerInterface(std::make_shared<CPlayerInterface>(elem.first), elem.first);
 	}
+
 	GH.totalRedraw();
 	if(color != PlayerColor::NEUTRAL)
 		giveTurn(color);
 }
 
-void ClientCommandManager::processCommand(const std::string &message, bool calledFromIngameConsole)
+void ClientCommandManager::handleSetBattleAICommand(std::istringstream& singleWordBuffer)
 {
-	std::istringstream singleWordBuffer;
-	singleWordBuffer.str(message);
-	std::string commandName;
-	singleWordBuffer >> commandName;
-	currentCallFromIngameConsole = calledFromIngameConsole;
+	std::string aiName;
+	singleWordBuffer >> aiName;
 
-	if(message==std::string("die, fool"))
+	printCommandMessage("Will try loading that AI to see if it is correct name...\n");
+	try
 	{
-		exit(EXIT_SUCCESS);
+		if(auto ai = CDynLibHandler::getNewBattleAI(aiName)) //test that given AI is indeed available... heavy but it is easy to make a typo and break the game
+		{
+			Settings neutralAI = settings.write["server"]["neutralAI"];
+			neutralAI->String() = aiName;
+			printCommandMessage("Setting changed, from now the battle ai will be " + aiName + "!\n");
+		}
 	}
-	else if(commandName == "redraw")
+	catch(std::exception &e)
 	{
-		GH.totalRedraw();
+		printCommandMessage("Failed opening " + aiName + ": " + e.what(), ELogLevel::WARN);
+		printCommandMessage("Setting not changed, AI not found or invalid!", ELogLevel::WARN);
 	}
-	else if(commandName == "screen")
-	{
-		printCommandMessage("Screenbuf points to ");
+}
 
-		if(screenBuf == screen)
-			printCommandMessage("screen", ELogLevel::ERROR);
-		else if(screenBuf == screen2)
-			printCommandMessage("screen2", ELogLevel::ERROR);
-		else
-			printCommandMessage("?!?", ELogLevel::ERROR);
+void ClientCommandManager::handleRedrawCommand()
+{
+	GH.totalRedraw();
+}
 
-		SDL_SaveBMP(screen, "Screen_c.bmp");
-		SDL_SaveBMP(screen2, "Screen2_c.bmp");
-	}
-	else if(commandName == "save")
+void ClientCommandManager::handleScreenCommand()
+{
+	printCommandMessage("Screenbuf points to ");
+
+	if(screenBuf == screen)
+		printCommandMessage("screen", ELogLevel::ERROR);
+	else if(screenBuf == screen2)
+		printCommandMessage("screen2", ELogLevel::ERROR);
+	else
+		printCommandMessage("?!?", ELogLevel::ERROR);
+
+	SDL_SaveBMP(screen, "Screen_c.bmp");
+	SDL_SaveBMP(screen2, "Screen2_c.bmp");
+}
+
+void ClientCommandManager::handleNotDialogCommand()
+{
+	LOCPLINT->showingDialog->setn(false);
+}
+
+void ClientCommandManager::handleGuiCommand()
+{
+	for(const auto & child : GH.listInt)
 	{
-		if(!CSH->client)
-		{
-			printCommandMessage("Game is not in playing state");
-			return;
-		}
-		std::string fname;
-		singleWordBuffer >> fname;
-		CSH->client->save(fname);
+		const auto childPtr = child.get();
+		if(const CIntObject * obj = dynamic_cast<const CIntObject*>(childPtr))
+			printInfoAboutInterfaceObject(obj, 0);
+		else
+			printCommandMessage(std::string(typeid(childPtr).name()) + "\n");
 	}
-//	else if(commandName=="load")
-//	{
-//		// TODO: this code should end the running game and manage to call startGame instead
-//		std::string fname;
-//		singleWordBuffer >> fname;
-//		CSH->client->loadGame(fname);
-//	}
-	else if(message=="convert txt")
+}
+
+void ClientCommandManager::handleConvertTextCommand()
+{
+	logGlobal->info("Searching for available maps");
+	std::unordered_set<ResourceID> mapList = CResourceHandler::get()->getFilteredFiles([&](const ResourceID & ident)
 	{
-		logGlobal->info("Searching for available maps");
-		std::unordered_set<ResourceID> mapList = CResourceHandler::get()->getFilteredFiles([&](const ResourceID & ident)
-		{
-			return ident.getType() == EResType::MAP;
-		});
+		return ident.getType() == EResType::MAP;
+	});
 
-		std::unordered_set<ResourceID> campaignList = CResourceHandler::get()->getFilteredFiles([&](const ResourceID & ident)
-		{
-			return ident.getType() == EResType::CAMPAIGN;
-		});
+	std::unordered_set<ResourceID> campaignList = CResourceHandler::get()->getFilteredFiles([&](const ResourceID & ident)
+	{
+		return ident.getType() == EResType::CAMPAIGN;
+	});
 
-		CMapService mapService;
+	CMapService mapService;
 
-		logGlobal->info("Loading maps for export");
-		for (auto const & mapName : mapList)
+	logGlobal->info("Loading maps for export");
+	for (auto const & mapName : mapList)
+	{
+		try
 		{
-			try
-			{
-				// load and drop loaded map - we only need loader to run over all maps
-				mapService.loadMap(mapName);
-			}
-			catch(std::exception & e)
-			{
-				logGlobal->error("Map %s is invalid. Message: %s", mapName.getName(), e.what());
-			}
+			// load and drop loaded map - we only need loader to run over all maps
+			mapService.loadMap(mapName);
 		}
-
-		logGlobal->info("Loading campaigns for export");
-		for (auto const & campaignName : campaignList)
+		catch(std::exception & e)
 		{
-			CCampaignState state(CCampaignHandler::getCampaign(campaignName.getName()));
-			for (auto const & part : state.camp->mapPieces)
-				delete state.getMap(part.first);
+			logGlobal->error("Map %s is invalid. Message: %s", mapName.getName(), e.what());
 		}
-
-		VLC->generaltexth->dumpAllTexts();
 	}
-	else if(message=="get config")
+
+	logGlobal->info("Loading campaigns for export");
+	for (auto const & campaignName : campaignList)
 	{
-		printCommandMessage("Command accepted.\t");
+		CCampaignState state(CCampaignHandler::getCampaign(campaignName.getName()));
+		for (auto const & part : state.camp->mapPieces)
+			delete state.getMap(part.first);
+	}
 
-		const boost::filesystem::path outPath =
-				VCMIDirs::get().userExtractedPath() / "configuration";
+	VLC->generaltexth->dumpAllTexts();
+}
 
-		boost::filesystem::create_directories(outPath);
+void ClientCommandManager::handleGetConfigCommand()
+{
+	printCommandMessage("Command accepted.\t");
 
-		const std::vector<std::string> contentNames = {"heroClasses", "artifacts", "creatures", "factions", "objects", "heroes", "spells", "skills"};
+	const boost::filesystem::path outPath = VCMIDirs::get().userExtractedPath() / "configuration";
 
-		for(auto contentName : contentNames)
-		{
-			auto & content = (*VLC->modh->content)[contentName];
+	boost::filesystem::create_directories(outPath);
 
-			auto contentOutPath = outPath / contentName;
-			boost::filesystem::create_directories(contentOutPath);
+	const std::vector<std::string> contentNames = { "heroClasses", "artifacts", "creatures", "factions", "objects", "heroes", "spells", "skills" };
 
-			for(auto & iter : content.modData)
-			{
-				const JsonNode & modData = iter.second.modData;
+	for(auto contentName : contentNames)
+	{
+		auto& content = (*VLC->modh->content)[contentName];
 
-				for(auto & nameAndObject : modData.Struct())
-				{
-					const JsonNode & object = nameAndObject.second;
+		auto contentOutPath = outPath / contentName;
+		boost::filesystem::create_directories(contentOutPath);
 
-					std::string name = CModHandler::makeFullIdentifier(object.meta, contentName, nameAndObject.first);
+		for(auto& iter : content.modData)
+		{
+			const JsonNode& modData = iter.second.modData;
 
-					boost::algorithm::replace_all(name,":","_");
+			for(auto& nameAndObject : modData.Struct())
+			{
+				const JsonNode& object = nameAndObject.second;
 
-					const boost::filesystem::path filePath = contentOutPath / (name + ".json");
-					boost::filesystem::ofstream file(filePath);
-					file << object.toJson();
-				}
+				std::string name = CModHandler::makeFullIdentifier(object.meta, contentName, nameAndObject.first);
+
+				boost::algorithm::replace_all(name, ":", "_");
+
+				const boost::filesystem::path filePath = contentOutPath / (name + ".json");
+				boost::filesystem::ofstream file(filePath);
+				file << object.toJson();
 			}
 		}
-
-		printCommandMessage("\rExtracting done :)\n");
-		printCommandMessage("Extracted files can be found in " + outPath.string() + " directory\n");
 	}
+
+	printCommandMessage("\rExtracting done :)\n");
+	printCommandMessage("Extracted files can be found in " + outPath.string() + " directory\n");
+}
+
+void ClientCommandManager::handleGetScriptsCommand()
+{
 #if SCRIPTING_ENABLED
-		else if(message=="get scripts")
-	{
-		printCommandMessage("Command accepted.\t");
+	printCommandMessage("Command accepted.\t");
 
-		const boost::filesystem::path outPath =
-			VCMIDirs::get().userExtractedPath() / "scripts";
+	const boost::filesystem::path outPath = VCMIDirs::get().userExtractedPath() / "scripts";
 
-		boost::filesystem::create_directories(outPath);
+	boost::filesystem::create_directories(outPath);
 
-		for(auto & kv : VLC->scriptHandler->objects)
-		{
-			std::string name = kv.first;
-			boost::algorithm::replace_all(name,":","_");
+	for(auto & kv : VLC->scriptHandler->objects)
+	{
+		std::string name = kv.first;
+		boost::algorithm::replace_all(name,":","_");
 
-			const scripting::ScriptImpl * script = kv.second.get();
-			boost::filesystem::path filePath = outPath / (name + ".lua");
-			boost::filesystem::ofstream file(filePath);
-			file << script->getSource();
-		}
-		printCommandMessage("\rExtracting done :)\n");
-		printCommandMessage("Extracted files can be found in " + outPath.string() + " directory\n");
+		const scripting::ScriptImpl * script = kv.second.get();
+		boost::filesystem::path filePath = outPath / (name + ".lua");
+		boost::filesystem::ofstream file(filePath);
+		file << script->getSource();
 	}
+	printCommandMessage("\rExtracting done :)\n");
+	printCommandMessage("Extracted files can be found in " + outPath.string() + " directory\n");
 #endif
-	else if(message=="get txt")
-	{
-		printCommandMessage("Command accepted.\t");
+}
 
-		const boost::filesystem::path outPath =
-				VCMIDirs::get().userExtractedPath();
+void ClientCommandManager::handleGetTextCommand()
+{
+	printCommandMessage("Command accepted.\t");
 
-		auto list =
-				CResourceHandler::get()->getFilteredFiles([](const ResourceID & ident)
-				{
-					return ident.getType() == EResType::TEXT && boost::algorithm::starts_with(ident.getName(), "DATA/");
-				});
+	const boost::filesystem::path outPath =
+			VCMIDirs::get().userExtractedPath();
 
-		for (auto & filename : list)
-		{
-			const boost::filesystem::path filePath = outPath / (filename.getName() + ".TXT");
+	auto list =
+			CResourceHandler::get()->getFilteredFiles([](const ResourceID & ident)
+			{
+				return ident.getType() == EResType::TEXT && boost::algorithm::starts_with(ident.getName(), "DATA/");
+			});
 
-			boost::filesystem::create_directories(filePath.parent_path());
+	for (auto & filename : list)
+	{
+		const boost::filesystem::path filePath = outPath / (filename.getName() + ".TXT");
 
-			boost::filesystem::ofstream file(filePath);
-			auto text = CResourceHandler::get()->load(filename)->readAll();
+		boost::filesystem::create_directories(filePath.parent_path());
 
-			file.write((char*)text.first.get(), text.second);
-		}
+		boost::filesystem::ofstream file(filePath);
+		auto text = CResourceHandler::get()->load(filename)->readAll();
 
-		printCommandMessage("\rExtracting done :)\n");
-		printCommandMessage("Extracted files can be found in " + outPath.string() + " directory\n");
+		file.write((char*)text.first.get(), text.second);
 	}
-	else if(commandName == "crash")
-	{
-		int *ptr = nullptr;
-		*ptr = 666;
-		//disaster!
-	}
-	else if(commandName == "mp" && adventureInt)
+
+	printCommandMessage("\rExtracting done :)\n");
+	printCommandMessage("Extracted files can be found in " + outPath.string() + " directory\n");
+}
+
+void ClientCommandManager::handleDef2bmpCommand(std::istringstream& singleWordBuffer)
+{
+	std::string URI;
+	singleWordBuffer >> URI;
+	std::unique_ptr<CAnimation> anim = std::make_unique<CAnimation>(URI);
+	anim->preload();
+	anim->exportBitmaps(VCMIDirs::get().userExtractedPath());
+}
+
+void ClientCommandManager::handleExtractCommand(std::istringstream& singleWordBuffer)
+{
+	std::string URI;
+	singleWordBuffer >> URI;
+
+	if(CResourceHandler::get()->existsResource(ResourceID(URI)))
 	{
-		if(const CGHeroInstance *h = adventureInt->curHero())
-			printCommandMessage(std::to_string(h->movement) + "; max: " + std::to_string(h->maxMovePoints(true)) + "/" + std::to_string(h->maxMovePoints(false)) + "\n");
+		const boost::filesystem::path outPath = VCMIDirs::get().userExtractedPath() / URI;
+
+		auto data = CResourceHandler::get()->load(ResourceID(URI))->readAll();
+
+		boost::filesystem::create_directories(outPath.parent_path());
+		boost::filesystem::ofstream outFile(outPath, boost::filesystem::ofstream::binary);
+		outFile.write((char*)data.first.get(), data.second);
 	}
-	else if(commandName == "bonuses")
+	else
+		printCommandMessage("File not found!", ELogLevel::ERROR);
+}
+
+void ClientCommandManager::handleBonusesCommand(std::istringstream & singleWordBuffer)
+{
+	if(currentCallFromIngameConsole)
 	{
-		bool jsonFormat = (message == "bonuses json");
-		auto format = [jsonFormat](const BonusList & b) -> std::string
-		{
-			if(jsonFormat)
-				return b.toJsonNode().toJson(true);
-			std::ostringstream ss;
-			ss << b;
-			return ss.str();
-		};
-		printCommandMessage("Bonuses of " + adventureInt->curArmy()->getObjectName() + "\n");
-		printCommandMessage(format(adventureInt->curArmy()->getBonusList()) + "\n");
-
-		printCommandMessage("\nInherited bonuses:\n");
-		TCNodes parents;
-		adventureInt->curArmy()->getParents(parents);
-		for(const CBonusSystemNode *parent : parents)
-		{
-			printCommandMessage(std::string("\nBonuses from ") + typeid(*parent).name() + "\n" + format(*parent->getAllBonuses(Selector::all, Selector::all)) + "\n");
-		}
+		printCommandMessage("Output for this command is too large for ingame chat! Please run it from client console.\n");
+		return;
 	}
-	else if(commandName == "not dialog")
+
+	std::string outputFormat;
+	singleWordBuffer >> outputFormat;
+
+	auto format = [outputFormat](const BonusList & b) -> std::string
 	{
-		LOCPLINT->showingDialog->setn(false);
-	}
-	else if(commandName == "gui")
+		if(outputFormat == "json")
+			return b.toJsonNode().toJson(true);
+
+		std::ostringstream ss;
+		ss << b;
+		return ss.str();
+	};
+	printCommandMessage("Bonuses of " + adventureInt->curArmy()->getObjectName() + "\n");
+	printCommandMessage(format(adventureInt->curArmy()->getBonusList()) + "\n");
+
+	printCommandMessage("\nInherited bonuses:\n");
+	TCNodes parents;
+	adventureInt->curArmy()->getParents(parents);
+	for(const CBonusSystemNode *parent : parents)
 	{
-		for(auto & child : GH.listInt)
-		{
-			const auto childPtr = child.get();
-			if(const CIntObject * obj = dynamic_cast<const CIntObject *>(childPtr))
-				printInfoAboutInterfaceObject(obj, 0);
-			else
-				printCommandMessage(std::string(typeid(childPtr).name()) + "\n");
-		}
+		printCommandMessage(std::string("\nBonuses from ") + typeid(*parent).name() + "\n" + format(*parent->getAllBonuses(Selector::all, Selector::all)) + "\n");
 	}
-	else if(commandName == "tell")
+}
+
+void ClientCommandManager::handleTellCommand(std::istringstream& singleWordBuffer)
+{
+	std::string what;
+	int id1, id2;
+	singleWordBuffer >> what >> id1 >> id2;
+
+	if(what == "hs")
 	{
-		std::string what;
-		int id1, id2;
-		singleWordBuffer >> what >> id1 >> id2;
-		if(what == "hs")
-		{
-			for(const CGHeroInstance *h : LOCPLINT->cb->getHeroesInfo())
-				if(h->type->getIndex() == id1)
-					if(const CArtifactInstance *a = h->getArt(ArtifactPosition(id2)))
-						printCommandMessage(a->nodeName());
-		}
+		for(const CGHeroInstance* h : LOCPLINT->cb->getHeroesInfo())
+			if(h->type->getIndex() == id1)
+				if(const CArtifactInstance* a = h->getArt(ArtifactPosition(id2)))
+					printCommandMessage(a->nodeName());
 	}
-	else if (commandName == "set")
-	{
-		std::string what, value;
-		singleWordBuffer >> what;
+}
 
-		Settings config = settings.write["session"][what];
+void ClientCommandManager::handleMpCommand()
+{
+	if(const CGHeroInstance* h = adventureInt->curHero())
+		printCommandMessage(std::to_string(h->movement) + "; max: " + std::to_string(h->maxMovePoints(true)) + "/" + std::to_string(h->maxMovePoints(false)) + "\n");
+}
 
-		singleWordBuffer >> value;
+void ClientCommandManager::handleSetCommand(std::istringstream& singleWordBuffer)
+{
+	std::string what, value;
+	singleWordBuffer >> what;
 
-		if (value == "on")
-		{
-			config->Bool() = true;
-			printCommandMessage("Option " + what + " enabled!", ELogLevel::INFO);
-		}
-		else if (value == "off")
-		{
-			config->Bool() = false;
-			printCommandMessage("Option " + what + " disabled!", ELogLevel::INFO);
-		}
-	}
-	else if(commandName == "unlock")
+	Settings config = settings.write["session"][what];
+
+	singleWordBuffer >> value;
+
+	if(value == "on")
 	{
-		std::string mxname;
-		singleWordBuffer >> mxname;
-		if(mxname == "pim" && LOCPLINT)
-			LOCPLINT->pim->unlock();
+		config->Bool() = true;
+		printCommandMessage("Option " + what + " enabled!", ELogLevel::INFO);
 	}
-	else if(commandName == "def2bmp")
+	else if(value == "off")
 	{
-		std::string URI;
-		singleWordBuffer >> URI;
-		std::unique_ptr<CAnimation> anim = std::make_unique<CAnimation>(URI);
-		anim->preload();
-		anim->exportBitmaps(VCMIDirs::get().userExtractedPath());
+		config->Bool() = false;
+		printCommandMessage("Option " + what + " disabled!", ELogLevel::INFO);
 	}
-	else if(commandName == "extract")
-	{
-		std::string URI;
-		singleWordBuffer >> URI;
+}
+
+void ClientCommandManager::handleUnlockCommand(std::istringstream& singleWordBuffer)
+{
+	std::string mxname;
+	singleWordBuffer >> mxname;
+	if(mxname == "pim" && LOCPLINT)
+		LOCPLINT->pim->unlock();
+}
 
 		if (CResourceHandler::get()->existsResource(ResourceID(URI)))
 		{
@@ -446,42 +508,9 @@ void ClientCommandManager::processCommand(const std::string &message, bool calle
 
 void ClientCommandManager::giveTurn(const PlayerColor &colorIdentifier)
 {
-	YourTurn yt;
-	yt.player = colorIdentifier;
-	yt.daysWithoutCastle = CSH->client->getPlayerState(colorIdentifier)->daysWithoutCastle;
-
-	ApplyClientNetPackVisitor visitor(*CSH->client, *CSH->client->gameState());
-	yt.visit(visitor);
-}
-
-void ClientCommandManager::printInfoAboutInterfaceObject(const CIntObject *obj, int level)
-{
-	std::stringstream sbuffer;
-	sbuffer << std::string(level, '\t');
-
-	sbuffer << typeid(*obj).name() << " *** ";
-	if (obj->active)
-	{
-#define PRINT(check, text) if (obj->active & CIntObject::check) sbuffer << text
-		PRINT(LCLICK, 'L');
-		PRINT(RCLICK, 'R');
-		PRINT(HOVER, 'H');
-		PRINT(MOVE, 'M');
-		PRINT(KEYBOARD, 'K');
-		PRINT(TIME, 'T');
-		PRINT(GENERAL, 'A');
-		PRINT(WHEEL, 'W');
-		PRINT(DOUBLECLICK, 'D');
-#undef  PRINT
-	}
-	else
-		sbuffer << "inactive";
-	sbuffer << " at " << obj->pos.x <<"x"<< obj->pos.y;
-	sbuffer << " (" << obj->pos.w <<"x"<< obj->pos.h << ")";
-	printCommandMessage(sbuffer.str(), ELogLevel::INFO);
-
-	for(const CIntObject *child : obj->children)
-		printInfoAboutInterfaceObject(child, level+1);
+	int* ptr = nullptr;
+	*ptr = 666;
+	//disaster!
 }
 
 void ClientCommandManager::printCommandMessage(const std::string &commandMessage, ELogLevel::ELogLevel messageType)
@@ -520,3 +549,128 @@ void ClientCommandManager::printCommandMessage(const std::string &commandMessage
 		}
 	}
 }
+
+void ClientCommandManager::printInfoAboutInterfaceObject(const CIntObject *obj, int level)
+{
+	std::stringstream sbuffer;
+	sbuffer << std::string(level, '\t');
+
+	sbuffer << typeid(*obj).name() << " *** ";
+	if (obj->active)
+	{
+#define PRINT(check, text) if (obj->active & CIntObject::check) sbuffer << text
+		PRINT(LCLICK, 'L');
+		PRINT(RCLICK, 'R');
+		PRINT(HOVER, 'H');
+		PRINT(MOVE, 'M');
+		PRINT(KEYBOARD, 'K');
+		PRINT(TIME, 'T');
+		PRINT(GENERAL, 'A');
+		PRINT(WHEEL, 'W');
+		PRINT(DOUBLECLICK, 'D');
+#undef  PRINT
+	}
+	else
+		sbuffer << "inactive";
+	sbuffer << " at " << obj->pos.x <<"x"<< obj->pos.y;
+	sbuffer << " (" << obj->pos.w <<"x"<< obj->pos.h << ")";
+	printCommandMessage(sbuffer.str(), ELogLevel::INFO);
+
+	for(const CIntObject *child : obj->children)
+		printInfoAboutInterfaceObject(child, level+1);
+}
+
+void ClientCommandManager::giveTurn(const PlayerColor &colorIdentifier)
+{
+	YourTurn yt;
+	yt.player = colorIdentifier;
+	yt.daysWithoutCastle = CSH->client->getPlayerState(colorIdentifier)->daysWithoutCastle;
+
+	ApplyClientNetPackVisitor visitor(*CSH->client, *CSH->client->gameState());
+	yt.visit(visitor);
+}
+
+void ClientCommandManager::processCommand(const std::string & message, bool calledFromIngameConsole)
+{
+	// split the message into individual words
+	std::istringstream singleWordBuffer;
+	singleWordBuffer.str(message);
+
+	// get command name, to be used for single word commands
+	std::string commandName;
+	singleWordBuffer >> commandName;
+
+	currentCallFromIngameConsole = calledFromIngameConsole;
+
+	if(message == std::string("die, fool"))
+		handleQuitCommand();
+
+	else if(commandName == "save")
+		handleSaveCommand(singleWordBuffer);
+
+	else if(commandName=="load")
+		handleLoadCommand(singleWordBuffer); // not implemented
+
+	else if(commandName == "gosolo")
+		handleGoSoloCommand();
+
+	else if(commandName == "autoskip")
+		handleAutoskipCommand();
+
+	else if(commandName == "controlai")
+		handleControlaiCommand(singleWordBuffer);
+
+	else if(commandName == "setBattleAI")
+		handleSetBattleAICommand(singleWordBuffer);
+
+	else if(commandName == "redraw")
+		handleRedrawCommand();
+
+	else if(commandName == "screen")
+		handleScreenCommand();
+
+	else if(commandName == "not dialog")
+		handleNotDialogCommand();
+
+	else if(commandName == "gui")
+		handleGuiCommand();
+
+	else if(message=="convert txt")
+		handleConvertTextCommand();
+
+	else if(message=="get config")
+		handleGetConfigCommand();
+
+	else if(message=="get scripts")
+		handleGetScriptsCommand();
+
+	else if(message=="get txt")
+		handleGetTextCommand();
+
+	else if(commandName == "def2bmp")
+		handleDef2bmpCommand(singleWordBuffer);
+
+	else if(commandName == "extract")
+		handleExtractCommand(singleWordBuffer);
+
+	else if(commandName == "bonuses")
+		handleBonusesCommand(singleWordBuffer);
+
+	else if(commandName == "tell")
+		handleTellCommand(singleWordBuffer);
+
+	else if(commandName == "mp" && adventureInt)
+		handleMpCommand();
+
+	else if (commandName == "set")
+		handleSetCommand(singleWordBuffer);
+
+	else if(commandName == "unlock")
+		handleUnlockCommand(singleWordBuffer);
+
+	else if(commandName == "crash")
+		handleCrashCommand();
+
+	else
+		printCommandMessage("Command not found :(", ELogLevel::ERROR);
+}

+ 76 - 6
client/ClientCommandManager.h

@@ -17,15 +17,85 @@ class CIntObject;
 
 class ClientCommandManager //take mantis #2292 issue about account if thinking about handling cheats from command-line
 {
-	bool currentCallFromIngameConsole = false;
+	bool currentCallFromIngameConsole = false; // commands can come from 2 sources: ingame console (chat) and client console
+	
+	// Quits the game (die, fool command)
+	void handleQuitCommand();
 
-	void giveTurn(const PlayerColor &color);
-	void printInfoAboutInterfaceObject(const CIntObject *obj, int level);
+	// Saves current game under the given filename
+	void handleSaveCommand(std::istringstream & singleWordBuffer);
+
+	// Loads a game with the given filename
+	void handleLoadCommand(std::istringstream & singleWordBuffer);
+
+	// AI takes over until the end of turn (unlike original H3 currently causes AI to take over until typed again)
+	void handleGoSoloCommand();
+
+	// Toggles autoskip mode on and off. In this mode, player turns are automatically skipped and only AI moves.
+	// However, GUI is still present and allows to observe AI moves. After this option is activated, you need to end first turn manually.
+	// Press [Shift] before your turn starts to not skip it.
+	void handleAutoskipCommand();
+
+	// Gives you control over specified AI player. If none is specified gives you control over all AI players
+	void handleControlaiCommand(std::istringstream& singleWordBuffer);
+
+	// Change battle AI used by neutral creatures to the one specified. Persists through game quit
+	void handleSetBattleAICommand(std::istringstream& singleWordBuffer);
+
+	// Redraw the current screen
+	void handleRedrawCommand();
+
+	// Prints information about current screen, and saves both screens as .bmp in root folder
+	void handleScreenCommand();
+
+	// Set the state indicating if dialog box is active to "no"
+	void handleNotDialogCommand();
+
+	// Displays tree view of currently present VCMI common GUI elements
+	void handleGuiCommand();
+
+	// Dumps all game text, maps text and campaign maps text into Client log between BEGIN TEXT EXPORT and END TEXT EXPORT
+	void handleConvertTextCommand();
+
+	// Saves current game configuration into extracted/configuration folder
+	void handleGetConfigCommand();
+
+	// Dumps all scripts in Extracted/Scripts
+	void handleGetScriptsCommand();
+
+	// Dumps all .txt files from DATA into Extracted/DATA
+	void handleGetTextCommand();
+
+	// Extract .def animation as BMP files
+	void handleDef2bmpCommand(std::istringstream& singleWordBuffer);
+
+	// Export file into Extracted directory
+	void handleExtractCommand(std::istringstream& singleWordBuffer);
+
+	// Print in console the current bonuses for curent army
+	void handleBonusesCommand(std::istringstream & singleWordBuffer);
+
+	// Get what artifact is present on artifact slot with specified ID for hero with specified ID
+	void handleTellCommand(std::istringstream& singleWordBuffer);
+
+	// Show current movement points, max movement points on land / max movement points on water.
+	void handleMpCommand();
+
+	// set <command> <on/off> - sets special temporary settings that reset on game quit.
+	void handleSetCommand(std::istringstream& singleWordBuffer);
+
+	// Unlocks specific mutex known in VCMI code as "pim"
+	void handleUnlockCommand(std::istringstream& singleWordBuffer);
+
+	// Crashes the game forcing an exception
+	void handleCrashCommand();
+
+	// Prints in Chat the given message
 	void printCommandMessage(const std::string &commandMessage, ELogLevel::ELogLevel messageType = ELogLevel::NOT_SET);
-	void handleGoSolo();
-	void handleControlAi(const std::string &colorName);
+	void printInfoAboutInterfaceObject(const CIntObject *obj, int level);
+	void giveTurn(const PlayerColor &color);
 
 public:
 	ClientCommandManager() = default;
-	void processCommand(const std::string &message, bool calledFromIngameConsole);
+	void processCommand(const std::string & message, bool calledFromIngameConsole);
 };