diff --git a/CTFAK/CTFAK.csproj b/CTFAK/CTFAK.csproj
index bd2803d..eb6c87c 100644
--- a/CTFAK/CTFAK.csproj
+++ b/CTFAK/CTFAK.csproj
@@ -8,7 +8,7 @@
Debug
AnyCPU
{86D99F9E-98FB-4E50-AB68-F5C115850C33}
- Exe
+ WinExe
CTFAK
CTFAK
v4.7.2
@@ -65,8 +65,8 @@
bin\x64\Release\
- TRACE
- true
+ WIN64
+ false
pdbonly
x64
7.3
@@ -80,6 +80,7 @@
x86
true
pdbonly
+ WIN32
diff --git a/CTFAK/GUI/MainForm.Designer.cs b/CTFAK/GUI/MainForm.Designer.cs
index 3ada21c..e1fe2d3 100644
--- a/CTFAK/GUI/MainForm.Designer.cs
+++ b/CTFAK/GUI/MainForm.Designer.cs
@@ -85,6 +85,7 @@
this.updateSettings = new System.Windows.Forms.Button();
this.colorBox = new System.Windows.Forms.TextBox();
this.packDataDialog = new System.Windows.Forms.SaveFileDialog();
+ this.dumpSelectedBtn = new System.Windows.Forms.Button();
this.ChunkCombo.SuspendLayout();
this.tabControl1.SuspendLayout();
this.mainTab.SuspendLayout();
@@ -114,9 +115,7 @@
//
// openFileDialog1
//
- this.openFileDialog1.FileName = "fnaf3.exe";
this.openFileDialog1.Filter = "CTF Executable|*.exe";
- this.openFileDialog1.InitialDirectory = "E:\\";
this.openFileDialog1.FileOk += new System.ComponentModel.CancelEventHandler(this.openFileDialog1_FileOk);
//
// treeView1
@@ -523,6 +522,7 @@
// objViewerTab
//
this.objViewerTab.BackColor = System.Drawing.Color.Black;
+ this.objViewerTab.Controls.Add(this.dumpSelectedBtn);
this.objViewerTab.Controls.Add(this.objViewerInfo);
this.objViewerTab.Controls.Add(this.imageViewerPlayAnim);
this.objViewerTab.Controls.Add(this.imageViewPictureBox);
@@ -550,9 +550,10 @@
// imageViewerPlayAnim
//
this.imageViewerPlayAnim.Dock = System.Windows.Forms.DockStyle.Bottom;
- this.imageViewerPlayAnim.Location = new System.Drawing.Point(201, 441);
+ this.imageViewerPlayAnim.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.imageViewerPlayAnim.Location = new System.Drawing.Point(201, 451);
this.imageViewerPlayAnim.Name = "imageViewerPlayAnim";
- this.imageViewerPlayAnim.Size = new System.Drawing.Size(731, 35);
+ this.imageViewerPlayAnim.Size = new System.Drawing.Size(731, 25);
this.imageViewerPlayAnim.TabIndex = 2;
this.imageViewerPlayAnim.Text = "Play Animation";
this.imageViewerPlayAnim.UseVisualStyleBackColor = true;
@@ -785,6 +786,18 @@
//
this.packDataDialog.FileOk += new System.ComponentModel.CancelEventHandler(this.packDataDialog_FileOk);
//
+ // dumpSelectedBtn
+ //
+ this.dumpSelectedBtn.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.dumpSelectedBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.dumpSelectedBtn.Location = new System.Drawing.Point(201, 426);
+ this.dumpSelectedBtn.Name = "dumpSelectedBtn";
+ this.dumpSelectedBtn.Size = new System.Drawing.Size(731, 25);
+ this.dumpSelectedBtn.TabIndex = 4;
+ this.dumpSelectedBtn.Text = "Dump Selected";
+ this.dumpSelectedBtn.UseVisualStyleBackColor = true;
+ this.dumpSelectedBtn.MouseClick += dumpSelectedBtn_Click;
+ //
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@@ -816,6 +829,8 @@
this.ResumeLayout(false);
}
+ private System.Windows.Forms.Button dumpSelectedBtn;
+
private System.Windows.Forms.ComboBox langComboBox;
private System.Windows.Forms.Label langLabel;
diff --git a/CTFAK/GUI/MainForm.cs b/CTFAK/GUI/MainForm.cs
index 75ccada..07db838 100644
--- a/CTFAK/GUI/MainForm.cs
+++ b/CTFAK/GUI/MainForm.cs
@@ -44,13 +44,17 @@ namespace CTFAK.GUI
private bool _isAudioPlaying;
private SoundPlayer _soundPlayer;
public Label ObjectViewerLabel;
+ public TreeNode LastSelected;
public MainForm(Color color)
{
//Buttons
InitializeComponent();
- Thread.CurrentThread.CurrentUICulture=new CultureInfo(LoadableSettings.instance["lang"].ToString());
+ if (LoadableSettings.instance["lang"]?.ToString()?.Length > 0)
+ {
+ Thread.CurrentThread.CurrentUICulture=new CultureInfo(LoadableSettings.instance["lang"].ToString());
+ }
ColorTheme = color;
foreach (Control item in Controls)
@@ -785,6 +789,7 @@ namespace CTFAK.GUI
private void advancedTreeView_AfterSelect(object sender, TreeViewEventArgs e)
{
ObjectViewerLabel?.Dispose();
+ LastSelected = objTreeView.SelectedNode;
var node = e.Node;
var loader = ((ChunkNode) node).loader;
string text=String.Empty;
@@ -952,5 +957,17 @@ namespace CTFAK.GUI
{
LoadableSettings.instance["lang"] = langComboBox.SelectedItem;
}
+
+
+
+ private void dumpSelectedBtn_Click(object sender, EventArgs e)
+ {
+ Logger.Log("Dumping");
+ var node = (ChunkNode) LastSelected;
+ var path =
+ $"{Settings.ImagePath}\\{Helper.GetTreePath(objTreeView, (ChunkNode) objTreeView.SelectedNode)}";
+ if (node == null) return;
+ ImageDumper.SaveFromNode(node);
+ }
}
}
\ No newline at end of file
diff --git a/CTFAK/MMFParser/EXE/ChunkList.cs b/CTFAK/MMFParser/EXE/ChunkList.cs
index 2dee7e0..37bcc4d 100644
--- a/CTFAK/MMFParser/EXE/ChunkList.cs
+++ b/CTFAK/MMFParser/EXE/ChunkList.cs
@@ -142,8 +142,17 @@ namespace CTFAK.MMFParser.EXE
Settings.Copyright = _chunkList.GetChunk()?.Value??"";
Settings.ProjectPath = _chunkList.GetChunk()?.Value??"";
- if (Exe.Instance.GameData.ProductBuild > 284)Decryption.MakeKey(Settings.AppName,Settings.Copyright,Settings.ProjectPath);
- else Decryption.MakeKey(Settings.ProjectPath, Settings.AppName, Settings.Copyright);
+ if (Settings.Build > 284)
+ {
+ Logger.Log("Using New Key");
+ Decryption.MakeKey(Settings.AppName,Settings.Copyright,Settings.ProjectPath);
+ }
+ else
+ {
+ Logger.Log("Using Old Key");
+ Decryption.MakeKey(Settings.ProjectPath, Settings.AppName, Settings.Copyright);
+ }
+ // Decryption.MakeKey(Settings.ProjectPath, Settings.AppName, Settings.Copyright);
}
}
diff --git a/CTFAK/MMFParser/EXE/Loaders/Banks/ImageBank.cs b/CTFAK/MMFParser/EXE/Loaders/Banks/ImageBank.cs
index 49efbdd..6cb8545 100644
--- a/CTFAK/MMFParser/EXE/Loaders/Banks/ImageBank.cs
+++ b/CTFAK/MMFParser/EXE/Loaders/Banks/ImageBank.cs
@@ -101,8 +101,8 @@ namespace CTFAK.MMFParser.EXE.Loaders.Banks
- if (Settings.Build >= 284)
- item.Handle -= 1;
+ //if (Settings.Build >= 284)
+ // item.Handle -= 1;
//images[item.handle] = item;
}
@@ -156,7 +156,7 @@ namespace CTFAK.MMFParser.EXE.Loaders.Banks
public void Read(bool load)
{
Handle = Reader.ReadInt32();
- if (Exe.Instance.GameData.ProductVersion != Constants.Products.MMF15) Handle -= 1;
+ if (Exe.Instance.GameData.ProductVersion != Constants.Products.MMF15&&Settings.Build>=284) Handle -= 1;
Position = (int) Reader.Tell();
if (load) Load();
else Preload();
@@ -165,7 +165,7 @@ namespace CTFAK.MMFParser.EXE.Loaders.Banks
public override void Read()
{
Handle = Reader.ReadInt32();
- if (Exe.Instance.GameData.ProductVersion != Constants.Products.MMF15) Handle -= 1;
+ if (Exe.Instance.GameData.ProductVersion != Constants.Products.MMF15&&Settings.Build>=284) Handle -= 1;
Position = (int) Reader.Tell();
Load();
}
diff --git a/CTFAK/MMFParser/EXE/Loaders/Objects/ObjectCommon.cs b/CTFAK/MMFParser/EXE/Loaders/Objects/ObjectCommon.cs
index 3d50987..2c08ae6 100644
--- a/CTFAK/MMFParser/EXE/Loaders/Objects/ObjectCommon.cs
+++ b/CTFAK/MMFParser/EXE/Loaders/Objects/ObjectCommon.cs
@@ -1,4 +1,6 @@
using System;
+using System.Collections.Generic;
+using System.Diagnostics;
using System.Drawing;
using CTFAK.Utils;
@@ -8,7 +10,6 @@ namespace CTFAK.MMFParser.EXE.Loaders.Objects
{
private ushort _valuesOffset;
private ushort _stringsOffset;
- private int Identifier;
private uint _fadeinOffset;
private uint _fadeoutOffset;
private ushort _movementsOffset;
@@ -16,6 +17,8 @@ namespace CTFAK.MMFParser.EXE.Loaders.Objects
private ushort _systemObjectOffset;
public ushort _counterOffset;
public ushort _extensionOffset;
+ private int Identifier;
+
public Animations Animations;
private long _end;
@@ -83,7 +86,7 @@ namespace CTFAK.MMFParser.EXE.Loaders.Objects
public AlterableValues Values;
public AlterableStrings Strings;
public Movements Movements;
- private ushort _unk;
+ private ushort _zeroUnk;
public Text Text;
@@ -101,58 +104,46 @@ namespace CTFAK.MMFParser.EXE.Loaders.Objects
public override void Read()
{
- //if(Parent.ObjectType!=2)return;
var currentPosition = Reader.Tell();
var size = Reader.ReadInt32();
if (Settings.Build >= 284)
{
_animationsOffset = Reader.ReadUInt16();
_movementsOffset = Reader.ReadUInt16();
- var version = Reader.ReadUInt16();
- _unk = Reader.ReadUInt16();
- _extensionOffset = Reader.ReadUInt16();
- _counterOffset = Reader.ReadUInt16();
- Flags.flag = Reader.ReadUInt16();
- _end = Reader.Tell() + (8+1) * 2;
-
- Reader.Seek(_end);
- _systemObjectOffset = Reader.ReadUInt16();
-
-
- _valuesOffset = Reader.ReadUInt16();
- _stringsOffset = Reader.ReadUInt16();
- NewFlags.flag = Reader.ReadUInt16();
- preferences.flag = Reader.ReadUInt16();
- Identifier = Reader.ReadInt32();
- BackColor = Reader.ReadColor();
- _fadeinOffset = Reader.ReadUInt32();
- _fadeoutOffset = Reader.ReadUInt32();
}
else
{
_movementsOffset = Reader.ReadUInt16();
_animationsOffset = Reader.ReadUInt16();
- var version = Reader.ReadUInt16();
- //_unk = Reader.ReadUInt16();
- _extensionOffset = Reader.ReadUInt16();
- _counterOffset = Reader.ReadUInt16();
- Flags.flag = Reader.ReadUInt16();
- _end = Reader.Tell() + (8+1) * 2;
-
- Reader.Seek(_end);
- _systemObjectOffset = Reader.ReadUInt16();
-
-
- _valuesOffset = Reader.ReadUInt16();
- _stringsOffset = Reader.ReadUInt16();
- NewFlags.flag = Reader.ReadUInt16();
- preferences.flag = Reader.ReadUInt16();
- Identifier = Reader.ReadInt32();
- BackColor = Reader.ReadColor();
- _fadeinOffset = Reader.ReadUInt32();
- _fadeoutOffset = Reader.ReadUInt32();
}
-
+ _zeroUnk = Reader.ReadUInt16();
+
+ if(_zeroUnk!=0) throw new NotImplementedException("Unknown value is not zero");
+ var version = Reader.ReadUInt16();
+
+ _extensionOffset = Reader.ReadUInt16();
+ _counterOffset = Reader.ReadUInt16();
+ Flags.flag = Reader.ReadUInt16();
+ var end = Reader.Tell()+(8+1)*2;
+ List qualifiers = new List();
+ while(true)
+ {
+ // break;
+ var value = Reader.ReadInt16();
+ if(value!=-1) qualifiers.Add(value);
+ else break;
+ }
+ Reader.Seek(end);
+ _systemObjectOffset = Reader.ReadUInt16();
+
+ _valuesOffset = Reader.ReadUInt16();
+ _stringsOffset = Reader.ReadUInt16();
+ NewFlags.flag = Reader.ReadUInt16();
+ preferences.flag = Reader.ReadUInt16();
+ Identifier = Reader.ReadInt32();
+ BackColor = Reader.ReadColor();
+ _fadeinOffset = Reader.ReadUInt32();
+ _fadeoutOffset = Reader.ReadUInt32();
if (_animationsOffset > 0)
{
Reader.Seek(currentPosition+_animationsOffset);
@@ -160,23 +151,45 @@ namespace CTFAK.MMFParser.EXE.Loaders.Objects
Animations.Read();
}
+ if (_movementsOffset > 0)
+ {
+ Reader.Seek(currentPosition+_movementsOffset);
+ Movements=new Movements(Reader);
+ Movements.Read();
+ }
+
if (_systemObjectOffset > 0)
{
Reader.Seek(currentPosition+_systemObjectOffset);
- if (Parent.ObjectType == 7) //Counter
+ switch (Parent.ObjectType)
{
-
- Counters=new Counters(Reader);
- Counters.Read();
+ //Text
+ case 3:
+ Text = new Text(Reader);
+ Text.Read();
+ break;
+ //Counter
+ case 7:
+ Counters=new Counters(Reader);
+ Counters.Read();
+ break;
+
}
- else if(Parent.ObjectType==3)//Text
+ }
+
+ if (_extensionOffset > 0)
+ {
+ Reader.Seek(currentPosition + _extensionOffset);
+
+ var dataSize = Reader.ReadInt32() - 20;
+ Reader.Skip(4); //maxSize;
+ ExtensionVersion = Reader.ReadInt32();
+ ExtensionId = Reader.ReadInt32();
+ ExtensionPrivate = Reader.ReadInt32();
+ if (dataSize != 0)
{
-
- Text = new Text(Reader);
- Text.Read();
-
+ ExtensionData = Reader.ReadBytes(dataSize);
}
-
}
// Logger.Log("anims: "+_animationsOffset);
diff --git a/CTFAK/MMFParser/Translation/PAME2MFA.cs b/CTFAK/MMFParser/Translation/PAME2MFA.cs
index 73fdeb6..ce80e64 100644
--- a/CTFAK/MMFParser/Translation/PAME2MFA.cs
+++ b/CTFAK/MMFParser/Translation/PAME2MFA.cs
@@ -26,23 +26,23 @@ namespace CTFAK.MMFParser.Translation
Message("Running Pame2MFA");
Message("Original MFA Build: "+mfa.BuildVersion);
Message("");
- //mfa.MfaBuild = 4;
- //mfa.Product = (int) game.ProductVersion;
- //mfa.BuildVersion = 283;
+ // mfa.MfaBuild = 4;
+ // mfa.Product = (int) game.ProductVersion;
+ // mfa.BuildVersion = 283;
mfa.Name = game.Name;
mfa.LangId = 8192;
mfa.Description = "";
mfa.Path = game.EditorFilename;
//mfa.Stamp = wtf;
- if (game.Fonts != null) mfa.Fonts = game.Fonts;
+ //if (game.Fonts != null) mfa.Fonts = game.Fonts;
//mfa.Sounds = game.Sounds;
//foreach (var item in mfa.Sounds.Items)
//{
// item.IsCompressed = false;
//}
- mfa.Music = game.Music;
+ //mfa.Music = game.Music;
mfa.Images.Items = game.Images.Images;
foreach (var key in mfa.Images.Items.Keys)
{
@@ -73,6 +73,7 @@ namespace CTFAK.MMFParser.Translation
mfa.Aboutbox = game.AboutText?.Length > 0
? game?.AboutText
: "";
+ //TODO: Controls
//Object Section
FrameItems = new Dictionary();
@@ -83,14 +84,14 @@ namespace CTFAK.MMFParser.Translation
if (item.ObjectType != 2) continue;
var newItem = new FrameItem(null);
newItem.Name = item.Name;
- newItem.ObjectType = item.ObjectType;
+ newItem.ObjectType = 2;//item.ObjectType;
newItem.Handle = item.Handle;
newItem.Transparent = item.Transparent ? 1:0;
newItem.InkEffect = item.InkEffect;
newItem.InkEffectParameter = item.InkEffectValue;
newItem.AntiAliasing = item.Antialias ? 1 : 0;
newItem.Flags = (int) item.Flags; //32 TODO:Fix this
- newItem.IconHandle = 12;
+ newItem.IconHandle = 10;
newItem.Chunks = new ChunkList(null);
var itemLoader = (ObjectCommon)item.Properties.Loader;
//Only actives
diff --git a/CTFAK/Program.cs b/CTFAK/Program.cs
index 456a2bc..4125de5 100644
--- a/CTFAK/Program.cs
+++ b/CTFAK/Program.cs
@@ -34,14 +34,14 @@ namespace CTFAK
// MFAGenerator.ReadTestMFA();
// Environment.Exit(0);
- /*AppDomain.CurrentDomain.FirstChanceException += (sender, eventArgs) =>
+ AppDomain.CurrentDomain.FirstChanceException += (sender, eventArgs) =>
{
if (eventArgs.Exception is ThreadAbortException) return;
var ex = (Exception) eventArgs.Exception;
Logger.Log("ERROR: ");
Logger.Log(ex.ToString());
- };*/
+ };
Settings.UseGUI = true;
diff --git a/CTFAK/Utils/Decryption.cs b/CTFAK/Utils/Decryption.cs
index 86caa8b..4c25d6b 100644
--- a/CTFAK/Utils/Decryption.cs
+++ b/CTFAK/Utils/Decryption.cs
@@ -9,20 +9,9 @@ namespace CTFAK.Utils
static class Decryption
{
private static byte[] _decryptionKey;
- public static byte MagicChar = 0;
-
- public static byte[] FixString(byte[] bytes)
- {
- List newBytes = new List();
- foreach (byte b in bytes)
- {
- if(b!=0) newBytes.Add(b);
- }
-
- return bytes; //newBytes.ToArray();
-
- }
+ public static byte MagicChar = 54;
+
public static void MakeKey(string data1, string data2, string data3)
{
@@ -95,9 +84,14 @@ namespace CTFAK.Utils
return decodedChunk;
}
+
+ #if WIN64
private const string _dllPath = "x64\\Decrypter-x64.dll";
- //private const string _dllPath = "x86\\Decrypter-x86.dll";
+ #else
+ private const string _dllPath = "x86\\Decrypter-x86.dll";
+ #endif
+
[DllImport(_dllPath, EntryPoint = "decode_chunk", CharSet = CharSet.Auto)]
public static extern IntPtr decode_chunk(IntPtr chunkData, int chunkSize, byte magicChar, IntPtr wrapperKey);
diff --git a/CTFAK/Utils/ImageDumper.cs b/CTFAK/Utils/ImageDumper.cs
index c7a4565..6da5cb5 100644
--- a/CTFAK/Utils/ImageDumper.cs
+++ b/CTFAK/Utils/ImageDumper.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using CTFAK.GUI;
@@ -16,6 +17,8 @@ namespace CTFAK.Utils
{
public static void SaveFromNode(ChunkNode node)
{
+ var timer = new Stopwatch();
+ timer.Start();
var bank = Exe.Instance.GameData.GameChunks.GetChunk();
var fullPath = $"{Settings.ImagePath}\\Sorted\\{node.FullPath}";
if (fullPath == null) return;
@@ -39,14 +42,25 @@ namespace CTFAK.Utils
SaveInstance(instance,bank,fullPath);
}
else if(node.loader is Backdrop) Console.WriteLine("Dumping Backdrop");
- else if(node.loader is Frame) Console.WriteLine("Dumping Frame");
-
-
-
+ else if(node.loader is Frame frame)
+ {
+ SaveFrame(frame,bank,fullPath);
+ }
+ else Console.WriteLine("Unknown: "+node.loader.GetType().Name);
+ timer.Stop();
+ Logger.Log("Done in "+timer.Elapsed.ToString("g"));
+ }
- else Console.WriteLine("Unknown: "+node.loader.GetType().Name);
+ public static void SaveFrame(Frame frame, ImageBank bank, string fullPath)
+ {
+ foreach (var inst in frame.Objects.Items)
+ {
+ var path = $"{fullPath}\\{Helper.CleanInput(inst.FrameItem.Name)}";
+ Logger.Log("Saving Object to "+path);
+ SaveInstance(inst,bank,path);
+ }
}
@@ -63,6 +77,7 @@ namespace CTFAK.Utils
if (inst.FrameItem.Properties.IsCommon)
{
var common = ((ObjectCommon)inst.FrameItem.Properties.Loader);
+ Directory.CreateDirectory(fullPath);
switch (common.Parent.ObjectType)
{
case 2:
@@ -72,7 +87,9 @@ namespace CTFAK.Utils
}
break;
case 7:
- foreach (int frame in common.Counters.Frames)
+ if (common?.Counters?.Frames.Count == 0) return;
+ if (common?.Counters?.Frames == null) return;
+ foreach (int frame in common?.Counters?.Frames)
{
var img = bank.FromHandle(frame);
img.Save(fullPath+$"\\{frame}.png");
@@ -101,12 +118,20 @@ namespace CTFAK.Utils
}
else
{
- for (int i = 0; i < anim.DirectionDict[0].Frames.Count; i++)
+ foreach (var dir in anim.DirectionDict.Values)
{
- Directory.CreateDirectory(fullPath);
- var frame = anim.DirectionDict[0].Frames[i];
- bank.Images[frame].Save($"{fullPath}\\{i}.png");
- }
+ for (int i = 0; i < dir.Frames.Count; i++)
+ {
+ Directory.CreateDirectory(fullPath);
+ var frame = dir.Frames[i];
+ bank.Images.TryGetValue(frame, out var img);
+ img?.Save($"{fullPath}\\{i}.png");
+ }
+
+ break;
+ }
+
+
}
}