From 019922238c2bff94f7e0af2676855cf66e5465e2 Mon Sep 17 00:00:00 2001 From: alcexhim Date: Sun, 20 Apr 2014 13:05:30 -0400 Subject: [PATCH] Added ChaosWorks plugin --- .../DataFormats/ChaosWorksVOLDataFormat.cs | 136 ++++++++++++++++++ .../Properties/AssemblyInfo.cs | 36 +++++ .../UniversalEditor.Plugins.ChaosWorks.csproj | 55 +++++++ 3 files changed, 227 insertions(+) create mode 100644 CSharp/Plugins/UniversalEditor.Plugins.ChaosWorks/DataFormats/ChaosWorksVOLDataFormat.cs create mode 100644 CSharp/Plugins/UniversalEditor.Plugins.ChaosWorks/Properties/AssemblyInfo.cs create mode 100644 CSharp/Plugins/UniversalEditor.Plugins.ChaosWorks/UniversalEditor.Plugins.ChaosWorks.csproj diff --git a/CSharp/Plugins/UniversalEditor.Plugins.ChaosWorks/DataFormats/ChaosWorksVOLDataFormat.cs b/CSharp/Plugins/UniversalEditor.Plugins.ChaosWorks/DataFormats/ChaosWorksVOLDataFormat.cs new file mode 100644 index 00000000..1b018c16 --- /dev/null +++ b/CSharp/Plugins/UniversalEditor.Plugins.ChaosWorks/DataFormats/ChaosWorksVOLDataFormat.cs @@ -0,0 +1,136 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using UniversalEditor.ObjectModels.FileSystem; + +namespace UniversalEditor.DataFormats +{ + public class ChaosWorksVOLDataFormat : DataFormat + { + DataFormatReference _dfr = null; + public override DataFormatReference MakeReference() + { + if (_dfr == null) + { + _dfr = base.MakeReference(); + _dfr.Capabilities.Add(typeof(FileSystemObjectModel), DataFormatCapabilities.All); + _dfr.Filters.Add("Chaos Works Engine volume", new byte?[][] { new byte?[] { 0x02, 0x42, 0x02, 0x43 }, new byte?[] { 0x02, 0x42, 0x02, 0x42 } }, new string[] { "*.vol" }); + _dfr.Filters[0].MagicByteOffsets = new int[] { -4 }; + _dfr.ExportOptions.Add(new ExportOptionBoolean("Compressed", "&Compress this archive using the LZRW1 algorithm", true)); + _dfr.Sources.Add("Based on a requested QuickBMS script by WRS from xentax.com"); + } + return _dfr; + } + + private bool mvarCompressed = false; + public bool Compressed { get { return mvarCompressed; } set { mvarCompressed = value; } } + + protected override void LoadInternal(ref ObjectModel objectModel) + { + FileSystemObjectModel fsom = (objectModel as FileSystemObjectModel); + if (fsom == null) return; + + IO.BinaryReader br = base.Stream.BinaryReader; + + br.BaseStream.Seek(-20, System.IO.SeekOrigin.End); + // 20 byte header at the end of the file + + int decompressedSize = br.ReadInt32(); + int dataToRead = br.ReadInt32(); + int fileCount = br.ReadInt32(); + int fileListOffset = br.ReadInt32(); + int version = br.ReadInt32(); + + // Version check made by client v1.2 + if (version == 0x42024202) + { + mvarCompressed = false; + throw new NotSupportedException("Volume is uncompressed (unknown method)"); + } + else if (version == 0x43024202) + { + // expected version + mvarCompressed = true; + } + else + { + throw new InvalidDataFormatException("Unsupported volume (0x" + version.ToString("X") + ")"); + } + + // get FNAME basename + + System.IO.MemoryStream ms = new System.IO.MemoryStream(); + System.IO.BinaryWriter bwms = new System.IO.BinaryWriter(ms); + + br.BaseStream.Position = 0; + + byte[] compressed = new byte[0]; + int i = 0; + while (!br.EndOfStream) + { + if (br.Remaining == 20) + { + // we are done reading the file, because we've encountered the footer! + break; + } + + short CHUNKSIZE = br.ReadInt16(); + + byte[] input = br.ReadBytes(CHUNKSIZE); + Array.Resize(ref compressed, compressed.Length + input.Length); + Array.Copy(input, 0, compressed, i, input.Length); + i += input.Length; + + if (br.EndOfStream) break; + } + + + byte[] uncompressed = UniversalEditor.Compression.LZRW1.LZRW1CompressionModule.Decompress(compressed); + bwms.Write(uncompressed, 0, uncompressed.Length); + + bwms.Flush(); + + ms.Position = 0; + + System.IO.File.WriteAllBytes(@"C:\Temp\New Folder\test.dat", ms.ToArray()); + + IO.BinaryReader brms = new IO.BinaryReader(ms); + brms.BaseStream.Position = fileListOffset; + if (brms.BaseStream.Position >= (brms.BaseStream.Length - (572 * fileCount))) throw new InvalidOperationException(); + + for (int f = 0; f < fileCount; f++) + { + string fileType = brms.ReadFixedLengthString(260); + string fileName = brms.ReadFixedLengthString(292); + int fileSize = brms.ReadInt32(); + int unknown1 = brms.ReadInt32(); + int fileOffset = brms.ReadInt32(); + int unknown2 = brms.ReadInt32(); + int unknown3 = brms.ReadInt32(); + + File file = new File(); + file.Size = fileSize; + file.Properties.Add("length", fileSize); + file.Properties.Add("offset", fileOffset); + file.Properties.Add("reader", brms); + file.DataRequest += file_DataRequest; + fsom.Files.Add(file); + } + } + + private void file_DataRequest(object sender, DataRequestEventArgs e) + { + File file = (sender as File); + int length = (int)file.Properties["length"]; + int offset = (int)file.Properties["offset"]; + IO.BinaryReader brms = (IO.BinaryReader)file.Properties["reader"]; + } + + protected override void SaveInternal(ObjectModel objectModel) + { + throw new NotImplementedException(); + } + } +} diff --git a/CSharp/Plugins/UniversalEditor.Plugins.ChaosWorks/Properties/AssemblyInfo.cs b/CSharp/Plugins/UniversalEditor.Plugins.ChaosWorks/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..7c3b30a9 --- /dev/null +++ b/CSharp/Plugins/UniversalEditor.Plugins.ChaosWorks/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +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("UniversalEditor.Plugins.ChaosWorks")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("City of Orlando")] +[assembly: AssemblyProduct("UniversalEditor.Plugins.ChaosWorks")] +[assembly: AssemblyCopyright("Copyright © City of Orlando 2012")] +[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("255ea862-bed4-421b-a448-bd6a735904cf")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/CSharp/Plugins/UniversalEditor.Plugins.ChaosWorks/UniversalEditor.Plugins.ChaosWorks.csproj b/CSharp/Plugins/UniversalEditor.Plugins.ChaosWorks/UniversalEditor.Plugins.ChaosWorks.csproj new file mode 100644 index 00000000..a5f16e75 --- /dev/null +++ b/CSharp/Plugins/UniversalEditor.Plugins.ChaosWorks/UniversalEditor.Plugins.ChaosWorks.csproj @@ -0,0 +1,55 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {30A2F772-8EC1-425A-8D5D-36A0BE4D6B66} + Library + Properties + UniversalEditor + UniversalEditor.Plugins.ChaosWorks + v3.5 + 512 + + + true + full + false + ..\..\Output\Debug\Plugins\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + ..\..\Output\Release\Plugins\ + TRACE + prompt + 4 + + + + + + + + + + + + {A92D520B-FFA3-4464-8CF6-474D18959E03} + UniversalEditor.Core + + + + + \ No newline at end of file