public static void unpack(string input) { StreamEx s = new StreamEx(input, System.IO.FileMode.Open, System.IO.FileAccess.Read); string unpackdir = Path.GetFullPath(input) + "_unpack"; if (!Directory.Exists(unpackdir)) { Directory.CreateDirectory(unpackdir); } Int32 fileCount = s.ReadInt32(); Console.WriteLine("文件头解析:共有{0}个文件", fileCount); for (int i = 0; i < fileCount; i++) { Int32 fileLength = s.ReadInt32(); StreamEx sNew = new StreamEx(unpackdir + "\\" + i.ToString("D5") + ".dds", FileMode.Create, FileAccess.Write); Console.WriteLine("正在解包文件{0}/{1}:{2}->{3}", i + 1, fileCount, s.Position, fileLength); sNew.WriteFromStream(s, fileLength); sNew.Close(); } }
public static void unpack(string input) { StreamEx s = new StreamEx(input, System.IO.FileMode.Open, System.IO.FileAccess.Read); string unpackdir = Path.GetFullPath(input) + "_unpack"; if (!Directory.Exists(unpackdir)) { Directory.CreateDirectory(unpackdir); } List <headerNode> headers = new List <headerNode>(); while (s.Position < 0xc000) { headerNode h = new headerNode(); h.fileName = s.ReadSimpleString(0x20); h.fileOffset = s.ReadInt32() + 0xc000; h.fileLength = s.ReadInt32(); s.Position += 8; if (h.fileLength == 0) { break; } headers.Add(h); } Console.WriteLine("文件头解析:共有{0}个文件", headers.Count); for (int i = 0; i < headers.Count; i++) { StreamEx sNew = new StreamEx(unpackdir + "\\" + headers[i].fileName, FileMode.Create, FileAccess.Write); Console.WriteLine("正在导出文件{0}/{1}:{2} ({3}<={4})", i + 1, headers.Count, headers[i].fileName, headers[i].fileOffset, headers[i].fileLength); s.Position = headers[i].fileOffset; byte[] d = s.Read(headers[i].fileLength); sNew.Write(d); } }
public static void Unpack(string input) { StreamEx s = new StreamEx(input, System.IO.FileMode.Open, System.IO.FileAccess.Read); // 52141C7E Int32 magicNumber = s.ReadInt32(); Int32 fileCount = s.ReadInt32(); string[] fileName = new string[fileCount]; Int32[] strangeNumber = new Int32[fileCount]; Int32[] fileLength = new Int32[fileCount]; Int32[] fileOffset = new Int32[fileCount]; for (int i = 0; i < fileCount; i++) { fileName[i] = s.ReadSimpleString(0x40); strangeNumber[i] = s.ReadInt32(); fileLength[i] = s.ReadInt32(); fileOffset[i] = s.ReadInt32(); Int32 one = s.ReadInt32(); } for (int i = 0; i < fileCount; i++) { s.Position = fileOffset[i]; Int32 strangeNumberAgain = s.ReadInt32(); Int32 fileLengthAgain = s.ReadInt32(); Int32 oneAgain = s.ReadInt32(); byte[] fileContent = s.Read(fileLength[i] - 12); // unpack StreamEx unpackFile = new StreamEx(fileName[i], System.IO.FileMode.Create, System.IO.FileAccess.Write); unpackFile.Write(fileContent); unpackFile.Close(); } }
static public int exportFile(string path) { StreamEx s = new StreamEx(path, FileMode.Open, FileAccess.Read); List <string> texts = new List <string>(); Int32 header = s.ReadInt32BigEndian(); if (header == _fixHeaderType1) { Console.Write("[SETU]"); Int32 textCount = s.ReadInt32(); Int32[] textOffset = new Int32[textCount]; for (int i = 0; i < textCount; i++) { textOffset[i] = s.ReadInt32(); } for (int i = 0; i < textCount; i++) { string txt = ""; if (textOffset[i] != 0) { s.Position = textOffset[i]; txt = readUnicodeString(s, 2); } texts.Add(txt); } } else if ((header >> 16) == _fixHeaderType2) { Console.Write("[0000]"); s.Position = 2; while (s.Position < s.Length) { texts.Add(readUnicodeString(s, 2)); } } else if (header == _fixHeaderType3) { Console.Write("[TCRC]"); Int32 textOffset = s.ReadInt32() + 8; List <Int32> indexes = new List <Int32>(); while (s.Position < textOffset) { s.Position += 4; indexes.Add(s.ReadInt32()); } if (s.ReadInt32BigEndian() != 0x54455854) //TEXT { throw new Exception("TEXT段错误"); } Int32 nextBlockOffset = s.ReadInt32() + (Int32)s.Position; textOffset += 8; texts.Add("{TEXT}"); for (int i = 0; i < indexes.Count; i++) { s.Position = textOffset + indexes[i]; texts.Add(readUnicodeString(s, 4)); } if (nextBlockOffset < s.Length) { s.Position = nextBlockOffset; if (s.ReadInt32BigEndian() == 0x4E504354) //NCPT { texts.Add("{NCPT}"); s.Position = s.ReadInt32() + s.Position; } if (s.ReadInt32BigEndian() == 0x4E414D45) //NAME { texts.Add("{NAME}"); Int32 nameBlockLength = s.ReadInt32(); s.Position += 2; while (s.Position < s.Length) { texts.Add(readUnicodeString(s, 2)); } } } } else { throw new Exception("不支持的文件头"); } for (int i = 0; i < texts.Count; i++) { // 处理字符集差异 foreach (KeyValuePair <string, string> kvp in _convertChar) { texts[i] = texts[i].Replace(kvp.Key, kvp.Value); } } Agemo.WriteFile(path + ".txt", _destEncoding, from txt in texts select txt + "{END}"); return(texts.Count); }
static public int importFile(string path) { string[] texts = Agemo.ReadFile(path + ".txt", _destEncoding); for (int i = 0; i < texts.Length; i++) { texts[i] = texts[i].Remove(texts[i].Length - 5); // 处理字符集差异 foreach (KeyValuePair <string, string> kvp in _convertChar) { texts[i] = texts[i].Replace(kvp.Value, kvp.Key); } } StreamEx ssource = new StreamEx(path, FileMode.Open, FileAccess.Read); StreamEx sdest = new StreamEx(path + ".imp", System.IO.FileMode.Create, System.IO.FileAccess.Write); Int32 header = ssource.ReadInt32BigEndian(); if (header == _fixHeaderType1) { Console.Write("[SETU]"); sdest.WriteInt32BigEndian(_fixHeaderType1); sdest.WriteInt32(texts.Length); Int32[] textOffset = new Int32[texts.Length]; for (int i = 0; i < texts.Length; i++) { sdest.WriteInt32(0); // 长度占位写0 } for (int i = 0; i < texts.Length; i++) { if (texts[i].Length == 0) { textOffset[i] = 0; continue; } textOffset[i] = (Int32)sdest.Position; // 文本偏移量 sdest.Write(_sourceEncoding.GetBytes(texts[i])); sdest.WriteInt16(0); // 结束0 } ssource.Position = ssource.Length - 139; sdest.WriteFromStream(ssource, 139); sdest.Position = 8; for (int i = 0; i < textOffset.Length; i++) { sdest.WriteInt32(textOffset[i]); } } else if ((header >> 16) == _fixHeaderType2) { Console.Write("[0000]"); sdest.WriteInt16(0); for (int i = 0; i < texts.Length; i++) { sdest.Write(_sourceEncoding.GetBytes(texts[i])); sdest.WriteInt16(0); } } else if (header == _fixHeaderType3) { Console.Write("[TCRC]"); Int32 textBlockOffset = ssource.ReadInt32() + 8; // 指向"TEXT" ssource.Position = 0; sdest.WriteFromStream(ssource, textBlockOffset); // 写至索引结束 sdest.WriteFromStream(ssource, 4); // 写入"TEXT" Int32 sourceTextLength = ssource.ReadInt32(); // 原文本段长度 sdest.WriteInt32(0); List <Int32> textIndexes = new List <Int32>(); if (texts[0] != "{TEXT}") { throw new Exception("文本分段错误"); } int iText = 1; for (; iText < texts.Length && texts[iText] != "{NCPT}" && texts[iText] != "{NAME}"; iText++) { textIndexes.Add((Int32)sdest.Position - textBlockOffset - 8); // 获取偏移 sdest.Write(_sourceEncoding.GetBytes(texts[iText])); // 写入文本 sdest.WriteInt32(0); // 写入0结尾 } Int32 destTextLength = (Int32)sdest.Position - textBlockOffset - 8; // 文本段长度 sdest.Position = 8; for (int i = 0; i < textIndexes.Count; i++) { sdest.Position += 4; sdest.WriteInt32(textIndexes[i]); } if (sdest.Position != textBlockOffset) { throw new Exception("文本段写入失败"); } sdest.Position += 4; sdest.WriteInt32(destTextLength); if (iText < texts.Length) { ssource.Position = textBlockOffset + 8 + sourceTextLength; sdest.Position = textBlockOffset + 8 + destTextLength; if (texts[iText] == "{NCPT}") { ssource.Position += 4; Int32 ncptLength = ssource.ReadInt32(); // get ncpt block length ssource.Position -= 8; sdest.WriteFromStream(ssource, ncptLength + 8); iText++; } if (texts[iText] == "{NAME}") { sdest.WriteInt32BigEndian(0x4E414D45); Int32 nameBlockLengthPosition = (Int32)sdest.Position; sdest.WriteInt32(0); // 长度占位 sdest.WriteInt16(0); for (iText = iText + 1; iText < texts.Length; iText++) { sdest.Write(_sourceEncoding.GetBytes(texts[iText])); sdest.WriteInt16(0); } Int32 nameBlockLength = (Int32)sdest.Position - nameBlockLengthPosition - 4; sdest.Position = nameBlockLengthPosition; sdest.WriteInt32(nameBlockLength); } } } else { throw new Exception("不支持的文件头"); } sdest.Close(); return(texts.Length); }