/// <summary> /// Populates the Mix database for usage /// </summary> public static void Initialize(string mainFile = "kafe") { Console.WriteLine("Initializing Mix system with main file \"{0}\"...", mainFile); fileList = new Dictionary <string, MixFileEntry>(); cache = new Dictionary <string, object>(); var mixfiles = new List <string>() { mainFile + ".zip" }; foreach (var zipFile in Directory.EnumerateFiles(".", "*.zip")) { if (zipFile.Substring(2).Equals(mainFile + ".zip", StringComparison.OrdinalIgnoreCase)) { continue; } Console.WriteLine(" * {0}", zipFile.Substring(2)); mixfiles.Add(zipFile.Substring(2)); } Console.WriteLine("Indexing contents..."); foreach (var mixfile in mixfiles) { if (!File.Exists(mixfile)) { Console.WriteLine("Mixfile \"{0}\" in list but nonexistant.", mixfile); continue; } using (var mStream = new BinaryReader(File.Open(mixfile, FileMode.Open))) { //This is not the "proper" way to do it. F**k that. while (true) { var header = mStream.ReadBytes(4); if (header[0] != 'P' || header[1] != 'K' || header[2] != 3 || header[3] != 4) { if (header[2] == 1 && header[3] == 2) //reached the Central Directory { break; } throw new FileLoadException(string.Format("Mixfile \"{0}\" has an incorrect header.", mixfile)); } mStream.BaseStream.Seek(4, SeekOrigin.Current); var method = mStream.ReadInt16(); mStream.BaseStream.Seek(8, SeekOrigin.Current); var moto = mStream.ReadBytes(4); var compressedSize = (moto[3] << 24) | (moto[2] << 16) | (moto[1] << 8) | moto[0]; //0x000000F8 moto = mStream.ReadBytes(4); var uncompressedSize = (moto[3] << 24) | (moto[2] << 16) | (moto[1] << 8) | moto[0]; //0x00000197 moto = mStream.ReadBytes(2); var filenameLength = (moto[1] << 8) | moto[0]; mStream.BaseStream.Seek(2, SeekOrigin.Current); var filename = new string(mStream.ReadChars(filenameLength)).Replace('/', '\\'); var offset = (int)mStream.BaseStream.Position; mStream.BaseStream.Seek(compressedSize, SeekOrigin.Current); if (filename.EndsWith("\\")) { continue; } var entry = new MixFileEntry() { Offset = offset, Length = compressedSize, IsCompressed = method == 8, Filename = filename, MixFile = mixfile, }; fileList[filename] = entry; } } } }
/// <summary> /// Populates the Mix database for usage /// </summary> /// <param name="mainFile">The primary archive's base name.</param> public static void Initialize(string mainFile = "Noxico") { Program.WriteLine("Mix.Initialize()"); fileList = new Dictionary <string, MixFileEntry>(); stringCache = new Dictionary <string, string>(); bitmapCache = new Dictionary <string, Bitmap>(); var mixfiles = new List <string>() { mainFile + ".nox" }; mixfiles.AddRange(Directory.EnumerateFiles(".", "*.nox").Select(x => x.Substring(2)).Where(x => !x.Equals(mainFile + ".nox", StringComparison.OrdinalIgnoreCase))); Program.WriteLine("Mixfiles enumerated. Indexing contents..."); foreach (var mixfile in mixfiles) { if (!File.Exists(mixfile)) { Program.WriteLine("Mixfile \"{0}\" in list but nonexistent.", mixfile); continue; } using (var mStream = new BinaryReader(File.Open(mixfile, FileMode.Open))) { //This is not the "proper" way to do it. F**k that. while (true) { var header = mStream.ReadBytes(4); if (header[0] != 'P' || header[1] != 'K' || header[2] != 3 || header[3] != 4) { if (header[2] == 1 && header[3] == 2) //reached the Central Directory { break; } throw new FileLoadException(string.Format("MIX file '{0}' has an incorrect header.", mixfile)); } mStream.BaseStream.Seek(4, SeekOrigin.Current); var method = mStream.ReadInt16(); mStream.BaseStream.Seek(8, SeekOrigin.Current); var moto = mStream.ReadBytes(4); var compressedSize = (moto[3] << 24) | (moto[2] << 16) | (moto[1] << 8) | moto[0]; //0x000000F8 moto = mStream.ReadBytes(4); var uncompressedSize = (moto[3] << 24) | (moto[2] << 16) | (moto[1] << 8) | moto[0]; //0x00000197 moto = mStream.ReadBytes(2); var filenameLength = (moto[1] << 8) | moto[0]; mStream.BaseStream.Seek(2, SeekOrigin.Current); var filename = new string(mStream.ReadChars(filenameLength)).Replace('/', '\\'); var offset = (int)mStream.BaseStream.Position; mStream.BaseStream.Seek(compressedSize, SeekOrigin.Current); if (filename.EndsWith("\\")) { continue; } if (filename.Contains("missions")) { continue; } var entry = new MixFileEntry() { Offset = offset, Length = compressedSize, IsCompressed = method == 8, Filename = filename, MixFile = mixfile, }; if (filename.EndsWith(".patch")) { filename = mixfile.GetHashCode() + filename; } fileList[filename] = entry; } } } if (!Directory.Exists("mods")) { return; } foreach (var dataDir in Directory.EnumerateDirectories("mods")) { foreach (var dataFile in Directory.EnumerateFiles(dataDir, "*.*", SearchOption.AllDirectories)) { var baseName = dataFile.Remove(0, dataDir.Length + 1); var entry = new MixFileEntry() { Offset = -1, Length = -1, IsCompressed = false, Filename = dataFile, MixFile = null, }; if (baseName.EndsWith(".patch")) { baseName = dataFile; } fileList[baseName] = entry; } } }
public void Load(string source) { if (fileList == null) { Reset(); } if (File.Exists(source)) { using (var mStream = new BinaryReader(File.Open(source, FileMode.Open))) { //This is not the "proper" way to do it. F**k that. while (true) { var header = mStream.ReadBytes(4); if (header[0] != 'P' || header[1] != 'K' || header[2] != 3 || header[3] != 4) { if (header[2] == 1 && header[3] == 2) //reached the Central Directory { break; } throw new FileLoadException(string.Format("Zip file '{0}' has an incorrect header.", source)); } mStream.BaseStream.Seek(4, SeekOrigin.Current); var method = mStream.ReadInt16(); mStream.BaseStream.Seek(8, SeekOrigin.Current); var moto = mStream.ReadBytes(4); var compressedSize = (moto[3] << 24) | (moto[2] << 16) | (moto[1] << 8) | moto[0]; //0x000000F8 moto = mStream.ReadBytes(4); var uncompressedSize = (moto[3] << 24) | (moto[2] << 16) | (moto[1] << 8) | moto[0]; //0x00000197 moto = mStream.ReadBytes(2); var filenameLength = (moto[1] << 8) | moto[0]; mStream.BaseStream.Seek(2, SeekOrigin.Current); var filename = new string(mStream.ReadChars(filenameLength)).Replace('/', '\\'); var offset = (int)mStream.BaseStream.Position; mStream.BaseStream.Seek(compressedSize, SeekOrigin.Current); if (filename.EndsWith("\\")) { continue; } var entry = new MixFileEntry() { Offset = offset, Length = compressedSize, IsCompressed = method == 8, Filename = filename, Source = source, IsInFolder = false, }; fileList[filename] = entry; } } } else if (Directory.Exists(source)) { foreach (var filename in Directory.EnumerateFiles(source)) { var fn = Path.GetFileName(filename); var entry = new MixFileEntry() { Offset = 0, Length = 0, IsCompressed = false, Filename = fn, Source = source, IsInFolder = true, }; fileList[fn] = entry; } } }