| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | #include "UnvirtContext.hpp"
 | 
					
						
							| 
									
										
										
										
											2023-09-12 17:03:06 +08:00
										 |  |  | #include <CK2/MgrImpls/CKPathManager.hpp>
 | 
					
						
							| 
									
										
										
										
											2023-08-31 12:37:23 +08:00
										 |  |  | #include <cstdarg>
 | 
					
						
							| 
									
										
										
										
											2023-10-28 18:17:53 +08:00
										 |  |  | #include <regex>
 | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace Unvirt::Context { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma region UnvirtContext Misc
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	UnvirtContext::UnvirtContext() : | 
					
						
							|  |  |  | 		m_Root(), m_Splitter(), m_Help(nullptr), | 
					
						
							| 
									
										
										
										
											2023-10-28 18:17:53 +08:00
										 |  |  | 		m_PageLen(10u), m_ListStyleIsFull(true), m_OrderExit(false), | 
					
						
							|  |  |  | 		m_SearchPart(SearchPart::None), m_SearchIdxResult(), | 
					
						
							| 
									
										
										
										
											2023-09-30 14:24:37 +08:00
										 |  |  | 		m_Ctx(nullptr), m_FileReader(nullptr), m_IsShallowRead(true) { | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// create command root
 | 
					
						
							|  |  |  | 		CmdHelper::CommandRoot* root = &m_Root; | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 		root | 
					
						
							|  |  |  | 		->Then((new CmdHelper::Literal("load")) | 
					
						
							|  |  |  | 			->Then((new CmdHelper::Choice("stage", { "deep", "shallow"})) | 
					
						
							|  |  |  | 				->Comment("The stage of loading. 'deep' will load to CKObject stage. 'shallow' will load to CKStateChunk stage.") | 
					
						
							|  |  |  | 				->Then((new CmdHelper::StringArgument("filepath")) | 
					
						
							|  |  |  | 					->Comment("The path to loading file.") | 
					
						
							|  |  |  | 					->Executes( | 
					
						
							|  |  |  | 						std::bind(&UnvirtContext::ProcLoad, this, std::placeholders::_1), | 
					
						
							| 
									
										
										
										
											2023-09-12 17:03:06 +08:00
										 |  |  | 						"Load a Virtools composition." | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 					) | 
					
						
							|  |  |  | 				) | 
					
						
							|  |  |  | 			) | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 		->Then((new CmdHelper::Literal("unload")) | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 			->Executes( | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 				std::bind(&UnvirtContext::ProcUnLoad, this, std::placeholders::_1), | 
					
						
							|  |  |  | 				"Release loaded Virtools composition." | 
					
						
							|  |  |  | 			) | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		) | 
					
						
							| 
									
										
										
										
											2023-08-28 22:20:46 +08:00
										 |  |  | 		->Then((new CmdHelper::Literal("save")) | 
					
						
							|  |  |  | 			->Then((new CmdHelper::StringArgument("filepath")) | 
					
						
							|  |  |  | 				->Comment("The path to save file.") | 
					
						
							|  |  |  | 				->Executes( | 
					
						
							|  |  |  | 					std::bind(&UnvirtContext::ProcSave, this, std::placeholders::_1), | 
					
						
							|  |  |  | 					"Save the loaded file into a new file." | 
					
						
							|  |  |  | 				) | 
					
						
							|  |  |  | 			) | 
					
						
							|  |  |  | 		) | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 		->Then((new CmdHelper::Literal("info")) | 
					
						
							|  |  |  | 			->Executes( | 
					
						
							|  |  |  | 				std::bind(&UnvirtContext::ProcInfo, this, std::placeholders::_1), | 
					
						
							|  |  |  | 				"Show the header info of loaded Virtools composition." | 
					
						
							|  |  |  | 			) | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		) | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 		->Then((new CmdHelper::Literal("ls")) | 
					
						
							| 
									
										
										
										
											2023-10-28 18:17:53 +08:00
										 |  |  | 			->Then((new CmdHelper::Choice("part", { "obj", "mgr", "search"})) | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 				->Comment("Which list you want to list.") | 
					
						
							|  |  |  | 				->Then((new CmdHelper::IntArgument("page", [](int32_t v) -> bool { return v > 0; })) | 
					
						
							|  |  |  | 					->Comment("The page index. Start with 1.") | 
					
						
							|  |  |  | 					->Executes( | 
					
						
							|  |  |  | 						std::bind(&UnvirtContext::ProcLs, this, std::placeholders::_1), | 
					
						
							|  |  |  | 						"List something about loaded Virtools composition." | 
					
						
							|  |  |  | 					) | 
					
						
							|  |  |  | 				) | 
					
						
							|  |  |  | 			) | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		) | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 		->Then((new CmdHelper::Literal("data")) | 
					
						
							|  |  |  | 			->Then((new CmdHelper::Choice("part", { "obj", "mgr"})) | 
					
						
							|  |  |  | 				->Comment("Which list you want to show data.") | 
					
						
							|  |  |  | 				->Then((new CmdHelper::IntArgument("index", [](int32_t v) -> bool { return v >= 0; })) | 
					
						
							|  |  |  | 					->Comment("The index. Start with 0.") | 
					
						
							|  |  |  | 					->Executes( | 
					
						
							|  |  |  | 						std::bind(&UnvirtContext::ProcData, this, std::placeholders::_1), | 
					
						
							|  |  |  | 						"Show the specific CKObject / CKBaseManager data." | 
					
						
							|  |  |  | 					) | 
					
						
							|  |  |  | 				) | 
					
						
							|  |  |  | 			) | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		) | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 		->Then((new CmdHelper::Literal("chunk")) | 
					
						
							|  |  |  | 			->Then((new CmdHelper::Choice("part", { "obj", "mgr"})) | 
					
						
							|  |  |  | 				->Comment("Which list you want to show chunk.") | 
					
						
							|  |  |  | 				->Then((new CmdHelper::IntArgument("index", [](int32_t v) -> bool { return v >= 0; })) | 
					
						
							|  |  |  | 					->Comment("The index. Start with 0.") | 
					
						
							|  |  |  | 					->Executes( | 
					
						
							|  |  |  | 						std::bind(&UnvirtContext::ProcChunk, this, std::placeholders::_1), | 
					
						
							|  |  |  | 						"Show the specific CKStateChunk data." | 
					
						
							|  |  |  | 					) | 
					
						
							|  |  |  | 				) | 
					
						
							|  |  |  | 			) | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		) | 
					
						
							| 
									
										
										
										
											2023-10-28 18:17:53 +08:00
										 |  |  | 		->Then((new CmdHelper::Literal("search")) | 
					
						
							|  |  |  | 			->Then((new CmdHelper::Choice("part", { "obj", "mgr"})) | 
					
						
							|  |  |  | 				->Comment("Which list you want to search.") | 
					
						
							|  |  |  | 				->Then((new CmdHelper::Choice("mode", { "plain", "re"})) | 
					
						
							|  |  |  | 					->Comment("The search mode. `plain` will search by substring and `re` will do regex search.") | 
					
						
							|  |  |  | 					->Then((new CmdHelper::StringArgument("text")) | 
					
						
							|  |  |  | 						->Comment("The text or regex to search.") | 
					
						
							|  |  |  | 						->Executes( | 
					
						
							|  |  |  | 							std::bind(&UnvirtContext::ProcSearch, this, std::placeholders::_1), | 
					
						
							|  |  |  | 							"Search object or manager by text or regex. Please note that the regex have limited UTF8 support and may cause undefined behavior." | 
					
						
							|  |  |  | 						) | 
					
						
							|  |  |  | 					) | 
					
						
							|  |  |  | 				) | 
					
						
							|  |  |  | 			) | 
					
						
							|  |  |  | 		) | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 		->Then((new CmdHelper::Literal("items")) | 
					
						
							|  |  |  | 			->Then((new CmdHelper::IntArgument("count", [](int32_t v) -> bool { return v > 0; })) | 
					
						
							|  |  |  | 				->Comment("The count of items you want to show in one page.") | 
					
						
							|  |  |  | 				->Executes( | 
					
						
							|  |  |  | 					std::bind(&UnvirtContext::ProcItems, this, std::placeholders::_1), | 
					
						
							|  |  |  | 					"Set up how many items should be listed in one page when using 'ls' command." | 
					
						
							|  |  |  | 				) | 
					
						
							|  |  |  | 			) | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		) | 
					
						
							| 
									
										
										
										
											2023-10-28 18:17:53 +08:00
										 |  |  | 		->Then((new CmdHelper::Literal("style")) | 
					
						
							|  |  |  | 			->Then((new CmdHelper::Choice("level", { "full", "simple"})) | 
					
						
							|  |  |  | 				->Comment("The amount of showen content.") | 
					
						
							|  |  |  | 				->Executes( | 
					
						
							|  |  |  | 					std::bind(&UnvirtContext::ProcStyle, this, std::placeholders::_1), | 
					
						
							|  |  |  | 					"Change the detail level of showen data in `ls` command." | 
					
						
							|  |  |  | 				) | 
					
						
							|  |  |  | 			) | 
					
						
							|  |  |  | 		) | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 		->Then((new CmdHelper::Literal("encoding")) | 
					
						
							|  |  |  | 			->Then((new CmdHelper::EncodingArgument("enc")) | 
					
						
							|  |  |  | 				->Comment("CKContext used encoding splitted by ','. Support mutiple encoding.") | 
					
						
							|  |  |  | 				->Executes( | 
					
						
							|  |  |  | 					std::bind(&UnvirtContext::ProcEncoding, this, std::placeholders::_1), | 
					
						
							|  |  |  | 					"Set the encoding series for CKContext." | 
					
						
							|  |  |  | 				) | 
					
						
							|  |  |  | 			) | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 		) | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 		->Then((new CmdHelper::Literal("temp")) | 
					
						
							|  |  |  | 			->Then((new CmdHelper::StringArgument("temppath")) | 
					
						
							|  |  |  | 				->Comment("The path to Temp folder.") | 
					
						
							|  |  |  | 				->Executes( | 
					
						
							|  |  |  | 					std::bind(&UnvirtContext::ProcTemp, this, std::placeholders::_1), | 
					
						
							|  |  |  | 					"Set the Temp path for CKContext." | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 				) | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 			) | 
					
						
							|  |  |  | 		) | 
					
						
							| 
									
										
										
										
											2023-09-12 17:03:06 +08:00
										 |  |  | 		->Then((new CmdHelper::Literal("rsc")) | 
					
						
							|  |  |  | 			->Then((new CmdHelper::Literal("clear")) | 
					
						
							|  |  |  | 				->Executes( | 
					
						
							|  |  |  | 					std::bind(&UnvirtContext::ProcRsc, this, std::placeholders::_1, true), | 
					
						
							|  |  |  | 					"Clear all data resources paths." | 
					
						
							|  |  |  | 				) | 
					
						
							|  |  |  | 			) | 
					
						
							|  |  |  | 			->Then((new CmdHelper::Literal("add")) | 
					
						
							|  |  |  | 				->Then((new CmdHelper::StringArgument("datares")) | 
					
						
							|  |  |  | 					->Comment("The data resources path .") | 
					
						
							|  |  |  | 					->Executes( | 
					
						
							|  |  |  | 						std::bind(&UnvirtContext::ProcRsc, this, std::placeholders::_1, false), | 
					
						
							|  |  |  | 						"Add a path to let Virtools find resources." | 
					
						
							|  |  |  | 					) | 
					
						
							|  |  |  | 				) | 
					
						
							|  |  |  | 			) | 
					
						
							|  |  |  | 		) | 
					
						
							| 
									
										
										
										
											2023-09-20 20:44:03 +08:00
										 |  |  | 		->Then((new CmdHelper::Literal("test")) | 
					
						
							|  |  |  | 			->Executes( | 
					
						
							|  |  |  | 				std::bind(&UnvirtContext::ProcTest, this, std::placeholders::_1), | 
					
						
							|  |  |  | 				"Call custom debugging function (only available in Debug mode)." | 
					
						
							|  |  |  | 			) | 
					
						
							|  |  |  | 		) | 
					
						
							| 
									
										
										
										
											2023-08-27 22:14:02 +08:00
										 |  |  | 		->Then((new CmdHelper::Literal("help")) | 
					
						
							|  |  |  | 			->Executes( | 
					
						
							|  |  |  | 				std::bind(&UnvirtContext::ProcHelp, this, std::placeholders::_1), | 
					
						
							|  |  |  | 				"Output this help page." | 
					
						
							|  |  |  | 			) | 
					
						
							|  |  |  | 		) | 
					
						
							| 
									
										
										
										
											2023-08-27 16:51:18 +08:00
										 |  |  | 		->Then((new CmdHelper::Literal("exit")) | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 			->Executes( | 
					
						
							|  |  |  | 				std::bind(&UnvirtContext::ProcExit, this, std::placeholders::_1), | 
					
						
							|  |  |  | 				"Exit program." | 
					
						
							|  |  |  | 			) | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 		// create help
 | 
					
						
							|  |  |  | 		m_Help = root->RootHelp(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// create context
 | 
					
						
							| 
									
										
										
										
											2023-09-01 12:19:06 +08:00
										 |  |  | 		LibCmo::CK2::CKStartUp(); | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 		m_Ctx = new LibCmo::CK2::CKContext(); | 
					
						
							|  |  |  | 		m_Ctx->SetOutputCallback(std::bind(&UnvirtContext::PrintContextMsg, this, std::placeholders::_1)); | 
					
						
							| 
									
										
										
										
											2023-10-02 17:45:59 +08:00
										 |  |  | 		m_Ctx->SetGlobalImagesSaveOptions(LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS::CKTEXTURE_EXTERNAL); | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	UnvirtContext::~UnvirtContext() { | 
					
						
							|  |  |  | 		if (m_Help != nullptr) | 
					
						
							|  |  |  | 			delete m_Help; | 
					
						
							| 
									
										
										
										
											2023-09-01 12:19:06 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// free context
 | 
					
						
							|  |  |  | 		ClearDocument(); | 
					
						
							|  |  |  | 		delete m_Ctx; | 
					
						
							|  |  |  | 		LibCmo::CK2::CKShutdown(); | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bool UnvirtContext::HasOpenedFile() { | 
					
						
							|  |  |  | 		return m_FileReader != nullptr; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	void UnvirtContext::ClearDocument() { | 
					
						
							|  |  |  | 		if (m_FileReader == nullptr) return; | 
					
						
							| 
									
										
										
										
											2023-10-28 18:17:53 +08:00
										 |  |  | 		// clear search result
 | 
					
						
							|  |  |  | 		m_SearchPart = SearchPart::None; | 
					
						
							|  |  |  | 		m_SearchIdxResult.clear(); | 
					
						
							| 
									
										
										
										
											2023-08-27 22:14:02 +08:00
										 |  |  | 		// delete reader
 | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		delete m_FileReader; | 
					
						
							|  |  |  | 		m_FileReader = nullptr; | 
					
						
							| 
									
										
										
										
											2023-09-30 14:24:37 +08:00
										 |  |  | 		m_IsShallowRead = true; | 
					
						
							| 
									
										
										
										
											2023-08-27 22:14:02 +08:00
										 |  |  | 		// clear context
 | 
					
						
							| 
									
										
										
										
											2023-09-12 17:03:06 +08:00
										 |  |  | 		m_Ctx->ClearAll(); | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-17 10:38:46 +08:00
										 |  |  | 	void UnvirtContext::PrintContextMsg(LibCmo::CKSTRING msg) { | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		if (msg != nullptr) { | 
					
						
							| 
									
										
										
										
											2023-08-27 22:14:02 +08:00
										 |  |  | 			fprintf(stdout, UNVIRT_TERMCOL_LIGHT_YELLOW(("[CKContext] ")) "%s\n", msg); | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-10-28 18:17:53 +08:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	void UnvirtContext::PrintCommonInfo(const char* u8_fmt, ...) { | 
					
						
							|  |  |  | 		va_list argptr; | 
					
						
							|  |  |  | 		va_start(argptr, u8_fmt); | 
					
						
							|  |  |  | 		std::vfprintf(stdout, u8_fmt, argptr); | 
					
						
							|  |  |  | 		va_end(argptr); | 
					
						
							|  |  |  | 		std::fputc('\n', stdout); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	void UnvirtContext::PrintCommonError(const char* u8_fmt, ...) { | 
					
						
							|  |  |  | 		va_list argptr; | 
					
						
							|  |  |  | 		va_start(argptr, u8_fmt); | 
					
						
							| 
									
										
										
										
											2023-08-27 22:14:02 +08:00
										 |  |  | 		std::fputs(UNVIRT_TERMCOLHDR_LIGHT_RED, stdout); | 
					
						
							|  |  |  | 		std::vfprintf(stdout, u8_fmt, argptr); | 
					
						
							|  |  |  | 		std::fputs(UNVIRT_TERMCOLTAIL, stdout); | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		va_end(argptr); | 
					
						
							| 
									
										
										
										
											2023-08-27 22:14:02 +08:00
										 |  |  | 		std::fputc('\n', stdout); | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma endregion
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma region Main Run
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	void UnvirtContext::Run() { | 
					
						
							|  |  |  | 		Unvirt::TerminalHelper::EnsureTerminalColor(); | 
					
						
							|  |  |  | 		Unvirt::TerminalHelper::EnsureTerminalEncoding(); | 
					
						
							|  |  |  | 		std::string u8cmd; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		while (true) { | 
					
						
							|  |  |  | 			// get command
 | 
					
						
							|  |  |  | 			TerminalHelper::GetCmdLine(u8cmd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// split cmd and parse it
 | 
					
						
							|  |  |  | 			auto cmds = m_Splitter.Convert(u8cmd); | 
					
						
							| 
									
										
										
										
											2023-09-20 15:25:43 +08:00
										 |  |  | 			if (cmds.empty()) continue; | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// get sub command
 | 
					
						
							|  |  |  | 			if (!m_Root.RootConsume(cmds)) { | 
					
						
							| 
									
										
										
										
											2023-08-27 22:14:02 +08:00
										 |  |  | 				this->PrintCommonError("Syntax error \"%s\".\nType 'help' for usage.", u8cmd.c_str()); | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (m_OrderExit) { | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma endregion
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma region Proc Detail
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 	void UnvirtContext::ProcLoad(const CmdHelper::ArgumentsMap* amap) { | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		// check pre-requirement
 | 
					
						
							|  |  |  | 		if (HasOpenedFile()) { | 
					
						
							| 
									
										
										
										
											2023-08-27 22:14:02 +08:00
										 |  |  | 			PrintCommonError("Already have a opened file. Close it before calling 'load'."); | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 		std::string filepath = *amap->Get<CmdHelper::StringArgument::vType>("filepath"); | 
					
						
							|  |  |  | 		bool is_deep = *amap->Get<CmdHelper::Choice::vType>("stage") == 0; | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// proc
 | 
					
						
							|  |  |  | 		m_FileReader = new LibCmo::CK2::CKFileReader(m_Ctx); | 
					
						
							|  |  |  | 		LibCmo::CK2::CKERROR err; | 
					
						
							|  |  |  | 		if (is_deep) { | 
					
						
							|  |  |  | 			err = m_FileReader->DeepLoad(filepath.c_str()); | 
					
						
							| 
									
										
										
										
											2023-09-30 14:24:37 +08:00
										 |  |  | 			m_IsShallowRead = false; | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			err = m_FileReader->ShallowLoad(filepath.c_str()); | 
					
						
							| 
									
										
										
										
											2023-09-30 14:24:37 +08:00
										 |  |  | 			m_IsShallowRead = true; | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if (err != LibCmo::CK2::CKERROR::CKERR_OK) { | 
					
						
							|  |  |  | 			// fail to load. release all.
 | 
					
						
							| 
									
										
										
										
											2023-08-28 22:20:46 +08:00
										 |  |  | 			PrintCommonError("Fail to load file. Function return: %s\n\t%s", | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 				Unvirt::AccessibleValue::GetCkErrorName(err).c_str(), | 
					
						
							|  |  |  | 				Unvirt::AccessibleValue::GetCkErrorDescription(err).c_str() | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			ClearDocument(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 	void UnvirtContext::ProcUnLoad(const CmdHelper::ArgumentsMap*) { | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		// check pre-requirement
 | 
					
						
							|  |  |  | 		if (!HasOpenedFile()) { | 
					
						
							|  |  |  | 			this->PrintCommonError("No loaded file."); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// free all
 | 
					
						
							|  |  |  | 		ClearDocument(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-28 22:20:46 +08:00
										 |  |  | 	void Unvirt::Context::UnvirtContext::ProcSave(const CmdHelper::ArgumentsMap* amap) { | 
					
						
							|  |  |  | 		// check pre-requirement
 | 
					
						
							|  |  |  | 		if (!HasOpenedFile()) { | 
					
						
							|  |  |  | 			PrintCommonError("No loaded file."); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		std::string filepath = *amap->Get<CmdHelper::StringArgument::vType>("filepath"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// construct writer from reader
 | 
					
						
							| 
									
										
										
										
											2023-09-30 14:24:37 +08:00
										 |  |  | 		LibCmo::CK2::CKFileWriter writer(m_Ctx, m_FileReader, m_IsShallowRead); | 
					
						
							| 
									
										
										
										
											2023-08-28 22:20:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// backup current file write mode
 | 
					
						
							|  |  |  | 		// and replace it with reader
 | 
					
						
							|  |  |  | 		LibCmo::CK2::CK_FILE_WRITEMODE backup = m_Ctx->GetFileWriteMode(); | 
					
						
							|  |  |  | 		m_Ctx->SetFileWriteMode(m_FileReader->GetFileInfo().FileWriteMode); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// run writer
 | 
					
						
							|  |  |  | 		LibCmo::CK2::CKERROR err = writer.Save(filepath.c_str()); | 
					
						
							|  |  |  | 		if (err != LibCmo::CK2::CKERROR::CKERR_OK) { | 
					
						
							|  |  |  | 			// fail to load. release all.
 | 
					
						
							|  |  |  | 			PrintCommonError("Fail to save file. Function return: %s\n\t%s", | 
					
						
							|  |  |  | 				Unvirt::AccessibleValue::GetCkErrorName(err).c_str(), | 
					
						
							|  |  |  | 				Unvirt::AccessibleValue::GetCkErrorDescription(err).c_str() | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// restore file write mode
 | 
					
						
							|  |  |  | 		m_Ctx->SetFileWriteMode(backup); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 	void UnvirtContext::ProcInfo(const CmdHelper::ArgumentsMap*) { | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		// check pre-requirement
 | 
					
						
							|  |  |  | 		if (!HasOpenedFile()) { | 
					
						
							|  |  |  | 			PrintCommonError("No loaded file."); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// print
 | 
					
						
							|  |  |  | 		Unvirt::StructFormatter::PrintCKFileInfo(m_FileReader->GetFileInfo()); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 	void UnvirtContext::ProcLs(const CmdHelper::ArgumentsMap* amap) { | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		// check pre-requirement
 | 
					
						
							|  |  |  | 		if (!HasOpenedFile()) { | 
					
						
							| 
									
										
										
										
											2023-08-27 22:14:02 +08:00
										 |  |  | 			PrintCommonError("No loaded file."); | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-28 18:17:53 +08:00
										 |  |  | 		// get 0 based page (-1)
 | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 		size_t page = *amap->Get<CmdHelper::IntArgument::vType>("page") - 1; | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// show list
 | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 		switch (*amap->Get<CmdHelper::Choice::vType>("part")) { | 
					
						
							|  |  |  | 			case 0: | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 			{ | 
					
						
							|  |  |  | 				// obj list
 | 
					
						
							| 
									
										
										
										
											2023-10-28 18:17:53 +08:00
										 |  |  | 				Unvirt::StructFormatter::PrintObjectList( | 
					
						
							|  |  |  | 					m_FileReader->GetFileObjects(),  | 
					
						
							|  |  |  | 					m_FileReader->GetFileInfo(),  | 
					
						
							|  |  |  | 					page, this->m_PageLen, | 
					
						
							|  |  |  | 					m_ListStyleIsFull | 
					
						
							|  |  |  | 				); | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 			case 1: | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 			{ | 
					
						
							|  |  |  | 				// mgr list
 | 
					
						
							| 
									
										
										
										
											2023-10-28 18:17:53 +08:00
										 |  |  | 				Unvirt::StructFormatter::PrintManagerList( | 
					
						
							|  |  |  | 					m_FileReader->GetManagersData(),  | 
					
						
							|  |  |  | 					page, this->m_PageLen, | 
					
						
							|  |  |  | 					m_ListStyleIsFull | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			case 2: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				// search list
 | 
					
						
							|  |  |  | 				switch (m_SearchPart) { | 
					
						
							|  |  |  | 					case SearchPart::None: | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						PrintCommonError("No search result to list."); | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					case SearchPart::Object: | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						Unvirt::StructFormatter::PrintSearchedObjectList( | 
					
						
							|  |  |  | 							m_SearchIdxResult, | 
					
						
							|  |  |  | 							m_FileReader->GetFileObjects(), | 
					
						
							|  |  |  | 							m_FileReader->GetFileInfo(), | 
					
						
							|  |  |  | 							page, this->m_PageLen, | 
					
						
							|  |  |  | 							m_ListStyleIsFull | 
					
						
							|  |  |  | 						); | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					case SearchPart::Manager: | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						Unvirt::StructFormatter::PrintSearchedManagerList( | 
					
						
							|  |  |  | 							m_SearchIdxResult, | 
					
						
							|  |  |  | 							m_FileReader->GetManagersData(), | 
					
						
							|  |  |  | 							page, this->m_PageLen, | 
					
						
							|  |  |  | 							m_ListStyleIsFull | 
					
						
							|  |  |  | 						); | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 	void UnvirtContext::ProcData( const CmdHelper::ArgumentsMap* amap) { | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 		// check pre-requirement
 | 
					
						
							|  |  |  | 		if (!HasOpenedFile()) { | 
					
						
							| 
									
										
										
										
											2023-08-27 22:14:02 +08:00
										 |  |  | 			PrintCommonError("No loaded file."); | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 		// get index
 | 
					
						
							|  |  |  | 		size_t index = *amap->Get<CmdHelper::IntArgument::vType>("index"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// show data
 | 
					
						
							|  |  |  | 		switch (*amap->Get<CmdHelper::Choice::vType>("part")) { | 
					
						
							|  |  |  | 			case 0: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				if (index >= m_FileReader->GetFileObjects().size()) { | 
					
						
							|  |  |  | 					PrintCommonError("Index out of range."); | 
					
						
							|  |  |  | 					return; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				Unvirt::StructFormatter::PrintCKObject(m_FileReader->GetFileObjects()[index].ObjPtr); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			case 1: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				if (index >= m_FileReader->GetManagersData().size()) { | 
					
						
							|  |  |  | 					PrintCommonError("Index out of range."); | 
					
						
							|  |  |  | 					return; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2023-10-28 18:17:53 +08:00
										 |  |  | 				// todo: finish manager display
 | 
					
						
							|  |  |  | 				PrintCommonError("Not supported now."); | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 				//Unvirt::StructFormatter::PrintCKBaseManager(m_FileReader->GetManagersData()[index].Data);
 | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 	void UnvirtContext::ProcChunk(const CmdHelper::ArgumentsMap* amap) { | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 		// check pre-requirement
 | 
					
						
							|  |  |  | 		if (!HasOpenedFile()) { | 
					
						
							| 
									
										
										
										
											2023-08-27 22:14:02 +08:00
										 |  |  | 			PrintCommonError("No loaded file."); | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 		// get index
 | 
					
						
							|  |  |  | 		size_t index = *amap->Get<CmdHelper::IntArgument::vType>("index"); | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 		// show data
 | 
					
						
							|  |  |  | 		switch (*amap->Get<CmdHelper::Choice::vType>("part")) { | 
					
						
							|  |  |  | 			case 0: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				if (index >= m_FileReader->GetFileObjects().size()) { | 
					
						
							|  |  |  | 					PrintCommonError("Index out of range."); | 
					
						
							|  |  |  | 					return; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				Unvirt::StructFormatter::PrintCKStateChunk(m_FileReader->GetFileObjects()[index].Data); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			case 1: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				if (index >= m_FileReader->GetManagersData().size()) { | 
					
						
							|  |  |  | 					PrintCommonError("Index out of range."); | 
					
						
							|  |  |  | 					return; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				Unvirt::StructFormatter::PrintCKStateChunk(m_FileReader->GetManagersData()[index].Data); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-28 18:17:53 +08:00
										 |  |  | 	void UnvirtContext::ProcSearch(const CmdHelper::ArgumentsMap* amap) { | 
					
						
							|  |  |  | 		// check pre-requirement
 | 
					
						
							|  |  |  | 		if (!HasOpenedFile()) { | 
					
						
							|  |  |  | 			PrintCommonError("No loaded file."); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// get search text
 | 
					
						
							|  |  |  | 		std::string search_text(*amap->Get<CmdHelper::StringArgument::vType>("text")); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 		// analyse search mode
 | 
					
						
							|  |  |  | 		std::function<bool(const LibCmo::XContainer::XString&)> search_fct = [](const LibCmo::XContainer::XString&) -> bool { return false; }; | 
					
						
							|  |  |  | 		switch (*amap->Get<CmdHelper::Choice::vType>("mode")) { | 
					
						
							|  |  |  | 			case 0: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				// plain mode
 | 
					
						
							|  |  |  | 				search_fct = [&search_text](const LibCmo::XContainer::XString& cmp) -> bool { | 
					
						
							|  |  |  | 					return cmp.find(search_text) != std::string::npos; | 
					
						
							|  |  |  | 				}; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			case 1: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				// regex mode
 | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				// try construct regex
 | 
					
						
							|  |  |  | 				std::regex re; | 
					
						
							|  |  |  | 				try { | 
					
						
							|  |  |  | 					re = std::regex(search_text, std::regex_constants::ECMAScript); | 
					
						
							|  |  |  | 				} catch (const std::regex_error& e) { | 
					
						
							|  |  |  | 					PrintCommonError("Invalid regular expressions: %s", e.what()); | 
					
						
							|  |  |  | 					return; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// use copy ctor capture to input regex
 | 
					
						
							|  |  |  | 				// because re will be freed when exiting this switch.
 | 
					
						
							|  |  |  | 				search_fct = [re](const LibCmo::XContainer::XString& cmp) -> bool { | 
					
						
							|  |  |  | 					return std::regex_search(cmp, re); | 
					
						
							|  |  |  | 				}; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// start search
 | 
					
						
							|  |  |  | 		switch (*amap->Get<CmdHelper::Choice::vType>("part")) { | 
					
						
							|  |  |  | 			case 0: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				// object
 | 
					
						
							|  |  |  | 				m_SearchPart = SearchPart::Object; | 
					
						
							|  |  |  | 				m_SearchIdxResult.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				size_t counter = 0; | 
					
						
							|  |  |  | 				for (const auto& obj : m_FileReader->GetFileObjects()) { | 
					
						
							|  |  |  | 					if (search_fct(obj.Name)) { | 
					
						
							|  |  |  | 						m_SearchIdxResult.emplace_back(counter); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					++counter; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			case 1: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				// manager
 | 
					
						
							|  |  |  | 				m_SearchPart = SearchPart::Manager; | 
					
						
							|  |  |  | 				m_SearchIdxResult.clear(); | 
					
						
							|  |  |  | 				PrintCommonError("Not supported now."); | 
					
						
							|  |  |  | 				// todo: remove this return when fixing manager searching.
 | 
					
						
							|  |  |  | 				return; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// report search result
 | 
					
						
							|  |  |  | 		if (m_SearchIdxResult.empty()) { | 
					
						
							|  |  |  | 			PrintCommonInfo("Search done, but no result."); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			PrintCommonInfo("Search done with %" PRIuSIZET " results. Use `ls search` to check them.", m_SearchIdxResult.size()); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 	void UnvirtContext::ProcItems(const CmdHelper::ArgumentsMap* amap) { | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		// assign
 | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 		m_PageLen = *amap->Get<CmdHelper::IntArgument::vType>("count"); | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-28 18:17:53 +08:00
										 |  |  | 	void UnvirtContext::ProcStyle(const CmdHelper::ArgumentsMap* amap) { | 
					
						
							|  |  |  | 		// set list style level
 | 
					
						
							|  |  |  | 		switch (*amap->Get<CmdHelper::Choice::vType>("level")) { | 
					
						
							|  |  |  | 			case 0: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				// full level
 | 
					
						
							|  |  |  | 				m_ListStyleIsFull = true; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			case 1: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				// simple level
 | 
					
						
							|  |  |  | 				m_ListStyleIsFull = false; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 	void UnvirtContext::ProcEncoding(const CmdHelper::ArgumentsMap* amap) { | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 		const auto& encodings = *amap->Get<CmdHelper::EncodingArgument::vType>("enc"); | 
					
						
							|  |  |  | 		m_Ctx->SetEncoding(encodings); | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 14:21:44 +08:00
										 |  |  | 	void UnvirtContext::ProcTemp(const CmdHelper::ArgumentsMap* amap) { | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		// assign
 | 
					
						
							| 
									
										
										
										
											2023-09-12 17:03:06 +08:00
										 |  |  | 		if (!m_Ctx->GetPathManager()->SetTempFolder(amap->Get<CmdHelper::StringArgument::vType>("temppath")->c_str())) { | 
					
						
							|  |  |  | 			PrintCommonError("Set temp folder failed. Check your path first."); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	void Unvirt::Context::UnvirtContext::ProcRsc(const CmdHelper::ArgumentsMap* amap, bool isClear) { | 
					
						
							|  |  |  | 		if (isClear) { | 
					
						
							|  |  |  | 			m_Ctx->GetPathManager()->ClearPath(); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			if (!m_Ctx->GetPathManager()->AddPath(amap->Get<CmdHelper::StringArgument::vType>("datares")->c_str())) { | 
					
						
							|  |  |  | 				PrintCommonError("Set data resource folder failed. Check your path first."); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-20 20:44:03 +08:00
										 |  |  | 	void Unvirt::Context::UnvirtContext::ProcTest(const CmdHelper::ArgumentsMap* amap) { | 
					
						
							|  |  |  | #if defined(LIBCMO_BUILD_DEBUG)
 | 
					
						
							|  |  |  | 		// MARK: Add the debug code here.
 | 
					
						
							| 
									
										
										
										
											2023-10-29 10:27:35 +08:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		// todo: temporaryly write Transparent Column Fixer code.
 | 
					
						
							|  |  |  | 		// move to independent app in future.
 | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		// check pre-requirement
 | 
					
						
							|  |  |  | 		if (!HasOpenedFile()) { | 
					
						
							|  |  |  | 			PrintCommonError("No loaded file."); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (!m_IsShallowRead) { | 
					
						
							|  |  |  | 			PrintCommonError("Transparent Column Fixer only accept shallow loaded file."); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// iterate objects
 | 
					
						
							|  |  |  | 		LibCmo::CKDWORD expcode = static_cast<LibCmo::CKDWORD>(LibCmo::CK2::CK_STATESAVEFLAGS_TEXTURE::CK_STATESAVE_TEXONLY); | 
					
						
							|  |  |  | 		LibCmo::CKDWORD modcode = static_cast<LibCmo::CKDWORD>(LibCmo::CK2::CK_STATESAVEFLAGS_TEXTURE::CK_STATESAVE_OLDTEXONLY); | 
					
						
							|  |  |  | 		for (const auto& cobj : m_FileReader->GetFileObjects()) { | 
					
						
							|  |  |  | 			if (cobj.ObjectCid == LibCmo::CK2::CK_CLASSID::CKCID_TEXTURE && cobj.Data != nullptr) { | 
					
						
							|  |  |  | 				LibCmo::CK2::CKFileObject& obj = const_cast<LibCmo::CK2::CKFileObject&>(cobj); | 
					
						
							|  |  |  | 				obj.Data->StartRead(); | 
					
						
							|  |  |  | 				auto chunkinfo = obj.Data->GetIdentifiersProfile(); | 
					
						
							|  |  |  | 				obj.Data->StopRead(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// find CK_STATESAVE_TEXONLY and change it to CK_STATESAVE_OLDTEXONLY
 | 
					
						
							|  |  |  | 				for (const auto& entry : chunkinfo) { | 
					
						
							|  |  |  | 					if (entry.m_Identifier == expcode) { | 
					
						
							|  |  |  | 						LibCmo::CKDWORD* p = static_cast<LibCmo::CKDWORD*>(entry.m_DataPtr); | 
					
						
							|  |  |  | 						p -= 2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						if (*p == expcode) { | 
					
						
							|  |  |  | 							*p = modcode; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-09-20 20:44:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 		PrintCommonError("Test command only available in Debug mode."); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-28 22:20:46 +08:00
										 |  |  | 	void Unvirt::Context::UnvirtContext::ProcHelp(const CmdHelper::ArgumentsMap*) { | 
					
						
							| 
									
										
										
										
											2023-08-27 22:14:02 +08:00
										 |  |  | 		m_Help->Print(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-27 16:45:07 +08:00
										 |  |  | 	void UnvirtContext::ProcExit(const CmdHelper::ArgumentsMap*) { | 
					
						
							| 
									
										
										
										
											2023-08-27 12:30:12 +08:00
										 |  |  | 		m_OrderExit = true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma endregion
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |