internal static void ReadCrc(this Els_kom_Core.Classes.KOMStream kOMStream, string crcfile, out byte[] crcdata, ref int entry_count, ref int crc_size) { crcdata = System.IO.File.ReadAllBytes(crcfile); System.IO.File.Delete(crcfile); entry_count++; crc_size = crcdata.Length; }
public void Unpack(string in_path, string out_path, string KOMFileName) { System.IO.BinaryReader reader = new System.IO.BinaryReader(System.IO.File.OpenRead(in_path), System.Text.Encoding.ASCII); reader.BaseStream.Position += 52; int entry_count = (int)reader.ReadUInt64(); // trying to understand this crap... This is where it starts to fail // for KOM V4 on Elsword's current data036.kom. int compressed = reader.ReadInt32(); int file_time = reader.ReadInt32(); int xml_size = reader.ReadInt32(); byte[] xmldatabuffer = reader.ReadBytes(xml_size); Els_kom_Core.Classes.KOMStream kOMStream = new Els_kom_Core.Classes.KOMStream(); kOMStream.DecryptCRCXml(compressed, ref xmldatabuffer, xml_size, System.Text.Encoding.ASCII); string xmldata = System.Text.Encoding.ASCII.GetString(xmldatabuffer); try { System.Collections.Generic.List <Els_kom_Core.Classes.EntryVer> entries = kOMStream.Make_entries_v4(xmldata, entry_count); foreach (var entry in entries) { // we iterate through every entry here and unpack the data. kOMStream.WriteOutput(reader, out_path, entry, SupportedKOMVersion); } } catch (System.Xml.XmlException) { throw new Els_kom_Core.Classes.UnpackingError("failure with xml entry data reading..."); } kOMStream.Dispose(); reader.Dispose(); }
internal static string GetSafeString(this Els_kom_Core.Classes.KOMStream kOMStream, string source) { if (source.Contains(new string(char.MinValue, 1))) { return(source.Substring(0, source.IndexOf(char.MinValue))); } return(source); }
internal static void DecryptCRCXml(this Els_kom_Core.Classes.KOMStream kOMStream, int key, ref byte[] data, int length, System.Text.Encoding encoding) { // Load the KOM V4 keymap file. LoadKeyMap(); if (!KeyMap.ContainsKey(key)) { return; } string keyStr = KeyMap[key].ToString(); string sha1Key = System.BitConverter.ToString(new System.Security.Cryptography.SHA1CryptoServiceProvider().ComputeHash(encoding.GetBytes(keyStr))).Replace("-", ""); Els_kom_Core.Classes.BlowFish blowfish = new Els_kom_Core.Classes.BlowFish(sha1Key); data = blowfish.Decrypt(data, System.Security.Cryptography.CipherMode.ECB); blowfish.Dispose(); }
internal static bool ReadInFile(this Els_kom_Core.Classes.KOMStream kOMStream, System.IO.BinaryReader binaryReader, out int destInt) { if (binaryReader == null) { throw new System.ArgumentNullException(nameof(binaryReader)); } long position = binaryReader.BaseStream.Position; int readInt = binaryReader.ReadInt32(); if ((binaryReader.BaseStream.Position - position) == sizeof(int)) { destInt = readInt; return(true); } destInt = int.MinValue; return(false); }
public void Unpack(string in_path, string out_path, string KOMFileName) { System.IO.BinaryReader reader = new System.IO.BinaryReader(System.IO.File.OpenRead(in_path), System.Text.Encoding.ASCII); reader.BaseStream.Position = 52; Els_kom_Core.Classes.KOMStream kOMStream = new Els_kom_Core.Classes.KOMStream(); kOMStream.ReadInFile(reader, out int entry_count); // without this dummy read the entry instances would not get the correct // data leading to an crash when tring to make an file with the entry name in the output path. kOMStream.ReadInFile(reader, out int size); System.Collections.Generic.List <Els_kom_Core.Classes.EntryVer> entries = kOMStream.Make_entries_v2(entry_count, reader); foreach (var entry in entries) { // we iterate through every entry here and unpack the data. kOMStream.WriteOutput(reader, out_path, entry, SupportedKOMVersion); } kOMStream.Dispose(); reader.Dispose(); }
internal static bool ReadInFile(this Els_kom_Core.Classes.KOMStream kOMStream, System.IO.BinaryReader binaryReader, out string destString, int length, System.Text.Encoding encoding) { if (binaryReader == null) { throw new System.ArgumentNullException(nameof(binaryReader)); } if (encoding == null) { throw new System.ArgumentNullException(nameof(encoding)); } long position = binaryReader.BaseStream.Position; byte[] readBytes = binaryReader.ReadBytes(length); if ((binaryReader.BaseStream.Position - position) == length) { destString = encoding.GetString(readBytes); return(true); } destString = null; return(false); }
public void Unpack(string in_path, string out_path, string KOMFileName) { System.IO.BinaryReader reader = new System.IO.BinaryReader(System.IO.File.OpenRead(in_path), System.Text.Encoding.ASCII); reader.BaseStream.Position += 52; int entry_count = (int)reader.ReadUInt64(); reader.BaseStream.Position += 4; int file_time = reader.ReadInt32(); int xml_size = reader.ReadInt32(); byte[] xmldatabuffer = reader.ReadBytes(xml_size); string xmldata = System.Text.Encoding.ASCII.GetString(xmldatabuffer); Els_kom_Core.Classes.KOMStream kOMStream = new Els_kom_Core.Classes.KOMStream(); System.Collections.Generic.List <Els_kom_Core.Classes.EntryVer> entries = kOMStream.Make_entries_v3(xmldata, entry_count); foreach (var entry in entries) { // we iterate through every entry here and unpack the data. kOMStream.WriteOutput(reader, out_path, entry, SupportedKOMVersion); } kOMStream.Dispose(); reader.Dispose(); }
public void Pack(string in_path, string out_path, string KOMFileName) { bool use_XoR = false; if (System.IO.File.Exists(in_path + "\\XoRNeeded.dummy")) { use_XoR = true; System.IO.File.Delete(in_path + "\\XoRNeeded.dummy"); } System.IO.BinaryWriter writer = new System.IO.BinaryWriter(System.IO.File.Create(out_path), System.Text.Encoding.ASCII); int entry_count = 0; int crc_size = 0; Els_kom_Core.Classes.KOMStream kOMStream = new Els_kom_Core.Classes.KOMStream(); kOMStream.ReadCrc(in_path + "\\crc.xml", out byte[] crc_data, ref entry_count, ref crc_size); kOMStream.Dispose(); System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(in_path); int offset = 0; System.Collections.Generic.List <Els_kom_Core.Classes.EntryVer> entries = new System.Collections.Generic.List <Els_kom_Core.Classes.EntryVer>(); foreach (var fi in di.GetFiles()) { entry_count++; byte[] file_data = System.IO.File.ReadAllBytes(in_path + "\\" + fi.Name); int originalsize = file_data.Length; if (use_XoR) { byte[] xorkey = System.Text.Encoding.UTF8.GetBytes("\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9"); Els_kom_Core.Classes.BlowFish.XorBlock(ref file_data, xorkey); } byte[] compressedData; try { Els_kom_Core.Classes.ZlibHelper.CompressData(file_data, out compressedData); } catch (Els_kom_Core.Classes.Zlib.ZStreamException) { throw new Els_kom_Core.Classes.PackingError("failed with zlib compression of entries."); } int compressedSize = compressedData.Length; offset += compressedSize; entries.Add(new Els_kom_Core.Classes.EntryVer(compressedData, fi.Name, originalsize, compressedSize, offset)); } if (use_XoR) { byte[] xorkey = System.Text.Encoding.UTF8.GetBytes("\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9"); Els_kom_Core.Classes.BlowFish.XorBlock(ref crc_data, xorkey); } byte[] compressedcrcData; try { Els_kom_Core.Classes.ZlibHelper.CompressData(crc_data, out compressedcrcData); } catch (Els_kom_Core.Classes.Zlib.ZStreamException) { throw new Els_kom_Core.Classes.PackingError("failed with zlib compression of crc.xml."); } int compressedcrc = compressedcrcData.Length; offset += compressedcrc; entries.Add(new Els_kom_Core.Classes.EntryVer(compressedcrcData, "crc.xml", crc_size, compressedcrc, offset)); writer.Write(KOMHeaderString.ToCharArray(), 0, KOMHeaderString.Length); writer.BaseStream.Position = 52; writer.Write(entry_count); writer.Write(1); foreach (var entry in entries) { writer.Write(entry.name.ToCharArray(), 0, entry.name.Length); int seek_amount = 60 - entry.name.Length; writer.BaseStream.Position += seek_amount; writer.Write(entry.uncompressed_size); writer.Write(entry.compressed_size); writer.Write(entry.relative_offset); } foreach (var entry in entries) { writer.Write(entry.entrydata, 0, entry.compressed_size); } writer.Dispose(); }
internal static System.Collections.Generic.List <Els_kom_Core.Classes.EntryVer> Make_entries_v3(this Els_kom_Core.Classes.KOMStream kOMStream, string xmldata, int entry_count) { System.Collections.Generic.List <Els_kom_Core.Classes.EntryVer> entries = new System.Collections.Generic.List <Els_kom_Core.Classes.EntryVer>(); var xml = System.Xml.Linq.XElement.Parse(xmldata); foreach (var fileElement in xml.Elements("File")) { var nameAttribute = fileElement.Attribute("Name"); var name = nameAttribute?.Value ?? "no value"; var sizeAttribute = fileElement.Attribute("Size"); var size = sizeAttribute == null ? -1 : System.Convert.ToInt32(sizeAttribute.Value); var CompressedSizeAttribute = fileElement.Attribute("CompressedSize"); var CompressedSize = CompressedSizeAttribute == null ? -1 : System.Convert.ToInt32(CompressedSizeAttribute.Value); var ChecksumAttribute = fileElement.Attribute("Checksum"); var Checksum = ChecksumAttribute == null ? -1 : int.Parse(ChecksumAttribute.Value, System.Globalization.NumberStyles.HexNumber); var FileTimeAttribute = fileElement.Attribute("FileTime"); var FileTime = FileTimeAttribute == null ? -1 : int.Parse(FileTimeAttribute.Value, System.Globalization.NumberStyles.HexNumber); var AlgorithmAttribute = fileElement.Attribute("Algorithm"); var Algorithm = AlgorithmAttribute == null ? -1 : System.Convert.ToInt32(AlgorithmAttribute.Value); var entry = new Els_kom_Core.Classes.EntryVer(name, size, CompressedSize, Checksum, FileTime, Algorithm); entries.Add(entry); } return(entries); }
internal static System.Collections.Generic.List <Els_kom_Core.Classes.EntryVer> Make_entries_v2(this Els_kom_Core.Classes.KOMStream kOMStream, int entrycount, System.IO.BinaryReader reader) { System.Collections.Generic.List <Els_kom_Core.Classes.EntryVer> entries = new System.Collections.Generic.List <Els_kom_Core.Classes.EntryVer>(); for (int i = 0; i < entrycount; i++) { kOMStream.ReadInFile(reader, out string key, 60, System.Text.Encoding.ASCII); kOMStream.ReadInFile(reader, out int originalsize); kOMStream.ReadInFile(reader, out int compressedSize); kOMStream.ReadInFile(reader, out int offset); var entry = new Els_kom_Core.Classes.EntryVer(kOMStream.GetSafeString(key), originalsize, compressedSize, offset); entries.Add(entry); } return(entries); }
internal static System.Collections.Generic.List <Els_kom_Core.Classes.EntryVer> Make_entries_v4(this Els_kom_Core.Classes.KOMStream kOMStream, string xmldata, int entry_count) { System.Collections.Generic.List <Els_kom_Core.Classes.EntryVer> entries = new System.Collections.Generic.List <Els_kom_Core.Classes.EntryVer>(); var xml = System.Xml.Linq.XElement.Parse(xmldata); foreach (var fileElement in xml.Elements("File")) { var nameAttribute = fileElement.Attribute("Name"); var name = nameAttribute?.Value ?? "no value"; var sizeAttribute = fileElement.Attribute("Size"); var size = sizeAttribute == null ? -1 : System.Convert.ToInt32(sizeAttribute.Value); var CompressedSizeAttribute = fileElement.Attribute("CompressedSize"); var CompressedSize = CompressedSizeAttribute == null ? -1 : System.Convert.ToInt32(CompressedSizeAttribute.Value); var ChecksumAttribute = fileElement.Attribute("Checksum"); var Checksum = ChecksumAttribute == null ? -1 : int.Parse(ChecksumAttribute.Value, System.Globalization.NumberStyles.HexNumber); var FileTimeAttribute = fileElement.Attribute("FileTime"); var FileTime = FileTimeAttribute == null ? -1 : int.Parse(FileTimeAttribute.Value, System.Globalization.NumberStyles.HexNumber); var AlgorithmAttribute = fileElement.Attribute("Algorithm"); var Algorithm = AlgorithmAttribute == null ? -1 : System.Convert.ToInt32(AlgorithmAttribute.Value); // on v4 at least on Elsword there is now an MappedID attribute. // this is even more of an reason to store some cache // file for not only kom v3 for the algorithm 2 & 3 // files to be able to get repacked to those // algorithm’s but also to store these unique // map id’s to this version of kom. var MappedIDAttribute = fileElement.Attribute("MappedID"); var MappedID = MappedIDAttribute?.Value ?? "no value"; var entry = new Els_kom_Core.Classes.EntryVer(name, size, CompressedSize, Checksum, FileTime, Algorithm, MappedID); entries.Add(entry); } return(entries); }