diff --git a/App.config b/App.config new file mode 100644 index 0000000..aee9adf --- /dev/null +++ b/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/CandyTool.csproj b/CandyTool.csproj new file mode 100644 index 0000000..2caac1f --- /dev/null +++ b/CandyTool.csproj @@ -0,0 +1,98 @@ + + + + + Debug + AnyCPU + {4585A548-C269-4E2F-9D93-C8395D9373D3} + Exe + CandyTool + CandyTool + v4.8.1 + 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 + + + x86 + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + SecurityRules.ruleset + + + icon.ico + + + + + FileExtractor.Program + + + false + + + false + + + + + + + + + + + + + + + + + + + + + + + + False + Microsoft .NET Framework 4.8.1 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + \ No newline at end of file diff --git a/CandyTool.csproj.user b/CandyTool.csproj.user new file mode 100644 index 0000000..51f6223 --- /dev/null +++ b/CandyTool.csproj.user @@ -0,0 +1,13 @@ + + + + publish\ + + + + + + en-US + false + + \ No newline at end of file diff --git a/CandyTool.sln b/CandyTool.sln new file mode 100644 index 0000000..e31582f --- /dev/null +++ b/CandyTool.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.11.35219.272 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CandyTool", "CandyTool.csproj", "{4585A548-C269-4E2F-9D93-C8395D9373D3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4585A548-C269-4E2F-9D93-C8395D9373D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4585A548-C269-4E2F-9D93-C8395D9373D3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4585A548-C269-4E2F-9D93-C8395D9373D3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4585A548-C269-4E2F-9D93-C8395D9373D3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {17B435F7-9B7E-4F59-BFF5-C491AB8A7D13} + EndGlobalSection +EndGlobal diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..8616324 --- /dev/null +++ b/Program.cs @@ -0,0 +1,86 @@ +using System; +using System.IO; +namespace FileExtractor +{ + class Program + { + static void Main(string[] args) + { + if (args.Length == 0) + { + Console.WriteLine( + "Drag and drop a file onto this exe to extract embedded SWAR and SBNK files."); + return; + } + foreach (string inputFile in args) + { + if (File.Exists(inputFile)) + { + ExtractFiles(inputFile); + } + else + { + Console.WriteLine($"File not found: {inputFile}"); + } + } + Console.WriteLine("Extraction completed successfully."); + } + static void ExtractFiles(string inputFile) + { + byte[] data = File.ReadAllBytes(inputFile); + int index = 0; + while (index < data.Length) + { + string fileType = null; + int fileSize = 0; + int headerStartIndex = 0; + if (IsMatch(data, index, "SWAR")) + { + fileType = ".swar"; + fileSize = BitConverter.ToInt32(data, index + 8); + headerStartIndex = index; + index += 12; + } + else if (IsMatch(data, index, "SBNK")) + { + fileType = ".sbnk"; + fileSize = BitConverter.ToInt32(data, index + 8); + headerStartIndex = index; + index += 12; + } + else + { + index++; + continue; + } + if (!Directory.Exists("extracted")) + { + Directory.CreateDirectory("extracted"); + } + string outputFilename = $"extracted/extracted_{index}_{fileType}"; + using (var outputFile = new FileStream(outputFilename, FileMode.Create, + FileAccess.Write)) + { + outputFile.Write(data, headerStartIndex, fileSize + 8); + } + while (index < data.Length && data[index] != 0xDD) + { + index++; + } + + if (index < data.Length) + { + index++; + } + } + } + static bool IsMatch(byte[] data, int index, string marker) + { + for (int i = 0; i < marker.Length; i++) + { + if (data[index + i] != marker[i]) return false; + } + return true; + } + } +} \ No newline at end of file diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..3c8b07b --- /dev/null +++ b/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Resources; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("CandyTool")] +[assembly: AssemblyDescription("Extract sounds from Mysims DS games .urf files.")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Landon & Emma")] +[assembly: AssemblyProduct("CandyTool")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("4585a548-c269-4e2f-9d93-c8395d9373d3")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: NeutralResourcesLanguage("en-AE")] diff --git a/icon.ico b/icon.ico new file mode 100644 index 0000000..4e0f6ff Binary files /dev/null and b/icon.ico differ diff --git a/src/extractor.py b/src/extractor.py deleted file mode 100644 index 1bca919..0000000 --- a/src/extractor.py +++ /dev/null @@ -1,48 +0,0 @@ -import os - -def extract_files(input_file): - with open(input_file, 'rb') as f: - data = f.read() - - index = 0 - while index < len(data): - if data[index:index+4] == b'SWAR': - file_type = ".swar" - index += 8 # Move to the size field - file_size = int.from_bytes(data[index:index+4], byteorder='little') - index += 4 # Move past the size field - header_data = b'SWAR' + data[index-8:index] # Prepend header with "SWAR" - elif data[index:index+4] == b'SBNK': - file_type = ".sbnk" - index += 8 # Move to the size field - file_size = int.from_bytes(data[index:index+4], byteorder='little') - index += 4 # Move past the size field - header_data = b'SBNK' + data[index-8:index] # Prepend header with "SBNK" - else: - index += 1 - continue - - # Create the 'extracted' folder if it doesn't exist - if not os.path.exists("extracted"): - os.mkdir("extracted") - - # Extract the header and the content - output_filename = f"extracted/extracted_{index}_{file_type}" - with open(output_filename, 'wb') as output_file: - output_file.write(header_data) # Write the header - output_file.write(data[index:index+file_size]) # Write the content - - # Move index to the end of the extracted file or until "DD" is encountered - while index < len(data) and data[index] != 0xDD: - index += 1 - - if index < len(data): - index += 1 # Move past the "DD" marker - -if __name__ == "__main__": - input_file = input("Enter the path to the file containing the embedded SWAR and SBNK files: ") - if os.path.exists(input_file): - extract_files(input_file) - print("Extraction completed successfully.") - else: - print("File not found.")