changeset 35:2c574c3d50a9

* Moved XOR key related things to a proper location * xclannad -v now displays the real version (as specified in configure.ac)
author thib
date Sun, 08 Mar 2009 19:16:36 +0000
parents b76a8da75ec3
children 6d1a5b7f0838
files system/file.cc system/file.h xlovesys.cc
diffstat 3 files changed, 81 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/system/file.cc
+++ b/system/file.cc
@@ -84,6 +84,7 @@ extern "C" {
 using namespace std;
 
 FILESEARCH file_searcher;
+KEYHOLDER key_holder;
 // #define delete fprintf(stderr,"file.cc: %d.",__LINE__), delete
 
 /* FILESEARCH class の default の振る舞い */
@@ -532,6 +533,58 @@ void SCN2kFILE::ListupFiles(int fname_le
 }
 
 /********************************************************
+** KEYHOLDER
+*/
+void KEYHOLDER::SetKey(char new_key[16])
+{
+	unsigned short int i;
+	for (i=0; i < 16; i++)
+		key[i] = new_key[i];
+}
+
+void KEYHOLDER::SetKey2(char new_key[33])
+{
+	unsigned short int i;
+	char tmp[3];
+	tmp[2] = '\0';
+	for (i=0; i < 16; i++) {
+		tmp[0] = new_key[i*2];
+		tmp[1] = new_key[i*2+1];
+		key[i] = strtoul(tmp, NULL, 16);
+	}
+}
+
+void KEYHOLDER::GuessKey(char *regname)
+{
+	char key1[16] = {
+		0xa8, 0x28, 0xfd, 0x66,
+		0xa0, 0x23, 0x77, 0x69,
+		0xf9, 0x45, 0xf8, 0x2c,
+		0x7c, 0x00, 0xad, 0xf4
+	};
+
+	char key2[16] = {
+		0xAF, 0x2F, 0xFB, 0x6B,
+		0xAF, 0x30, 0x77, 0x17,
+		0x87, 0x48, 0xFE, 0x2C,
+		0x68, 0x1A, 0xB9, 0xF0
+	};
+
+
+	if (strcmp(regname, "KEY\\CLANNAD_FV") == 0) {
+		SetKey(key2);
+	}
+	else {
+		SetKey(key1);
+	}
+}
+
+const char * KEYHOLDER::GetKey(void)
+{
+	return key;
+}
+
+/********************************************************
 ** FILESEARCH クラスの実装
 */
 
@@ -599,43 +652,6 @@ int FILESEARCH::InitRoot(char* root) {
 	return 0;
 }
 
-void FILESEARCH::SetXorKey(char *key)
-{
-	unsigned short int i;
-	for (i=0; i < 16; i++)
-		xor_key[i] = key[i];
-}
-
-void FILESEARCH::GuessXorKey(char *regname)
-{
-	char key1[16] = {
-		0xa8, 0x28, 0xfd, 0x66,
-		0xa0, 0x23, 0x77, 0x69,
-		0xf9, 0x45, 0xf8, 0x2c,
-		0x7c, 0x00, 0xad, 0xf4
-	};
-
-	char key2[16] = {
-		0xAF, 0x2F, 0xFB, 0x6B,
-		0xAF, 0x30, 0x77, 0x17,
-		0x87, 0x48, 0xFE, 0x2C,
-		0x68, 0x1A, 0xB9, 0xF0
-	};
-
-
-	if (strcmp(regname, "KEY\\CLANNAD_FV") == 0) {
-		SetXorKey(key2);
-	}
-	else {
-		SetXorKey(key1);
-	}
-}
-
-const char * FILESEARCH::GetXorKey(void)
-{
-	return xor_key;
-}
-
 void FILESEARCH::SetFileInformation(FILETYPE tp, ARCTYPE is_arc, char* filename) {
 	int type = tp;
 	if (type < 0 || type >= TYPEMAX) return;
@@ -1456,7 +1472,7 @@ bool ARCINFO2k::ExecExtract(void) {
 		while(lzExtract(Extract_DataType_SCN2k(), char(), s, d, send, dend)) ;
 	}
 	if (read_little_endian_int(data+4) == 0x1adb2) { // Little Busters!
-		const char *decode_key = file_searcher.GetXorKey();
+		const char *decode_key = key_holder.GetKey();
 		int header_size = info.private_data;
 		for (i=0x100; i<=0x200 && header_size+i < info.filesize; i++) {
 			ret_data[header_size+i] ^= decode_key[i&0x0f];
--- a/system/file.h
+++ b/system/file.h
@@ -105,6 +105,17 @@ class SCN2kFILE;
 /* ARCINFO はファイルを読み込むために必要 */
 class ARCINFO;
 class ARCFILE_ATOM;
+
+class KEYHOLDER {
+public:
+	void SetKey(char[16]);
+	void SetKey2(char[33]);
+	void GuessKey(char*);
+	const char* GetKey(void);
+private:
+	char key[16];
+};
+
 class FILESEARCH {
 public:
 #define TYPEMAX 14
@@ -136,7 +147,6 @@ private:
 	/* デフォルトの information */
 	static ARCTYPE default_is_archived[TYPEMAX];
 	static char* default_dirnames[TYPEMAX];
-	char xor_key[16];
 public:
 	FILESEARCH(void);
 	~FILESEARCH();
@@ -154,9 +164,6 @@ public:
 	/* ある種類のファイルをすべてリストアップ
 	** 末尾は NULL pointer
 	*/
-	void SetXorKey(char*);
-	void GuessXorKey(char*);
-	const char* GetXorKey(void);
 	char** ListAll(FILETYPE type);
 };
 
@@ -225,5 +232,6 @@ public:
 };
 
 extern FILESEARCH file_searcher;
+extern KEYHOLDER key_holder;
 
 #endif // !defined(__KANON_FILE_H__)
--- a/xlovesys.cc
+++ b/xlovesys.cc
@@ -62,10 +62,11 @@ int main(int argc, char *argv[]) {
 	int opt = 0, end = 0, screenmode = 0;
 	char rootPath[1024]  = "/mnt/KEY/CLANNAD";
 	char font[1024]      = "msgothic.ttc";
+	char* xor_key = NULL;
 	Uint32 videoOptions  = SDL_HWSURFACE;
 
 	while(1) {
-		opt = getopt(argc, argv, "fdt:c:r:vh?");
+		opt = getopt(argc, argv, "fdt:c:r:k:vh?");
 		if(opt == -1) {break;}
 
 		switch(opt) {
@@ -82,11 +83,14 @@ int main(int argc, char *argv[]) {
 				strncpy(rootPath, optarg, 1023);
 				break;
 			case 'v':
-				// FIXME: "VERSION" undeclared?
-				// printf("xclannad %s\n", VERSION);
-				printf("xclannad 0.05e\n");
+				printf("xclannad %s\n", VERSION);
 				end = 1;
 				break;
+			case 'k':
+				if (xor_key == NULL)
+					xor_key = new char[33];
+				strncpy(xor_key, optarg, 32);
+				break;
 			case 'h':
 			case '?':
 				printf("\nUsage: %s [OPTIONS]\n\n", argv[0]);
@@ -94,6 +98,7 @@ int main(int argc, char *argv[]) {
 				printf("  -d    : double buffer mode\n");
 				printf("  -t    : set font (typeface)\n");
 				printf("  -r    : set root path (default /mnt/KEY/CLANNAD)\n");
+				printf("  -k    : set xor key, if needed\n");
 				printf("  -v    : show version and exit\n");
 				printf("  -h -? : show help and exit\n\n");
 				end = 1;
@@ -114,7 +119,12 @@ int main(int argc, char *argv[]) {
 	if (strcmp(regname, key_lb_orig) == 0) { // "リトルバスターズ! -> LittleBustersに#REGNAMEを変更
 		config.SetParaStr("#REGNAME", key_lb_new);
 	}
-	file_searcher.GuessXorKey((char*)regname);
+	if (xor_key == NULL)
+		key_holder.GuessKey((char*)regname);
+	else {
+		key_holder.SetKey2(xor_key);
+		delete[] xor_key;
+	}
 	SetFont(font);
 
 	MuSys mu(config);