Animation support for Advanced Image Viewer

master
1987kostya
parent 87b30637fb
commit 8bcb0cd8a9

@ -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;

@ -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<ImageBank>());
var viewer = new FrameViewer(frm, Exe.Instance.GameData.GameChunks.GetChunk<ImageBank>());
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<MusicBank>() != null)
Exe.Instance.GameData.GameChunks.GetChunk<MusicBank>().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<ImageBank>() == 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<MusicBank>() == 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<ImageBank>();
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<ImageBank>();
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<Bitmap> frames = new List<Bitmap>();
foreach (var dir in anim.DirectionDict)
{
foreach (var frame in dir.Value.Frames)
{
frames.Add(Exe.Instance.GameData.GameChunks.GetChunk<ImageBank>().Images[frame].Bitmap);
}
animThread.Start(new Tuple<List<Bitmap>,AnimationDirection>(frames,dir.Value));
}
}
}
public void PlayAnimation(object o)
{
var (frames,anim) = (Tuple<List<Bitmap>,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]);
}
}
}
}

@ -2,6 +2,7 @@
{
public interface IPlugin
{
object Activate(object input);
}

@ -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;
}
}
}

Loading…
Cancel
Save