Added SE-style image dumping

master
1987kostya 4 years ago
parent e576dbb890
commit a226652837

@ -8,7 +8,7 @@
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{86D99F9E-98FB-4E50-AB68-F5C115850C33}</ProjectGuid>
<OutputType>Exe</OutputType>
<OutputType>WinExe</OutputType>
<RootNamespace>CTFAK</RootNamespace>
<AssemblyName>CTFAK</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
@ -65,8 +65,8 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DefineConstants>WIN64</DefineConstants>
<Optimize>false</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
@ -80,6 +80,7 @@
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>pdbonly</DebugType>
<DefineConstants>WIN32</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Reference Include="Be.Windows.Forms.HexBox, Version=1.6.1.0, Culture=neutral, PublicKeyToken=null">

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

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

@ -142,8 +142,17 @@ namespace CTFAK.MMFParser.EXE
Settings.Copyright = _chunkList.GetChunk<Copyright>()?.Value??"";
Settings.ProjectPath = _chunkList.GetChunk<EditorFilename>()?.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);
}
}

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

@ -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,48 +104,38 @@ 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();
}
_zeroUnk = Reader.ReadUInt16();
if(_zeroUnk!=0) throw new NotImplementedException("Unknown value is not zero");
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);
var end = Reader.Tell()+(8+1)*2;
List<Int16> qualifiers = new List<Int16>();
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();
@ -151,8 +144,6 @@ namespace CTFAK.MMFParser.EXE.Loaders.Objects
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)
{
//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
{
Text = new Text(Reader);
Text.Read();
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)
{
ExtensionData = Reader.ReadBytes(dataSize);
}
}
// Logger.Log("anims: "+_animationsOffset);

@ -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<int,FrameItem>();
@ -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

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

@ -9,19 +9,8 @@ namespace CTFAK.Utils
static class Decryption
{
private static byte[] _decryptionKey;
public static byte MagicChar = 0;
public static byte MagicChar = 54;
public static byte[] FixString(byte[] bytes)
{
List<byte> newBytes = new List<byte>();
foreach (byte b in bytes)
{
if(b!=0) newBytes.Add(b);
}
return bytes; //newBytes.ToArray();
}
public static void MakeKey(string data1, string data2, string data3)
{
@ -96,8 +85,13 @@ 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);

@ -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<ImageBank>();
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)
{
for (int i = 0; i < dir.Frames.Count; i++)
{
Directory.CreateDirectory(fullPath);
var frame = anim.DirectionDict[0].Frames[i];
bank.Images[frame].Save($"{fullPath}\\{i}.png");
var frame = dir.Frames[i];
bank.Images.TryGetValue(frame, out var img);
img?.Save($"{fullPath}\\{i}.png");
}
break;
}
}
}

Loading…
Cancel
Save