using System; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Threading; using System.Windows.Forms; using DotNetCTFDumper.MMFParser.ChunkLoaders; using DotNetCTFDumper.MMFParser.ChunkLoaders.Banks; using DotNetCTFDumper.MMFParser.Data; using DotNetCTFDumper.MMFParser.Decompiling; using DotNetCTFDumper.Utils; namespace DotNetCTFDumper.GUI { public partial class MainForm : Form { public static bool IsDumpingImages; public static bool IsDumpingSounds; public static bool IsDumpingMusics; public static bool BreakImages; public static bool BreakSounds; public static bool BreakMusics; public Thread LoaderThread; public Color ColorTheme = Color.FromArgb(223,114,38); public PackDataForm PackForm; public MainForm() { //Buttons InitializeComponent(); cryptKeyBtn.ForeColor = ColorTheme; dumpSortedBtn.ForeColor = ColorTheme; showHexBtn.ForeColor = ColorTheme; FolderBTN.ForeColor = ColorTheme; MFABtn.ForeColor = ColorTheme; imagesButton.ForeColor = ColorTheme; soundsButton.ForeColor = ColorTheme; packDataBtn.ForeColor = ColorTheme; //Menu saveChunkBtn.ForeColor = ColorTheme; saveChunkBtn.BackColor=Color.Black; viewHexBtn.ForeColor = ColorTheme; viewHexBtn.BackColor=Color.Black; previewFrameBtn.ForeColor = ColorTheme; previewFrameBtn.BackColor=Color.Black; //Labels label1.ForeColor = ColorTheme; label1.Text = Settings.DumperVersion; button1.ForeColor = ColorTheme; GameInfo.ForeColor = ColorTheme; loadingLabel.ForeColor = ColorTheme; imageLabel.ForeColor = ColorTheme; soundLabel.ForeColor=ColorTheme; //Other treeView1.ForeColor = ColorTheme; listBox1.ForeColor = ColorTheme; imageBar.ForeColor = ColorTheme; soundBar.ForeColor = ColorTheme; } private void openFileDialog1_FileOk(object sender, CancelEventArgs e) { var worker = new BackgroundWorker(); worker.DoWork += worker_DoWork; worker.RunWorkerCompleted += worker_RunWorkerCompleted; worker.RunWorkerAsync(); } void worker_DoWork(object sender, DoWorkEventArgs e) { StartReading(); } void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { AfterLoad(); } private void button1_Click(object sender, EventArgs e) { openFileDialog1.ShowDialog(); } private void MainForm_Load(object sender, EventArgs e) { loadingLabel.Visible = false; listBox1.Items.Clear(); } private void StartReading() { var path = openFileDialog1.FileName; Program.ReadFile(path, Settings.Verbose, Settings.DumpImages, Settings.DumpSounds); imageBar.Value = 0; soundBar.Value = 0; GameInfo.Text = ""; loadingLabel.Visible = true; imageLabel.Text = "Using nonGUI mode"; soundLabel.Text = "Using nonGUI mode"; MFABtn.Visible = false; FolderBTN.Visible = false; imagesButton.Visible = false; soundsButton.Visible = false; musicsButton.Visible = false; cryptKeyBtn.Visible = false; showHexBtn.Visible = false; dumpSortedBtn.Visible = false; packDataBtn.Visible = false; } private void treeView1_AfterDblClick(object sender, EventArgs e) { ChunkCombo.Show(Cursor.Position); } private void treeView1_RightClick(object sender, MouseEventArgs e) { if ((e.Button & MouseButtons.Right) != 0) { ChunkCombo.Show(Cursor.Position); } } private void ChunkCombo_ItemSelected(object sender, ToolStripItemClickedEventArgs e) { switch (e.ClickedItem.Name) { case "saveChunkBtn": var chunk = ((ChunkNode) treeView1.SelectedNode).chunk; if ( chunk!= null) { chunk.Save(); } break; case "viewHexBtn": ShowHex(); break; case "previewFrameBtn": var selected = ((ChunkNode) treeView1.SelectedNode).loader; if (selected is Frame frm) { var viewer = new FrameViewer(frm,Exe.Instance.GameData.GameChunks.GetChunk()); viewer.Show(); } break; } } private void treeView1_AfterSelect(object sender, TreeViewEventArgs e) { var nodeChunk = ((ChunkNode) treeView1.SelectedNode).chunk; var nodeLoader = ((ChunkNode) treeView1.SelectedNode).loader; listBox1.Items.Clear(); if (nodeChunk != null) { listBox1.Items.Add($"Name: {nodeChunk.Name}"); listBox1.Items.Add($"Id: {nodeChunk.Id}"); listBox1.Items.Add($"Flag: {nodeChunk.Flag}"); listBox1.Items.Add($"Size: {nodeChunk.Size.ToPrettySize()}"); if (nodeChunk.DecompressedSize>-1)listBox1.Items.Add($"Decompressed Size: {nodeChunk.DecompressedSize.ToPrettySize()}"); } if (nodeLoader != null) { var extData = nodeLoader.GetReadableData(); if (extData.Length > 0) { listBox1.Items.Add(""); listBox1.Items.Add("Loader Data:"); foreach (var item in extData) { var splitFlags = item.Split(';'); foreach (var splitItem in splitFlags) listBox1.Items.Add(splitItem); } } } } public void AfterLoad() { //GameData gameData = null; var exe = Exe.Instance; var gameData = exe.GameData; treeView1.Nodes.Clear(); foreach (var item in gameData.GameChunks.Chunks) { string ActualName = item.Name; if (item.Loader is Frame frm) ActualName = ActualName + " "+frm.Name; ChunkNode newNode = Helper.GetChunkNode(item,ActualName); //if (item.Loader != null) newNode = new ChunkNode(ActualName, item.Loader); //else newNode = new ChunkNode(ActualName, item); treeView1.Nodes.Add(newNode); if (item.Loader is Frame frame) foreach (var frmChunk in frame.Chunks.Chunks) { var frameNode = Helper.GetChunkNode(frmChunk); newNode.Nodes.Add(frameNode); if (frameNode.loader is ObjectInstances) { var objs = frame.Chunks.GetChunk(); if (objs != null) { foreach (var frmitem in objs.Items) { var objNode = new ChunkNode(frmitem.Name, frmitem); frameNode.Nodes.Add(objNode); } } } } } MFABtn.Visible = true; FolderBTN.Visible = true; imagesButton.Visible = true; soundsButton.Visible = true; musicsButton.Visible = true; cryptKeyBtn.Visible = true; //showHexBtn.Visible = true; dumpSortedBtn.Visible = true; packDataBtn.Visible = true; GameInfo.Visible = true; loadingLabel.Visible = false; var toLog = ""; toLog += $"Title:{Exe.Instance.GameData.Name}\n"; toLog += $"Copyright:{Exe.Instance.GameData.Copyright}\n"; toLog += $"Editor Filename: {Exe.Instance.GameData.EditorFilename}\n"; toLog += $"Product Version: {Exe.Instance.GameData.ProductVersion}\n"; toLog += $"Build: {Exe.Instance.GameData.Build}\n"; toLog += $"Runtime Version: {Exe.Instance.GameData.RuntimeVersion}\n"; toLog += $"Number Of Images: {Exe.Instance.GameData.Images.NumberOfItems}\n"; toLog += $"Number Of Sounds: {(Exe.Instance.GameData.Sounds!= null ? Exe.Instance.GameData.Sounds.NumOfItems: 0)}\n"; toLog += $"Unique FrameItems: {Exe.Instance.GameData.Frameitems.NumberOfItems}\n"; toLog += $"Frame Count: {Exe.Instance.GameData.Frames.Count}\n"; toLog += $"Chunks Count: {Exe.Instance.GameData.GameChunks.Chunks.Count}\n"; //toLog += $"Runtime Subversion: {Exe.LatestInst.GameData.RuntimeSubversion}\n"; GameInfo.Text = toLog; } public void UpdateImageBar(int index, int all) { all -= 1; imageBar.Value = (int) (index / (float) all * 100); imageLabel.Text = $"{index}/{all}"; } public void UpdateSoundBar(int index, int all) { all -= 1; soundBar.Value = (int) (index / (float) all * 100); soundLabel.Text = $"{index}/{all}"; } public void UpdateMusicBar(int index, int all) { all -= 1; musicBar.Value = (int) (index / (float) all * 100); musicLabel.Text = $"{index}/{all}"; } private void FolderBTN_Click(object sender, EventArgs e) { Process.Start($"{Settings.DumpPath}"); } private void MFABtn_Click(object sender, EventArgs e) { MFAGenerator.BuildMFA(); } private void soundsButton_Click(object sender, EventArgs e) { if (!IsDumpingSounds) { SetSoundElements(true); Backend.DumpSounds(this,true,true); } else { BreakSounds = true; IsDumpingSounds = false; SetSoundElements(false); } } private void imagesButton_Click(object sender, EventArgs e) { if (!IsDumpingImages) { SetImageElements(true); Backend.DumpImages(this,true,true); } else { BreakImages = true; IsDumpingImages = false; SetImageElements(false); } } public void SetSoundElements(bool state) { soundBar.Visible = state; soundLabel.Visible = state; soundsButton.Text = state ? "Cancel":"Dump Sounds"; soundBar.Value = 0; } public void SetImageElements(bool state) { imageBar.Visible = state; imageLabel.Visible = state; imagesButton.Text = state ? "Cancel":"Dump Images"; imageBar.Value = 0; } public void SetMusicElements(bool state) { musicBar.Visible = state; musicLabel.Visible = state; musicsButton.Text = state ? "Cancel":"Dump Musics"; musicBar.Value = 0; } private void cryptKeyBtn_Click(object sender, EventArgs e) { var rawData = ""; if (Settings.Build > 284) { rawData += Settings.AppName; rawData += Settings.Copyright; rawData += Settings.ProjectPath; } else { rawData += Settings.ProjectPath; rawData += Settings.AppName; rawData += Settings.Copyright; } var KeyForm = new CryptoKeyForm(rawData,ColorTheme); KeyForm.Show(); } private void ShowHex() { if ((ChunkNode) treeView1.SelectedNode != null) { var node = ((ChunkNode) treeView1.SelectedNode); HexViewForm hexform = null; hexform = new HexViewForm(node.chunk.ChunkData, node.chunk.RawData, ColorTheme, $"Hew View: {node.chunk.Name}"); hexform.Show(); } } private void dumpSortedBtn_Click(object sender, EventArgs e) { imageBar.Visible = true; imageLabel.Visible = true; var worker = new BackgroundWorker(); worker.DoWork += (senderA, eA) => { Settings.DumpImages = true; var bank = Exe.Instance.GameData.GameChunks.GetChunk(); bank.SaveImages=false; bank.Read(); }; worker.RunWorkerCompleted += (senderA, eA) => { imageBar.Visible = false; imageLabel.Visible = false; ImageDumper.DumpImages(); }; worker.RunWorkerAsync(); } private void tabPage1_Click(object sender, EventArgs e) { throw new System.NotImplementedException(); } private void packDataBtn_Click(object sender, EventArgs e) { if(PackForm==null)PackForm = new PackDataForm(Exe.Instance.PackData,ColorTheme); PackForm.Show(); } private void musicsButton_Click(object sender, EventArgs e) { if (!IsDumpingMusics) { Backend.DumpMusics(this,true,true); } else { BreakMusics = true; IsDumpingMusics = false; SetMusicElements(false); } } } }