private void Initalize(Stream blfStream) { _stream = new EndianStream(blfStream, Endian.BigEndian); // Load Campaign shit LoadCampaign(); }
/// <summary> /// Creates a new Instance of the TableSystem. /// </summary> /// <param name="input">Input stream to write/save the TableSystem to.</param> /// <param name="loadTables">Load the tables after loading into stream (defaults to false).</param> public TableSystem(string filePath, bool loadTables = false) { _stream = new EndianStream(new FileStream(filePath, FileMode.OpenOrCreate), Endian.BigEndian); if (loadTables) LoadTables(); }
/// <summary> /// Creates a new Instance of the TableSystem. /// </summary> /// <param name="input">Input stream to write/save the TableSystem to.</param> /// <param name="loadTables">Load the tables after loading into stream (defaults to false).</param> public TableSystem(Stream input, bool loadTables = false) { _stream = new EndianStream(input, Endian.BigEndian); if (loadTables) LoadTables(); }
private void Initalize(Stream blfStream, EngineDatabase database) { _stream = new EndianStream(blfStream, Endian.BigEndian); // Load MapInfo data from file LoadMapInfo(database); }
public static BitmapSource Deswizzle(string FilePath, int resizeWidth = -1, int resizeHeight = -1, bool onlyResizeIfGreater = false, bool dontSettingsResize = false) { //Open the temp dds var fs = new FileStream(FilePath, FileMode.Open, FileAccess.ReadWrite); var es = new EndianStream(fs, Endian.LittleEndian); //Read the dds header es.SeekTo(0x0C); int height = es.ReadInt32(); int width = es.ReadInt32(); //Read our random bytes es.SeekTo(0x5C); string randomBuf = BitConverter.ToString(es.ReadBlock(12)).Replace("-", ""); //Read the buffer es.SeekTo(0x80); int size = width*height*4; byte[] buffer = es.ReadBlock(size); es.Close(); Bitmap bitmap = null; //A2R10G10B10 switch (randomBuf) { case "FF03000000FC0F000000F03F": bitmap = DeswizzleA2R10G10B10(buffer, width, height); if (App.AssemblyStorage.AssemblySettings.XdkScreenshotGammaCorrect) { BitmapData imageData = (bitmap).LockBits( new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); GammaCorrect(App.AssemblyStorage.AssemblySettings.XdkScreenshotGammaModifier, imageData); bitmap.UnlockBits(imageData); } break; case "0000FF0000FF0000FF000000": bitmap = DeswizzleA8R8G8B8(buffer, width, height); break; } if (bitmap == null) return null; // Resize if (App.AssemblyStorage.AssemblySettings.XdkResizeImages && !dontSettingsResize) bitmap = ResizeImage(bitmap); if (width != -1 && height != -1) if (onlyResizeIfGreater && (bitmap.Width > width && bitmap.Height > height)) bitmap = ResizeImage(bitmap, width, height); else bitmap = ResizeImage(bitmap, width, height); return loadBitmap(bitmap); }
private void Initalize(Stream blfStream) { _blfStream = new EndianStream(blfStream, Endian.BigEndian); if (!isValidBLF()) { Close(); throw new Exception("Invalid BLF Container!"); } LoadChunkTable(); }
private void btnSaveAll_Click(object sender, RoutedEventArgs e) { for (int i = 0; i < _locales.Count; i++) _currentLocaleTable.Strings[i].Value = ReplaceTags(_locales[i].Locale); using (EndianStream stream = new EndianStream(_streamManager.OpenReadWrite(), _streamManager.SuggestedEndian)) { _currentLanguage.SaveStrings(stream, _currentLocaleTable); _cache.SaveChanges(stream); } MetroMessageBox.Show("Locales Saved", "Locales saved successfully!"); }
public static BitmapSource Deswizzle(string FilePath) { //Open the temp dds var fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read); var es = new EndianStream(fs, Endian.LittleEndian); //Read the dds header es.SeekTo(0x0C); var height = es.ReadInt32(); var width = es.ReadInt32(); //Read our random bytes es.SeekTo(0x5C); var randomBuf = BitConverter.ToString(es.ReadBlock(12)).Replace("-", ""); //Read the buffer es.SeekTo(0x80); var size = width * height * 4; var buffer = es.ReadBlock(size); es.Close(); Bitmap bitmap = null; //A2R10G10B10 switch (randomBuf) { case "FF03000000FC0F000000F03F": bitmap = DeswizzleA2R10G10B10(buffer, width, height); if (Settings.XDKScreenshotGammaCorrect) { var imageData = (bitmap).LockBits( new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); GammaCorrect(Settings.XDKScreenshotGammaModifier, imageData); bitmap.UnlockBits(imageData); } break; case "0000FF0000FF0000FF000000": bitmap = DeswizzleA8R8G8B8(buffer, width, height); break; } if (bitmap == null) return null; // Resize if (Settings.XDKResizeImages) bitmap = ResizeImage(bitmap); return loadBitmap(bitmap); }
private void btnCreatePatchModifiedMap_Click(object sender, RoutedEventArgs e) { var ofd = new OpenFileDialog { Title = "Assembly - Select a Modified Map file", Filter = "Blam Cache Files|*.map" }; if (ofd.ShowDialog() != DialogResult.OK) return; txtCreatePatchModifiedMap.Text = ofd.FileName; txtCreatePatchOutputName.Text = Path.GetFileNameWithoutExtension(ofd.FileName); var fileStream = new FileStream(ofd.FileName, FileMode.Open); var cacheStream = new EndianStream(fileStream, Endian.BigEndian); var versionInfo = new CacheFileVersionInfo(cacheStream); var engine = App.AssemblyStorage.AssemblySettings.DefaultDatabase.FindEngineByVersion(versionInfo.BuildString); if (engine != null && engine.Name != null) { switch (engine.Name) { case "Halo 2 Vista": cboxCreatePatchTargetGame.SelectedIndex = (int)TargetGame.Halo2Vista; break; case "Halo 3: ODST": cboxCreatePatchTargetGame.SelectedIndex = (int)TargetGame.Halo3ODST; break; default: if (engine.Name.Contains("Halo 3")) cboxCreatePatchTargetGame.SelectedIndex = (int)TargetGame.Halo3; else if (engine.Name.Contains("Halo: Reach")) cboxCreatePatchTargetGame.SelectedIndex = (int)TargetGame.HaloReach; else if (engine.Name.Contains("Halo 4")) cboxCreatePatchTargetGame.SelectedIndex = (int)TargetGame.Halo4; else cboxCreatePatchTargetGame.SelectedIndex = 5; // Other break; } } cacheStream.Close(); }
private static void Main(string[] args) { if (args.Length != 3) { Console.WriteLine("Usage: mapexpand <map file> <section> <page count>"); Console.WriteLine(); Console.WriteLine("Available sections:"); Console.WriteLine(" stringidindex"); Console.WriteLine(" stringiddata"); Console.WriteLine(" tagnameindex"); Console.WriteLine(" tagnamedata"); Console.WriteLine(" resource"); Console.WriteLine(" tag"); return; } int pageCount; if (!int.TryParse(args[2], out pageCount) || pageCount <= 0) { Console.WriteLine("The page count must be a positive integer."); return; } Console.WriteLine("Reading..."); var stream = new EndianStream(File.Open(args[0], FileMode.Open, FileAccess.ReadWrite), Endian.BigEndian); var version = new CacheFileVersionInfo(stream); if (version.Engine != EngineType.ThirdGeneration) { Console.WriteLine("Only third-generation map files are supported."); return; } var database = XMLEngineDatabaseLoader.LoadDatabase("Formats/Engines.xml"); var buildInfo = database.FindEngineByVersion(version.BuildString); var cacheFile = new ThirdGenCacheFile(stream, buildInfo, version.BuildString); FileSegmentGroup area; FileSegment section; int pageSize; switch (args[1]) { case "stringidindex": area = cacheFile.StringArea; section = cacheFile.StringIDIndexTable; pageSize = 0x1000; break; case "stringiddata": area = cacheFile.StringArea; section = cacheFile.StringIDDataTable; pageSize = 0x1000; break; case "tagnameindex": area = cacheFile.StringArea; section = cacheFile.FileNameIndexTable; pageSize = 0x1000; break; case "tagnamedata": area = cacheFile.StringArea; section = cacheFile.FileNameDataTable; pageSize = 0x1000; break; case "resource": area = null; section = cacheFile.RawTable; pageSize = 0x1000; break; case "tag": area = cacheFile.MetaArea; section = cacheFile.MetaArea.Segments[0]; pageSize = 0x10000; break; default: Console.WriteLine("Invalid section name: \"{0}\"", args[1]); return; } Console.WriteLine("- Engine version: {0}", version.BuildString); Console.WriteLine("- Internal name: {0}", cacheFile.InternalName); Console.WriteLine("- Scenario name: {0}", cacheFile.ScenarioName); Console.WriteLine(); Console.WriteLine("Injecting empty pages..."); var injectSize = pageCount * pageSize; section.Resize(section.Size + injectSize, stream); Console.WriteLine("Adjusting the header..."); cacheFile.SaveChanges(stream); stream.Close(); Console.WriteLine(); var offset = section.Offset; if (section.ResizeOrigin == SegmentResizeOrigin.End) offset += section.ActualSize - injectSize; if (area != null) Console.WriteLine("Successfully injected 0x{0:X} bytes at 0x{1:X} (offset 0x{2:X}).", injectSize, area.BasePointer, offset); else Console.WriteLine("Successfully injected 0x{0:X} bytes at offset 0x{1:X}.", injectSize, offset); }
private void loadBLF() { try { _blf = new PureBLF(_blfLocation); var imgChunkData = new List<byte>(_blf.BLFChunks[1].ChunkData); imgChunkData.RemoveRange(0, 0x08); Dispatcher.Invoke(new Action(delegate { var image = new BitmapImage(); image.BeginInit(); image.StreamSource = new MemoryStream(imgChunkData.ToArray()); image.EndInit(); imgBLF.Source = image; var stream = new EndianStream(new MemoryStream(imgChunkData.ToArray<byte>()), Endian.BigEndian); stream.SeekTo(0x0); ushort imageMagic = stream.ReadUInt16(); switch (imageMagic) { case 0xFFD8: blfImageFormat = "JPEG"; break; case 0x8950: blfImageFormat = "PNG"; break; case 0x424D: blfImageFormat = "BMP"; break; default: blfImageFormat = "Unknown"; break; } // Add Image Info paneImageInfo.Children.Insert(0, new MapHeaderEntry("Image Format:", blfImageFormat)); paneImageInfo.Children.Insert(1, new MapHeaderEntry("Image Width:", image.PixelWidth + "px")); paneImageInfo.Children.Insert(2, new MapHeaderEntry("Image Height", image.PixelHeight + "px")); // Add BLF Info paneBLFInfo.Children.Insert(0, new MapHeaderEntry("BLF Length:", "0x" + _blf.BLFStream.Length.ToString("X"))); paneBLFInfo.Children.Insert(1, new MapHeaderEntry("BLF Chunks:", _blf.BLFChunks.Count.ToString(CultureInfo.InvariantCulture))); if (App.AssemblyStorage.AssemblySettings.StartpageHideOnLaunch) App.AssemblyStorage.AssemblySettings.HomeWindow.ExternalTabClose(Home.TabGenre.StartPage); RecentFiles.AddNewEntry(new FileInfo(_blfLocation).Name, _blfLocation, "BLF Image", Settings.RecentFileType.Blf); Close(); })); } catch (Exception ex) { Close(); Dispatcher.Invoke(new Action(delegate { MetroMessageBox.Show("Unable to open BLF", ex.Message.ToString(CultureInfo.InvariantCulture)); App.AssemblyStorage.AssemblySettings.HomeWindow.ExternalTabClose((LayoutDocument)Parent); })); } }
// Patch Applying private void btnApplyPatch_Click(object sender, RoutedEventArgs e) { try { // Check the user isn't completly retarded if (!CheckAllApplyMandatoryFields() || currentPatch == null) return; // Paths var unmoddedMapPath = txtApplyPatchUnmodifiedMap.Text; var outputPath = txtApplyPatchOutputMap.Text; // Copy the original map to the destination path File.Copy(unmoddedMapPath, outputPath, true); // Open the destination map using (var stream = new EndianStream(File.Open(outputPath, FileMode.Open, FileAccess.ReadWrite), Endian.BigEndian)) { var formatsPath = Path.Combine(VariousFunctions.GetApplicationLocation(), "Formats"); var loader = new BuildInfoLoader(Path.Combine(formatsPath, "SupportedBuilds.xml"), formatsPath); var cacheFile = CacheFileLoader.LoadCacheFile(stream, loader); if (currentPatch.MapInternalName != null && cacheFile.InternalName != currentPatch.MapInternalName) { MetroMessageBox.Show("Unable to apply patch", "Hold on there! That patch is for " + currentPatch.MapInternalName + ".map, and the unmodified map file you selected doesn't seem to match that. Find the correct file and try again."); return; } // Apply the patch! if (currentPatch.MapInternalName == null) currentPatch.MapInternalName = cacheFile.InternalName; // Because Ascension doesn't include this, and ApplyPatch() will complain otherwise PatchApplier.ApplyPatch(currentPatch, cacheFile, stream); // Check for blf snaps if (cbApplyPatchBlfExtraction.IsChecked != null && (PatchApplicationPatchExtra.Visibility == Visibility.Visible && (bool)cbApplyPatchBlfExtraction.IsChecked)) { var extractDir = Path.GetDirectoryName(outputPath); var blfDirectory = Path.Combine(extractDir, "images"); var infDirectory = Path.Combine(extractDir, "info"); if (!Directory.Exists(blfDirectory)) Directory.CreateDirectory(blfDirectory); if (!Directory.Exists(infDirectory)) Directory.CreateDirectory(infDirectory); var infPath = Path.Combine(infDirectory, Path.GetFileName(currentPatch.CustomBlfContent.MapInfoFileName)); File.WriteAllBytes(infPath, currentPatch.CustomBlfContent.MapInfo); foreach (var blfContainerEntry in currentPatch.CustomBlfContent.BlfContainerEntries) { var blfPath = Path.Combine(blfDirectory, Path.GetFileName(blfContainerEntry.FileName)); File.WriteAllBytes(blfPath, blfContainerEntry.BlfContainer); } } } MetroMessageBox.Show("Patch Applied!", "Your patch has been applied successfully. Have fun!"); } catch (Exception ex) { MetroException.Show(ex); } }
static void Main(string[] args) { if (args.Length != 2) { Console.WriteLine("Usage: mapexpand <map file> <page count>"); Console.WriteLine("Pages are multiples of 0x10000 bytes."); return; } int pageCount; if (!int.TryParse(args[1], out pageCount) || pageCount <= 0) { Console.WriteLine("The page count must be a positive integer."); return; } Console.WriteLine("Reading..."); EndianStream stream = new EndianStream(File.Open(args[0], FileMode.Open, FileAccess.ReadWrite), Endian.BigEndian); CacheFileVersionInfo version = new CacheFileVersionInfo(stream); if (version.Engine != EngineType.ThirdGeneration) { Console.WriteLine("Only third-generation map files are supported."); return; } BuildInfoLoader infoLoader = new BuildInfoLoader(XDocument.Load("Formats/SupportedBuilds.xml"), "Formats/"); BuildInformation buildInfo = infoLoader.LoadBuild(version.BuildString); ThirdGenCacheFile cacheFile = new ThirdGenCacheFile(stream, buildInfo, version.BuildString); Console.WriteLine("- Engine version: {0}", version.BuildString); Console.WriteLine("- Internal name: {0}", cacheFile.InternalName); Console.WriteLine("- Scenario name: {0}", cacheFile.ScenarioName); Console.WriteLine("- File size: 0x{0:X}", cacheFile.FileSize); Console.WriteLine("- Virtual size: 0x{0:X}", cacheFile.MetaArea.Size); for (int i = 0; i < cacheFile.Partitions.Length; i++) { var partition = cacheFile.Partitions[i]; if (partition.BasePointer != null) Console.WriteLine(" - Partition {0} at 0x{1:X}-0x{2:X} (size=0x{3:X})", i, partition.BasePointer.AsPointer(), partition.BasePointer.AsPointer() + partition.Size - 1, partition.Size); } Console.WriteLine("- Meta pointer mask: 0x{0:X}", cacheFile.MetaArea.PointerMask); Console.WriteLine("- Locale pointer mask: 0x{0:X}", (uint)-cacheFile.LocaleArea.PointerMask); Console.WriteLine("- String pointer mask: 0x{0:X}", cacheFile.StringArea.PointerMask); Console.WriteLine(); Console.WriteLine("Injecting empty pages..."); int injectSize = pageCount * 0x10000; Console.WriteLine("- Start address: 0x{0:X} (offset 0x{1:X})", cacheFile.MetaArea.BasePointer - injectSize, cacheFile.MetaArea.Offset); cacheFile.MetaArea.Resize(cacheFile.MetaArea.Size + injectSize, stream); Console.WriteLine(); Console.WriteLine("Adjusting the header..."); cacheFile.SaveChanges(stream); Console.WriteLine(); Console.WriteLine("Successfully injected 0x{0:X} bytes at 0x{1:X} (offset 0x{2:X}).", injectSize, cacheFile.MetaArea.BasePointer, cacheFile.MetaArea.Offset); stream.Close(); }
private void btnInjectImage_Click(object sender, RoutedEventArgs e) { try { var ofd = new OpenFileDialog { Title = "Opem an image to be injected", Filter = "JPEG Image (*.jpg)|*.jpg|JPEG Image (*.jpeg)|*.jpeg" }; if (!((bool) ofd.ShowDialog())) return; var newImage = File.ReadAllBytes(ofd.FileName); var stream = new EndianStream(new MemoryStream(newImage), Endian.BigEndian); // Check if it's a JIFI stream.SeekTo(0x02); var imageMagic = stream.ReadAscii(); if (imageMagic != "JFIF") throw new Exception("Invalid image type, it has to be a JPEG (JFIF in the header)."); // Check if it's the right size var image = new BitmapImage(); image.BeginInit(); image.StreamSource = new MemoryStream(newImage); image.EndInit(); if (image.PixelWidth != ((BitmapImage)imgBLF.Source).PixelWidth || image.PixelHeight != ((BitmapImage)imgBLF.Source).PixelHeight) throw new Exception(string.Format("Image isn't the right size. It must be {0}x{1}", ((BitmapImage)imgBLF.Source).PixelWidth, ((BitmapImage)imgBLF.Source).PixelHeight)); // It's the right everything! Let's inject var newImageChunkData = new List<byte>(); newImageChunkData.AddRange(new byte[] { 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 }); var imageLength = BitConverter.GetBytes(newImage.Length); Array.Reverse(imageLength); newImageChunkData.AddRange(imageLength); newImageChunkData.AddRange(newImage); // Write data to chunk file _blf.BLFChunks[1].ChunkData = newImageChunkData.ToArray<byte>(); _blf.RefreshRelativeChunkData(); _blf.UpdateChunkTable(); imgBLF.Source = image; MetroMessageBox.Show("Injected!", "The BLF Image has been injected."); } catch (Exception ex) { MetroMessageBox.Show("Inject Failed!", "The BLF Image failed to be injected: \n " + ex.Message); } }
private EndianStream skipExifData(EndianStream image) { Bitmap bitmap = new Bitmap(image.BaseStream); Stream output = new MemoryStream(); // load into bitmap, remove all exlif data foreach (PropertyItem item in bitmap.PropertyItems) { if (item.Type == 2) bitmap.RemovePropertyItem(item.Id); } bitmap.Save(output, ImageFormat.Jpeg); return new EndianStream(output, image.Endianness); }
private void Initalize(Stream blfStream) { _stream = new EndianStream(blfStream, Endian.BigEndian); // Load MapInfo shit LoadMapInfo(); }
private void UpdateMeta(MetaWriter.SaveType type, bool onlyUpdateChanged, bool showActionDialog = true) { if (type == MetaWriter.SaveType.File) { using (EndianStream stream = new EndianStream(_streamManager.OpenReadWrite(), _streamManager.SuggestedEndian)) { #if DEBUG_SAVE_ALL MetaWriter metaUpdate = new MetaWriter(writer, (uint)_tag.RawTag.MetaLocation.AsOffset(), _cache, _buildInfo, type, null); #else MetaWriter metaUpdate = new MetaWriter(stream, (uint)_tag.RawTag.MetaLocation.AsOffset(), _cache, _buildInfo, type, _fileChanges); #endif metaUpdate.WriteFields(_pluginVisitor.Values); _cache.SaveChanges(stream); _fileChanges.MarkAllUnchanged(); } if (showActionDialog) MetroMessageBox.Show("Meta Saved", "The metadata has been saved back to the original file."); } else if (_rteProvider != null) { using (IStream metaStream = _rteProvider.GetMetaStream(_cache)) { if (metaStream != null) { FieldChangeSet changes = onlyUpdateChanged ? _memoryChanges : null; MetaWriter metaUpdate = new MetaWriter(metaStream, _tag.RawTag.MetaLocation.AsPointer(), _cache, _buildInfo, type, changes); metaUpdate.WriteFields(_pluginVisitor.Values); if (showActionDialog) { if (onlyUpdateChanged) MetroMessageBox.Show("Meta Poked", "All changed metadata has been poked to the game."); else MetroMessageBox.Show("Meta Poked", "The metadata has been poked to the game."); } } else { switch (_rteProvider.ConnectionType) { case RTEConnectionType.Console: MetroMessageBox.Show("Connection Error", "Unable to connect to your Xbox 360 console. Make sure that XBDM is enabled, you have the Xbox 360 SDK installed, and that your console's IP has been set correctly."); break; case RTEConnectionType.LocalProcess: MetroMessageBox.Show("Connection Error", "Unable to connect to the game. Make sure that it is running on your computer and that the map you are poking to is currently loaded."); break; } } } } }
private void StartupDetermineType(string path) { try { if (File.Exists(path)) { // Magic Check var stream = new EndianStream(new FileStream(path, FileMode.Open), Endian.BigEndian); stream.SeekTo(0); switch (stream.ReadAscii(0x04).ToLower()) { case "head": // Map File stream.Close(); AddCacheTabModule(path); return; case "asmp": // Patch File stream.Close(); AddPatchTabModule(path); return; case "_blf": // BLF Container, needs more checking stream.Close(); var blf = new PureBLF(path); blf.Close(); if (blf.BLFChunks.Count > 2) { switch (blf.BLFChunks[1].ChunkMagic) { case "levl": AddInfooTabModule(path); return; case "mapi": AddImageTabModule(path); return; } } MetroMessageBox.Show("Unsupported BLF Type", "The selected BLF file is not supported in assembly."); return; default: MetroMessageBox.Show("Unsupported file type", "The selected file is not supported in assembly."); return; } } MetroMessageBox.Show("Unable to find file", "The selected file could no longer be found"); } catch (Exception ex) { MetroException.Show(ex); } }
// Patch Applying private void btnApplyPatch_Click(object sender, RoutedEventArgs e) { try { // Check the user isn't completly retarded if (!CheckAllApplyMandatoryFields() || currentPatch == null) return; // Check the output name if (currentPatch.OutputName != "") if (Path.GetFileNameWithoutExtension(txtApplyPatchOutputMap.Text) != currentPatch.OutputName) if (MetroMessageBox.Show("Warning", "This patch suggests to use the filename \"" + currentPatch.OutputName + ".map\" to save this map. This filename may be required in order for the map to work correctly.\r\n\r\nAre you sure you want to save this map as \"" + Path.GetFileName(txtApplyPatchOutputMap.Text) + "\"?", MetroMessageBox.MessageBoxButtons.OkCancel) != MetroMessageBox.MessageBoxResult.OK) { Close(); return; } // Paths string unmoddedMapPath = txtApplyPatchUnmodifiedMap.Text; string outputPath = txtApplyPatchOutputMap.Text; // Copy the original map to the destination path File.Copy(unmoddedMapPath, outputPath, true); // Open the destination map using (var stream = new EndianStream(File.Open(outputPath, FileMode.Open, FileAccess.ReadWrite), Endian.BigEndian)) { EngineDatabase engineDb = XMLEngineDatabaseLoader.LoadDatabase("Formats/Engines.xml"); ICacheFile cacheFile = CacheFileLoader.LoadCacheFile(stream, engineDb); if (currentPatch.MapInternalName != null && cacheFile.InternalName != currentPatch.MapInternalName) { MetroMessageBox.Show("Unable to apply patch", "Hold on there! That patch is for " + currentPatch.MapInternalName + ".map, and the unmodified map file you selected doesn't seem to match that. Find the correct file and try again."); return; } // Apply the patch! if (currentPatch.MapInternalName == null) currentPatch.MapInternalName = cacheFile.InternalName; // Because Ascension doesn't include this, and ApplyPatch() will complain otherwise PatchApplier.ApplyPatch(currentPatch, cacheFile, stream); // Check for blf snaps if (cbApplyPatchBlfExtraction.IsChecked != null && (PatchApplicationPatchExtra.Visibility == Visibility.Visible && (bool) cbApplyPatchBlfExtraction.IsChecked)) { string extractDir = Path.GetDirectoryName(outputPath); string blfDirectory = Path.Combine(extractDir, "images"); string infDirectory = Path.Combine(extractDir, "info"); if (!Directory.Exists(blfDirectory)) Directory.CreateDirectory(blfDirectory); if (!Directory.Exists(infDirectory)) Directory.CreateDirectory(infDirectory); string infPath = Path.Combine(infDirectory, Path.GetFileName(currentPatch.CustomBlfContent.MapInfoFileName)); File.WriteAllBytes(infPath, currentPatch.CustomBlfContent.MapInfo); foreach (BlfContainerEntry blfContainerEntry in currentPatch.CustomBlfContent.BlfContainerEntries) { string blfPath = Path.Combine(blfDirectory, Path.GetFileName(blfContainerEntry.FileName)); File.WriteAllBytes(blfPath, blfContainerEntry.BlfContainer); } } } MetroMessageBox.Show("Patch Applied!", "Your patch has been applied successfully. Have fun!"); } catch (Exception ex) { MetroException.Show(ex); } }
private void ProcessMapHeader() { using (IReader reader = new EndianStream(new MemoryStream(MapHeader), Endian.LittleEndian)) { reader.SeekTo(MapTypeOffset); MapType = (CacheFileType) reader.ReadInt32(); reader.SeekTo(MapNameOffset); MapName = reader.ReadAscii(); reader.SeekTo(ScenarioNameOffset); ScenarioName = reader.ReadAscii(); } }
private void btnExtractInfo_Click(object sender, RoutedEventArgs e) { System.Windows.Clipboard.SetText("Name: " + txtApplyPatchName.Text + "\r\nDescription: " + txtApplyPatchDesc.Text); var messageString = "The patch name and description has been copied to the clipboard."; if (currentPatch.Screenshot != null) try { var stream = new EndianStream(new MemoryStream(currentPatch.Screenshot), Endian.BigEndian); stream.SeekTo(0x0); ushort imageMagic = stream.ReadUInt16(); var sfd = new SaveFileDialog(); sfd.Title = "Assembly - Save Patch Image"; switch (imageMagic) { case 0x8950: sfd.Filter = "PNG Image (*.png)|*.png"; break; default: sfd.Filter = "JPEG Image (*.jpg)|*.jpg"; break; } if (sfd.ShowDialog() == DialogResult.OK) { File.WriteAllBytes(sfd.FileName, currentPatch.Screenshot); messageString += "\r\n\r\nThe patch image has been saved."; } } catch (Exception ex) { messageString += "\r\n\r\nThe patch image could not saved: \n" + ex.Message; } MetroMessageBox.Show("Information Extracted!", messageString); }
private void btnInjectImage_Click(object sender, RoutedEventArgs e) { try { _blf = new PureBLF(_blfLocation); var ofd = new OpenFileDialog { Title = "Open an image to be injected", Filter = "JPEG Image (*.jpg,*.jpeg,)|*.jpg;*.jpeg|PNG Image [H3/ODST]|*.png|BMP Image [H3/ODST]|*.bmp" }; if (!((bool)ofd.ShowDialog())) { Close(); return; } byte[] newImage = File.ReadAllBytes(ofd.FileName); var stream = new EndianStream(new MemoryStream(newImage), Endian.BigEndian); // Check if it's a supported image stream.SeekTo(0x0); ushort imageMagic = stream.ReadUInt16(); if (imageMagic != 0xFFD8 && imageMagic != 0x8950 && imageMagic != 0x424D) throw new Exception("Invalid image type. Only JPEG, PNG, and BMP are supported."); // Check for size and dimension differences var imageSize = new FileInfo(ofd.FileName).Length; var image = new BitmapImage(); image.BeginInit(); image.StreamSource = new MemoryStream(newImage); image.EndInit(); string sizeMessage = ""; string dimensionMessage = ""; if (new FileInfo(ofd.FileName).Length >= 0x1C000) sizeMessage = String.Format("- The size of the new image (0x{0}) exceeds Halo 3/ODST's modified limit of 0x1C000. This image will not display in those games as a result. Can be ignored otherwise.\n", imageSize.ToString("X")); if (image.PixelWidth != ((BitmapImage)imgBLF.Source).PixelWidth || image.PixelHeight != ((BitmapImage)imgBLF.Source).PixelHeight) dimensionMessage = String.Format("- The dimensions of the new image ({0}x{1}) are not the same as the dimensions of the original image ({2}x{3}). This blf may appear stretched or not appear at all as a result.\n", image.PixelWidth, image.PixelHeight, ((BitmapImage)imgBLF.Source).PixelWidth, ((BitmapImage)imgBLF.Source).PixelHeight); if (dimensionMessage != "" || sizeMessage != "") if (MetroMessageBox.Show("Warning", "There were some potential issue(s) found with your new image;\n\n" + String.Format("{0}{1}", sizeMessage, dimensionMessage) + "\nInject anyway?", MetroMessageBox.MessageBoxButtons.OkCancel) != MetroMessageBox.MessageBoxResult.OK) { Close(); return; } // It's the right everything! Let's inject var newImageChunkData = new List<byte>(); newImageChunkData.AddRange(new byte[] { 0x00, 0x00, 0x00, 0x00 }); byte[] imageLength = BitConverter.GetBytes(newImage.Length); Array.Reverse(imageLength); newImageChunkData.AddRange(imageLength); newImageChunkData.AddRange(newImage); // Write data to chunk file _blf.BLFChunks[1].ChunkData = newImageChunkData.ToArray<byte>(); _blf.RefreshRelativeChunkData(); _blf.UpdateChunkTable(); // Update eof offset value var eofstream = new EndianStream(new MemoryStream(_blf.BLFChunks[2].ChunkData), Endian.BigEndian); uint eofFixup = (uint)_blf.BLFStream.Length - 0x111; //real cheap but hey it works and is always the same in all games eofstream.SeekTo(0); eofstream.WriteUInt32(eofFixup); _blf.RefreshRelativeChunkData(); _blf.UpdateChunkTable(); Close(); MetroMessageBox.Show("Injected!", "The BLF Image has been injected. This image tab will now close."); App.AssemblyStorage.AssemblySettings.HomeWindow.ExternalTabClose(_tab); } catch (Exception ex) { Close(); MetroMessageBox.Show("Inject Failed!", "The BLF Image failed to be injected: \n " + ex.Message); } }