diff --git a/DotNetCTFDumper.sln b/DotNetCTFDumper.sln new file mode 100644 index 0000000..8bc3e90 --- /dev/null +++ b/DotNetCTFDumper.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30517.126 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetCTFDumper", "NetMFAPatcher\DotNetCTFDumper.csproj", "{86D99F9E-98FB-4E50-AB68-F5C115850C33}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {86D99F9E-98FB-4E50-AB68-F5C115850C33}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {86D99F9E-98FB-4E50-AB68-F5C115850C33}.Debug|Any CPU.Build.0 = Debug|Any CPU + {86D99F9E-98FB-4E50-AB68-F5C115850C33}.Release|Any CPU.ActiveCfg = Release|Any CPU + {86D99F9E-98FB-4E50-AB68-F5C115850C33}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {3E9F5D62-DBC6-4734-88CF-23880CA92DF2} + EndGlobalSection +EndGlobal diff --git a/ImageBank.cs b/ImageBank.cs new file mode 100644 index 0000000..2256dbd --- /dev/null +++ b/ImageBank.cs @@ -0,0 +1,226 @@ +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Numerics; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.Chunks +{ + class ImageBank:ChunkLoader + { + public override void Print() + { + + } + + public override void Read() + { + reader = new ByteIO(chunk.chunk_data); + var number_of_items = reader.ReadUInt32(); + Console.WriteLine("Total images: "+number_of_items); + Console.WriteLine("OnImageBankStart: " + reader.Tell()); + for (int i = 0; i < number_of_items; i++) + { + var item = new ImageItem(); + item.reader = reader; + item.Read(); + item.Save(i.ToString()+".raw"); + + + + + } + + } + } + class ImageItem:ChunkLoader + { + + int handle; + int position; + int checksum; + int references; + int width; + int height; + int graphic_mode; + int x_hotspot; + int y_hotspot; + int action_x; + int action_y; + //tranparent,add later + int indexed; + byte[] image; + byte[] alpha; + private int currentSize; + private byte[] currentImage; + private byte[] curPoints; + private int currentN; + + public void ReadRGB(byte[] data,int width,int heigth,TestPoint pointClass) + { + var n = 0; + var i = 0; + List points = new List(); + var pad = GetPadding(width, 3); + for (int y = 0; y < heigth; y++) + { + for (int x = 0; x < width; x++) + { + points.AddRange(pointClass.Read(data, n)); + n += 3;//pointClass.size; + i += 1; + } + n += 3;//(int)pad + pointClass.size; + + } + curPoints = points.ToArray(); + currentN = n; + } + public void ReadAlpha(byte[] data, int width, int heigth, int position) + { + + var n = 0; + var i = 0; + List points = new List(); + var pad = GetPadding(width, 1, 4); + for (int y = 0; y < heigth; y++) + { + for (int x = 0; x < heigth; x++) + { + points[i] = data[n + position]; + n++; + i++; + + } + n += (int)pad; + } + curPoints = points.ToArray(); + + + + } + + 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(); + Load(); + + + } + public void Load() + { + + + reader.Seek(position); + + + + var decompressedImg = Decompressor.Decompress(reader); + var image_data = new ByteIO(decompressedImg); + var start = image_data.Tell(); + checksum = image_data.ReadInt32(); + references = image_data.ReadInt32(); + var size = image_data.ReadUInt32(); + width = image_data.ReadInt16(); + height = image_data.ReadInt16(); + graphic_mode = image_data.ReadByte();//Graphic mode is always 4 for SL + var flags = image_data.ReadSByte(); + image_data.Skip(2); + x_hotspot = image_data.ReadInt16(); + 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(); + //transparence + + } + int alpha_size=0; + byte[] data; + if (false)//lzx flag + { + var decompressed_size = image_data.ReadUInt32(); + image_data = Decompressor.decompress_asReader(image_data, (int)(image_data.Size() - image_data.Tell()), (int)decompressed_size); + } + else + { + //image_data = image_data.ReadBytes(-1) + data = image_data.ReadBytes((int)reader.Size()); + var curPoint = new TestPoint(); + ReadRGB(data,width,height,curPoint); + var image = curPoints; + var image_size = currentN; + this.image = image; + alpha_size = (int)(size - image_size); + + } + var pad = (alpha_size - width * height) / height; + //ReadAlpha(data, width, height, (int)(size - alpha_size)); + //alpha = curPoints; + + + + } + public void Save(string filename) + { + + File.WriteAllBytes(filename,image); + + } + + public override void Print() + { + + } + } + + public class TestPoint + { + public int size = 3; + public byte[] Read(byte[]data,int position) + { + byte r=0; + byte g=0; + byte b=0; + try + { + + + b = data[position]; + g = data[position + 1]; + r = data[position + 2]; + } + catch + { + + Console.WriteLine(position); + } + return (new List() { r, g, b }).ToArray(); + } + + + } + + +} diff --git a/NetMFAPatcher/App.config b/NetMFAPatcher/App.config new file mode 100644 index 0000000..56efbc7 --- /dev/null +++ b/NetMFAPatcher/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/NetMFAPatcher/Chunks/AppHeader.cs b/NetMFAPatcher/Chunks/AppHeader.cs new file mode 100644 index 0000000..2d2e857 --- /dev/null +++ b/NetMFAPatcher/Chunks/AppHeader.cs @@ -0,0 +1,160 @@ +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.Chunks +{ + class AppHeader:ChunkLoader + { + int size; + int windowWidth; + int windowHeight; + int initialScore; + int initialLives; + public int numberOfFrames; + public override void Read() + { + reader = new ByteIO(chunk.chunk_data); + Logger.Log(reader.Tell().ToString()); + size = reader.ReadInt32(); + var flags = reader.ReadInt16();//raw,need convert + var new_flags = reader.ReadInt16();//read flags or no balls + var graphics_mode = reader.ReadInt16();//i am serious + var otherflags = reader.ReadInt16();//last chance to get balls back + windowWidth = reader.ReadInt16(); + windowHeight = reader.ReadInt16(); + initialScore = (int)(reader.ReadUInt32() ^ 0xffffffff); + initialLives = (int)(reader.ReadUInt32() ^ 0xffffffff); + var controls = new Controls(reader); + controls.Read(); + //controls.Print(); + + var borderColor = reader.ReadBytes(4); + borderColor.Log(true,"X2"); + numberOfFrames = reader.ReadInt32(); + var frameRate = reader.ReadInt32(); + var windowsMenuIndex = reader.ReadSByte(); + + + + + + + + } + public override void Print() + { + Logger.Log($"ScreenRes: {windowWidth}x{windowHeight}"); + Logger.Log($"Score: {initialScore}, Lives: {initialLives}"); + Logger.Log($"Frame count: {numberOfFrames}"); + Logger.Log(""); + + } + + + } + + + + + public class Controls + { + public List items; + ByteIO reader; + public Controls(ByteIO reader) { this.reader = reader; } + + public void Read() + { + items = new List(); + for (int i = 0; i <4; i++) + { + var item = new PlayerControl(reader); + items.Add(item); + item.Read(); + + + } + + } + public void Print() + { + Logger.Log("Controls: "); + foreach(var item in items) + { + item.Print(); + } + + } + + } + public class PlayerControl + { + int controlType = 0; + ByteIO reader; + Keys keys; + + public PlayerControl(ByteIO reader) { this.reader = reader; } + public void Read() + { + + keys = new Keys(reader); + controlType = reader.ReadInt16(); + keys.Read(); + + } + public void Print() + { + Logger.Log("PlayerControl:"); + Logger.Log($"ControlType: {controlType}"); + keys.Print(); + + } + + } + public class Keys + { + int up; + int down; + int left; + int right; + int button1; + int button2; + int button3; + int button4; + ByteIO reader; + public Keys(ByteIO reader) { this.reader = reader; } + + + public void Read() + { + up = reader.ReadInt16(); + down = reader.ReadInt16(); + left = reader.ReadInt16(); + right = reader.ReadInt16(); + button1 = reader.ReadInt16(); + button2 = reader.ReadInt16(); + button3 = reader.ReadInt16(); + button4 = reader.ReadInt16(); + + } + public void Print() + { + Logger.Log($"Up: {up}"); + Logger.Log($"Down: {down}"); + Logger.Log($"Left: {left}"); + Logger.Log($"Right: {right}"); + Logger.Log($"Button1: {button1}"); + Logger.Log($"Button2: {button2}"); + Logger.Log($"Button3: {button3}"); + Logger.Log($"Button4: {button4}"); + + + } + + } + + +} diff --git a/NetMFAPatcher/Chunks/ChunkLoader.cs b/NetMFAPatcher/Chunks/ChunkLoader.cs new file mode 100644 index 0000000..cc48247 --- /dev/null +++ b/NetMFAPatcher/Chunks/ChunkLoader.cs @@ -0,0 +1,27 @@ +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static NetMFAPatcher.mmfparser.ChunkList; + +namespace NetMFAPatcher.Chunks +{ + public abstract class ChunkLoader + { + public Chunk chunk; + public ByteIO reader; + + + public abstract void Read(); + + + public abstract void Print(); + + + + + + } +} diff --git a/NetMFAPatcher/Chunks/Frame.cs b/NetMFAPatcher/Chunks/Frame.cs new file mode 100644 index 0000000..be1ce8a --- /dev/null +++ b/NetMFAPatcher/Chunks/Frame.cs @@ -0,0 +1,52 @@ +using NetMFAPatcher.mmfparser; +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.Chunks +{ + class FrameName : StringChunk + { + } + class FramePassword : StringChunk + { + } + public class Frame : ChunkLoader + { + ByteIO reader; + public string name; + public string password; + public int width; + public int height; + //background, idk what type is it + //flags + int top; + int bottom; + int left; + int right; + + + + public override void Print() + { + + } + + public override void Read() + { + var FrameReader = new ByteIO(chunk.chunk_data); + var chunks = new ChunkList(); + chunks.verbose = false; + chunks.Read(FrameReader); + var name = chunks.get_chunk(); + Logger.Log(name.value); + + + } + } + + +} diff --git a/NetMFAPatcher/Chunks/ImageBank.cs b/NetMFAPatcher/Chunks/ImageBank.cs new file mode 100644 index 0000000..2256dbd --- /dev/null +++ b/NetMFAPatcher/Chunks/ImageBank.cs @@ -0,0 +1,226 @@ +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Numerics; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.Chunks +{ + class ImageBank:ChunkLoader + { + public override void Print() + { + + } + + public override void Read() + { + reader = new ByteIO(chunk.chunk_data); + var number_of_items = reader.ReadUInt32(); + Console.WriteLine("Total images: "+number_of_items); + Console.WriteLine("OnImageBankStart: " + reader.Tell()); + for (int i = 0; i < number_of_items; i++) + { + var item = new ImageItem(); + item.reader = reader; + item.Read(); + item.Save(i.ToString()+".raw"); + + + + + } + + } + } + class ImageItem:ChunkLoader + { + + int handle; + int position; + int checksum; + int references; + int width; + int height; + int graphic_mode; + int x_hotspot; + int y_hotspot; + int action_x; + int action_y; + //tranparent,add later + int indexed; + byte[] image; + byte[] alpha; + private int currentSize; + private byte[] currentImage; + private byte[] curPoints; + private int currentN; + + public void ReadRGB(byte[] data,int width,int heigth,TestPoint pointClass) + { + var n = 0; + var i = 0; + List points = new List(); + var pad = GetPadding(width, 3); + for (int y = 0; y < heigth; y++) + { + for (int x = 0; x < width; x++) + { + points.AddRange(pointClass.Read(data, n)); + n += 3;//pointClass.size; + i += 1; + } + n += 3;//(int)pad + pointClass.size; + + } + curPoints = points.ToArray(); + currentN = n; + } + public void ReadAlpha(byte[] data, int width, int heigth, int position) + { + + var n = 0; + var i = 0; + List points = new List(); + var pad = GetPadding(width, 1, 4); + for (int y = 0; y < heigth; y++) + { + for (int x = 0; x < heigth; x++) + { + points[i] = data[n + position]; + n++; + i++; + + } + n += (int)pad; + } + curPoints = points.ToArray(); + + + + } + + 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(); + Load(); + + + } + public void Load() + { + + + reader.Seek(position); + + + + var decompressedImg = Decompressor.Decompress(reader); + var image_data = new ByteIO(decompressedImg); + var start = image_data.Tell(); + checksum = image_data.ReadInt32(); + references = image_data.ReadInt32(); + var size = image_data.ReadUInt32(); + width = image_data.ReadInt16(); + height = image_data.ReadInt16(); + graphic_mode = image_data.ReadByte();//Graphic mode is always 4 for SL + var flags = image_data.ReadSByte(); + image_data.Skip(2); + x_hotspot = image_data.ReadInt16(); + 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(); + //transparence + + } + int alpha_size=0; + byte[] data; + if (false)//lzx flag + { + var decompressed_size = image_data.ReadUInt32(); + image_data = Decompressor.decompress_asReader(image_data, (int)(image_data.Size() - image_data.Tell()), (int)decompressed_size); + } + else + { + //image_data = image_data.ReadBytes(-1) + data = image_data.ReadBytes((int)reader.Size()); + var curPoint = new TestPoint(); + ReadRGB(data,width,height,curPoint); + var image = curPoints; + var image_size = currentN; + this.image = image; + alpha_size = (int)(size - image_size); + + } + var pad = (alpha_size - width * height) / height; + //ReadAlpha(data, width, height, (int)(size - alpha_size)); + //alpha = curPoints; + + + + } + public void Save(string filename) + { + + File.WriteAllBytes(filename,image); + + } + + public override void Print() + { + + } + } + + public class TestPoint + { + public int size = 3; + public byte[] Read(byte[]data,int position) + { + byte r=0; + byte g=0; + byte b=0; + try + { + + + b = data[position]; + g = data[position + 1]; + r = data[position + 2]; + } + catch + { + + Console.WriteLine(position); + } + return (new List() { r, g, b }).ToArray(); + } + + + } + + +} diff --git a/NetMFAPatcher/Chunks/SoundBank.cs b/NetMFAPatcher/Chunks/SoundBank.cs new file mode 100644 index 0000000..0744a7f --- /dev/null +++ b/NetMFAPatcher/Chunks/SoundBank.cs @@ -0,0 +1,96 @@ +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.Chunks +{ + class SoundBank : ChunkLoader + { + public int num_of_items = 0; + public int references = 0; + public List items; + public override void Print() + { + + } + + public override void Read() + { + //Implementing for standalone-only because of my lazyness + reader = new ByteIO(chunk.chunk_data); + items = new List(); + num_of_items = reader.ReadInt32(); + for (int i = 0; i < num_of_items; i++) + { + var item = new SoundItem(); + item.reader = reader; + item.Read(); + items.Add(item); + + + } + + + + + } + } + public class SoundBase : ChunkLoader + { + public int handle; + public string name = "ERROR"; + public byte[] data; + public override void Print() + { + + } + + public override void Read() + { + + } + + } + public class SoundItem:SoundBase + { + public bool compressed; + public int checksum; + public int references; + public override void Read() + { + var start = reader.Tell(); + handle = (int)reader.ReadUInt32(); + checksum = reader.ReadInt32(); + references = reader.ReadInt32(); + var decompressed_size = reader.ReadInt32(); + reader.ReadUInt32();//flags + var reserved = reader.ReadInt32(); + var name_lenght = reader.ReadInt32(); + ByteIO SoundData; + if (true)//compressed + { + var size = reader.ReadInt32(); + SoundData = new ByteIO(Decompressor.decompress_block(reader,size,decompressed_size)); + } + else + { + SoundData = new ByteIO(reader.ReadBytes(decompressed_size)); + } + name = SoundData.ReadWideString(name_lenght); + this.data = SoundData.ReadBytes((int)SoundData.Size()); + name = Helper.CleanInput(name); + Console.WriteLine($"Dumping {name}"); + + string path = $"DUMP\\{Program.filename}\\SoundBank\\{name}.wav"; + File.WriteAllBytes(path, data); + + + + + } + } +} diff --git a/NetMFAPatcher/Chunks/StringChunk.cs b/NetMFAPatcher/Chunks/StringChunk.cs new file mode 100644 index 0000000..c4673c6 --- /dev/null +++ b/NetMFAPatcher/Chunks/StringChunk.cs @@ -0,0 +1,58 @@ +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.Chunks +{ + class StringChunk : ChunkLoader + { + public string value; + + + public override void Read() + { + reader = new ByteIO(chunk.chunk_data); + value = reader.ReadWideString1();//reader.ReadWideString(); + + + } + public override void Print() + { + //Logger.Log($"{chunk.name}: {value}"); + } + + + } + class AppName : StringChunk + { + } + class AppAuthor : StringChunk + { + } + class ExtPath : StringChunk + { + } + class EditorFilename : StringChunk + { + } + class TargetFilename : StringChunk + { + } + class AppDoc : StringChunk + { + } + class AboutText : StringChunk + { + } + class Copyright : StringChunk + { + } + class DemoFilePath : StringChunk + { + } + + +} diff --git a/NetMFAPatcher/Chunks/yves.cs b/NetMFAPatcher/Chunks/yves.cs new file mode 100644 index 0000000..26838d9 --- /dev/null +++ b/NetMFAPatcher/Chunks/yves.cs @@ -0,0 +1,60 @@ +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.Chunks +{ + public class AppIcon + { + ByteIO reader; + List points; + + + public AppIcon(ByteIO reader) + { + this.reader = reader; + } + public void Read() + { + reader.ReadBytes(reader.ReadInt32() - 4); + var color_indexes = new byte[16 * 16 * 3]; + for (int i = 0; i < 16*16; i++) + { + + var b = reader.ReadByte(); + var g = reader.ReadByte(); + var r = reader.ReadByte(); + reader.ReadSByte(); + color_indexes.Append(r); + color_indexes.Append(g); + color_indexes.Append(b); + } + points = new List(); + for (int y = 0; y < 16; y++) + { + var x_list = new List(); + for (int x = 0; x < 16; x++) + { + x_list.Add(color_indexes[reader.ReadByte()]); + } + //var points = x_list.// this.points; + //how to add lists? + } + + Dump(); + + + + } + public void Dump() + { + + + } + } +} diff --git a/NetMFAPatcher/DotNetCTFDumper.csproj b/NetMFAPatcher/DotNetCTFDumper.csproj new file mode 100644 index 0000000..67b38f3 --- /dev/null +++ b/NetMFAPatcher/DotNetCTFDumper.csproj @@ -0,0 +1,125 @@ + + + + + Debug + AnyCPU + {86D99F9E-98FB-4E50-AB68-F5C115850C33} + Exe + NetMFAPatcher + DotNetCTFDumper + v4.7.2 + 512 + true + true + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + On + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + E:\ClickTFReader-master\DUMP\fnaf-world\CHUNKS\Ionic.Zlib.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + Microsoft .NET Framework 4.7.2 %28x86 и x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + \ No newline at end of file diff --git a/NetMFAPatcher/Helper.cs b/NetMFAPatcher/Helper.cs new file mode 100644 index 0000000..73c3b4b --- /dev/null +++ b/NetMFAPatcher/Helper.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher +{ + static class Helper + { + public static byte[] ToBytes(this string str) + { + return Encoding.ASCII.GetBytes(str); + + + } + public static string GetString(this byte[] bytes) + { + return Encoding.ASCII.GetString(bytes); + + + } + public static string Log(this byte[] bytes, bool log = true, string format = "") + { + string Temp = String.Empty; + for (int i = 0; i < bytes.Length; i++) + { + var item = bytes[i]; + if (i > 0) + { + Temp += " " + item.ToString(format); + + } + else + { + Temp += item.ToString(format); + } + + } + if (log) + { + + + Console.WriteLine(Temp); + } + return Temp; + + + } + + } +} diff --git a/NetMFAPatcher/Program.cs b/NetMFAPatcher/Program.cs new file mode 100644 index 0000000..85f7474 --- /dev/null +++ b/NetMFAPatcher/Program.cs @@ -0,0 +1,249 @@ +using NetMFAPatcher.chunkloaders; +using NetMFAPatcher.Utils; +using NetMFAPatcher.mmfparser; +using System; +using System.IO; +using System.Collections; +using NetMFAPatcher.mfa; + +namespace NetMFAPatcher +{ + class Program + { + public static PackData pack_data; + public static GameData game_data; + //public static string path = @"H:\fnaf-world.exe"; + //public static string path = @"D:\SteamLibrary\steamapps\common\Five Nights at Freddy's Sister Location\SisterLocation.exe"; + public static string path = "";//TODO: Make Selectable + + public static string GameName;// = Path.GetFileNameWithoutExtension(path); + public static string DumpPath;// = $"DUMP\\{GameName}"; + + public static bool doMFA=false; + public static bool DumpImages = false; + public static bool DumpSounds = false; + public static bool verbose; + + + [STAThread] + static void Main(string[] args) + { + string Path=""; + bool Verbose=false; + bool DumpImages=true; + bool DumpSounds=true; + bool CreateFolders=true; + if (args.Length == 0) + { + if (true) + { + + + ByteIO mfaReader = new ByteIO(@"E:\SUPERDECOMPILER\Tests\mmftest.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); + } + if (args.Length > 0) + { + Path = args[0]; + } + if (args.Length > 1) + { + Boolean.TryParse(args[1],out Verbose); + } + if (args.Length > 2) + { + Boolean.TryParse(args[2],out DumpImages); + } + if(args.Length>3) + { + Boolean.TryParse(args[3],out DumpSounds); + } + if(args[0]=="-h"||args[0]=="-help") + { + Logger.Log($"DotNetCTFDumper: 0.0.5",true,ConsoleColor.Green); + Logger.Log($"Lauch Args:", true, ConsoleColor.Green); + Logger.Log($" Filename - path to your exe or mfa", true, ConsoleColor.Green); + Logger.Log($" Info - Dump debug info to console(default:true)", true, ConsoleColor.Green); + Logger.Log($" DumpImages - Dump images to 'DUMP\\[your game]\\ImageBank'(default:false)", true, ConsoleColor.Green); + Logger.Log($" DumpSounds - Dump sounds to 'DUMP\\[your game]\\SoundBank'(default:true)\n", true, ConsoleColor.Green); + Logger.Log($"Exaple: DotNetCTFDumper.exe E:\\SisterLocation.exe true true false true", true, ConsoleColor.Green); + Console.ReadKey(); + Environment.Exit(0); + + } + + + ReadFile(Path,Verbose,DumpImages,DumpSounds); + + + } + public static void ReadFile(string path,bool verbose=false,bool dumpImages=false,bool dumpSounds=true) + { + GameName = Path.GetFileNameWithoutExtension(path); + DumpPath = $"DUMP\\{GameName}"; + PrepareFolders(); + + DumpImages = dumpImages; + DumpSounds = dumpSounds; + Program.verbose = verbose; + if (File.Exists(path)) + { + + + if (path.EndsWith(".exe")) + { + doMFA = false; + + ByteIO exeReader = new ByteIO(path, FileMode.Open); + + + ParseExe(exeReader); + Logger.Log("Finished!", true, ConsoleColor.Yellow); + Console.ReadKey(); + } + else if (path.EndsWith(".mfa")) + { + Logger.Log("MFA reading is currently unstable"); + Logger.Log("Are you sure?"); + Console.ReadKey(); + + ByteIO mfaReader = new ByteIO(path, FileMode.Open); + var mfa = new MFA(mfaReader); + mfa.Read(); + Console.ReadKey(); + } + else + { + Logger.Log($"File '{path}' is not a valid file", true, ConsoleColor.Red); + } + } + else + { + Logger.Log($"File '{path}' does not exist",true,ConsoleColor.Red); + } + + + + + + } + public static void PrepareFolders() + { + Directory.CreateDirectory($"{DumpPath}\\CHUNKS\\OBJECTINFO"); + Directory.CreateDirectory($"{DumpPath}\\CHUNKS\\FRAMES"); + Directory.CreateDirectory($"{DumpPath}\\ImageBank"); + Directory.CreateDirectory($"{DumpPath}\\MusicBank"); + Directory.CreateDirectory($"{DumpPath}\\SoundBank"); + 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); + } + } + } +} \ No newline at end of file diff --git a/NetMFAPatcher/Properties/AssemblyInfo.cs b/NetMFAPatcher/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..154510b --- /dev/null +++ b/NetMFAPatcher/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Общие сведения об этой сборке предоставляются следующим набором +// набора атрибутов. Измените значения этих атрибутов для изменения сведений, +// связанные с этой сборкой. +[assembly: AssemblyTitle("DotNetCTFDumper")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("DotNetCTFDumper")] +[assembly: AssemblyCopyright("Kostya Ivanin © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми +// для компонентов COM. Если необходимо обратиться к типу в этой сборке через +// из модели COM задайте для атрибута ComVisible этого типа значение true. +[assembly: ComVisible(false)] + +// Следующий GUID представляет идентификатор typelib, если этот проект доступен из модели COM +[assembly: Guid("86d99f9e-98fb-4e50-ab68-f5c115850c33")] + +// Сведения о версии сборки состоят из указанных ниже четырех значений: +// +// Основной номер версии +// Дополнительный номер версии +// Номер сборки +// Номер редакции +// +// Можно задать все значения или принять номера сборки и редакции по умолчанию +// используя "*", как показано ниже: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/NetMFAPatcher/Scanner.cs b/NetMFAPatcher/Scanner.cs new file mode 100644 index 0000000..5181adc --- /dev/null +++ b/NetMFAPatcher/Scanner.cs @@ -0,0 +1,62 @@ +using NetMFAPatcher; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +static class Scanner +{ + static readonly int[] Empty = new int[0]; + private static byte[] GetBytes(string value) + { + var myStr = value; + + return myStr.Split(' ').Select(s => byte.Parse(s, System.Globalization.NumberStyles.HexNumber)).ToArray(); + } + public static int[] Locate(this byte[] self,string candidate) + { + var actualBytes = GetBytes(candidate);//Encoding.ASCII.GetBytes(candidate); + return self.Locate(actualBytes); + } + + public static int[] Locate(this byte[] self, byte[] candidate) + { + if (IsEmptyLocate(self, candidate)) + return Empty; + + var list = new List(); + + for (int i = 0; i < self.Length; i++) + { + if (!IsMatch(self, i, candidate)) + continue; + + list.Add(i); + } + + return list.Count == 0 ? Empty : list.ToArray(); + } + + static bool IsMatch(byte[] array, int position, byte[] candidate) + { + if (candidate.Length > (array.Length - position)) + return false; + + for (int i = 0; i < candidate.Length; i++) + if (array[position + i] != candidate[i]) + return false; + + return true; + } + + static bool IsEmptyLocate(byte[] array, byte[] candidate) + { + return array == null + || candidate == null + || array.Length == 0 + || candidate.Length == 0 + || candidate.Length > array.Length; + } + + +} diff --git a/NetMFAPatcher/Utils/ByteFlag.cs b/NetMFAPatcher/Utils/ByteFlag.cs new file mode 100644 index 0000000..77b78bc --- /dev/null +++ b/NetMFAPatcher/Utils/ByteFlag.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.utils +{ + public static class ByteFlag + { + public static bool getFlag(int flagbyte,int pos) + { + var mask = Math.Pow(2, pos); + var result = flagbyte & (int)mask; + return result == mask; + + } + } +} diff --git a/NetMFAPatcher/Utils/ByteIO.cs b/NetMFAPatcher/Utils/ByteIO.cs new file mode 100644 index 0000000..a7a8d48 --- /dev/null +++ b/NetMFAPatcher/Utils/ByteIO.cs @@ -0,0 +1,139 @@ +using System; +using System.Text; +using System.IO; +using System.Drawing; + +namespace NetMFAPatcher.Utils +{ + public class ByteIO : BinaryReader + { + public ByteIO(Stream input) : base(input) + { + } + + public ByteIO(Stream input, Encoding encoding) : base(input, encoding) + { + } + + public ByteIO(Stream input, Encoding encoding, bool leaveOpen) : base(input, encoding, leaveOpen) + { + } + + public ByteIO(byte[] data) : base(new MemoryStream(data)) + { + } + + public ByteIO(string path, FileMode fileMode) : base(new FileStream(path, fileMode)) + { + } + + public void Seek(Int64 offset, SeekOrigin seekOrigin = SeekOrigin.Begin) + { + BaseStream.Seek(offset, seekOrigin); + } + + public void Skip(Int64 count) + { + BaseStream.Seek(count, SeekOrigin.Current); + } + public byte[] ReadFourCC() + { + return Encoding.UTF8.GetBytes(ReadAscii(4)); + } + + public Int64 Tell() + { + return BaseStream.Position; + } + + public Int64 Size() + { + return BaseStream.Length; + } + + public bool Check(int size) + { + return Size() - Tell() >= size; + } + + public bool eof() + { + return BaseStream.Position < BaseStream.Length; + } + + public UInt16 PeekUInt16() + { + UInt16 value = ReadUInt16(); + Seek(-2, SeekOrigin.Current); + return value; + } + + public Int16 PeekInt16() + { + Int16 value = ReadInt16(); + Seek(-2, SeekOrigin.Current); + return value; + } + + + public string ReadAscii(int length = -1) + { + string str = ""; + if (length >= 0) + { + for (int i = 0; i < length; i++) + { + str += Convert.ToChar(ReadByte()); + } + } + else + { + byte b = ReadByte(); + while (b != 0) + { + str += Convert.ToChar(b); + b = ReadByte(); + } + } + + return str; + } + + + public string ReadWideString(int length = -1) + { + String str = ""; + if (length >= 0) + { + for (int i = 0; i < length; i++) + { + str += Convert.ToChar(ReadUInt16()); + } + } + else + { + var b = ReadUInt16(); + while (b != 0) + { + str += Convert.ToChar(b); + b = ReadUInt16(); + } + } + + return str; + } + public Color ReadColor() + { + + var r = ReadByte(); + var g = ReadByte(); + var b = ReadByte(); + Skip(1); + Color color = Color.FromArgb(b, g, r); + + return color; + + } + + } +} \ No newline at end of file diff --git a/NetMFAPatcher/Utils/ByteWriter.cs b/NetMFAPatcher/Utils/ByteWriter.cs new file mode 100644 index 0000000..4dd5700 --- /dev/null +++ b/NetMFAPatcher/Utils/ByteWriter.cs @@ -0,0 +1,71 @@ +using System; +using System.Text; +using System.IO; +using System.Drawing; + +namespace NetMFAPatcher.Utils +{ + public class ByteWriter : BinaryWriter + { + public ByteWriter(Stream input) : base(input) + { + } + + public ByteWriter(Stream input, Encoding encoding) : base(input, encoding) + { + } + + public ByteWriter(Stream input, Encoding encoding, bool leaveOpen) : base(input, encoding, leaveOpen) + { + } + + public ByteWriter(byte[] data) : base(new MemoryStream(data)) + { + } + + public ByteWriter(string path, FileMode fileMode) : base(new FileStream(path, fileMode)) + { + } + + public void Seek(Int64 offset, SeekOrigin seekOrigin = SeekOrigin.Begin) + { + BaseStream.Seek(offset, seekOrigin); + } + + public void Skip(Int64 count) + { + BaseStream.Seek(count, SeekOrigin.Current); + } + + + public Int64 Tell() + { + return BaseStream.Position; + } + + public Int64 Size() + { + return BaseStream.Length; + } + + public bool Check(int size) + { + return Size() - Tell() >= size; + } + + public bool eof() + { + return BaseStream.Position < BaseStream.Length; + } + + + + + + + + + + + } +} \ No newline at end of file diff --git a/NetMFAPatcher/Utils/Decompressor.cs b/NetMFAPatcher/Utils/Decompressor.cs new file mode 100644 index 0000000..2d626ca --- /dev/null +++ b/NetMFAPatcher/Utils/Decompressor.cs @@ -0,0 +1,37 @@ +using System; + +namespace NetMFAPatcher.Utils +{ + public static class Decompressor + { + public static byte[] Decompress(ByteIO exeReader) + { + Int32 decomp_size = exeReader.ReadInt32(); + Int32 comp_size = exeReader.ReadInt32(); + return decompress_block(exeReader, comp_size, decomp_size); + + } + public static ByteIO DecompressAsReader(ByteIO exeReader) + { + Int32 decomp_size = exeReader.ReadInt32(); + Int32 comp_size = exeReader.ReadInt32(); + byte[] compressedData = exeReader.ReadBytes(comp_size); + byte[] actualData = Ionic.Zlib.ZlibStream.UncompressBuffer(compressedData); + return new ByteIO(actualData); + } + public static byte[] decompress_block(ByteIO reader,int size,int decomp_size) + { + byte[] compressedData = reader.ReadBytes(size); + byte[] actualData = Ionic.Zlib.ZlibStream.UncompressBuffer(compressedData); + return actualData; + + } + + public static ByteIO decompress_asReader(ByteIO image_data, int v, int decompressed_size) + { + return new ByteIO(decompress_block(image_data, v, decompressed_size)); + } + } + + +} diff --git a/NetMFAPatcher/Utils/Decryption.cs b/NetMFAPatcher/Utils/Decryption.cs new file mode 100644 index 0000000..409bbe1 --- /dev/null +++ b/NetMFAPatcher/Utils/Decryption.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.utils +{ + class Decryption + { + } +} diff --git a/NetMFAPatcher/Utils/Helper.cs b/NetMFAPatcher/Utils/Helper.cs new file mode 100644 index 0000000..289c844 --- /dev/null +++ b/NetMFAPatcher/Utils/Helper.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace NetMFAPatcher +{ + static class Helper + { + public static byte[] ToBytes(this string str) + { + return Encoding.ASCII.GetBytes(str); + + + } + public static int getPadding(int width, int pad=2) + { + int num = pad - width * 3 % pad; + if(num==pad) + { + num = 0; + } + return (int)Math.Ceiling((double)((float)num/3f)); + } + public static string CleanInput(string strIn) + { + try + { + return Regex.Replace(strIn, @"[^\w\.@-]", "", + RegexOptions.None, TimeSpan.FromSeconds(1.5)); + } + + catch (RegexMatchTimeoutException) + { + return String.Empty; + } + } + public static string GetString(this byte[] bytes) + { + string str = ""; + for (int i = 0; i < bytes.Length; i++) + { + str += Convert.ToChar(bytes[i]); + + } + return str; + + + } + public static string Log(this byte[] bytes, bool log = true, string format = "") + { + string Temp = String.Empty; + for (int i = 0; i < bytes.Length; i++) + { + var item = bytes[i]; + if (i > 0) + { + Temp += " " + item.ToString(format); + + } + else + { + Temp += item.ToString(format); + } + + } + if (log) + { + + + Console.WriteLine(Temp); + } + return Temp; + + + } + + } +} diff --git a/NetMFAPatcher/Utils/ImageHelper.cs b/NetMFAPatcher/Utils/ImageHelper.cs new file mode 100644 index 0000000..e379a09 --- /dev/null +++ b/NetMFAPatcher/Utils/ImageHelper.cs @@ -0,0 +1,34 @@ +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.utils +{ + public static class ImageHelper + { + public static Color ReadPoint(byte[] data,int position) + { + //byte b2 = binaryReader.ReadByte(); + //byte b3 = binaryReader.ReadByte(); + //byte b4 = binaryReader.ReadByte(); + byte b2 = data[position]; + byte b3 = data[position+1]; + byte b4 = data[position+2]; + return Color.FromArgb((int)b4, (int)b3, (int)b2); + + } + public static Color ReadSixteen(byte[] data, int position) + { + var newShort = (data[position] | data[position + 1] << 8); + byte r = (byte)((newShort & 31744) >> 10); + byte g = (byte)((newShort & 992) >> 5); + byte b = (byte)((newShort & 31)); + return Color.FromArgb((int)b, (int)g, (int)r); + + } + } +} diff --git a/NetMFAPatcher/Utils/Logger.cs b/NetMFAPatcher/Utils/Logger.cs new file mode 100644 index 0000000..813a49f --- /dev/null +++ b/NetMFAPatcher/Utils/Logger.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.Utils +{ + public static class Logger + { + static StreamWriter writer; + public static void Log(string text, bool logToScreen = true,ConsoleColor color = ConsoleColor.White) + { + if (writer == null) + { + File.Delete("Dump.log"); + writer = new StreamWriter("Dump.log", true); + writer.AutoFlush = true; + + } + writer.WriteLine(text); + + if (logToScreen) + { + Console.ForegroundColor = color; + Console.WriteLine(text); + Console.ForegroundColor = ConsoleColor.White; + + } + + } + } +} diff --git a/NetMFAPatcher/mmfparser/ChunkList.cs b/NetMFAPatcher/mmfparser/ChunkList.cs new file mode 100644 index 0000000..fa54ea2 --- /dev/null +++ b/NetMFAPatcher/mmfparser/ChunkList.cs @@ -0,0 +1,212 @@ +using NetMFAPatcher.chunkloaders; +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.IO; +using static NetMFAPatcher.mmfparser.Constants; + +namespace NetMFAPatcher.mmfparser +{ + public class ChunkList + { + List chunks = new List(); + public bool verbose = true; + + public void Read(ByteIO exeReader) + { + chunks.Clear(); + while (true) + { + Chunk chunk = new Chunk(chunks.Count, this); + chunk.Read(exeReader); + chunk.loader = LoadChunk(chunk); + + if (chunk.loader != null) + { + if (chunk.loader.verbose) + { + chunk.loader.Print(); + } + } + + chunks.Add(chunk); + + if (chunk.id == 32639) break; //LAST chunkID + } + + Logger.Log(verbose ? $" Total Chunks Count: {chunks.Count}":"ChunkList Done", true, ConsoleColor.Blue); + } + + public class Chunk + { + ChunkList chunk_list; + public string name = "UNKNOWN"; + int uid; + public int id = 0; + + public ChunkLoader loader; + public byte[] chunk_data; + public ChunkFlags flag; + int size = 0; + int decompressed_size = 0; + bool verbose = true; + + public Chunk(int Actualuid, ChunkList actual_chunk_list) + { + uid = Actualuid; + chunk_list = actual_chunk_list; + } + + public ByteIO get_reader() + { + return new ByteIO(chunk_data); + } + + public void Read(ByteIO exeReader) + { + id = exeReader.ReadInt16(); + name = ((ChunkNames) id).ToString(); + + flag = (ChunkFlags) exeReader.ReadInt16(); + size = exeReader.ReadInt32(); + + switch (flag) + { + case ChunkFlags.Encrypted: + chunk_data = exeReader.ReadBytes(size); + break; + case ChunkFlags.CompressedAndEncrypyed: + chunk_data = exeReader.ReadBytes(size); + break; + case ChunkFlags.Compressed: + chunk_data = Decompressor.Decompress(exeReader); + break; + case ChunkFlags.NotCompressed: + chunk_data = exeReader.ReadBytes(size); + break; + } + + if (chunk_data != null) + { + decompressed_size = chunk_data.Length; + string path = $"{Program.DumpPath}\\CHUNKS\\{name}.chunk"; + File.WriteAllBytes(path, chunk_data); + } + if(verbose) + { + Print(false); + + } + } + + public void Print(bool extented) + { + if(extented) + { + Logger.Log($"Chunk: {name} ({uid})", true, ConsoleColor.DarkCyan); + Logger.Log($" ID: {id} - 0x{id.ToString("X")}", true, ConsoleColor.DarkCyan); + Logger.Log($" Flags: {flag}", true, ConsoleColor.DarkCyan); + Logger.Log($" Loader: {(loader != null ? loader.GetType().Name : "Empty Loader")}", true, + ConsoleColor.DarkCyan); + Logger.Log($" Size: {size} B", true, ConsoleColor.DarkCyan); + Logger.Log($" Decompressed Size: {decompressed_size} B", true, ConsoleColor.DarkCyan); + Logger.Log("---------------------------------------------", true, ConsoleColor.DarkCyan); + + } + else + { + Logger.Log($"Chunk: {name} ({uid})", true, ConsoleColor.DarkCyan); + Logger.Log($" ID: {id} - 0x{id.ToString("X")}", true, ConsoleColor.DarkCyan); + Logger.Log($" Decompressed Size: {decompressed_size} B", true, ConsoleColor.DarkCyan); + Logger.Log($" Flags: {flag}", true, ConsoleColor.DarkCyan); + Logger.Log("---------------------------------------------", true, ConsoleColor.DarkCyan); + } + + } + } + + public enum ChunkFlags + { + NotCompressed = 0, + Compressed = 1, + Encrypted = 2, + CompressedAndEncrypyed = 3 + } + + public ChunkLoader LoadChunk(Chunk chunk) + { + ChunkLoader loader = null; + switch (chunk.id) + { + case 8739: + loader = new AppHeader(chunk); + break; + case 8740: + loader = new AppName(chunk); + break; + case 8741: + loader = new AppAuthor(chunk); + break; + case 8743: + loader = new ExtPath(chunk); + break; + case 8750: + loader = new EditorFilename(chunk); + break; + case 8751: + loader = new TargetFilename(chunk); + break; + case 8752: + loader = new AppDoc(chunk); + break; + case 8757: + loader = new AppIcon(chunk); + break; + case 8762: + loader = new AboutText(chunk); + break; + case 8763: + loader = new Copyright(chunk); + break; + case 13123: + loader = new DemoFilePath(chunk); + break; + case 13109: + loader = new FrameName(chunk); + break; + case 13107: + loader = new Frame(chunk); + break; + case 26214: + loader = new ImageBank(chunk); + break; + case 26216: + loader = new SoundBank(chunk); + break; + } + + if (loader != null) + { + loader.Read(); + } + return loader; + } + + + public T get_chunk() where T : ChunkLoader + { + foreach (Chunk chunk in chunks) + { + if (chunk.loader != null) + { + if (chunk.loader.GetType().Name == typeof(T).Name) + { + return (T) chunk.loader; + } + } + } + + return null; //I hope this wont happen + } + } +} \ No newline at end of file diff --git a/NetMFAPatcher/mmfparser/Constants.cs b/NetMFAPatcher/mmfparser/Constants.cs new file mode 100644 index 0000000..6d951e8 --- /dev/null +++ b/NetMFAPatcher/mmfparser/Constants.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.mmfparser +{ + public static class Constants + { + public static readonly string GAME_HEADER = "PAME"; + public static readonly string UNICODE_GAME_HEADER = "PAMU";//"50 41 4D 55"; + public static bool isUnicode; + public enum Products + { + MMF1, + MMF15, + MMF2, + CNC1 + + } + public enum ChunkNames + { + Preview=4368, + AppMiniHeader=8738, + AppHeader=8739, + AppName=8740, + AppAuthor=8741, + AppMenu=8742, + ExtPath=8743, + Extensions=8744, + FrameItems=8745, + GlobalEvents=8746, + FrameHandles=8747, + ExtData=8748, + Additional_Extension=8749, + AppEditorFilename=8750, + AppTargetFilename=8751, + AppDoc=8752, + OtherExt=8753, + GlobalValues=8754, + GlobalStrings=8755, + Extensions2=8756, + AppIcon=8757, + DemoVersion=8758, + SecNum=8759, + BinaryFiles=8760, + AppMenuImages=8761, + AboutText=8762, + Copyright=8763, + GlobalValuesNames=8764, + GlobalStringNames=8765, + MVTexts=8766, + FrameItems2=8767, + ExeOnly=8768, + Protection=8770, + Shaders=8771, + AppHeader2=8773, + Frame=13107, + FrameHeader=13108, + FrameName=13109, + FramePassword=13110, + FramePalette=13111, + FrameItemInstances=13112, + FrameFadeInFrame=13113, + FrameFadeOutFrame=13114, + FrameFadeIn=13115, + FrameFadeOut=13116, + FrameEvents=13117, + FramePlayHeader=13118, + AdditionalFrameItem=13119, + AdditionalFrameItemInstance2=13120, + FrameLayers=13121, + FrameVirtualRect=13122, + DemoFilePath=13123, + RandomSeed=13124, + FrameLayerEffects=13125, + BlurayFrameOptions=13126, + MVTimerBase=13127, + MosaicImageTable=13128, + FrameEffects=13129, + FrameIphoneOptions=13130, + ObjInfoHeader=17476, + ObjInfoName=17477, + ObjectsCommon=17478, + ObjectUnknown=17479, + ObjectEffects=17480, + ImagesOffsets=21845, + FontsOffsets=21846, + SoundsOffsets=21847, + MusicsOffsets=21848, + Images=26214, + Fonts=26215, + Sounds=26216, + Musics=26217, + Last=32639 + + + + + + + + + + + } + } +} diff --git a/NetMFAPatcher/mmfparser/DataLoader.cs b/NetMFAPatcher/mmfparser/DataLoader.cs new file mode 100644 index 0000000..ebb81f4 --- /dev/null +++ b/NetMFAPatcher/mmfparser/DataLoader.cs @@ -0,0 +1,33 @@ +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static NetMFAPatcher.mmfparser.ChunkList; + +namespace mmfparser +{ + public abstract class DataLoader + { + private Chunk chunk; + public ByteIO reader; + public bool verbose = true; + + protected DataLoader(ByteIO reader) + { + this.reader = reader; + } + protected DataLoader(Chunk chunk) + { + this.chunk = chunk; + this.reader = chunk.get_reader(); + } + + public abstract void Read(); + //public abstract void Write(); + public abstract void Print(); + + + } +} diff --git a/NetMFAPatcher/mmfparser/GameData.cs b/NetMFAPatcher/mmfparser/GameData.cs new file mode 100644 index 0000000..1af5a1a --- /dev/null +++ b/NetMFAPatcher/mmfparser/GameData.cs @@ -0,0 +1,60 @@ +using NetMFAPatcher.chunkloaders; +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 +{ + public class GameData + { + public int runtime_version; + public int runtime_subversion; + public int product_build; + public int product_version; + public Products build; + public ChunkList gameChunks; + public void Read(ByteIO exeReader) + { + string magic = exeReader.ReadAscii(4); + + + if (magic == Constants.UNICODE_GAME_HEADER) Constants.isUnicode = true; + else if (magic == Constants.GAME_HEADER) Constants.isUnicode = false; + else + { + Logger.Log("Header Fucked Up", true, ConsoleColor.Red); + } + + runtime_version = exeReader.ReadUInt16(); + runtime_subversion = exeReader.ReadUInt16(); + product_version = exeReader.ReadInt32(); + product_build = exeReader.ReadInt32(); + build = (Products)runtime_version; + + + Print(); + Logger.Log("Press any key to continue",true,ConsoleColor.Magenta); + Console.ReadKey(); + + gameChunks = new ChunkList(); + gameChunks.Read(exeReader); + + } + public void Print() + { + Logger.Log("GameData Info:", true, ConsoleColor.DarkGreen); + Logger.Log($" Runtime Version: {runtime_version}", true, ConsoleColor.DarkGreen); + Logger.Log($" Runtime Subversion: { runtime_subversion}", true, ConsoleColor.DarkGreen); + Logger.Log($" Product Version: { product_version}", true, ConsoleColor.DarkGreen); + Logger.Log($" Product Build: {product_build}", true, ConsoleColor.DarkGreen); + Logger.Log($" {(isUnicode ? "Unicode" : "NonUnicode")} Game", true, ConsoleColor.DarkGreen); + + } + + + } +} diff --git a/NetMFAPatcher/mmfparser/MFA.cs b/NetMFAPatcher/mmfparser/MFA.cs new file mode 100644 index 0000000..586af7c --- /dev/null +++ b/NetMFAPatcher/mmfparser/MFA.cs @@ -0,0 +1,188 @@ + + +using NetMFAPatcher.Utils; +using mmfparser.mfaloaders; +using NetMFAPatcher.chunkloaders; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NetMFAPatcher.mmfparser; +using NetMFAPatcher.mmfparser.mfaloaders; +using NetMFAPatcher.mmfparser.chunkloaders; +using System.IO; +using Frame = NetMFAPatcher.mmfparser.mfaloaders.Frame; +using mmfparser; + +namespace NetMFAPatcher.mfa +{ + class MFA : DataLoader + { + + public override void Print() + { + //Logger.Log($"MFA Product:{product}"); + //Logger.Log($"MFA Build:{mfaBuild}"); + //Logger.Log($"MFA Product:{buildVersion}"); + + } + + public override void Read() + { + Logger.Log($"MFA HEADER:{reader.ReadAscii(4)}"); + var mfaBuild = reader.ReadInt32(); + var product = reader.ReadInt32(); + var buildVersion = reader.ReadInt32(); + + var name = reader.ReadAscii(reader.ReadInt32()); + var description = reader.ReadAscii(reader.ReadInt32()); + var path = reader.ReadAscii(reader.ReadInt32()); + var stamp = reader.ReadBytes(reader.ReadInt32()); + + + + Logger.Log(reader.ReadAscii(4)); + var fonts = new FontBank(reader); + fonts.Read(); + + Logger.Log("FontsDone\n"); + + Logger.Log(reader.ReadAscii(4)); + var sounds = new SoundBank(reader); + sounds.isCompressed = false; + sounds.Read(); + + Logger.Log("SoundsDone\n"); + + Logger.Log(reader.ReadAscii(4)); + var music = new MusicBank(reader); + music.Read(); + + Logger.Log("MusicDone\n"); + + //Logger.Log(reader.ReadAscii(4)); + //var icons = new AGMIBank(reader); + //icons.Read(); + + //Logger.Log("IconDone\n"); + + //Logger.Log(reader.ReadAscii(4)); + + + + reader.Seek(1191186); + + var author = reader.ReadAscii(reader.ReadInt32()); + reader.ReadInt32(); + var copyright = reader.ReadAscii(reader.ReadInt32()); + reader.ReadInt32(); + var company = reader.ReadAscii(reader.ReadInt32()); + var version = reader.ReadAscii(reader.ReadInt32()); + var windowX = reader.ReadInt32(); + var 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()); + var initialScore = reader.ReadInt32(); + var initialLifes = reader.ReadInt32(); + var frameRate = reader.ReadInt32(); + var buildType = reader.ReadInt32(); + var buildPath = reader.ReadAscii(reader.ReadInt32()); + reader.ReadInt32(); + var commandLine = reader.ReadAscii(reader.ReadInt32()); + var aboutbox = reader.ReadAscii(reader.ReadInt32()); + reader.ReadInt32(); + var binCount = reader.ReadInt32();//wtf i cant put it in loop fuck shit + + for (int i = 0; i < binCount; i++) + { + reader.ReadBytes(reader.ReadInt32());//binaryfiles + } + var controls = new mmfparser.mfaloaders.Controls(reader); + controls.Read(); + + var menuSize = reader.ReadUInt32(); + var currentPosition = reader.Tell(); + var menu = new AppMenu(reader); + menu.Read(); + reader.Seek(menuSize + currentPosition); + + var windowMenuIndex = reader.ReadInt32(); + int[] menuImages = new int[65535];//govnokod suka + var MICount = reader.ReadInt32(); + for (int i = 0; i < MICount; i++) + { + var id = reader.ReadInt32(); + menuImages[id] = reader.ReadInt32(); + } + + + + + var globalValues = new ValueList(reader); + globalValues.Read(); + var globalStrings = new ValueList(reader); + globalStrings.Read(); + var globalEvents = reader.ReadBytes(reader.ReadInt32()); + var graphicMode = reader.ReadInt32(); + + + + var icoCount = reader.ReadInt32(); + for (int i = 0; i < icoCount; i++) + { + reader.ReadInt32(); + } + + var qualCount = reader.ReadInt32(); + for (int i = 0; i < qualCount; i++)//qualifiers + { + var nameQ = reader.ReadAscii(reader.ReadInt32()); + var handleQ = reader.ReadInt32(); + } + var extCount = reader.ReadInt32(); + for (int i = 0; i < extCount; i++) + { + var handleE = reader.ReadInt32(); + var filenameE = reader.ReadAscii(reader.ReadInt32()); + var nameE = reader.ReadAscii(reader.ReadInt32()); + var magicE = reader.ReadInt32(); + var subType = reader.ReadBytes(reader.ReadInt32()); + + + } + List frameOffsets = new List(); + var offCount = reader.ReadInt32(); + for (int i = 0; i < offCount; i++) + { + frameOffsets.Add(reader.ReadInt32()); + } + var nextOffset = reader.ReadInt32(); + foreach (var item in frameOffsets) + { + reader.Seek(item); + var testframe = new Frame(reader); + testframe.Read(); + Console.WriteLine($"Done reading frame '{testframe.name}'"); + + } + + + + + + + + + + } + public MFA(ByteIO reader) : base(reader) + { + } + + + } +} diff --git a/NetMFAPatcher/mmfparser/PackData.cs b/NetMFAPatcher/mmfparser/PackData.cs new file mode 100644 index 0000000..811024f --- /dev/null +++ b/NetMFAPatcher/mmfparser/PackData.cs @@ -0,0 +1,85 @@ +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection.Emit; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.mmfparser +{ + public class PackData + { + public PackFile[] items; + public PackData() + { + + } + public void Read(ByteIO exeReader) + { + long start = exeReader.Tell(); + byte[] header = exeReader.ReadBytes(8); + + exeReader.Skip(8); + uint header_size = exeReader.ReadUInt32(); + uint data_size = exeReader.ReadUInt32(); + + exeReader.Seek((int)(start + data_size - 32)); + exeReader.Skip(4); + exeReader.Seek(start + 16); + + uint format_version = exeReader.ReadUInt32(); + exeReader.Skip(8); + + uint count = exeReader.ReadUInt32(); + + Logger.Log($"Found {count.ToString()} Pack Files:", true, ConsoleColor.Blue); + + long offset = exeReader.Tell(); + for (int i = 0; i < count; i++) + { + if (!exeReader.Check(2)) break; + UInt16 value = exeReader.ReadUInt16(); + if (!exeReader.Check(value)) break; + exeReader.ReadBytes(value); + exeReader.Skip(value); + if (!exeReader.Check(value)) break; + } + exeReader.BaseStream.Position -= 5;//wtf lol + header = exeReader.ReadFourCC(); + + exeReader.Seek(offset); + for (int i = 0; i < count; i++) new PackFile().Read(exeReader); + + Logger.Log("\nPackdata Done\n", true, ConsoleColor.Blue); + + } + + } + public class PackFile + { + string PackFilename = "ERROR"; + int bingo = 0; + byte[] data; + + public void Read(ByteIO exeReader) + { + UInt16 len = exeReader.ReadUInt16(); + PackFilename = exeReader.ReadWideString(len); + bingo = exeReader.ReadInt32(); + data = exeReader.ReadBytes(exeReader.ReadInt32()); + + Dump(); + } + public void Dump() + { + Logger.Log($"Dumping {PackFilename}", true, ConsoleColor.DarkBlue); + string path = $"{Program.DumpPath}\\extensions\\" + PackFilename; + File.WriteAllBytes(path, data); + } + + } + +} diff --git a/NetMFAPatcher/mmfparser/chunkloaders/AppHeader.cs b/NetMFAPatcher/mmfparser/chunkloaders/AppHeader.cs new file mode 100644 index 0000000..78c5ebf --- /dev/null +++ b/NetMFAPatcher/mmfparser/chunkloaders/AppHeader.cs @@ -0,0 +1,163 @@ +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NetMFAPatcher.mmfparser; + +namespace NetMFAPatcher.chunkloaders +{ + class AppHeader : ChunkLoader + { + int size; + int windowWidth; + int windowHeight; + int initialScore; + int initialLives; + public int numberOfFrames; + + + public override void Read() + { + reader = new ByteIO(chunk.chunk_data); + size = reader.ReadInt32(); + var flags = reader.ReadInt16(); //raw,need convert + var new_flags = reader.ReadInt16(); //read flags or no balls + var graphics_mode = reader.ReadInt16(); //i am serious + var otherflags = reader.ReadInt16(); //last chance to get balls back + windowWidth = reader.ReadInt16(); + windowHeight = reader.ReadInt16(); + initialScore = (int) (reader.ReadUInt32() ^ 0xffffffff); + initialLives = (int) (reader.ReadUInt32() ^ 0xffffffff); + var controls = new Controls(reader); + controls.Read(); + controls.Print(); + + var borderColor = reader.ReadBytes(4); + numberOfFrames = reader.ReadInt32(); + var frameRate = reader.ReadInt32(); + var windowsMenuIndex = reader.ReadSByte(); + } + + public override void Print() + { + Logger.Log($"ScreenRes: {windowWidth}x{windowHeight}", true, ConsoleColor.DarkMagenta); + Logger.Log($"Score: {initialScore}, Lives: {initialLives}", true, ConsoleColor.DarkMagenta); + Logger.Log($"Frame count: {numberOfFrames}", true, ConsoleColor.DarkMagenta); + Logger.Log(""); + } + + + public AppHeader(ByteIO reader) : base(reader) + { + } + + public AppHeader(ChunkList.Chunk chunk) : base(chunk) + { + } + } + + + public class Controls:ChunkLoader + { + public List items; + ByteIO reader; + + public Controls(ByteIO reader) : base(reader) + { + this.reader = reader; + } + + + + public override void Read() + { + items = new List(); + for (int i = 0; i < 4; i++) + { + var item = new PlayerControl(reader); + items.Add(item); + item.Read(); + } + } + + public override void Print() + { + Logger.Log("Controls: ",true,ConsoleColor.Yellow); + foreach (var item in items) + { + item.Print(); + } + } + } + + public class PlayerControl + { + int controlType = 0; + ByteIO reader; + Keys keys; + + public PlayerControl(ByteIO reader) + { + this.reader = reader; + } + + public void Read() + { + keys = new Keys(reader); + controlType = reader.ReadInt16(); + keys.Read(); + } + + public void Print() + { + Logger.Log(" PlayerControl:", true, ConsoleColor.Yellow); + Logger.Log($" ControlType: {controlType}", true, ConsoleColor.Yellow); + keys.Print(); + } + } + + public class Keys + { + int up; + int down; + int left; + int right; + int button1; + int button2; + int button3; + int button4; + ByteIO reader; + + public Keys(ByteIO reader) + { + this.reader = reader; + } + + + public void Read() + { + up = reader.ReadInt16(); + down = reader.ReadInt16(); + left = reader.ReadInt16(); + right = reader.ReadInt16(); + button1 = reader.ReadInt16(); + button2 = reader.ReadInt16(); + button3 = reader.ReadInt16(); + button4 = reader.ReadInt16(); + } + + public void Print() + { + Logger.Log($" Up: {up}", true, ConsoleColor.Yellow); + Logger.Log($" Down: {down}", true, ConsoleColor.Yellow); + Logger.Log($" Left: {left}", true, ConsoleColor.Yellow); + Logger.Log($" Right: {right}", true, ConsoleColor.Yellow); + Logger.Log($" Button1: {button1}", true, ConsoleColor.Yellow); + Logger.Log($" Button2: {button2}", true, ConsoleColor.Yellow); + Logger.Log($" Button3: {button3}", true, ConsoleColor.Yellow); + Logger.Log($" Button4: {button4}", true, ConsoleColor.Yellow); + } + } +} \ No newline at end of file diff --git a/NetMFAPatcher/mmfparser/chunkloaders/AppMenu.cs b/NetMFAPatcher/mmfparser/chunkloaders/AppMenu.cs new file mode 100644 index 0000000..d0535e1 --- /dev/null +++ b/NetMFAPatcher/mmfparser/chunkloaders/AppMenu.cs @@ -0,0 +1,126 @@ +using NetMFAPatcher.chunkloaders; +using NetMFAPatcher.utils; +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.mmfparser.chunkloaders +{ + class AppMenu : ChunkLoader + { + public List items = new List(); + public AppMenu(ByteIO reader) : base(reader) + { + } + + public AppMenu(ChunkList.Chunk chunk) : base(chunk) + { + } + public override void Print() + { + throw new NotImplementedException(); + } + + public override void Read() + { + var current_position = reader.Tell(); + var header_size = reader.ReadUInt32(); + var menu_offset = reader.ReadInt32(); + var menu_size = reader.ReadInt32(); + if (menu_size == 0) return; + var accel_offset = reader.ReadInt32(); + var accel_size = reader.ReadInt32(); + reader.Seek(current_position + menu_offset); + reader.Skip(4); + + Load(); + + reader.Seek(current_position + accel_offset); + + for (int i = 0; i < accel_size/8; i++) + { + reader.ReadByte(); + reader.Skip(1); + reader.ReadInt16(); + reader.ReadInt16(); + reader.Skip(2); + Console.WriteLine("AfterCycleOffset: " + reader.Tell()); + } + + } + public void Load() + { + while(true) + { + var new_item = new AppMenuItem(reader); + new_item.Read(); + items.Add(new_item); + + if (new_item.name.Contains("About")) break; + if (true)//ByteFlag.getFlag(new_item.flags,4)) + { + Load(); + + } + if (true)//ByteFlag.getFlag(new_item.flags, 7)) + { + + break; + } + + + } + + + } + } + class AppMenuItem : ChunkLoader + { + public string name = ""; + public int flags = 0; + public int id = 0; + public string mnemonic = ""; + public AppMenuItem(ByteIO reader) : base(reader) + { + } + + public AppMenuItem(ChunkList.Chunk chunk) : base(chunk) + { + } + public override void Print() + { + throw new NotImplementedException(); + } + + public override void Read() + { + var flags = reader.ReadInt16(); + if (!ByteFlag.getFlag(flags,4)) + { + id = reader.ReadInt16(); + + } + name = reader.ReadWideString(); + + for (int i = 0; i < name.Length; i++) + { + if(name[i]=='&') + { + mnemonic = name[i + 1].ToString().ToUpper(); + } + name = name.Replace("&", ""); + + } + Console.WriteLine(name); + } + public void Load() + { + + + } + } + +} diff --git a/NetMFAPatcher/mmfparser/chunkloaders/ChunkLoader.cs b/NetMFAPatcher/mmfparser/chunkloaders/ChunkLoader.cs new file mode 100644 index 0000000..7bf7478 --- /dev/null +++ b/NetMFAPatcher/mmfparser/chunkloaders/ChunkLoader.cs @@ -0,0 +1,34 @@ +using NetMFAPatcher.mfa; +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static NetMFAPatcher.mmfparser.ChunkList; + +namespace NetMFAPatcher.chunkloaders +{ + public abstract class ChunkLoader//:DataLoader + { + public Chunk chunk; + public ByteIO reader; + public bool verbose = true; + + protected ChunkLoader(ByteIO reader) + { + this.reader = reader; + } + protected ChunkLoader(Chunk chunk) + { + this.chunk = chunk; + this.reader = chunk.get_reader(); + } + + + public abstract void Read(); + + + public abstract void Print(); + } +} \ No newline at end of file diff --git a/NetMFAPatcher/mmfparser/chunkloaders/Frame.cs b/NetMFAPatcher/mmfparser/chunkloaders/Frame.cs new file mode 100644 index 0000000..b8abf69 --- /dev/null +++ b/NetMFAPatcher/mmfparser/chunkloaders/Frame.cs @@ -0,0 +1,73 @@ +using NetMFAPatcher.mmfparser; +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.chunkloaders +{ + class FrameName : StringChunk + { + public FrameName(ByteIO reader) : base(reader) + { + } + + public FrameName(ChunkList.Chunk chunk) : base(chunk) + { + } + } + + class FramePassword : StringChunk + { + public FramePassword(ByteIO reader) : base(reader) + { + } + + public FramePassword(ChunkList.Chunk chunk) : base(chunk) + { + } + } + + public class Frame : ChunkLoader + { + ByteIO reader; + public string name; + public string password; + public int width; + + public int height; + + //background, idk what type is it + //flags + int top; + int bottom; + int left; + int right; + + + public override void Print() + { + } + + public override void Read() + { + var FrameReader = new ByteIO(chunk.chunk_data); + var chunks = new ChunkList(); + + chunks.verbose = false; + //chunks.Read(FrameReader); + + //var name = chunks.get_chunk(); + } + + public Frame(ByteIO reader) : base(reader) + { + } + + public Frame(ChunkList.Chunk chunk) : base(chunk) + { + } + } +} \ No newline at end of file diff --git a/NetMFAPatcher/mmfparser/chunkloaders/StringChunk.cs b/NetMFAPatcher/mmfparser/chunkloaders/StringChunk.cs new file mode 100644 index 0000000..f5974af --- /dev/null +++ b/NetMFAPatcher/mmfparser/chunkloaders/StringChunk.cs @@ -0,0 +1,135 @@ +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NetMFAPatcher.mmfparser; + +namespace NetMFAPatcher.chunkloaders +{ + class StringChunk : ChunkLoader + { + public string value; + + + public override void Read() + { + reader = new ByteIO(chunk.chunk_data); + value = reader.ReadWideString(); + } + + public override void Print() + { + Logger.Log($"{chunk.name} contains: {value}\n",true,ConsoleColor.DarkCyan); + } + + + public StringChunk(ByteIO reader) : base(reader) + { + } + + public StringChunk(ChunkList.Chunk chunk) : base(chunk) + { + } + } + + class AppName : StringChunk + { + public AppName(ByteIO reader) : base(reader) + { + } + + public AppName(ChunkList.Chunk chunk) : base(chunk) + { + } + } + + class AppAuthor : StringChunk + { + public AppAuthor(ByteIO reader) : base(reader) + { + } + + public AppAuthor(ChunkList.Chunk chunk) : base(chunk) + { + } + } + + class ExtPath : StringChunk + { + public ExtPath(ByteIO reader) : base(reader) + { + } + + public ExtPath(ChunkList.Chunk chunk) : base(chunk) + { + } + } + + class EditorFilename : StringChunk + { + public EditorFilename(ByteIO reader) : base(reader) + { + } + + public EditorFilename(ChunkList.Chunk chunk) : base(chunk) + { + } + } + + class TargetFilename : StringChunk + { + public TargetFilename(ByteIO reader) : base(reader) + { + } + + public TargetFilename(ChunkList.Chunk chunk) : base(chunk) + { + } + } + + class AppDoc : StringChunk + { + public AppDoc(ByteIO reader) : base(reader) + { + } + + public AppDoc(ChunkList.Chunk chunk) : base(chunk) + { + } + } + + class AboutText : StringChunk + { + public AboutText(ByteIO reader) : base(reader) + { + } + + public AboutText(ChunkList.Chunk chunk) : base(chunk) + { + } + } + + class Copyright : StringChunk + { + public Copyright(ByteIO reader) : base(reader) + { + } + + public Copyright(ChunkList.Chunk chunk) : base(chunk) + { + } + } + + class DemoFilePath : StringChunk + { + public DemoFilePath(ByteIO reader) : base(reader) + { + } + + public DemoFilePath(ChunkList.Chunk chunk) : base(chunk) + { + } + } +} \ No newline at end of file diff --git a/NetMFAPatcher/mmfparser/chunkloaders/banks/DebugImageBank.cs b/NetMFAPatcher/mmfparser/chunkloaders/banks/DebugImageBank.cs new file mode 100644 index 0000000..dc41151 --- /dev/null +++ b/NetMFAPatcher/mmfparser/chunkloaders/banks/DebugImageBank.cs @@ -0,0 +1,193 @@ +using NetMFAPatcher.mmfparser; +using NetMFAPatcher.utils; +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Linq; +using System.Numerics; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.chunkloaders +{ + class DebugImageBank : ChunkLoader + { + Dictionary images = new Dictionary(); + public DebugImageBank(ByteIO reader) : base(reader) + { + } + + public DebugImageBank(ChunkList.Chunk chunk) : base(chunk) + { + } + public override void Print() + { + + } + + public override void Read() + { + reader = new ByteIO(chunk.chunk_data); + var number_of_items = reader.ReadUInt32(); + Console.WriteLine($"Found {number_of_items} images"); + for (int i = 0; i < number_of_items; i++) + { + var item = new DebugImageItem(reader); + item.Read(); + item.handle -= 1; + + //images[item.handle] = item; + + + + } + + } + } + class DebugImageItem : ChunkLoader + { + + public int handle; + int position; + int checksum; + int references; + int width; + int height; + int graphic_mode; + int x_hotspot; + int y_hotspot; + int action_x; + int action_y; + public int flags; + public int size; + //tranparent,add later + int indexed; + byte[] image; + byte[] alpha; + ByteIO image_data; + + public bool isCompressed = true; + + public override void Read() + { + handle = reader.ReadInt32(); + position = (int)reader.Tell(); + if (!Program.DumpImages) return; + Save($"{Program.DumpPath}\\ImageBank\\{handle}.png"); + + } + + public void Save(string filename) + { + Bitmap result; + var image_data = Decompressor.DecompressAsReader(reader); + using (ByteIO binaryReader = image_data) + { + int num = 0; + byte b = 0; + short num2; + short num3; + if (true) + { + binaryReader.ReadInt32(); + binaryReader.ReadInt32(); + num = (int)binaryReader.ReadUInt32(); + num2 = binaryReader.ReadInt16(); + num3 = binaryReader.ReadInt16(); + graphic_mode = binaryReader.ReadByte(); + b = (byte)binaryReader.ReadSByte(); + binaryReader.BaseStream.Position += 2; + binaryReader.ReadInt16(); + binaryReader.ReadInt16(); + binaryReader.ReadInt16(); + binaryReader.ReadInt16(); + binaryReader.ReadByte(); + binaryReader.ReadByte(); + binaryReader.ReadByte(); + binaryReader.ReadByte(); + + } + var colorSize = 3; + Bitmap bitmap = new Bitmap((int)num2, (int)num3); + Color[,] array = new Color[(int)num2, (int)num3]; + int num4 = Helper.getPadding((int)num2, 2); + int num5 = 0; + for (int i = 0; i < (int)num3; i++) + { + for (int j = 0; j < (int)num2; j++) + { + byte[] colorData=null; + if(graphic_mode==4) + { + colorSize = 3; + colorData = binaryReader.ReadBytes(colorSize); + array[j, i] = ImageHelper.ReadPoint(colorData, 0); + } + else + { + colorSize = 2; + colorData = binaryReader.ReadBytes(colorSize); + array[j, i] = ImageHelper.ReadSixteen(colorData, 0); + } + + + + + num5 += 3; + } + binaryReader.ReadBytes(num4 * 3); + num5 += num4 * 3; + } + int num6 = num - num5; + if (b == 16) + { + num4 = (num6 - (int)(num2 * num3)) / (int)num3; + for (int k = 0; k < (int)num3; k++) + { + for (int l = 0; l < (int)num2; l++) + { + byte b5 = binaryReader.ReadByte(); + Color color = array[l, k]; + array[l, k] = Color.FromArgb((int)b5, (int)color.R, (int)color.G, (int)color.B); + } + binaryReader.ReadBytes(num4); + } + } + for (int m = 0; m < (int)num3; m++) + { + for (int n = 0; n < (int)num2; n++) + { + bitmap.SetPixel(n, m, array[n, m]); + } + } + result = bitmap; + } + result.Save(filename); + } + + + + + + + + + + public override void Print() + { + + } + public DebugImageItem(ByteIO reader) : base(reader) + { + } + + public DebugImageItem(ChunkList.Chunk chunk) : base(chunk) + { + } + + + } +} diff --git a/NetMFAPatcher/mmfparser/chunkloaders/banks/FontBank.cs b/NetMFAPatcher/mmfparser/chunkloaders/banks/FontBank.cs new file mode 100644 index 0000000..ff06a91 --- /dev/null +++ b/NetMFAPatcher/mmfparser/chunkloaders/banks/FontBank.cs @@ -0,0 +1,38 @@ + +using NetMFAPatcher.mmfparser; +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.chunkloaders +{ + class FontBank : ChunkLoader + { + int numberOfItems; + public override void Print() + { + Logger.Log($"FontCount:{numberOfItems.ToString()}"); + } + + public override void Read() + { + numberOfItems = reader.ReadInt32(); + + + + + + } + public FontBank(ByteIO reader) : base(reader) + { + } + + public FontBank(ChunkList.Chunk chunk) : base(chunk) + { + } + } + +} diff --git a/NetMFAPatcher/mmfparser/chunkloaders/banks/ImageBank.cs b/NetMFAPatcher/mmfparser/chunkloaders/banks/ImageBank.cs new file mode 100644 index 0000000..385855d --- /dev/null +++ b/NetMFAPatcher/mmfparser/chunkloaders/banks/ImageBank.cs @@ -0,0 +1,308 @@ +using NetMFAPatcher.mmfparser; +using NetMFAPatcher.utils; +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Linq; +using System.Numerics; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.chunkloaders +{ + class ImageBank : ChunkLoader + { + Dictionary images = new Dictionary(); + public ImageBank(ByteIO reader) : base(reader) + { + } + + public ImageBank(ChunkList.Chunk chunk) : base(chunk) + { + } + public override void Print() + { + + } + + public override void Read() + { + reader = new ByteIO(chunk.chunk_data); + var number_of_items = reader.ReadUInt32(); + Console.WriteLine($"Found {number_of_items} images"); + for (int i = 0; i < number_of_items; i++) + { + var item = new ImageItem(reader); + //item.isCompressed = false; + + + item.Read(); + item.handle -= 1; + + //images[item.handle] = item; + + + + } + + } + } + class ImageItem : ChunkLoader + { + + public int handle; + int position; + int checksum; + int references; + int width; + int height; + int graphic_mode; + int x_hotspot; + int y_hotspot; + int action_x; + int action_y; + public int flags; + public int size; + //tranparent,add later + int indexed; + byte[] image; + byte[] alpha; + ByteIO image_data; + + public bool isCompressed = true; + + + public (byte[] points, int n) ReadRGB(byte[] data, int width, int heigth, TestPoint pointClass) + { + var n = 0; + var i = 0; + List points = new List(); + var pad = GetPadding(width, 3); + for (int y = 1; y < heigth; y++) + { + 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; + + + } + + 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++) + { + for (int x = 1; x < heigth; x++) + { + points[i] = data[n + position]; + n++; + i++; + + } + 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() + { + + + reader.Seek(position); + + if (isCompressed) + { + image_data = Decompressor.DecompressAsReader(reader); + + } + else + { + image_data = reader; + } + + var start = image_data.Tell(); + checksum = image_data.ReadInt32(); + references = image_data.ReadInt32(); + size = (int)image_data.ReadUInt32(); + width = image_data.ReadInt16(); + height = image_data.ReadInt16(); + graphic_mode = image_data.ReadByte();//Graphic mode is always 4 for SL + flags = image_data.ReadByte(); + + image_data.Skip(2); + x_hotspot = image_data.ReadInt16(); + 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"); + + + + return; + + + + + + + + + } + public void Save(string filename) + { + Bitmap bitmap = new Bitmap((int)width, (int)height); + Color[,] array = new Color[(int)width, (int)height]; + int num4 = Helper.getPadding((int)width, 2); + int num5 = 0; + using (ByteIO binaryReader = image_data) + { + int colorSize = 3; + for (int i = 0; i < (int)height; i++) + { + for (int j = 0; j < (int)width; j++) + { + byte[] colorData = null; + if (graphic_mode == 4) + { + colorSize = 3; + colorData = binaryReader.ReadBytes(colorSize); + array[j, i] = ImageHelper.ReadPoint(colorData, 0); + } + else + { + colorSize = 2; + colorData = binaryReader.ReadBytes(colorSize); + array[j, i] = ImageHelper.ReadSixteen(colorData, 0); + } + num5 += 3; + } + binaryReader.ReadBytes(num4 * 3); + num5 += num4 * 3; + } + int num6 = size - num5; + if (flags == 16) + { + num4 = (num6 - (int)(width * height)) / (int)height; + for (int k = 0; k < (int)height; k++) + { + for (int l = 0; l < (int)width; l++) + { + byte Calpha = binaryReader.ReadByte(); + Color color = array[l, k]; + array[l, k] = Color.FromArgb(Calpha, color.R, color.G, color.B); + } + binaryReader.ReadBytes(num4); + } + } + for (int m = 0; m < (int)height; m++) + { + for (int n = 0; n < (int)width; n++) + { + bitmap.SetPixel(n, m, array[n, m]); + } + } + + + } + bitmap.Save(filename, ImageFormat.Png); + } + + + + + + public override void Print() + { + + } + public ImageItem(ByteIO reader) : base(reader) + { + } + + public ImageItem(ChunkList.Chunk chunk) : base(chunk) + { + } + } + + public class TestPoint + { + public int size = 3; + public (byte r, byte g, byte b) Read(byte[] data, int position) + { + byte r = 0; + byte g = 0; + byte b = 0; + try + { + + + b = data[position]; + g = data[position + 1]; + r = data[position + 2]; + } + catch + { + + Console.WriteLine(position); + } + return (r, g, b); + } + + + } + + +} diff --git a/NetMFAPatcher/mmfparser/chunkloaders/banks/MusicBank.cs b/NetMFAPatcher/mmfparser/chunkloaders/banks/MusicBank.cs new file mode 100644 index 0000000..2914d54 --- /dev/null +++ b/NetMFAPatcher/mmfparser/chunkloaders/banks/MusicBank.cs @@ -0,0 +1,68 @@ +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NetMFAPatcher.mmfparser; + +namespace NetMFAPatcher.chunkloaders +{ + class MusicBank : ChunkLoader + { + public int num_of_items = 0; + public int references = 0; + public List items; + + public override void Print() + { + } + + public override void Read() + { + //Someone is using this lol? + items = new List(); + num_of_items = reader.ReadInt32(); + for (int i = 0; i < num_of_items; i++) + { + var item = new MusicFile(reader); + item.Read(); + items.Add(item); + } + } + + public MusicBank(ByteIO reader) : base(reader) + { + } + + public MusicBank(ChunkList.Chunk chunk) : base(chunk) + { + } + } + + public class MusicFile : ChunkLoader + { + public int handle; + public string name = "ERROR"; + public byte[] data; + + public override void Print() + { + } + + public override void Read() + { + } + + public MusicFile(ByteIO reader) : base(reader) + { + } + + public MusicFile(ChunkList.Chunk chunk) : base(chunk) + { + } + } + + +} \ No newline at end of file diff --git a/NetMFAPatcher/mmfparser/chunkloaders/banks/SoundBank.cs b/NetMFAPatcher/mmfparser/chunkloaders/banks/SoundBank.cs new file mode 100644 index 0000000..998b250 --- /dev/null +++ b/NetMFAPatcher/mmfparser/chunkloaders/banks/SoundBank.cs @@ -0,0 +1,125 @@ +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NetMFAPatcher.mmfparser; + +namespace NetMFAPatcher.chunkloaders +{ + class SoundBank : ChunkLoader + { + public int num_of_items = 0; + public int references = 0; + public List items; + public bool isCompressed = true; + + public override void Print() + { + } + + public override void Read() + { + //Implementing for standalone-only because of my lazyness + items = new List(); + num_of_items = reader.ReadInt32(); + for (int i = 0; i < num_of_items; i++) + { + var item = new SoundItem(reader); + item.isCompressed = isCompressed; + item.Read(); + + items.Add(item); + } + } + + public SoundBank(ByteIO reader) : base(reader) + { + } + + public SoundBank(ChunkList.Chunk chunk) : base(chunk) + { + } + } + + public class SoundBase : ChunkLoader + { + public int handle; + public string name = "ERROR"; + public byte[] data; + + public override void Print() + { + } + + public override void Read() + { + } + + public SoundBase(ByteIO reader) : base(reader) + { + } + + public SoundBase(ChunkList.Chunk chunk) : base(chunk) + { + } + } + + public class SoundItem : SoundBase + { + public bool compressed; + public int checksum; + public int references; + public bool isCompressed = true; + + public override void Read() + { + var start = reader.Tell(); + + handle = (int) reader.ReadUInt32(); + checksum = reader.ReadInt32(); + references = reader.ReadInt32(); + var decompressed_size = reader.ReadInt32(); + reader.ReadUInt32(); //flags + var reserved = reader.ReadInt32(); + var name_lenght = reader.ReadInt32(); + ByteIO SoundData; + if (isCompressed) //compressed + { + var size = reader.ReadInt32(); + SoundData = new ByteIO(Decompressor.decompress_block(reader, size, decompressed_size)); + } + else + { + SoundData = new ByteIO(reader.ReadBytes(decompressed_size)); + } + if (isCompressed) + { + name = SoundData.ReadWideString(name_lenght); + } + else + { + name = SoundData.ReadAscii(name_lenght); + + } + + + this.data = SoundData.ReadBytes((int) SoundData.Size()); + name = Helper.CleanInput(name); + Console.WriteLine($"Dumping {name}"); + + string path = $"{Program.DumpPath}\\SoundBank\\{name}.wav"; + File.WriteAllBytes(path, data); + } + + public SoundItem(ByteIO reader) : base(reader) + { + } + + public SoundItem(ChunkList.Chunk chunk) : base(chunk) + { + } + } +} \ No newline at end of file diff --git a/NetMFAPatcher/mmfparser/chunkloaders/yves.cs b/NetMFAPatcher/mmfparser/chunkloaders/yves.cs new file mode 100644 index 0000000..4240ee9 --- /dev/null +++ b/NetMFAPatcher/mmfparser/chunkloaders/yves.cs @@ -0,0 +1,73 @@ +using NetMFAPatcher.mmfparser; +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.chunkloaders +{ + public class AppIcon:ChunkLoader + { + List points; + + + public AppIcon(ByteIO reader) : base(reader) + { + } + + public AppIcon(ChunkList.Chunk chunk) : base(chunk) + { + } + + public override void Read() + { + Logger.Log("dumpingIcon"); + reader.ReadBytes(reader.ReadInt32() - 4); + List color_indexes = new List(); + for (int i = 0; i < 16*16; i++) + { + + var b = reader.ReadByte(); + var g = reader.ReadByte(); + var r = reader.ReadByte(); + reader.ReadByte(); + color_indexes.Add(r); + color_indexes.Add(g); + color_indexes.Add(b); + } + points = new List(); + for (int y = 0; y < 16; y++) + { + var x_list = new List(); + for (int x = 0; x < 16; x++) + { + x_list.Add(color_indexes[reader.ReadByte()]); + } + //x_list.AddRange(points); + //points = x_list; + x_list.AddRange(points); + points = x_list; + + + + } + File.WriteAllBytes("fatcock.raw", points.ToArray()); + + + + + + } + + + public override void Print() + { + + } + } +} diff --git a/NetMFAPatcher/mmfparser/mfaloaders/ChunkList.cs b/NetMFAPatcher/mmfparser/mfaloaders/ChunkList.cs new file mode 100644 index 0000000..ca7abaf --- /dev/null +++ b/NetMFAPatcher/mmfparser/mfaloaders/ChunkList.cs @@ -0,0 +1,38 @@ +using mmfparser; +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.mmfparser.mfaloaders +{ + class ChunkList : DataLoader + { + List items = new List(); + public override void Print() + { + throw new NotImplementedException(); + } + + public override void Read() + { + var start = reader.Tell(); + while(true) + { + var id = reader.ReadByte(); + if(id==0) break; + Console.WriteLine("ChunkFound:"+id); + + + + + } + + + + } + public ChunkList(ByteIO reader) : base(reader) { } + } +} diff --git a/NetMFAPatcher/mmfparser/mfaloaders/Controls.cs b/NetMFAPatcher/mmfparser/mfaloaders/Controls.cs new file mode 100644 index 0000000..1cdd338 --- /dev/null +++ b/NetMFAPatcher/mmfparser/mfaloaders/Controls.cs @@ -0,0 +1,80 @@ +using mmfparser; +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.mmfparser.mfaloaders +{ + class Controls : DataLoader + { + public List items; + + public Controls(ByteIO reader) : base(reader) + { + } + + + public override void Print() + { + throw new NotImplementedException(); + } + + public override void Read() + { + items = new List(); + var count = reader.ReadInt32(); + for (int i = 0; i < count; i++) + { + var item = new mmfparser.mfaloaders.PlayerControl(reader); + items.Add(item); + item.Read(); + } + } + } + + class PlayerControl : DataLoader + { + int controlType; + + + + public PlayerControl(ByteIO reader) : base(reader) + { + + } + + + public override void Print() + { + throw new NotImplementedException(); + } + + public override void Read() + { + controlType = reader.ReadInt32(); + var count = reader.ReadInt32(); + var up = reader.ReadInt32(); + var down = reader.ReadInt32(); + var left = reader.ReadInt32(); + var right = reader.ReadInt32(); + var button1 = reader.ReadInt32(); + var button2 = reader.ReadInt32(); + var button3 = reader.ReadInt32(); + var button4 = reader.ReadInt32(); + for (int i = 0; i < 8; i++) + { + reader.ReadInt32(); + } + + + + } + } + + + + +} diff --git a/NetMFAPatcher/mmfparser/mfaloaders/Frame.cs b/NetMFAPatcher/mmfparser/mfaloaders/Frame.cs new file mode 100644 index 0000000..5e4e7f7 --- /dev/null +++ b/NetMFAPatcher/mmfparser/mfaloaders/Frame.cs @@ -0,0 +1,98 @@ +using mmfparser; +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.mmfparser.mfaloaders +{ + class Frame : DataLoader + { + public string name = "ERROR"; + + public Frame(ByteIO reader) : base(reader) + { + } + + + public override void Print() + { + throw new NotImplementedException(); + } + + public override void Read() + { + var handle = reader.ReadInt32(); + name = reader.ReadAscii(reader.ReadInt32()); + var sizeX = reader.ReadInt32(); + var sizeY = reader.ReadInt32(); + var background = reader.ReadColor(); + var flags = reader.ReadInt32(); + var maxObjects = reader.ReadInt32(); + var password = reader.ReadAscii(reader.ReadInt32()); + reader.Skip(4); + var lastViewedX = reader.ReadInt32(); + var lastViewedY = reader.ReadInt32(); + + var paletteNum = reader.ReadInt32(); + List palette = new List(); + for (int i = 0; i < paletteNum; i++) + { + palette.Add(reader.ReadColor()); + } + var stampHandle = reader.ReadInt32(); + var activeLayer = reader.ReadInt32(); + var layersCunt = reader.ReadInt32(); + var layers = new List(); + for (int i = 0; i < layersCunt; i++) + { + var layer = new Layer(reader); + layer.Read(); + layers.Add(layer); + + } + //fadein + + //fadeout + reader.Skip(2); + var frameitems = new List(); + var frameitemsCount = reader.ReadInt32(); + + for (int i = 0; i < frameitemsCount; i++) + { + var frameitem = new FrameItem(reader); + frameitem.Read(); + frameitems.Add(frameitem); + //break; + + } + + + + //ПРОЧИТАЙ ЭТО + //вжух и весь код для фрейма готов + //блин не сработало + //я задолбался, завтра доделаю + //короче я из будущего, тут надо с циклами аккуратно работать, надо создавать переменную для размера + //тип var frameCount = reader.ReadInt32(); + //for(int i=0;i=32)//extension base + { + //swallow some cum + + } + else + { + Console.WriteLine("BeforeLoad:"+reader.Tell()); + var loader = new Active(reader); + loader.Read(); + reader.Skip(56); + Console.WriteLine("AfterLoad:" + reader.Tell()); + } + Print(); + + + + } + public FrameItem(ByteIO reader):base(reader) + { } + } +} diff --git a/NetMFAPatcher/mmfparser/mfaloaders/ImageBank.cs b/NetMFAPatcher/mmfparser/mfaloaders/ImageBank.cs new file mode 100644 index 0000000..c4b9778 --- /dev/null +++ b/NetMFAPatcher/mmfparser/mfaloaders/ImageBank.cs @@ -0,0 +1,55 @@ +using NetMFAPatcher.chunkloaders; +using NetMFAPatcher.mmfparser; +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace mmfparser.mfaloaders +{ + class AGMIBank : DataLoader + { + public override void Print() + { + throw new NotImplementedException(); + } + + public override void Read() + { + Logger.Log("TEX READ"); + var graphicMode = reader.ReadInt32(); + Logger.Log($"GraphicMode:{graphicMode}"); + var paletteVersion = reader.ReadInt16(); + Logger.Log($"PaletteVersion:{paletteVersion}"); + + var paletteEntries = reader.ReadInt16(); + Logger.Log($"PaletteEntries:{paletteEntries}"); + + + for (int i = 0; i < 256; i++) + { + reader.ReadColor(); + } + var count = reader.ReadInt32(); + Logger.Log($"Number of image items: {count.ToString()}"); + for (int i = 0; i < count; i++) + { + var item = new ImageItem(reader); + item.Read(); + + + + } + + } + public AGMIBank(ByteIO reader) : base(reader) + { + } + + public AGMIBank(ChunkList.Chunk chunk) : base(chunk) + { + } + } +} diff --git a/NetMFAPatcher/mmfparser/mfaloaders/Layer.cs b/NetMFAPatcher/mmfparser/mfaloaders/Layer.cs new file mode 100644 index 0000000..f622537 --- /dev/null +++ b/NetMFAPatcher/mmfparser/mfaloaders/Layer.cs @@ -0,0 +1,38 @@ +using mmfparser; +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.mmfparser.mfaloaders +{ + class Layer : DataLoader + { + public string name="ERROR"; + public float xCoefficient; + public float yCoefficient; + public int flags; + + + public override void Print() + { + throw new NotImplementedException(); + } + + public override void Read() + { + name = reader.ReadAscii(reader.ReadInt32()); + flags = reader.ReadInt32(); + xCoefficient = reader.ReadSingle(); + yCoefficient = reader.ReadSingle(); + + + + } + public Layer(ByteIO reader):base(reader) + { + } + } +} diff --git a/NetMFAPatcher/mmfparser/mfaloaders/ValueList.cs b/NetMFAPatcher/mmfparser/mfaloaders/ValueList.cs new file mode 100644 index 0000000..b0ff8df --- /dev/null +++ b/NetMFAPatcher/mmfparser/mfaloaders/ValueList.cs @@ -0,0 +1,80 @@ +using mmfparser; +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.mmfparser.mfaloaders +{ + class ValueList : DataLoader + { + public List items = new List(); + public ValueList(ByteIO reader) : base(reader) + { + } + + + public override void Print() + { + throw new NotImplementedException(); + } + + public override void Read() + { + var count = reader.ReadInt32(); + for (int i = 0; i < count; i++) + { + var item = new ValueItem(reader); + item.Read(); + items.Add(item); + + } + + + } + } + class ValueItem: DataLoader + { + public object value; + public string name; + + public ValueItem(ByteIO reader) : base(reader) + { + } + + + public override void Print() + { + throw new NotImplementedException(); + } + + public override void Read() + { + name = reader.ReadAscii(reader.ReadInt32()); + var type = reader.ReadInt32(); + switch (type) + { + case 2://string + value = reader.ReadAscii(reader.ReadInt32()); + break; + case 0://int + value = reader.ReadInt32(); + break; + case 1://double + value = reader.ReadDouble(); + break; + } + + + } + } + + +} + + + + + diff --git a/NetMFAPatcher/mmfparser/mfaloaders/mfachunks/Active.cs b/NetMFAPatcher/mmfparser/mfaloaders/mfachunks/Active.cs new file mode 100644 index 0000000..d94c6ad --- /dev/null +++ b/NetMFAPatcher/mmfparser/mfaloaders/mfachunks/Active.cs @@ -0,0 +1,25 @@ +using mmfparser; +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.mmfparser.mfaloaders.mfachunks +{ + class Active : AnimationObject + { + public override void Print() + { + base.Print(); + + } + + public override void Read() + { + base.Read(); + } + public Active(ByteIO reader) : base(reader) { } + } +} diff --git a/NetMFAPatcher/mmfparser/mfaloaders/mfachunks/AnimationObject.cs b/NetMFAPatcher/mmfparser/mfaloaders/mfachunks/AnimationObject.cs new file mode 100644 index 0000000..a16230b --- /dev/null +++ b/NetMFAPatcher/mmfparser/mfaloaders/mfachunks/AnimationObject.cs @@ -0,0 +1,79 @@ +using mmfparser; +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.mmfparser.mfaloaders.mfachunks +{ + class AnimationObject:ObjectLoader + { + List items = new List(); + public override void Read() + { + base.Read(); + if(reader.ReadByte()!=0) + { + var animationCount = reader.ReadInt32(); + for (int i = 0; i < animationCount; i++) + { + var item = new Animation(reader); + item.Read(); + items.Add(item); + } + } + + } + + public AnimationObject(ByteIO reader) : base(reader) { } + } + class Animation : DataLoader + { + public string name = "Animation-UNKNOWN"; + public override void Print() + { + Logger.Log($" Found animation: {name} "); + } + + public override void Read() + { + name = reader.ReadAscii(reader.ReadInt32()); + var directionCount = reader.ReadInt32(); + var directions = new List(); + for (int i = 0; i < directionCount; i++) + { + var direction = new AnimationDirection(reader); + direction.Read(); + directions.Add(direction); + } + + + + } + public Animation(ByteIO reader) : base(reader) { } + } + class AnimationDirection : DataLoader + { + public string name = "Animation-UNKNOWN"; + public override void Print() + { + throw new NotImplementedException(); + } + + public override void Read() + { + var index = reader.ReadInt32(); + var minSpeed = reader.ReadInt32(); + var maxSpeed= reader.ReadInt32(); + var repeat= reader.ReadInt32(); + var backTo= reader.ReadInt32(); + var frames = new List(); + + } + public AnimationDirection(ByteIO reader) : base(reader) { } + } + +} + diff --git a/NetMFAPatcher/mmfparser/mfaloaders/mfachunks/Behaviours.cs b/NetMFAPatcher/mmfparser/mfaloaders/mfachunks/Behaviours.cs new file mode 100644 index 0000000..4bb36dc --- /dev/null +++ b/NetMFAPatcher/mmfparser/mfaloaders/mfachunks/Behaviours.cs @@ -0,0 +1,48 @@ +using mmfparser; +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.mmfparser.mfaloaders.mfachunks +{ + class Behaviours : DataLoader + { + List items = new List(); + public override void Print() + { + throw new NotImplementedException(); + } + + public override void Read() + { + var count = reader.ReadInt32(); + for (int i = 0; i < count; i++) + { + var item = new Behaviour(reader); + item.Read(); + items.Add(item); + } + } + public Behaviours(ByteIO reader) : base(reader) { } + } + class Behaviour : DataLoader + { + public string name = "ERROR"; + public ByteIO data; + public override void Print() + { + throw new NotImplementedException(); + } + + public override void Read() + { + name = reader.ReadAscii(reader.ReadInt32()); + data = new ByteIO(reader.ReadBytes(reader.ReadInt32())); + + } + public Behaviour(ByteIO reader) : base(reader) { } + } +} diff --git a/NetMFAPatcher/mmfparser/mfaloaders/mfachunks/Movements.cs b/NetMFAPatcher/mmfparser/mfaloaders/mfachunks/Movements.cs new file mode 100644 index 0000000..7ed67f3 --- /dev/null +++ b/NetMFAPatcher/mmfparser/mfaloaders/mfachunks/Movements.cs @@ -0,0 +1,68 @@ +using mmfparser; +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.mmfparser.mfaloaders.mfachunks +{ + class Movements : DataLoader + { + public List items = new List(); + public override void Print() + { + throw new NotImplementedException(); + } + + public override void Read() + { + var count = reader.ReadInt32(); + for (int i = 0; i < count; i++) + { + var item = new Movement(reader); + item.Read(); + items.Add(item); + + } + + + } + public Movements(ByteIO reader) : base(reader) { } + } + class Movement : DataLoader + { + public string name="ERROR"; + + public override void Print() + { + throw new NotImplementedException(); + } + + public override void Read() + { + name = reader.ReadAscii(reader.ReadInt32()); + var extension = reader.ReadBytes(reader.ReadInt32()); + var identifier = reader.ReadInt32(); + var dataSize = reader.ReadInt32(); + if(extension.Length>0) + { + var newReader = new ByteIO(reader.ReadBytes(dataSize)); + + + } + else + { + var player = reader.ReadInt16(); + var type = reader.ReadInt16(); + var movingAtStart = reader.ReadByte(); + reader.Skip(3); + var directionAtStart = reader.ReadInt32(); + //implement types, but i am tired, fuck this shit + } + + } + public Movement(ByteIO reader) : base(reader) { } + } +} diff --git a/NetMFAPatcher/mmfparser/mfaloaders/mfachunks/ObjectLoader.cs b/NetMFAPatcher/mmfparser/mfaloaders/mfachunks/ObjectLoader.cs new file mode 100644 index 0000000..9738658 --- /dev/null +++ b/NetMFAPatcher/mmfparser/mfaloaders/mfachunks/ObjectLoader.cs @@ -0,0 +1,76 @@ +using mmfparser; +using NetMFAPatcher.Utils; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NetMFAPatcher.mmfparser.mfaloaders.mfachunks +{ + class ObjectLoader : DataLoader + { + public int objectFlags; + public int newObjectFlags; + public Color backgroundColor; + List qualifiers = new List(); + public ValueList values; + public ValueList strings; + public Movements movements; + public Behaviours behaviours; + + public override void Print() + { + Logger.Log("Object Loader: "); + Logger.Log(" Values:"); + foreach (var item in values.items) + { + 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("\n Movements:"); + foreach (var item in movements.items) + { + Logger.Log($" Movement {item.name}"); + } + Logger.Log("\n"); + } + + public override void Read() + { + objectFlags = reader.ReadInt32(); + newObjectFlags = reader.ReadInt32(); + backgroundColor = reader.ReadColor(); + var end = reader.Tell() + 2 * 9; + for (int i = 0; i < 9; i++) + { + var value = reader.ReadInt16(); + if(value==-1) + { + break; + } + qualifiers.Add(value); + } + reader.Seek(end); + + values = new ValueList(reader); + values.Read(); + strings = new ValueList(reader); + strings.Read(); + movements = new Movements(reader); + movements.Read(); + behaviours = new Behaviours(reader); + behaviours.Read(); + Print(); + + + + } + public ObjectLoader(ByteIO reader) : base(reader) { } + } +} diff --git a/NetMFAPatcher/packages.config b/NetMFAPatcher/packages.config new file mode 100644 index 0000000..4b0596a --- /dev/null +++ b/NetMFAPatcher/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/TestDecompressor/App.config b/TestDecompressor/App.config new file mode 100644 index 0000000..56efbc7 --- /dev/null +++ b/TestDecompressor/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/TestDecompressor/Program.cs b/TestDecompressor/Program.cs new file mode 100644 index 0000000..58bbb43 --- /dev/null +++ b/TestDecompressor/Program.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using System.IO; +using System.IO.Compression; + +namespace TestDecompressor +{ + + + public class Program + { + static string directoryPath = @"c:\temp"; + public static void Main() + { + + DirectoryInfo directorySelected = new DirectoryInfo(directoryPath); + Compress(directorySelected); + + foreach (FileInfo fileToDecompress in directorySelected.GetFiles("*.chunk")) + { + Decompress(fileToDecompress); + } + Console.ReadKey(); + } + + public static void Compress(DirectoryInfo directorySelected) + { + + foreach (FileInfo file in directorySelected.GetFiles("*.xml")) + using (FileStream originalFileStream = file.OpenRead()) + { + if ((File.GetAttributes(file.FullName) & FileAttributes.Hidden) + != FileAttributes.Hidden & file.Extension != ".cmp") + { + using (FileStream compressedFileStream = File.Create(file.FullName + ".cmp")) + { + using (DeflateStream compressionStream = new DeflateStream(compressedFileStream, CompressionMode.Compress)) + { + originalFileStream.CopyTo(compressionStream); + } + } + + FileInfo info = new FileInfo(directoryPath + "\\" + file.Name + ".cmp"); + Console.WriteLine("Compressed {0} from {1} to {2} bytes.", file.Name, file.Length, info.Length); + } + } + } + + public static void Decompress(FileInfo fileToDecompress) + { + using (FileStream originalFileStream = fileToDecompress.OpenRead()) + { + string currentFileName = fileToDecompress.FullName; + string newFileName = currentFileName.Remove(currentFileName.Length - fileToDecompress.Extension.Length); + + using (FileStream decompressedFileStream = File.Create(newFileName)) + { + using (DeflateStream decompressionStream = new DeflateStream(originalFileStream, CompressionMode.Decompress)) + { + decompressionStream.CopyTo(decompressedFileStream); + Console.WriteLine("Decompressed: {0}", fileToDecompress.Name); + } + } + } + } + } +} diff --git a/TestDecompressor/Properties/AssemblyInfo.cs b/TestDecompressor/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..59ed31a --- /dev/null +++ b/TestDecompressor/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Общие сведения об этой сборке предоставляются следующим набором +// набора атрибутов. Измените значения этих атрибутов для изменения сведений, +// связанные с этой сборкой. +[assembly: AssemblyTitle("TestDecompressor")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("TestDecompressor")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми +// для компонентов COM. Если необходимо обратиться к типу в этой сборке через +// из модели COM задайте для атрибута ComVisible этого типа значение true. +[assembly: ComVisible(false)] + +// Следующий GUID представляет идентификатор typelib, если этот проект доступен из модели COM +[assembly: Guid("3d4c851a-8c6b-4898-a766-b1364937f695")] + +// Сведения о версии сборки состоят из указанных ниже четырех значений: +// +// Основной номер версии +// Дополнительный номер версии +// Номер сборки +// Номер редакции +// +// Можно задать все значения или принять номера сборки и редакции по умолчанию +// используя "*", как показано ниже: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/TestDecompressor/TestDecompressor.csproj b/TestDecompressor/TestDecompressor.csproj new file mode 100644 index 0000000..0f38647 --- /dev/null +++ b/TestDecompressor/TestDecompressor.csproj @@ -0,0 +1,53 @@ + + + + + Debug + AnyCPU + {3D4C851A-8C6B-4898-A766-B1364937F695} + Exe + TestDecompressor + TestDecompressor + v4.7.2 + 512 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tests/cncscore.ini b/Tests/cncscore.ini new file mode 100644 index 0000000..e69de29 diff --git a/Tests/mmftest.001 b/Tests/mmftest.001 new file mode 100644 index 0000000..0e782dd Binary files /dev/null and b/Tests/mmftest.001 differ diff --git a/Tests/mmftest.mfa b/Tests/mmftest.mfa new file mode 100644 index 0000000..3fb1409 Binary files /dev/null and b/Tests/mmftest.mfa differ diff --git a/Tests/test.001 b/Tests/test.001 new file mode 100644 index 0000000..0606775 Binary files /dev/null and b/Tests/test.001 differ diff --git a/Tests/test.exe b/Tests/test.exe new file mode 100644 index 0000000..6fce07a Binary files /dev/null and b/Tests/test.exe differ diff --git a/Tests/test.mfa b/Tests/test.mfa new file mode 100644 index 0000000..47730a0 Binary files /dev/null and b/Tests/test.mfa differ diff --git a/Tests/test.mfa.bak b/Tests/test.mfa.bak new file mode 100644 index 0000000..7d97915 Binary files /dev/null and b/Tests/test.mfa.bak differ diff --git a/dumper.zip b/dumper.zip new file mode 100644 index 0000000..596e21d Binary files /dev/null and b/dumper.zip differ