diff --git a/DotNetCTFDumper.sln b/DotNetCTFDumper.sln index cea16a0..e54f29b 100644 --- a/DotNetCTFDumper.sln +++ b/DotNetCTFDumper.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.30517.126 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetCTFDumper", "DotNetCTFDumper\DotNetCTFDumper.csproj", "{86D99F9E-98FB-4E50-AB68-F5C115850C33}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExamplePlugin", "ExamplePlugin\ExamplePlugin.csproj", "{9A4499BF-534F-4397-AF0D-C663688A20E5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -21,6 +23,14 @@ Global {86D99F9E-98FB-4E50-AB68-F5C115850C33}.Release|Any CPU.Build.0 = Release|Any CPU {86D99F9E-98FB-4E50-AB68-F5C115850C33}.Release|x64.ActiveCfg = Release|x64 {86D99F9E-98FB-4E50-AB68-F5C115850C33}.Release|x64.Build.0 = Release|x64 + {9A4499BF-534F-4397-AF0D-C663688A20E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9A4499BF-534F-4397-AF0D-C663688A20E5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9A4499BF-534F-4397-AF0D-C663688A20E5}.Debug|x64.ActiveCfg = Debug|Any CPU + {9A4499BF-534F-4397-AF0D-C663688A20E5}.Debug|x64.Build.0 = Debug|Any CPU + {9A4499BF-534F-4397-AF0D-C663688A20E5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9A4499BF-534F-4397-AF0D-C663688A20E5}.Release|Any CPU.Build.0 = Release|Any CPU + {9A4499BF-534F-4397-AF0D-C663688A20E5}.Release|x64.ActiveCfg = Release|Any CPU + {9A4499BF-534F-4397-AF0D-C663688A20E5}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/DotNetCTFDumper/GUI/MainForm.Designer.cs b/DotNetCTFDumper/GUI/MainForm.Designer.cs index e641a2d..af20a52 100644 --- a/DotNetCTFDumper/GUI/MainForm.Designer.cs +++ b/DotNetCTFDumper/GUI/MainForm.Designer.cs @@ -71,6 +71,9 @@ this.advDumpTab = new System.Windows.Forms.TabPage(); this.advancedPictureBox = new System.Windows.Forms.PictureBox(); this.advancedTreeView = new System.Windows.Forms.TreeView(); + this.pluginTab = new System.Windows.Forms.TabPage(); + this.activatePluginBtn = new System.Windows.Forms.Button(); + this.pluginsList = new System.Windows.Forms.ListBox(); this.packDataDialog = new System.Windows.Forms.SaveFileDialog(); this.ChunkCombo.SuspendLayout(); this.tabControl1.SuspendLayout(); @@ -80,6 +83,7 @@ this.cryptKeyTab.SuspendLayout(); this.advDumpTab.SuspendLayout(); ((System.ComponentModel.ISupportInitialize) (this.advancedPictureBox)).BeginInit(); + this.pluginTab.SuspendLayout(); this.SuspendLayout(); // // button1 @@ -380,6 +384,7 @@ this.tabControl1.Controls.Add(this.packDataTab); this.tabControl1.Controls.Add(this.cryptKeyTab); this.tabControl1.Controls.Add(this.advDumpTab); + this.tabControl1.Controls.Add(this.pluginTab); this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; this.tabControl1.Font = new System.Drawing.Font("Courier New", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte) (204))); this.tabControl1.HotTrack = true; @@ -456,6 +461,7 @@ this.mfaLogBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; this.mfaLogBox.Size = new System.Drawing.Size(405, 479); this.mfaLogBox.TabIndex = 0; + this.mfaLogBox.Text = "MFA Generation is currently unstable\r\nUSE AT YOUR OWN RISK"; // // packDataTab // @@ -596,7 +602,7 @@ // // advancedPictureBox // - this.advancedPictureBox.BackColor = System.Drawing.Color.DimGray; + this.advancedPictureBox.BackColor = System.Drawing.Color.FromArgb(((int) (((byte) (64)))), ((int) (((byte) (64)))), ((int) (((byte) (64))))); this.advancedPictureBox.Dock = System.Windows.Forms.DockStyle.Fill; this.advancedPictureBox.Location = new System.Drawing.Point(170, 3); this.advancedPictureBox.Name = "advancedPictureBox"; @@ -614,6 +620,40 @@ this.advancedTreeView.TabIndex = 0; this.advancedTreeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.advancedTreeView_AfterSelect); // + // pluginTab + // + this.pluginTab.BackColor = System.Drawing.Color.Black; + this.pluginTab.Controls.Add(this.activatePluginBtn); + this.pluginTab.Controls.Add(this.pluginsList); + this.pluginTab.Location = new System.Drawing.Point(4, 24); + this.pluginTab.Name = "pluginTab"; + this.pluginTab.Size = new System.Drawing.Size(935, 479); + this.pluginTab.TabIndex = 5; + this.pluginTab.Text = "Plugins"; + // + // activatePluginBtn + // + 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.Name = "activatePluginBtn"; + this.activatePluginBtn.Size = new System.Drawing.Size(140, 67); + this.activatePluginBtn.TabIndex = 1; + this.activatePluginBtn.Text = "Activate"; + this.activatePluginBtn.UseVisualStyleBackColor = true; + this.activatePluginBtn.Click += new System.EventHandler(this.activatePluginBtn_Click); + // + // pluginsList + // + this.pluginsList.Dock = System.Windows.Forms.DockStyle.Left; + this.pluginsList.FormattingEnabled = true; + this.pluginsList.ItemHeight = 15; + this.pluginsList.Location = new System.Drawing.Point(0, 0); + this.pluginsList.Name = "pluginsList"; + this.pluginsList.Size = new System.Drawing.Size(252, 479); + this.pluginsList.TabIndex = 0; + // // packDataDialog // this.packDataDialog.FileOk += new System.ComponentModel.CancelEventHandler(this.packDataDialog_FileOk); @@ -641,9 +681,15 @@ this.cryptKeyTab.PerformLayout(); this.advDumpTab.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize) (this.advancedPictureBox)).EndInit(); + this.pluginTab.ResumeLayout(false); this.ResumeLayout(false); } + private System.Windows.Forms.Button activatePluginBtn; + private System.Windows.Forms.ListBox pluginsList; + + private System.Windows.Forms.TabPage pluginTab; + private System.Windows.Forms.PictureBox advancedPictureBox; private System.Windows.Forms.TreeView advancedTreeView; diff --git a/DotNetCTFDumper/GUI/MainForm.cs b/DotNetCTFDumper/GUI/MainForm.cs index 56179da..417662c 100644 --- a/DotNetCTFDumper/GUI/MainForm.cs +++ b/DotNetCTFDumper/GUI/MainForm.cs @@ -11,6 +11,8 @@ using DotNetCTFDumper.MMFParser; using DotNetCTFDumper.MMFParser.EXE; using DotNetCTFDumper.MMFParser.EXE.Loaders; using DotNetCTFDumper.MMFParser.EXE.Loaders.Banks; +using DotNetCTFDumper.MMFParser.EXE.Loaders.Objects; +using DotNetCTFDumper.MMFParser.MFA.Loaders.mfachunks; using DotNetCTFDumper.MMFParser.Translation; using DotNetCTFDumper.Utils; @@ -41,7 +43,8 @@ namespace DotNetCTFDumper.GUI foreach (Control item in Controls) { item.ForeColor = ColorTheme; - item.BackColor=Color.Black; + 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) @@ -56,7 +59,7 @@ namespace DotNetCTFDumper.GUI foreach (Control item in tabPage.Controls) { item.ForeColor = ColorTheme; - item.BackColor=Color.Black; + 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) @@ -278,6 +281,7 @@ namespace DotNetCTFDumper.GUI InitKeyTab(); InitPackDataTab(); InitAdvancedDump(); + InitPlugins(); var toLog = ""; toLog += $"Title:{Exe.Instance.GameData.Name}\n"; toLog += $"Copyright:{Exe.Instance.GameData.Copyright}\n"; @@ -576,20 +580,78 @@ namespace DotNetCTFDumper.GUI var bank = Exe.Instance.GameData.GameChunks.GetChunk(); var items = bank.Images.ToList(); var filtered = items.OrderBy(x=>x.Value.Handle); - foreach (var keypair in filtered) + foreach (Frame frame in Exe.Instance.GameData.Frames) + { + var frameNode = new ChunkNode(frame.Name,frame); + advancedTreeView.Nodes.Add(frameNode); + if (frame.Objects != null) + { + foreach (ObjectInstance objInst in frame.Objects.Items) + { + var objInstNode = new ChunkNode(objInst.FrameItem.Name, objInst); + frameNode.Nodes.Add(objInstNode); + var loader = objInst.FrameItem.Properties.Loader; + if (loader is ObjectCommon common) + { + if (common.Animations != null) + { + foreach (var pair in common.Animations.AnimationDict) + { + var animNode = new ChunkNode($"Animation {pair.Key}", pair.Value); + objInstNode.Nodes.Add(animNode); + foreach (var dir in pair.Value.DirectionDict) + { + for (int a = 0; a < dir.Value.Frames.Count; a++) + { + var animFrame = dir.Value.Frames[a]; + bank.Images.TryGetValue(animFrame, out var img); + var animFrameNode = new ChunkNode(a.ToString(), img); + animNode.Nodes.Add(animFrameNode); + } + } + } + } + } + else if (loader is Backdrop backdrop) + { + var backdropNode = new ChunkNode("Image", bank.Images[backdrop.Image]); + objInstNode.Nodes.Add(backdropNode); + } + } + } + } + } + + public void InitPlugins() + { + PluginAPI.PluginAPI.InitializePlugins(); + foreach (var plugin in PluginAPI.PluginAPI.Plugins) { - advancedTreeView.Nodes.Add(new ChunkNode(keypair.Key.ToString(),keypair.Value)); + pluginsList.Items.Add(plugin.Name); + } + } private void advancedTreeView_AfterSelect(object sender, TreeViewEventArgs e) { var node = e.Node; - var img = ((ImageItem) ((ChunkNode) node).loader); - if(img.Bitmap==null)img.Load(); + if (!(((ChunkNode) node).loader is ImageItem)) + { + advancedPictureBox.Image = advancedPictureBox.ErrorImage; + } + else + { + var img = ((ImageItem) ((ChunkNode) node).loader); + advancedPictureBox.Image = img.Bitmap; + } - advancedPictureBox.Image = img.Bitmap; + } + + private void activatePluginBtn_Click(object sender, EventArgs e) + { + PluginAPI.PluginAPI.Plugins[pluginsList.SelectedIndex].pluginClass.Activate(null); } } } \ No newline at end of file diff --git a/DotNetCTFDumper/MMFParser/EXE/Loaders/ObjectInfo.cs b/DotNetCTFDumper/MMFParser/EXE/Loaders/ObjectInfo.cs index a87b2d0..ac4405c 100644 --- a/DotNetCTFDumper/MMFParser/EXE/Loaders/ObjectInfo.cs +++ b/DotNetCTFDumper/MMFParser/EXE/Loaders/ObjectInfo.cs @@ -114,11 +114,16 @@ namespace DotNetCTFDumper.MMFParser.EXE.Loaders bmp = images.Images[firstFrameHandle]; } } - else if (ObjectType == 1) + else if (ObjectType == 1)//Backdrop { images.Images.TryGetValue(((Backdrop) Properties.Loader).Image, out var img); bmp = img; } + else if (ObjectType==0)//QuickBackdrop + { + + } + return bmp; } @@ -152,7 +157,12 @@ namespace DotNetCTFDumper.MMFParser.EXE.Loaders { //TODO: Fix shit - if (ObjectType == 1)//Backdrop + if(ObjectType==0)//QuickBackdrop + { + + + } + else if (ObjectType == 1)//Backdrop { Loader = new Backdrop(Reader); } diff --git a/DotNetCTFDumper/PluginAPI/IPlugin.cs b/DotNetCTFDumper/PluginAPI/IPlugin.cs index 788089b..a43bd98 100644 --- a/DotNetCTFDumper/PluginAPI/IPlugin.cs +++ b/DotNetCTFDumper/PluginAPI/IPlugin.cs @@ -2,7 +2,7 @@ { public interface IPlugin { - - + object Activate(object input); + } } \ No newline at end of file diff --git a/DotNetCTFDumper/PluginAPI/PluginAPI.cs b/DotNetCTFDumper/PluginAPI/PluginAPI.cs index d2327c6..d1d9128 100644 --- a/DotNetCTFDumper/PluginAPI/PluginAPI.cs +++ b/DotNetCTFDumper/PluginAPI/PluginAPI.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; using System.Drawing; +using System.IO; using System.Linq; +using System.Reflection; using DotNetCTFDumper.MMFParser.EXE.Loaders; using DotNetCTFDumper.MMFParser.MFA; using DotNetCTFDumper.MMFParser.MFA.Loaders; @@ -10,33 +12,56 @@ using Layer = DotNetCTFDumper.MMFParser.MFA.Loaders.Layer; namespace DotNetCTFDumper.PluginAPI { - public class PluginAPI + public static class PluginAPI { - public static Frame GetEmptyFrame(List palette, int handle = 0, int x = 640, int y = 480, - string name = "New Frame") + public static string PluginPath = System.IO.Path.Combine( + Directory.GetCurrentDirectory(), + "Plugins"); + + public static List Plugins = new List(); + + public static void InitializePlugins() { - var frame = new Frame(null) + Plugins.Clear(); + DirectoryInfo pluginDirectory = new DirectoryInfo(PluginPath); + if (!pluginDirectory.Exists) + pluginDirectory.Create(); + + + var pluginFiles = Directory.GetFiles(PluginPath, "*.dll"); + foreach (var file in pluginFiles) { - Handle = 0, - Name = name, - Password = "", - SizeX = x, - SizeY = y, - Background = Color.Green, - Palette = palette, - Layers = new List(), - Folders = new List(), - Items = new List(), - Events = MFA.emptyEvents, - Chunks = MFA.emptyFrameChunks - }; - frame.Flags.flag = 260; - //frame.Instances = template.Frames[0].Instances; - var testLayer = new Layer(null) {Name = "New Super Layer"}; - frame.Layers.Add(testLayer); - - - return frame; + Assembly asm = Assembly.LoadFrom(file); + var types = asm.GetTypes().Where(t => + t.GetInterfaces().Where(i => i.FullName == typeof(IPlugin).FullName).Any()); + foreach (var type in types) + { + var pluginClass = asm.CreateInstance(type.FullName) as IPlugin; + var plugin = new Plugin(type.Name,"Kostya",pluginClass); + Plugins.Add(plugin); + } + } } } -} \ No newline at end of file + + public class Plugin + { + public string Name; + + public Plugin(string name, string author, IPlugin pluginClass) + { + Name = name; + Author = author; + this.pluginClass = pluginClass; + } + + public string Author; + public IPlugin pluginClass; + + } +} + + + + + diff --git a/DotNetCTFDumper/Program.cs b/DotNetCTFDumper/Program.cs index 3793a62..efb4797 100644 --- a/DotNetCTFDumper/Program.cs +++ b/DotNetCTFDumper/Program.cs @@ -56,7 +56,7 @@ namespace DotNetCTFDumper ConsoleColor.Green); Logger.Log(" DumpSounds - Dump sounds to 'DUMP\\[your game]\\SoundBank'(default:true)\n", true, ConsoleColor.Green); - Logger.Log("Exaple: DotNetCTFDumper.exe E:\\SisterLocation.exe true true false true", true, + Logger.Log("Example: DotNetCTFDumper.exe E:\\SisterLocation.exe true true false true", true, ConsoleColor.Green); Console.ReadKey(); Environment.Exit(0); @@ -113,8 +113,8 @@ namespace DotNetCTFDumper Directory.CreateDirectory($"{Settings.SoundPath}"); Directory.CreateDirectory($"{Settings.MusicPath}"); Directory.CreateDirectory($"{Settings.ChunkPath}"); - Directory.CreateDirectory($"{Settings.ExtensionPath}"); + Directory.CreateDirectory($"{PluginAPI.PluginAPI.PluginPath}"); } public static void InitNativeLibrary() {