From 8bcb0cd8a9d93d31fc68d89d7878e46ffad86f7c Mon Sep 17 00:00:00 2001 From: 1987kostya Date: Sat, 19 Dec 2020 11:23:10 +0600 Subject: [PATCH] Animation support for Advanced Image Viewer --- DotNetCTFDumper/GUI/MainForm.Designer.cs | 49 +++- DotNetCTFDumper/GUI/MainForm.cs | 284 ++++++++++++++--------- DotNetCTFDumper/PluginAPI/IPlugin.cs | 1 + DotNetCTFDumper/PluginAPI/PluginAPI.cs | 70 +++++- 4 files changed, 288 insertions(+), 116 deletions(-) diff --git a/DotNetCTFDumper/GUI/MainForm.Designer.cs b/DotNetCTFDumper/GUI/MainForm.Designer.cs index af20a52..58e4c82 100644 --- a/DotNetCTFDumper/GUI/MainForm.Designer.cs +++ b/DotNetCTFDumper/GUI/MainForm.Designer.cs @@ -69,9 +69,12 @@ this.hexBox1 = new Be.Windows.Forms.HexBox(); this.charBox = new System.Windows.Forms.TextBox(); this.advDumpTab = new System.Windows.Forms.TabPage(); + this.advancedInfoLabel = new System.Windows.Forms.Label(); + this.advancedPlayAnimation = new System.Windows.Forms.Button(); this.advancedPictureBox = new System.Windows.Forms.PictureBox(); this.advancedTreeView = new System.Windows.Forms.TreeView(); this.pluginTab = new System.Windows.Forms.TabPage(); + this.pluginLogBox = new System.Windows.Forms.TextBox(); this.activatePluginBtn = new System.Windows.Forms.Button(); this.pluginsList = new System.Windows.Forms.ListBox(); this.packDataDialog = new System.Windows.Forms.SaveFileDialog(); @@ -590,6 +593,8 @@ // advDumpTab // this.advDumpTab.BackColor = System.Drawing.Color.DimGray; + this.advDumpTab.Controls.Add(this.advancedInfoLabel); + this.advDumpTab.Controls.Add(this.advancedPlayAnimation); this.advDumpTab.Controls.Add(this.advancedPictureBox); this.advDumpTab.Controls.Add(this.advancedTreeView); this.advDumpTab.ForeColor = System.Drawing.Color.FromArgb(((int) (((byte) (255)))), ((int) (((byte) (128)))), ((int) (((byte) (0))))); @@ -600,6 +605,27 @@ this.advDumpTab.TabIndex = 1; this.advDumpTab.Text = "Advanced"; // + // advancedInfoLabel + // + this.advancedInfoLabel.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.advancedInfoLabel.BackColor = System.Drawing.Color.FromArgb(((int) (((byte) (64)))), ((int) (((byte) (64)))), ((int) (((byte) (64))))); + this.advancedInfoLabel.Location = new System.Drawing.Point(777, 3); + this.advancedInfoLabel.Name = "advancedInfoLabel"; + this.advancedInfoLabel.Size = new System.Drawing.Size(155, 63); + this.advancedInfoLabel.TabIndex = 3; + this.advancedInfoLabel.Text = "DEBUG"; + // + // advancedPlayAnimation + // + this.advancedPlayAnimation.Dock = System.Windows.Forms.DockStyle.Bottom; + this.advancedPlayAnimation.Location = new System.Drawing.Point(170, 441); + this.advancedPlayAnimation.Name = "advancedPlayAnimation"; + this.advancedPlayAnimation.Size = new System.Drawing.Size(762, 35); + this.advancedPlayAnimation.TabIndex = 2; + this.advancedPlayAnimation.Text = "Play Animation"; + this.advancedPlayAnimation.UseVisualStyleBackColor = true; + this.advancedPlayAnimation.Click += new System.EventHandler(this.advancedPlayAnimation_Click); + // // advancedPictureBox // this.advancedPictureBox.BackColor = System.Drawing.Color.FromArgb(((int) (((byte) (64)))), ((int) (((byte) (64)))), ((int) (((byte) (64))))); @@ -623,6 +649,7 @@ // pluginTab // this.pluginTab.BackColor = System.Drawing.Color.Black; + this.pluginTab.Controls.Add(this.pluginLogBox); this.pluginTab.Controls.Add(this.activatePluginBtn); this.pluginTab.Controls.Add(this.pluginsList); this.pluginTab.Location = new System.Drawing.Point(4, 24); @@ -631,14 +658,25 @@ this.pluginTab.TabIndex = 5; this.pluginTab.Text = "Plugins"; // + // pluginLogBox + // + this.pluginLogBox.Dock = System.Windows.Forms.DockStyle.Right; + this.pluginLogBox.Location = new System.Drawing.Point(530, 0); + this.pluginLogBox.Multiline = true; + this.pluginLogBox.Name = "pluginLogBox"; + this.pluginLogBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + this.pluginLogBox.Size = new System.Drawing.Size(405, 479); + this.pluginLogBox.TabIndex = 2; + // // activatePluginBtn // + this.activatePluginBtn.Dock = System.Windows.Forms.DockStyle.Fill; this.activatePluginBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.activatePluginBtn.Font = new System.Drawing.Font("Feast of Flesh BB", 12F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((byte) (77))); this.activatePluginBtn.ForeColor = System.Drawing.Color.FromArgb(((int) (((byte) (255)))), ((int) (((byte) (128)))), ((int) (((byte) (0))))); - this.activatePluginBtn.Location = new System.Drawing.Point(258, 3); + this.activatePluginBtn.Location = new System.Drawing.Point(252, 0); this.activatePluginBtn.Name = "activatePluginBtn"; - this.activatePluginBtn.Size = new System.Drawing.Size(140, 67); + this.activatePluginBtn.Size = new System.Drawing.Size(683, 479); this.activatePluginBtn.TabIndex = 1; this.activatePluginBtn.Text = "Activate"; this.activatePluginBtn.UseVisualStyleBackColor = true; @@ -682,9 +720,16 @@ this.advDumpTab.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize) (this.advancedPictureBox)).EndInit(); this.pluginTab.ResumeLayout(false); + this.pluginTab.PerformLayout(); this.ResumeLayout(false); } + private System.Windows.Forms.Label advancedInfoLabel; + + private System.Windows.Forms.Button advancedPlayAnimation; + + public System.Windows.Forms.TextBox pluginLogBox; + private System.Windows.Forms.Button activatePluginBtn; private System.Windows.Forms.ListBox pluginsList; diff --git a/DotNetCTFDumper/GUI/MainForm.cs b/DotNetCTFDumper/GUI/MainForm.cs index 417662c..634d575 100644 --- a/DotNetCTFDumper/GUI/MainForm.cs +++ b/DotNetCTFDumper/GUI/MainForm.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; @@ -15,6 +16,8 @@ using DotNetCTFDumper.MMFParser.EXE.Loaders.Objects; using DotNetCTFDumper.MMFParser.MFA.Loaders.mfachunks; using DotNetCTFDumper.MMFParser.Translation; using DotNetCTFDumper.Utils; +using Animation = DotNetCTFDumper.MMFParser.EXE.Loaders.Objects.Animation; +using AnimationDirection = DotNetCTFDumper.MMFParser.EXE.Loaders.Objects.AnimationDirection; namespace DotNetCTFDumper.GUI { @@ -28,14 +31,14 @@ namespace DotNetCTFDumper.GUI public static bool BreakMusics; public static bool Loaded; public Thread LoaderThread; - public Color ColorTheme = Color.FromArgb(223,114,38); - + public Color ColorTheme = Color.FromArgb(223, 114, 38); + public delegate void SaveHandler(int index, int all); public delegate void IncrementSortedProgressBar(int all); - - + + public MainForm() { //Buttons @@ -43,13 +46,13 @@ namespace DotNetCTFDumper.GUI foreach (Control item in Controls) { item.ForeColor = ColorTheme; - if(!(item is PictureBox)&&!(item is TabPage))item.BackColor=Color.Black; - - if(item is Button) item.BackColor=Color.FromArgb(30,30,30); + if (!(item is PictureBox) && !(item is TabPage)) item.BackColor = Color.Black; + + if (item is Button) item.BackColor = Color.FromArgb(30, 30, 30); if (item is Label) { - item.BackColor = Color.Transparent; + //item.BackColor = Color.Transparent; item.Refresh(); } } @@ -59,34 +62,35 @@ namespace DotNetCTFDumper.GUI foreach (Control item in tabPage.Controls) { item.ForeColor = ColorTheme; - if(!(item is PictureBox)&&!(item is TabPage))item.BackColor=Color.Black; - if(item is Button) item.BackColor=Color.FromArgb(30,30,30); + if (!(item is PictureBox) && !(item is TabPage)&&!(item is Label)) item.BackColor = Color.Black; + if (item is Button) item.BackColor = Color.FromArgb(30, 30, 30); if (item is Label) { - item.BackColor = Color.Transparent; + //item.BackColor = Color.Transparent; item.Refresh(); } - + } } - + foreach (var item in ChunkCombo.Items) { - ((ToolStripItem)item).ForeColor = ColorTheme; - ((ToolStripItem)item).BackColor=Color.Black; + ((ToolStripItem) item).ForeColor = ColorTheme; + ((ToolStripItem) item).BackColor = Color.Black; } - hexBox1.ForeColor = ColorTheme; - hexBox1.InfoForeColor = Color.FromArgb(ColorTheme.R/2, ColorTheme.G/2, ColorTheme.B/2); - hexBox1.SelectionForeColor=Color.FromArgb(ColorTheme.R, ColorTheme.G, ColorTheme.B); - hexBox1.SelectionBackColor=Color.FromArgb(ColorTheme.R/4, ColorTheme.G/4, ColorTheme.B/4); - hexBox1.ShadowSelectionColor=Color.FromArgb(150,ColorTheme.R/4, ColorTheme.G/4, ColorTheme.B/4); + + hexBox1.ForeColor = ColorTheme; + hexBox1.InfoForeColor = Color.FromArgb(ColorTheme.R / 2, ColorTheme.G / 2, ColorTheme.B / 2); + hexBox1.SelectionForeColor = Color.FromArgb(ColorTheme.R, ColorTheme.G, ColorTheme.B); + hexBox1.SelectionBackColor = Color.FromArgb(ColorTheme.R / 4, ColorTheme.G / 4, ColorTheme.B / 4); + hexBox1.ShadowSelectionColor = Color.FromArgb(150, ColorTheme.R / 4, ColorTheme.G / 4, ColorTheme.B / 4); label1.Text = Settings.DumperVersion; - - Pame2Mfa.OnMessage += (obj)=> + + Pame2Mfa.OnMessage += (obj) => { var date = DateTime.Now; - string msg = (string)obj; + string msg = (string) obj; mfaLogBox.AppendText(msg.Length > 0 ? $"[{date.Hour,2}:{date.Minute,2}:{date.Second,2}:{date.Millisecond,3}] {msg}\r\n" : "\r\n"); @@ -104,13 +108,13 @@ namespace DotNetCTFDumper.GUI } - + private void openFileDialog1_FileOk(object sender, CancelEventArgs e) { var worker = new BackgroundWorker(); - worker.DoWork +=(workSender,workE)=> StartReading(); - worker.RunWorkerCompleted += (workSender,workE)=> AfterLoad(); + worker.DoWork += (workSender, workE) => StartReading(); + worker.RunWorkerCompleted += (workSender, workE) => AfterLoad(); worker.RunWorkerAsync(); } @@ -124,16 +128,16 @@ namespace DotNetCTFDumper.GUI loadingLabel.Visible = false; listBox1.Items.Clear(); } - - + + private void StartReading() { var path = openFileDialog1.FileName; loadingLabel.Visible = true; Program.ReadFile(path, Settings.Verbose, Settings.DumpImages, Settings.DumpSounds); - + imageBar.Value = 0; - soundBar.Value = 0; + soundBar.Value = 0; GameInfo.Text = ""; imageLabel.Text = "Using nonGUI mode"; soundLabel.Text = "Using nonGUI mode"; @@ -143,34 +147,37 @@ namespace DotNetCTFDumper.GUI soundsButton.Visible = false; musicsButton.Visible = false; dumpSortedBtn.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) + if (chunk != null) { chunk.Save(); } + break; case "viewHexBtn": ShowHex(); @@ -179,7 +186,7 @@ namespace DotNetCTFDumper.GUI var selected = ((ChunkNode) treeView1.SelectedNode).loader; if (selected is Frame frm) { - var viewer = new FrameViewer(frm,Exe.Instance.GameData.GameChunks.GetChunk()); + var viewer = new FrameViewer(frm, Exe.Instance.GameData.GameChunks.GetChunk()); viewer.Show(); } @@ -191,18 +198,19 @@ namespace DotNetCTFDumper.GUI { 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 (nodeChunk.DecompressedSize > -1) + listBox1.Items.Add($"Decompressed Size: {nodeChunk.DecompressedSize.ToPrettySize()}"); } - + if (nodeLoader != null) { var extData = nodeLoader.GetReadableData(); @@ -218,8 +226,9 @@ namespace DotNetCTFDumper.GUI } } } - GameInfo.BackColor=Color.Transparent; - + + GameInfo.BackColor = Color.Transparent; + GameInfo.Refresh(); } @@ -233,7 +242,7 @@ namespace DotNetCTFDumper.GUI 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); @@ -263,13 +272,14 @@ namespace DotNetCTFDumper.GUI foreach (var key in items.ItemDict.Keys) { var frameItem = items.ItemDict[key]; - var objNode = new ChunkNode($"{(Constants.ObjectType)frameItem.ObjectType} - {frameItem.Name}", frameItem); + var objNode = new ChunkNode($"{(Constants.ObjectType) frameItem.ObjectType} - {frameItem.Name}", + frameItem); newNode.Nodes.Add(objNode); } } } - + FolderBTN.Visible = true; imagesButton.Visible = true; soundsButton.Visible = true; @@ -284,7 +294,7 @@ namespace DotNetCTFDumper.GUI InitPlugins(); var toLog = ""; toLog += $"Title:{Exe.Instance.GameData.Name}\n"; - toLog += $"Copyright:{Exe.Instance.GameData.Copyright}\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"; @@ -302,13 +312,13 @@ namespace DotNetCTFDumper.GUI if (Exe.Instance.GameData.GameChunks.GetChunk() != null) Exe.Instance.GameData.GameChunks.GetChunk().OnMusicSaved += UpdateMusicBar; ImageDumper.SortedImageSaved += IncrementSortedBar; - - + + GameInfo.Text = toLog; } - + public void UpdateImageBar(int index, int all) { @@ -323,6 +333,7 @@ namespace DotNetCTFDumper.GUI soundBar.Value = (int) (index / (float) all * 100); soundLabel.Text = $"{index}/{all}"; } + public void UpdateMusicBar(int index, int all) { all -= 1; @@ -347,7 +358,7 @@ namespace DotNetCTFDumper.GUI Process.Start($"{Settings.DumpPath}"); } - + private void soundsButton_Click(object sender, EventArgs e) { @@ -356,8 +367,8 @@ namespace DotNetCTFDumper.GUI { SetSoundElements(true); IsDumpingSounds = true; - Backend.DumpSounds(this,true,true); - + Backend.DumpSounds(this, true, true); + } else { @@ -366,6 +377,7 @@ namespace DotNetCTFDumper.GUI SetSoundElements(false); } } + private void imagesButton_Click(object sender, EventArgs e) { if (Exe.Instance.GameData.GameChunks.GetChunk() == null) return; @@ -373,9 +385,9 @@ namespace DotNetCTFDumper.GUI { SetImageElements(true); IsDumpingImages = true; - Backend.DumpImages(this,true,true); - - + Backend.DumpImages(this, true, true); + + } else { @@ -384,6 +396,7 @@ namespace DotNetCTFDumper.GUI SetImageElements(false); } } + private void musicsButton_Click(object sender, EventArgs e) { if (Exe.Instance.GameData.GameChunks.GetChunk() == null) return; @@ -391,7 +404,7 @@ namespace DotNetCTFDumper.GUI { SetMusicElements(true); IsDumpingMusics = true; - Backend.DumpMusics(this,true,true); + Backend.DumpMusics(this, true, true); } else { @@ -399,29 +412,31 @@ namespace DotNetCTFDumper.GUI IsDumpingMusics = false; SetMusicElements(false); } - + } - + public void SetSoundElements(bool state) { soundBar.Visible = state; soundLabel.Visible = state; - soundsButton.Text = state ? "Cancel":"Dump Sounds"; + 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"; + 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"; + musicsButton.Text = state ? "Cancel" : "Dump Musics"; musicBar.Value = 0; } @@ -451,9 +466,9 @@ namespace DotNetCTFDumper.GUI { Settings.DumpImages = true; var bank = Exe.Instance.GameData.GameChunks.GetChunk(); - bank.SaveImages=false; + bank.SaveImages = false; bank.Read(); - + }; worker.RunWorkerCompleted += (senderA, eA) => { @@ -464,34 +479,35 @@ namespace DotNetCTFDumper.GUI worker.RunWorkerAsync(); } - - - + + + private void dumpMFAButton_Click(object sender, EventArgs e) { var worker = new BackgroundWorker(); - worker.DoWork +=(workSender,workE)=> MFAGenerator.BuildMFA(); - worker.RunWorkerCompleted += (workSender, workE) => - { - Logger.Log("MFA Done", true, ConsoleColor.Yellow); - var res = MessageBox.Show("Dump Extensions?","Finished",MessageBoxButtons.YesNo); - if (res == DialogResult.Yes) - { - foreach (var item in Exe.Instance.PackData.Items) - { - item.Dump(); - Pame2Mfa.Message("Dumping "+item.PackFilename); - } - - } - Process.Start($"{Settings.DumpPath}"); + worker.DoWork += (workSender, workE) => MFAGenerator.BuildMFA(); + worker.RunWorkerCompleted += (workSender, workE) => + { + Logger.Log("MFA Done", true, ConsoleColor.Yellow); + var res = MessageBox.Show("Dump Extensions?", "Finished", MessageBoxButtons.YesNo); + if (res == DialogResult.Yes) + { + foreach (var item in Exe.Instance.PackData.Items) + { + item.Dump(); + Pame2Mfa.Message("Dumping " + item.PackFilename); + } + + } - }; - - worker.RunWorkerAsync(); + Process.Start($"{Settings.DumpPath}"); + + }; + + worker.RunWorkerAsync(); } public void InitKeyTab() @@ -510,11 +526,12 @@ namespace DotNetCTFDumper.GUI rawData += Settings.AppName; rawData += Settings.Copyright; } + try { var previewKey = Decryption.MakeKeyFromBytes(rawData, (byte) int.Parse((charBox.Text))); - hexBox1.ByteProvider=new DynamicByteProvider(previewKey); - + hexBox1.ByteProvider = new DynamicByteProvider(previewKey); + } catch { @@ -529,6 +546,7 @@ namespace DotNetCTFDumper.GUI { packDataListBox.Items.Add(item.PackFilename); } + UpdatePackInfo(0); } @@ -537,6 +555,7 @@ namespace DotNetCTFDumper.GUI var item = Exe.Instance.PackData.Items[index]; infoLabel.Text = $"Name: {item.PackFilename}\nSize: {item.Data.Length.ToPrettySize()}"; } + private void dumpPackButton_Click(object sender, EventArgs e) { var item = Exe.Instance.PackData.Items[packDataListBox.SelectedIndex]; @@ -545,7 +564,7 @@ namespace DotNetCTFDumper.GUI if (item.PackFilename.EndsWith(".mfx")) packDataDialog.Filter = "Clickteam Extension(*.mfx)|.mfx"; else if (item.PackFilename.EndsWith(".dll")) packDataDialog.Filter = "Clickteam Module(*.dll)|.dll"; - + packDataDialog.InitialDirectory = Path.GetFullPath(Settings.ExtensionPath); packDataDialog.ShowDialog(); } @@ -557,20 +576,30 @@ namespace DotNetCTFDumper.GUI item.Dump(); } } + private void packDataDialog_FileOk(object sender, CancelEventArgs e) { var item = Exe.Instance.PackData.Items[packDataListBox.SelectedIndex]; item.Dump(packDataDialog.FileName); } - - private void packDataListBox_SelectedIndexChanged(object sender, EventArgs e)=>UpdatePackInfo(packDataListBox.SelectedIndex); - private void plusCharBtn_Click(object sender, EventArgs e){ charBox.Text = (byte.Parse(charBox.Text) + 1).ToString(); InitKeyTab();} - + private void packDataListBox_SelectedIndexChanged(object sender, EventArgs e) => + UpdatePackInfo(packDataListBox.SelectedIndex); + + private void plusCharBtn_Click(object sender, EventArgs e) + { + charBox.Text = (byte.Parse(charBox.Text) + 1).ToString(); + InitKeyTab(); + } - private void minusCharButton_Click(object sender, EventArgs e){ charBox.Text = (byte.Parse(charBox.Text) - 1).ToString(); InitKeyTab();} - private void charBox_TextChanged(object sender, EventArgs e)=>InitKeyTab(); + private void minusCharButton_Click(object sender, EventArgs e) + { + charBox.Text = (byte.Parse(charBox.Text) - 1).ToString(); + InitKeyTab(); + } + + private void charBox_TextChanged(object sender, EventArgs e) => InitKeyTab(); @@ -579,10 +608,10 @@ namespace DotNetCTFDumper.GUI { var bank = Exe.Instance.GameData.GameChunks.GetChunk(); var items = bank.Images.ToList(); - var filtered = items.OrderBy(x=>x.Value.Handle); + var filtered = items.OrderBy(x => x.Value.Handle); foreach (Frame frame in Exe.Instance.GameData.Frames) { - var frameNode = new ChunkNode(frame.Name,frame); + var frameNode = new ChunkNode(frame.Name, frame); advancedTreeView.Nodes.Add(frameNode); if (frame.Objects != null) { @@ -621,37 +650,74 @@ namespace DotNetCTFDumper.GUI } } } - - public void InitPlugins() + private void advancedPlayAnimation_Click(object sender, EventArgs e) { - PluginAPI.PluginAPI.InitializePlugins(); - foreach (var plugin in PluginAPI.PluginAPI.Plugins) + if (((ChunkNode) advancedTreeView.SelectedNode).loader is Animation anim) { - pluginsList.Items.Add(plugin.Name); + var animThread = new Thread(PlayAnimation); + List frames = new List(); + foreach (var dir in anim.DirectionDict) + { + foreach (var frame in dir.Value.Frames) + { + frames.Add(Exe.Instance.GameData.GameChunks.GetChunk().Images[frame].Bitmap); + } + animThread.Start(new Tuple,AnimationDirection>(frames,dir.Value)); + } + } - + } + public void PlayAnimation(object o) + { + var (frames,anim) = (Tuple,AnimationDirection>) o; + var fps = (float)anim.MaxSpeed; + float delay = 1f/fps; + Console.WriteLine((int) (delay*1200)); + foreach (Bitmap frame in frames) + { + advancedPictureBox.Image = frame; + advancedInfoLabel.Text = $"Current frame: {frames.IndexOf(frame)}\nAnimation Speed: {fps}"; + Thread.Sleep((int) (delay*1500)); + } + } private void advancedTreeView_AfterSelect(object sender, TreeViewEventArgs e) { var node = e.Node; - if (!(((ChunkNode) node).loader is ImageItem)) + if (((ChunkNode) node).loader is ImageItem) { - advancedPictureBox.Image = advancedPictureBox.ErrorImage; + var img = ((ImageItem) ((ChunkNode) node).loader); + advancedPictureBox.Image = img.Bitmap; } - else + + } + + + + public void InitPlugins() + { + PluginAPI.PluginAPI.InitializePlugins(); + foreach (var plugin in PluginAPI.PluginAPI.Plugins) { - var img = ((ImageItem) ((ChunkNode) node).loader); - advancedPictureBox.Image = img.Bitmap; + pluginsList.Items.Add(plugin.Name); + } - + } private void activatePluginBtn_Click(object sender, EventArgs e) { - PluginAPI.PluginAPI.Plugins[pluginsList.SelectedIndex].pluginClass.Activate(null); + PluginAPI.PluginAPI.ActivatePlugin(PluginAPI.PluginAPI.Plugins[pluginsList.SelectedIndex]); } + + } -} \ No newline at end of file +} + + + + + diff --git a/DotNetCTFDumper/PluginAPI/IPlugin.cs b/DotNetCTFDumper/PluginAPI/IPlugin.cs index a43bd98..b3f488c 100644 --- a/DotNetCTFDumper/PluginAPI/IPlugin.cs +++ b/DotNetCTFDumper/PluginAPI/IPlugin.cs @@ -2,6 +2,7 @@ { public interface IPlugin { + object Activate(object input); } diff --git a/DotNetCTFDumper/PluginAPI/PluginAPI.cs b/DotNetCTFDumper/PluginAPI/PluginAPI.cs index d1d9128..c38a5a0 100644 --- a/DotNetCTFDumper/PluginAPI/PluginAPI.cs +++ b/DotNetCTFDumper/PluginAPI/PluginAPI.cs @@ -4,6 +4,7 @@ using System.Drawing; using System.IO; using System.Linq; using System.Reflection; +using DotNetCTFDumper.MMFParser.EXE; using DotNetCTFDumper.MMFParser.EXE.Loaders; using DotNetCTFDumper.MMFParser.MFA; using DotNetCTFDumper.MMFParser.MFA.Loaders; @@ -37,27 +38,86 @@ namespace DotNetCTFDumper.PluginAPI foreach (var type in types) { var pluginClass = asm.CreateInstance(type.FullName) as IPlugin; - var plugin = new Plugin(type.Name,"Kostya",pluginClass); + string name = "ERROR"; + foreach (var attribute in asm.GetCustomAttributes(typeof(CTFDumperPluginAttribute))) + { + name = ((CTFDumperPluginAttribute) attribute).Name; + } + + var plugin = new Plugin(name,"Kostya",asm,pluginClass); + + + Plugins.Add(plugin); } } } + + public static object ActivatePlugin(Plugin plugin) + { + foreach (var attribute in plugin.Asm.GetCustomAttributes(typeof(CTFDumperPluginAttribute))) + { + + if (((CTFDumperPluginAttribute) attribute).Type == PluginIOType.GameData) + { + return plugin.pluginClass.Activate(Exe.Instance.GameData); + } + else throw new NotImplementedException("Not Supported"); + + } + throw new NotImplementedException("Critical error "); + } + + public static void Message(string msg, bool showTime = true) + { + var date = DateTime.Now; + if (showTime) + Program.MyForm.pluginLogBox.AppendText( + $"[{date.Hour,2}:{date.Minute,2}:{date.Second,2}:{date.Millisecond,3}] " + msg + "\r\n"); + else Program.MyForm.pluginLogBox.AppendText(msg + "\r\n"); + } + } public class Plugin { public string Name; - - public Plugin(string name, string author, IPlugin pluginClass) + public Assembly Asm; + public string Author; + public IPlugin pluginClass; + public Plugin(string name, string author,Assembly asm, IPlugin pluginClass) { Name = name; Author = author; + Asm=asm; this.pluginClass = pluginClass; } - public string Author; - public IPlugin pluginClass; + + + } + + public enum PluginIOType + { + GameData, + PackData, + MFA, + Chunk, + ChunkLoader, + MFALoader + } + + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)] + public class CTFDumperPluginAttribute : Attribute + { + public string Name { get; } + public PluginIOType Type { get; } + public CTFDumperPluginAttribute(string name, PluginIOType type) + { + Name = name; + Type = type; + } } }