Fixed some bugs, code was optimised, started working on GUI, new decryption system(requires new lib), key is now stored in C# application. Data is being combined inside C# application

master
1987kostya 5 years ago
parent d248c19715
commit 1db74b1962

@ -88,10 +88,17 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="GUI\MainForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="GUI\MainForm.Designer.cs">
<DependentUpon>MainForm.cs</DependentUpon>
</Compile>
<Compile Include="MMFParser\ChunkLoaders\AppMenu.cs" />
<Compile Include="MMFParser\ChunkLoaders\banks\DebugImageBank.cs" />
<Compile Include="MMFParser\ChunkLoaders\Events\Events.cs" />
<Compile Include="MMFParser\ChunkLoaders\Events\EventsParts.cs" />
<Compile Include="MMFParser\ChunkLoaders\Events\Expressions\Expression.cs" />
<Compile Include="MMFParser\ChunkLoaders\Events\Parameters\Position.cs" />
<Compile Include="MMFParser\ChunkLoaders\Events\Parameters\Int.cs" />
<Compile Include="MMFParser\ChunkLoaders\Events\Parameters\GlobalValue.cs" />
@ -106,11 +113,13 @@
<Compile Include="MMFParser\ChunkLoaders\Events\Parameters\Create.cs" />
<Compile Include="MMFParser\ChunkLoaders\Events\Parameters\Time.cs" />
<Compile Include="MMFParser\ChunkLoaders\Events\Parameters\ParamObject.cs" />
<Compile Include="MMFParser\ChunkLoaders\ExtData.cs" />
<Compile Include="MMFParser\ChunkLoaders\Globals.cs" />
<Compile Include="MMFParser\ChunkLoaders\ObjectInfo.cs" />
<Compile Include="MMFParser\ChunkLoaders\FrameItems.cs" />
<Compile Include="MMFParser\ChunkLoaders\ObjectNames.cs" />
<Compile Include="MMFParser\Data\DataLoader.cs" />
<Compile Include="MMFParser\Data\EXE.cs" />
<Compile Include="MMFParser\MFALoaders\ChunkList.cs" />
<Compile Include="MMFParser\MFALoaders\Frame.cs" />
<Compile Include="MMFParser\MFALoaders\FrameItem.cs" />
@ -165,7 +174,9 @@
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<Folder Include="MMFParser\ChunkLoaders\Events\Expressions\" />
<EmbeddedResource Include="GUI\MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

@ -0,0 +1,130 @@
namespace NetMFAPatcher.GUI
{
partial class MainForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
this.treeView1 = new System.Windows.Forms.TreeView();
this.listBox1 = new System.Windows.Forms.ListBox();
this.GameInfo = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// button1
//
this.button1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.button1.ForeColor = System.Drawing.Color.Lime;
this.button1.Location = new System.Drawing.Point(12, 12);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(83, 23);
this.button1.TabIndex = 0;
this.button1.Text = "Select File";
this.button1.UseVisualStyleBackColor = false;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// openFileDialog1
//
this.openFileDialog1.FileName = "SisterLocation.exe";
this.openFileDialog1.Filter = "CTF Executable|*.exe";
this.openFileDialog1.InitialDirectory = "E:\\Games\\sl\\SisterLocation.exe";
this.openFileDialog1.FileOk += new System.ComponentModel.CancelEventHandler(this.openFileDialog1_FileOk);
//
// treeView1
//
this.treeView1.BackColor = System.Drawing.Color.Black;
this.treeView1.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.treeView1.ForeColor = System.Drawing.Color.Lime;
this.treeView1.Location = new System.Drawing.Point(645, 12);
this.treeView1.Name = "treeView1";
this.treeView1.Size = new System.Drawing.Size(286, 426);
this.treeView1.TabIndex = 1;
this.treeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterSelect);
//
// listBox1
//
this.listBox1.BackColor = System.Drawing.Color.Black;
this.listBox1.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.listBox1.ForeColor = System.Drawing.Color.Lime;
this.listBox1.FormattingEnabled = true;
this.listBox1.Location = new System.Drawing.Point(459, 12);
this.listBox1.Name = "listBox1";
this.listBox1.Size = new System.Drawing.Size(180, 299);
this.listBox1.TabIndex = 2;
this.listBox1.SelectedIndexChanged += new System.EventHandler(this.listBox1_SelectedIndexChanged);
//
// GameInfo
//
this.GameInfo.AutoSize = true;
this.GameInfo.ForeColor = System.Drawing.Color.Lime;
this.GameInfo.Location = new System.Drawing.Point(9, 49);
this.GameInfo.Name = "GameInfo";
this.GameInfo.Size = new System.Drawing.Size(144, 13);
this.GameInfo.TabIndex = 3;
this.GameInfo.Text = "GameInfo would appear here";
//
// label1
//
this.label1.AutoSize = true;
this.label1.ForeColor = System.Drawing.Color.Lime;
this.label1.Location = new System.Drawing.Point(101, 17);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(245, 13);
this.label1.TabIndex = 4;
this.label1.Text = "CTF Dumper by Kostya and cool guys from discord";
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.Black;
this.ClientSize = new System.Drawing.Size(943, 507);
this.Controls.Add(this.label1);
this.Controls.Add(this.GameInfo);
this.Controls.Add(this.listBox1);
this.Controls.Add(this.treeView1);
this.Controls.Add(this.button1);
this.Name = "MainForm";
this.Text = "DotNetCTFDumper";
this.Load += new System.EventHandler(this.MainForm_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button button1;
private System.Windows.Forms.OpenFileDialog openFileDialog1;
private System.Windows.Forms.TreeView treeView1;
private System.Windows.Forms.ListBox listBox1;
private System.Windows.Forms.Label GameInfo;
private System.Windows.Forms.Label label1;
}
}

@ -0,0 +1,94 @@
using NetMFAPatcher.MMFParser.Data;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace NetMFAPatcher.GUI
{
public partial class MainForm : Form
{
public Thread loaderThread;
public MainForm()
{
InitializeComponent();
}
private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
{
var worker = new BackgroundWorker();
worker.DoWork += (senderA, eA) =>
{
StartReading();
};
worker.RunWorkerCompleted += (senderA, eA) =>
{
AfterLoad();
};
worker.RunWorkerAsync();
}
private void button1_Click(object sender, EventArgs e)
{
openFileDialog1.ShowDialog();
}
private void MainForm_Load(object sender, EventArgs e)
{
listBox1.Items.Clear();
}
void StartReading()
{
var path = openFileDialog1.FileName;
Program.ReadFile(path, false, false, false);
}
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
var currentFrame = EXE.LatestInst.game_data.Frames[treeView1.SelectedNode.Index];
listBox1.Items.Clear();
listBox1.Items.Add($"Size: {currentFrame.width}x{currentFrame.height}");
listBox1.Items.Add($"Number of objects: {currentFrame.CountOfObjs}");
}
public void AfterLoad()
{
var gameData = EXE.LatestInst.game_data;
foreach (var item in gameData.Frames)
{
treeView1.Nodes.Add(item.name);
}
string toLog = "";
toLog += $"Title:{EXE.LatestInst.game_data.Name}\n";
toLog += $"Copyright:{EXE.LatestInst.game_data.Copyright}\n";
toLog += $"Editor Filename: {EXE.LatestInst.game_data.EditorFilename}\n";
//toLog += $"Build Filename: {EXE.LatestInst.game_data.TargetFilename}\n";
toLog += $"Product Build: {EXE.LatestInst.game_data.product_build}\n";
toLog += $"Build: {EXE.LatestInst.game_data.build}\n";
toLog += $"Runtime Version: {EXE.LatestInst.game_data.runtime_version}\n";
GameInfo.Text = toLog;
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
}

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="openFileDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>25</value>
</metadata>
</root>

@ -54,20 +54,21 @@ namespace NetMFAPatcher.MMFParser.ChunkLoaders.Events
}
}
else if(identifier==EventCount)
else if (identifier == EventCount)
{
var size = reader.ReadInt32();
}
else if(identifier==EventgroupData)
else if (identifier == EventgroupData)
{
var size = reader.ReadInt32();
var end_position = reader.Tell() + size;
while(true)
while (true)
{
var eg = new EventGroup(reader);
eg.Read();
}
}
else if (identifier == End) break;
}
@ -140,13 +141,25 @@ namespace NetMFAPatcher.MMFParser.ChunkLoaders.Events
Actions.Add(item);
}
reader.Seek(currentPosition + size);
if(Conditions[0].items[0].loader!=null)
Console.WriteLine("IF:");
if (Conditions!=null)
{
Logger.Log(Conditions[0].items[0].loader.ToString());
Console.ReadKey();
foreach (var item in Conditions)
{
Console.WriteLine("\t" + item.ToString());
}
}
Console.WriteLine("DO:");
if (Actions != null)
{
foreach (var item in Actions)
{
Console.WriteLine("\t" + item.ToString());
}
}
}
}

@ -49,8 +49,14 @@ namespace NetMFAPatcher.MMFParser.ChunkLoaders.Events
items.Add(item);
}
reader.Seek(currentPosition + size);
}
public override string ToString()
{
return $"Condition {ObjectType}-{num}-{(items.Count > 0 ? items[0].ToString() : "cock")}";
}
}
@ -90,6 +96,12 @@ namespace NetMFAPatcher.MMFParser.ChunkLoaders.Events
}
}
public override string ToString()
{
return $"Action {ObjectType}-{num}-{(items.Count>0?items[0].ToString():"cock")}";
}
}
@ -110,11 +122,18 @@ namespace NetMFAPatcher.MMFParser.ChunkLoaders.Events
var current_position = reader.Tell();
var size = reader.ReadInt16();
Code = reader.ReadInt16();
Logger.Log(Code.ToString());
var ActualLoader = Helper.LoadParameter(Code,reader);
if(loader!=null)
this.loader = ActualLoader;
if (loader!=null)
{
this.loader = ActualLoader;
loader.Read();
}
else
{
//throw new Exception("Loader is null");
}
reader.Seek(current_position+size);
@ -123,20 +142,27 @@ namespace NetMFAPatcher.MMFParser.ChunkLoaders.Events
{
get
{
if(loader.GetType().GetField("value")!=null)
if (loader != null)
{
return loader.GetType().GetField("value").GetValue(loader);
}
else
{
return null;
if (loader.GetType().GetField("value") != null)
{
return loader.GetType().GetField("value").GetValue(loader);
}
else
{
return null;
}
}
else return null;
}
}
public override string ToString()
{
if (value != null) return (string)value;
else return "UNKNOWN-PARAM";
if (loader != null) return loader.ToString();
else return "UNK-PARAMETER";
}
}

@ -0,0 +1,29 @@
using mmfparser;
using NetMFAPatcher.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static NetMFAPatcher.mmfparser.Constants;
namespace NetMFAPatcher.MMFParser.ChunkLoaders.Events.Expressions
{
class Expression : DataLoader
{
public ObjectType ObjectType;
public int num;
public int ObjectInfo;
public int ObjectInfoList;
public Expression(ByteIO reader) : base(reader) { }
public override void Print()
{
throw new NotImplementedException();
}
public override void Read()
{
}
}
}

@ -17,11 +17,11 @@ namespace NetMFAPatcher.MMFParser.ChunkLoaders.Events.Parameters
{
Timer = reader.ReadInt32();
Loops = reader.ReadInt32();
Logger.Log($"Time time: {Timer} loops: {Loops}");
}
public override string ToString()
{
return $"Time time: {Timer} loops: {Loops}";
}
}

@ -0,0 +1,25 @@
using NetMFAPatcher.chunkloaders;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static NetMFAPatcher.MMFParser.Data.ChunkList;
namespace NetMFAPatcher.MMFParser.ChunkLoaders
{
class ExtData : ChunkLoader
{
public ExtData(Chunk chunk) : base(chunk) { }
public override void Print(bool ext)
{
throw new NotImplementedException();
}
public override void Read()
{
var filename = reader.ReadAscii();
//var data = reader.ReadBytes();
}
}
}

@ -48,11 +48,7 @@ namespace NetMFAPatcher.MMFParser.Data
{
chunk.BuildKey();
}
if (chunk.id == 8755)
{
Console.WriteLine("Fisting Found");
Console.ReadKey();
}
if (chunk.id == 32639) break; //LAST chunkID
@ -96,12 +92,11 @@ namespace NetMFAPatcher.MMFParser.Data
switch (flag)
{
case ChunkFlags.Encrypted:
chunk_data = Decryption.DecodeChunk(exeReader.ReadBytes(size),size,54);
case ChunkFlags.Encrypted:
chunk_data = Decryption.DecodeChunk(exeReader.ReadBytes(size),size);
break;
case ChunkFlags.CompressedAndEncrypyed:
chunk_data = Decryption.DecodeMode3(exeReader.ReadBytes(size), size,id, 54);
chunk_data = Decryption.DecodeMode3(exeReader.ReadBytes(size), size,id);
break;
case ChunkFlags.Compressed:
chunk_data = Decompressor.Decompress(exeReader);
@ -121,7 +116,7 @@ namespace NetMFAPatcher.MMFParser.Data
int.TryParse(name,out tempId);
if(tempId==id)
{
chunk_data.Log(true, "X2");
//chunk_data.Log(true, "X2");
}
}
@ -152,26 +147,26 @@ namespace NetMFAPatcher.MMFParser.Data
}
public void BuildKey()
{
string title = "Five Nights at Candy's 3";
string title = "";
string copyright = "";
string project = @"C:\Users\Emil\Desktop\Five Nights at Candy's 3\Five Nights At Candy's 3.mfa";
string project = "";
var titleChunk = chunk_list.get_chunk<AppName>();
if (titleChunk != null) title = titleChunk.value;
var copyrightChunk = chunk_list.get_chunk<Copyright>();
if (copyrightChunk != null) copyright = copyrightChunk.value;
var projectChunk = chunk_list.get_chunk<EditorFilename>();
if (projectChunk != null) project = projectChunk.value;
if (Program.game_data.product_build > 284)
if (EXE.LatestInst.game_data.product_build >= 284)
{
Decryption.MakeKey(title, copyright, project, 54);
Decryption.MakeKey(title, copyright, project);
}
else
{
Decryption.MakeKey(project, title, copyright, 54);
Decryption.MakeKey(project, title, copyright);
}
Logger.Log("New Key!");
@ -215,7 +210,7 @@ namespace NetMFAPatcher.MMFParser.Data
case 8752:
loader = new AppDoc(chunk);
break;
case 8745://
case 8745:
loader = new FrameItems(chunk);
break;
case 8757:
@ -256,7 +251,7 @@ namespace NetMFAPatcher.MMFParser.Data
loader = new ObjectHeader(chunk);
break;
case 8788:
loader = new ObjectNames(chunk);
//loader = new ObjectNames(chunk);
break;
case 8754:
loader = new GlobalValues(chunk);
@ -265,13 +260,15 @@ namespace NetMFAPatcher.MMFParser.Data
loader = new GlobalStrings(chunk);
break;
case 13117:
loader = new Events(chunk);
//loader = new Events(chunk);//NOT WORKING
break;
}
if (loader != null)
{
//Logger.Log($"Reading {loader.GetType().Name}...",true,ConsoleColor.Yellow);
loader.Read();
}
return loader;
}
@ -290,7 +287,7 @@ namespace NetMFAPatcher.MMFParser.Data
}
}
//Logger.Log($"ChunkLoader {typeof(T).Name} not found", true, ConsoleColor.Red);
return null; //I hope this wont happen
return null;
}
public T get_loader<T>(ChunkLoader loader) where T : ChunkLoader
{

@ -0,0 +1,92 @@
using NetMFAPatcher.Utils;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NetMFAPatcher.MMFParser.Data
{
class EXE
{
public PackData pack_data;
public GameData game_data;
public static EXE LatestInst;
public void ParseExe(ByteIO exeReader)
{
LatestInst = this;
Logger.Log($"Executable: {Program.GameName}\n", true, ConsoleColor.DarkRed);
string Header1 = exeReader.ReadAscii(2);
Logger.Log("EXE Header: " + Header1, true, ConsoleColor.Yellow);
if (Header1 != "MZ")
{
Console.WriteLine("Invalid executable signature");
Console.ReadKey();
Environment.Exit(0);
}
exeReader.Seek(60, SeekOrigin.Begin);
UInt16 hdr_offset = exeReader.ReadUInt16();
exeReader.Seek(hdr_offset, SeekOrigin.Begin);
string peHdr = exeReader.ReadAscii(2);
Logger.Log("PE Header: " + peHdr, true, ConsoleColor.Yellow);
exeReader.Skip(4);
UInt16 num_of_sections = exeReader.ReadUInt16();
exeReader.Skip(16);
int optional_header = 28 + 68;
int data_dir = 16 * 8;
exeReader.Skip(optional_header + data_dir);
int possition = 0;
for (int i = 0; i < num_of_sections; i++)
{
var entry = exeReader.Tell();
var section_name = exeReader.ReadAscii();
if (section_name == ".extra")
{
exeReader.Seek(entry + 20);
possition = (int)exeReader.ReadUInt32();
break;
}
if (i >= num_of_sections - 1)
{
exeReader.Seek(entry + 16);
uint size = exeReader.ReadUInt32();
uint address = exeReader.ReadUInt32();
possition = (int)(address + size);
break;
}
exeReader.Seek(entry + 40);
}
exeReader.Seek((int)possition);
UInt16 first_short = exeReader.PeekUInt16();
Logger.Log("First Short: " + first_short.ToString("X2"), true, ConsoleColor.Yellow);
if (first_short == 0x7777)
{
Logger.Log("Found PackData header!\nReading PackData header.", true, ConsoleColor.Blue);
pack_data = new PackData();
pack_data.Read(exeReader);
game_data = new GameData();
game_data.Read(exeReader);
Console.ForegroundColor = ConsoleColor.DarkGreen;
}
else
{
Logger.Log("Failed to find PackData header!\n", true, ConsoleColor.Red);
}
}
}
}

@ -61,7 +61,7 @@ namespace NetMFAPatcher.MMFParser.Data
//Checking for header
if (magic == Constants.UNICODE_GAME_HEADER) Constants.isUnicode = true;//PAMU
else if (magic == Constants.GAME_HEADER) Constants.isUnicode = false;//PAME
else Logger.Log("Header Fucked Up", true, ConsoleColor.Red);//Header not found
else Logger.Log("Couldn't found any known headers", true, ConsoleColor.Red);//Header not found
runtime_version = exeReader.ReadUInt16(); //
runtime_subversion = exeReader.ReadUInt16(); //0
@ -69,18 +69,13 @@ namespace NetMFAPatcher.MMFParser.Data
product_build = exeReader.ReadInt32(); //CTF Build
build = (Products)runtime_version;
//Print();
//Logger.Log("Press any key to continue", true, ConsoleColor.Magenta);
//Console.ReadKey();
gameChunks = new ChunkList(); //Reading game chunks
gameChunks.Read(exeReader);
//Load chunks into gamedata for easier access
if (gameChunks.get_chunk<AppName>() != null) Name = gameChunks.get_chunk<AppName>().value;
if (gameChunks.get_chunk<Copyright>() != null) Copyright = gameChunks.get_chunk<Copyright>().value;
if(gameChunks.get_chunk<AppAuthor>()!=null) Author = gameChunks.get_chunk<AppAuthor>().value;
if (gameChunks.get_chunk<AppAuthor>()!=null) Author = gameChunks.get_chunk<AppAuthor>().value;
if (gameChunks.get_chunk<EditorFilename>() != null) EditorFilename = gameChunks.get_chunk<EditorFilename>().value;
if (gameChunks.get_chunk<TargetFilename>() != null) TargetFilename = gameChunks.get_chunk<TargetFilename>().value;
if (gameChunks.get_chunk<AppMenu>() != null) Menu = gameChunks.get_chunk<AppMenu>();
@ -93,7 +88,7 @@ namespace NetMFAPatcher.MMFParser.Data
if (gameChunks.get_chunk<GlobalStrings>() != null) GStrings = gameChunks.get_chunk<GlobalStrings>();
if (gameChunks.get_chunk<GlobalValues>() != null) GValues = gameChunks.get_chunk<GlobalValues>();
if (gameChunks.get_chunk<FrameItems>() != null) Frameitems = gameChunks.get_chunk<FrameItems>();
Frames = gameChunks.Frames;
Frames = gameChunks.Frames; //Its a list, so i have to manually parse them in chunk list.
Print();
}

@ -1,6 +1,4 @@

using NetMFAPatcher.Utils;
using NetMFAPatcher.Utils;
using mmfparser.mfaloaders;
using NetMFAPatcher.chunkloaders;
using System;
@ -50,20 +48,26 @@ namespace NetMFAPatcher.mfa
public override void Read()
{
Logger.Log($"MFA HEADER:{reader.ReadAscii(4)}");
mfaBuild = reader.ReadInt32();
product = reader.ReadInt32();
Logger.Log($"MFA HEADER:{reader.ReadAscii(4)}\n");
mfaBuild = reader.ReadInt32();
product = reader.ReadInt32();
buildVersion = reader.ReadInt32();
Console.WriteLine($"mfaBuild: {mfaBuild}, product: {product}, buildVersion: {buildVersion}");
var reserved = reader.ReadInt32();
name = reader.ReadAscii(reader.ReadInt32());
description = reader.ReadAscii(reader.ReadInt32());
path = reader.ReadAscii(reader.ReadInt32());
stamp = reader.ReadBytes(reader.ReadInt32());
Console.WriteLine(path);
name = Helper.AutoReadUnicode(reader);
description = Helper.AutoReadUnicode(reader);
path = Helper.AutoReadUnicode(reader);
Console.WriteLine($"\nMFAName: {name}\nDescription: {description}\nPath: {path}");
stamp = reader.ReadBytes(reader.ReadInt32());
if(reader.ReadAscii(4)!="ATNF")
if (reader.ReadAscii(4) != "ATNF")
{
throw new Exception("Invalid Font Bank");
}
@ -87,39 +91,58 @@ namespace NetMFAPatcher.mfa
var music = new MusicBank(reader);
music.Read();
//if (reader.ReadAscii(4) != "AGMI")
//{
// throw new Exception("Invalid Icon Bank");
//}
//var icons = new AGMIBank(reader);
//icons.Read();
if (reader.ReadAscii(4) != "AGMI")
{
throw new Exception("Invalid Icon Bank");
}
var icons = new AGMIBank(reader);
icons.Read();
if (reader.ReadAscii(4) != "AGMI")
{
throw new Exception("Invalid Image Bank");
}
var images = new AGMIBank(reader);
images.Read();
if (Helper.AutoReadUnicode(reader) != name) throw new Exception("Invalid name");
author = Helper.AutoReadUnicode(reader);
var newDesc = Helper.AutoReadUnicode(reader);
if ( newDesc!= description) throw new Exception("Invalid description: "+newDesc);
reader.Seek(17710);//hardcoded offset
reader.ReadInt32();//checkDefault
author = reader.ReadAscii(reader.ReadInt32());
reader.ReadInt32();//checkDefault
copyright = reader.ReadAscii(reader.ReadInt32());
reader.ReadInt32();//checkDefault
copyright = Helper.AutoReadUnicode(reader);
company = reader.ReadAscii(reader.ReadInt32());
version = reader.ReadAscii(reader.ReadInt32());
company = Helper.AutoReadUnicode(reader);
Console.WriteLine("Company: "+company);
version = Helper.AutoReadUnicode(reader);
Console.WriteLine("Version: " + version);
windowX = reader.ReadInt32();
windowY = reader.ReadInt32();
var borderColor = reader.ReadBytes(4);
var displayFlags = reader.ReadInt32();
var graphicFlags = reader.ReadInt32();
var helpFile = reader.ReadBytes(reader.ReadInt32());
var vitalizePreview = reader.ReadBytes(reader.ReadInt32());
Console.WriteLine($"Window:{windowX}x{windowY}");
var borderColor = reader.ReadColor();
var displayFlags = reader.ReadUInt32();
var graphicFlags = reader.ReadUInt32();
var helpFile = Helper.AutoReadUnicode(reader);
Console.WriteLine(reader.Tell());
var vitalizePreview = reader.ReadInt32();
var initialScore = reader.ReadInt32();
var initialLifes = reader.ReadInt32();
var frameRate = reader.ReadInt32();
var buildType = reader.ReadInt32();
var buildPath = reader.ReadAscii(reader.ReadInt32());
var buildPath = Helper.AutoReadUnicode(reader);
reader.ReadInt32();
var commandLine = reader.ReadAscii(reader.ReadInt32());
var aboutbox = reader.ReadAscii(reader.ReadInt32());
var commandLine = Helper.AutoReadUnicode(reader);
var aboutbox = Helper.AutoReadUnicode(reader);
Console.WriteLine(aboutbox);
reader.ReadInt32();
var binCount = reader.ReadInt32();//wtf i cant put it in loop fuck shit
@ -153,7 +176,7 @@ namespace NetMFAPatcher.mfa
globalStrings = new ValueList(reader);
globalStrings.Read();
var globalEvents = reader.ReadBytes(reader.ReadInt32());
var graphicMode = reader.ReadInt32();
var graphicMode = reader.ReadInt32();;
@ -173,8 +196,8 @@ namespace NetMFAPatcher.mfa
for (int i = 0; i < extCount; i++)//extensions
{
var handleE = reader.ReadInt32();
var filenameE = reader.ReadAscii(reader.ReadInt32());
var nameE = reader.ReadAscii(reader.ReadInt32());
var filenameE = Helper.AutoReadUnicode(reader);
var nameE = Helper.AutoReadUnicode(reader);
var magicE = reader.ReadInt32();
var subType = reader.ReadBytes(reader.ReadInt32());
@ -195,6 +218,7 @@ namespace NetMFAPatcher.mfa
}
reader.Seek(nextOffset);

@ -35,7 +35,7 @@ namespace NetMFAPatcher.MMFParser.Data
uint count = exeReader.ReadUInt32();
Logger.Log($"Found {count.ToString()} Pack Files:", true, ConsoleColor.Blue);
Logger.Log($"Found {count} Pack Files:", true, ConsoleColor.Blue);
long offset = exeReader.Tell();
for (int i = 0; i < count; i++)

@ -8,13 +8,14 @@ using NetMFAPatcher.mfa;
using NetMFAPatcher.utils;
using System.Runtime.InteropServices;
using NetMFAPatcher.MMFParser.Data;
using NetMFAPatcher.GUI;
using System.Windows.Forms;
namespace NetMFAPatcher
{
class Program
{
public static PackData pack_data;
public static GameData game_data;
//public static string path = @"H:\fnaf-world.exe";//test
//public static string path = @"D:\SteamLibrary\steamapps\common\Five Nights at Freddy's Sister Location\SisterLocation.exe";
public static string path = "";//TODO: Make Selectable
@ -28,7 +29,7 @@ namespace NetMFAPatcher
public static bool verbose;
public static bool LogAll=false;
public static bool UseGUI = false;
[STAThread]
static void Main(string[] args)
@ -37,55 +38,17 @@ namespace NetMFAPatcher
bool Verbose=false;
bool DumpImages=true;
bool DumpSounds=true;
bool CreateFolders=true;
if (args.Length == 0)
if(args.Length==0)
{
if (true)
{
ByteIO mfaReader = new ByteIO(@"E:\anaconda-mode3\Application.mfa", FileMode.Open);
var mfa = new MFA(mfaReader);
mfa.Read();
Console.ReadKey();
Environment.Exit(0);
}
else
{
var testWriter = new ByteWriter(@"C:\testcock.bin",FileMode.OpenOrCreate);
testWriter.Write(0);
testWriter.BaseStream.Close();
var testReader = new ByteIO(@"C:\testcock.bin",FileMode.Open);
}
Console.ReadKey();
Environment.Exit(0);
Logger.Log("Finished!", true, ConsoleColor.Yellow);
Logger.Log("Args are not provided, launch dumper with -h or -help for help");
Logger.Log("Press any key to exit or press Z to launch with default args(debug only)");
var key = Console.ReadKey();
if(key.Key==ConsoleKey.Z)
{
Console.WriteLine("");
ReadFile("H:\\SteamLibrary\\steamapps\\common\\Freddy Fazbear's Pizzeria Simulator\\Pizzeria Simulator.exe", Verbose, DumpImages, DumpSounds);
}
if (key.Key == ConsoleKey.X)
{
Console.WriteLine("");
ReadFile("E:\\Games\\sl\\SisterLocation.exe", Verbose, DumpImages, DumpSounds);
}
Environment.Exit(0);
UseGUI = true;
var form = new MainForm();
Application.Run(form);
}
if (args.Length > 0)
{
Path = args[0];
@ -116,8 +79,8 @@ namespace NetMFAPatcher
}
if(args.Length>0) ReadFile(Path, Verbose, DumpImages, DumpSounds);
ReadFile(Path,Verbose,DumpImages,DumpSounds);
}
@ -137,16 +100,16 @@ namespace NetMFAPatcher
if (path.EndsWith(".exe"))
{
doMFA = false;
ByteIO exeReader = new ByteIO(path, FileMode.Open);
ParseExe(exeReader);
EXE currentEXE = new EXE();
currentEXE.ParseExe(exeReader);
Logger.Log("Finished!", true, ConsoleColor.Yellow);
Console.ReadKey();
if(!UseGUI) Console.ReadKey();
}
else if (path.EndsWith(".mfa"))
{
doMFA = true;
Logger.Log("MFA reading is currently unstable");
Logger.Log("Are you sure?");
Console.ReadKey();
@ -181,76 +144,6 @@ namespace NetMFAPatcher
Directory.CreateDirectory($"{DumpPath}\\extensions");
}
public static void ParseExe(ByteIO exeReader)
{
Logger.Log($"Executable: {GameName}\n",true,ConsoleColor.DarkRed);
var es = exeReader.ReadAscii(2);
Logger.Log("EXE Header: " + es, true, ConsoleColor.Yellow);
if (es != "MZ")
{
Console.WriteLine("Invalid executable signature");
Environment.Exit(0);
}
exeReader.Seek(60,SeekOrigin.Begin);
UInt16 hdr_offset = exeReader.ReadUInt16();
exeReader.Seek(hdr_offset, SeekOrigin.Begin);
string peHdr = exeReader.ReadAscii(2);
Logger.Log("PE Header: " + peHdr, true, ConsoleColor.Yellow);
exeReader.Skip(4);
UInt16 num_of_sections = exeReader.ReadUInt16();
exeReader.Skip(16);
var optional_header = 28 + 68;
var data_dir = 16 * 8;
exeReader.Skip(optional_header + data_dir);
uint possition = 0;
for (int i = 0; i < num_of_sections; i++)
{
var entry = exeReader.Tell();
var section_name = exeReader.ReadAscii();
if (section_name == ".extra")
{
exeReader.Seek(entry + 20);
possition = exeReader.ReadUInt32();
break;
}
if (i >= num_of_sections - 1)
{
exeReader.Seek(entry + 16);
uint size = exeReader.ReadUInt32();
uint address = exeReader.ReadUInt32();
possition = address + size;
break;
}
exeReader.Seek(entry + 40);
}
exeReader.Seek((int) possition);
UInt16 first_short = exeReader.PeekUInt16();
Logger.Log("First Short: " + first_short.ToString("X2"), true, ConsoleColor.Yellow);
if (first_short == 0x7777)
{
Logger.Log("Found PackData header!\nReading PackData header.", true, ConsoleColor.Blue);
pack_data = new PackData();
pack_data.Read(exeReader);
game_data = new GameData();
game_data.Read(exeReader);
Console.ForegroundColor = ConsoleColor.DarkGreen;
}
else
{
Logger.Log("Failed to find PackData header!\n", true, ConsoleColor.Red);
}
}
}
}

@ -1,6 +1,7 @@
using NetMFAPatcher.Utils;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
@ -10,44 +11,30 @@ namespace NetMFAPatcher.utils
{
class Decryption
{
public static byte[] key;
public static string storedName;
public static string storedCopyright;
public static string storedPath;
public static void MakeKey(string STitle, string SCopyright,string SProject, byte MagicChar)
public static byte[] DecryptionKey;
public static byte MagicChar=54;
public static void MakeKey(string STitle, string SCopyright,string SProject)
{
storedName = STitle;
storedCopyright = SCopyright;
storedPath = SProject;
byte[] nameBytes = Encoding.ASCII.GetBytes(STitle);
var name = Marshal.StringToHGlobalAnsi(STitle);//Marshal.AllocHGlobal(STitle.Length);
Marshal.Copy(nameBytes, 0, name, STitle.Length);
var RawKey = "";
RawKey += STitle;
RawKey += SCopyright;
RawKey += SProject;
Logger.Log("Combined data "+RawKey,true,ConsoleColor.Yellow);
var RawKeyPTR = Marshal.StringToHGlobalAnsi(RawKey);
byte[] copyrightBytes = Encoding.ASCII.GetBytes(SCopyright);
var copyright = Marshal.StringToHGlobalAnsi(SCopyright);
Marshal.Copy(copyrightBytes, 0, copyright, SCopyright.Length);
byte[] filenameBytes = Encoding.ASCII.GetBytes(SProject);
var pathfilename = Marshal.StringToHGlobalAnsi(SProject);
Marshal.Copy(filenameBytes, 0, pathfilename, SProject.Length);
var ptr = Decryption.make_key(name, copyright, pathfilename, MagicChar);
var ptr = Decryption.make_key_combined(RawKeyPTR, MagicChar);
byte[] Key = new byte[257];
Marshal.Copy(ptr, Key, 0, 256);
Marshal.FreeHGlobal(name);
Marshal.FreeHGlobal(copyright);
Marshal.FreeHGlobal(pathfilename);
key = Key;
key.Log(true, "X2");
Marshal.FreeHGlobal(RawKeyPTR);
DecryptionKey = Key;
Logger.Log($"First 16-Bytes of key: {DecryptionKey.GetHex(16)}",true,ConsoleColor.Yellow);
File.WriteAllBytes($"{Program.DumpPath}\\key.bin", DecryptionKey);
}
public static byte[] DecodeMode3(byte[] ChunkData, int ChunkSize,int ChunkID, byte MagicChar)
public static byte[] DecodeMode3(byte[] ChunkData, int ChunkSize,int ChunkID)
{
var reader = new ByteIO(ChunkData);
var DecompressedSize = reader.ReadUInt32();
@ -57,27 +44,38 @@ namespace NetMFAPatcher.utils
{
chunkData[0] ^= (byte)(((byte)ChunkID & 0xFF) ^ ((byte)ChunkID >> 0x8));
}
var data = new ByteIO(DecodeChunk(chunkData,ChunkSize,MagicChar));
var rawData = DecodeChunk(chunkData, ChunkSize);
var data = new ByteIO(rawData);
var compressed_size = data.ReadUInt32();
return Decompressor.decompress_block(data, (int)compressed_size, (int)DecompressedSize);
}
public static byte[] DecodeChunk(byte[] ChunkData, int ChunkSize,byte MagicChar)
public static byte[] DecodeChunk(byte[] ChunkData, int ChunkSize)
{
IntPtr InputChunkPtr = Marshal.AllocHGlobal(ChunkSize);
Marshal.Copy(ChunkData, 0, InputChunkPtr, ChunkSize-4);
var OutputChunkPtr = decode_chunk(InputChunkPtr, ChunkSize, MagicChar);
IntPtr InputChunkPtr = Marshal.AllocHGlobal(ChunkData.Length);
Marshal.Copy(ChunkData, 0, InputChunkPtr, ChunkData.Length);
IntPtr KeyPtr = Marshal.AllocHGlobal(DecryptionKey.Length);
Marshal.Copy(DecryptionKey, 0, KeyPtr, DecryptionKey.Length);
var OutputChunkPtr = decode_chunk(InputChunkPtr, ChunkSize, MagicChar, KeyPtr);
byte[] DecodedChunk = new byte[ChunkSize];
Marshal.Copy(OutputChunkPtr, DecodedChunk,0,ChunkSize);
return DecodedChunk;
Marshal.FreeHGlobal(InputChunkPtr);
Marshal.FreeHGlobal(KeyPtr);
return DecodedChunk;
}
[DllImport("Decrypter-x64.dll", EntryPoint = "decode_chunk", CharSet = CharSet.Auto)]
public static extern IntPtr decode_chunk(IntPtr chunk_data,int chunk_size, byte magic_char);
public static extern IntPtr decode_chunk(IntPtr chunk_data, int chunk_size, byte magic_char,IntPtr wrapper_key);
[DllImport("Decrypter-x64.dll", EntryPoint = "make_key", CharSet = CharSet.Auto)]
public static extern IntPtr make_key(IntPtr c_title, IntPtr c_copyright, IntPtr c_project, byte magic_char);
[DllImport("Decrypter-x64.dll", EntryPoint = "make_key_combined", CharSet = CharSet.Auto)]
public static extern IntPtr make_key_combined(IntPtr data, byte magic_char);
}
}

@ -55,28 +55,78 @@ namespace NetMFAPatcher
return Temp;
}
public static string AutoReadUnicode(ByteIO reader)
{
var len = reader.ReadInt16();
reader.Skip(2);
return reader.ReadWideString(len);
}
public static DataLoader LoadParameter(int code, ByteIO reader)
{
DataLoader item = null;
if(code==13)
if (code == 1)
{
item = new Every(reader);
item = new ParamObject(reader);
}
if (code == 2)
{
item = new Time(reader);
}
if(item!=null) item.Read();
if (code==3|| code == 10|| code == 11 || code == 12 || code == 17 || code == 26 || code == 31 || code == 43 || code == 57 || code == 58 || code == 60 || code == 61)
{
item = new Short(reader);
}
return item;
}
public static string GetHex(this byte[] data, int count=-1,int position=0)
{
var actualCount = count;
if (actualCount == -1) actualCount = data.Length;
string temp = "";
for (int i = 0; i < actualCount; i++)
{
temp += data[i].ToString("X2");
temp += " ";
}
return temp;
}
public static void PrintHex(this byte[] data)
{
var blockSize = 16;
var blocks = data.Split<byte>(blockSize);
foreach (var block in blocks)
{
string charAcc = "";
foreach (var b in block)
{
if (b < 128 && b > 32) charAcc += Convert.ToChar(b);
else charAcc += '.';
}
var b_len = block.Count();
//var accLen=
}
}
/// <summary>
/// Splits an array into several smaller arrays.
/// </summary>
/// <typeparam name="T">The type of the array.</typeparam>
/// <param name="array">The array to split.</param>
/// <param name="size">The size of the smaller arrays.</param>
/// <returns>An array containing smaller arrays.</returns>
public static IEnumerable<IEnumerable<T>> Split<T>(this T[] array, int size)
{
for (var i = 0; i < (float)array.Length / size; i++)
{
yield return array.Skip(i * size).Take(size);
}
}
}
}

@ -48,7 +48,6 @@ namespace NetMFAPatcher.mmfparser.chunkloaders
reader.ReadInt16();
reader.ReadInt16();
reader.Skip(2);
Console.WriteLine("AfterCycleOffset: " + reader.Tell());
}
}

@ -23,7 +23,6 @@ namespace NetMFAPatcher.mmfparser.chunkloaders
public override void Read()
{
Console.WriteLine("Reading FrameItems");
var count = reader.ReadInt32();
for (int i = 0; i < count; i++)

@ -22,7 +22,7 @@ namespace NetMFAPatcher.chunkloaders
public override void Print(bool ext)
{
//Logger.Log($"{chunk.name} contains: {value}\n",true,ConsoleColor.DarkCyan);
Logger.Log($"{chunk.name} contains: {value}\n",true,ConsoleColor.DarkCyan);
}

@ -33,6 +33,7 @@ namespace NetMFAPatcher.chunkloaders
{
reader = new ByteIO(chunk.chunk_data);
var number_of_items = reader.ReadUInt32();
if (!Program.DumpImages) return;
Console.WriteLine($"Found {number_of_items} images");
for (int i = 0; i < number_of_items; i++)
{
@ -73,78 +74,33 @@ namespace NetMFAPatcher.chunkloaders
byte[] alpha;
ByteIO image_data;
public bool isCompressed = true;
public bool isCompressed = true;
public (byte[] points, int n) ReadRGB(byte[] data, int width, int heigth, TestPoint pointClass)
public override void Read()
{
var n = 0;
var i = 0;
List<byte> points = new List<byte>();
var pad = GetPadding(width, 3);
for (int y = 1; y < heigth; y++)
handle = reader.ReadInt32();
position = (int)reader.Tell();
if (Program.DumpImages)
{
for (int x = 1; x < width; x++)
{
var a = pointClass.Read(data, n);
points.Add(a.r);
points.Add(a.g);
points.Add(a.b);
n += 3;//pointClass.size;
i += 1;
}
n += 3;//(int)pad + pointClass.size;
Load();
return;
}
return (points.ToArray(), n);
}
public byte[] ReadAlpha(byte[] data, int width, int heigth, int position)
{
var n = 0;
var i = 0;
byte[] points = new byte[width * heigth * 16];
var pad = GetPadding(width, 1, 4);
for (int y = 1; y < heigth; y++)
else
{
for (int x = 1; x < heigth; x++)
if (isCompressed)
{
points[i] = data[n + position];
n++;
i++;
reader.Skip(8);
size = (int)reader.ReadUInt32();
reader.Skip(size + 20);
}
else
{
reader.Skip(4);
size = (int)reader.ReadUInt32();
reader.Seek(size + position);
}
n += (int)pad;
}
return points;
}
public double GetPadding(int width, int classSize, int bytes = 2)
{
var pad = bytes - ((width * classSize) % bytes);
if (pad == bytes) pad = 0;
var padding = Math.Ceiling((float)(pad / classSize));
return padding;//Correct
}
public override void Read()
{
handle = reader.ReadInt32();
position = (int)reader.Tell();
if (!Program.DumpImages) return;
Load();
}
public void Load()
@ -156,7 +112,6 @@ namespace NetMFAPatcher.chunkloaders
if (isCompressed)
{
image_data = Decompressor.DecompressAsReader(reader);
}
else
{
@ -164,9 +119,19 @@ namespace NetMFAPatcher.chunkloaders
}
var start = image_data.Tell();
if (!isCompressed)
{
}
checksum = image_data.ReadInt32();
references = image_data.ReadInt32();
size = (int)image_data.ReadUInt32();
if (!isCompressed)
{
image_data = new ByteIO(image_data.ReadBytes(size + 20));
}
width = image_data.ReadInt16();
height = image_data.ReadInt16();
graphic_mode = image_data.ReadByte();//Graphic mode is always 4 for SL
@ -177,23 +142,19 @@ namespace NetMFAPatcher.chunkloaders
y_hotspot = image_data.ReadInt16();
action_x = image_data.ReadInt16();
action_y = image_data.ReadInt16();
Logger.Log($"Size: {width}x{height}");
for (int i = 0; i < 4; i++)
{
image_data.ReadByte();
}
Save($"{Program.DumpPath}\\ImageBank\\" + handle.ToString() + ".png");
//Save($"{Program.DumpPath}\\ImageBank\\" + handle.ToString() + ".png");
Save("cum.png");
return;

@ -26,7 +26,7 @@ namespace NetMFAPatcher.chunkloaders
//Implementing for standalone-only because of my lazyness
items = new List<SoundItem>();
num_of_items = reader.ReadInt32();
return;
for (int i = 0; i < num_of_items; i++)
{
var item = new SoundItem(reader);

@ -30,13 +30,14 @@ namespace NetMFAPatcher.mmfparser.mfaloaders
public override void Read()
{
var handle = reader.ReadInt32();
name = reader.ReadAscii(reader.ReadInt32());
name = Helper.AutoReadUnicode(reader);
Console.WriteLine(name);
sizeX = reader.ReadInt32();
sizeY = reader.ReadInt32();
var background = reader.ReadColor();
var flags = reader.ReadInt32();
maxObjects = reader.ReadInt32();
var password = reader.ReadAscii(reader.ReadInt32());
var password = Helper.AutoReadUnicode(reader);
reader.Skip(4);
var lastViewedX = reader.ReadInt32();
var lastViewedY = reader.ReadInt32();

@ -18,7 +18,7 @@ namespace NetMFAPatcher.mmfparser.mfaloaders
public bool transparent;
public int inkEffect;
public int inkEffectParameter;
public bool antiAliasing;
public int antiAliasing;
public int flags;
public int iconType;
@ -31,13 +31,13 @@ namespace NetMFAPatcher.mmfparser.mfaloaders
{
objectType = reader.ReadInt32();
handle = reader.ReadInt32();
name = reader.ReadAscii(reader.ReadInt32());
name = Helper.AutoReadUnicode(reader);
var transparent1 = reader.ReadInt32();
inkEffect = reader.ReadInt32();
inkEffectParameter = reader.ReadInt32();
//antiAliasing = (bool)reader.ReadInt32();
reader.ReadInt32();
antiAliasing = reader.ReadInt32();
flags = reader.ReadInt32();
iconType = reader.ReadInt32();
if(iconType==1)
@ -57,11 +57,11 @@ namespace NetMFAPatcher.mmfparser.mfaloaders
}
else
{
Console.WriteLine("BeforeLoad:"+reader.Tell());
var loader = new Active(reader);
loader.Read();
reader.Skip(56);
Console.WriteLine("AfterLoad:" + reader.Tell());
}
Print();

@ -37,9 +37,12 @@ namespace mmfparser.mfaloaders
Logger.Log($"Number of image items: {count.ToString()}");
for (int i = 0; i < count; i++)
{
Console.WriteLine("READING IMAGE: " + reader.Tell());
var item = new ImageItem(reader);
item.isCompressed = true;
var currentPos = reader.Tell();
item.Read();

@ -23,7 +23,7 @@ namespace NetMFAPatcher.mmfparser.mfaloaders
public override void Read()
{
name = reader.ReadAscii(reader.ReadInt32());
name = Helper.AutoReadUnicode(reader);
flags = reader.ReadInt32();
xCoefficient = reader.ReadSingle();
yCoefficient = reader.ReadSingle();

@ -52,12 +52,12 @@ namespace NetMFAPatcher.mmfparser.mfaloaders
public override void Read()
{
name = reader.ReadAscii(reader.ReadInt32());
name = Helper.AutoReadUnicode(reader);
var type = reader.ReadInt32();
switch (type)
{
case 2://string
value = reader.ReadAscii(reader.ReadInt32());
value = Helper.AutoReadUnicode(reader);
break;
case 0://int
value = reader.ReadInt32();

@ -42,8 +42,8 @@ namespace NetMFAPatcher.mmfparser.mfaloaders.mfachunks
public override void Read()
{
name = reader.ReadAscii(reader.ReadInt32());
var extension = reader.ReadBytes(reader.ReadInt32());
name = Helper.AutoReadUnicode(reader);
var extension = Helper.AutoReadUnicode(reader);
var identifier = reader.ReadInt32();
var dataSize = reader.ReadInt32();
if(extension.Length>0)

@ -26,12 +26,12 @@ namespace NetMFAPatcher.mmfparser.mfaloaders.mfachunks
Logger.Log(" Values:");
foreach (var item in values.items)
{
Logger.Log($" Value {item.name} contains {item.value}");
Logger.Log($" Value {item.name} contains '{item.value}'");
}
Logger.Log("\n Strings:");
foreach (var item in strings.items)
{
Logger.Log($" String {item.name} contains {item.value}");
Logger.Log($" String {item.name} contains '{item.value}'");
}
Logger.Log("\n Movements:");
foreach (var item in movements.items)
@ -66,6 +66,7 @@ namespace NetMFAPatcher.mmfparser.mfaloaders.mfachunks
movements.Read();
behaviours = new Behaviours(reader);
behaviours.Read();
reader.Skip(56);
Print();

Loading…
Cancel
Save