diff --git a/PCK-Studio/Classes/FileTypes/ARCFile.cs b/PCK-Studio/Classes/FileTypes/ARCFile.cs index ee32bcfd..a6782a21 100644 --- a/PCK-Studio/Classes/FileTypes/ARCFile.cs +++ b/PCK-Studio/Classes/FileTypes/ARCFile.cs @@ -1,61 +1,15 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; namespace PckStudio.Classes.FileTypes { - public struct ConsoleArchive + // filepath to file data + public class ConsoleArchive : Dictionary { - public ConsoleArchive() - { - } - - public Dictionary Files = new Dictionary(); + public int SizeOfFile(string filepath) => this[filepath].Length; } - public class ConsoleArchiveItem - { - public string Name { get; set; } - public int Size { get; set; } - public int Position { get; set; } - - public ConsoleArchiveItem(string name, int size, int position) - { - Name = name; - Size = size; - Position = position; - } - } - - public class ConsoleArchiveActions - { - - - public ConsoleArchive AddItem(ConsoleArchive archive, string ItemName, byte[] data) - { - archive.Files.Add(ItemName, data); - return archive; - } - public ConsoleArchive RemoveItem(ConsoleArchive archive, string ItemName) - { - if(archive.Files.ContainsKey(ItemName)) - archive.Files.Remove(ItemName); - return archive; - } - public ConsoleArchive EditItem(ConsoleArchive archive, string ItemName, byte[] data) - { - archive.Files[ItemName] = data; - return archive; - } - public ConsoleArchive Clear(ConsoleArchive archive) - { - archive.Files = null; - archive = new ConsoleArchive(); - return archive; - } - - - } - -} +} \ No newline at end of file diff --git a/PCK-Studio/Classes/IO/ARC/ARCFileReader.cs b/PCK-Studio/Classes/IO/ARC/ARCFileReader.cs index 36baae40..ac496199 100644 --- a/PCK-Studio/Classes/IO/ARC/ARCFileReader.cs +++ b/PCK-Studio/Classes/IO/ARC/ARCFileReader.cs @@ -8,68 +8,42 @@ namespace PckStudio.Classes.IO.ARC { internal class ARCFileReader : StreamDataReader { - + public static ConsoleArchive Read(Stream stream) + { + return new ARCFileReader().ReadFromStream(stream); + } private ARCFileReader() : base(true) - { } - - public ConsoleArchive Parse(byte[] data, ConsoleArchive source) { - return Parse(new MemoryStream(data), source); - } - public ConsoleArchive Parse(string Filepath, ConsoleArchive source) - { - return Parse(new MemoryStream(File.ReadAllBytes(Filepath)), source); } - public ConsoleArchive Parse(MemoryStream s, ConsoleArchive archive) + private ConsoleArchive ReadFromStream(Stream stream) { - List items = new List(); - Encoding encoding = Encoding.UTF8; - int NumberOfFiles = ReadInt(s); - - + ConsoleArchive _archive = new ConsoleArchive(); + int NumberOfFiles = ReadInt(stream); for(int i = 0; i < NumberOfFiles; i++) { - string name = ReadString(s); - int pos = ReadInt(s); - int size = ReadInt(s); - - ConsoleArchiveItem citem = new ConsoleArchiveItem(name, size, pos); - items.Add(citem); - - + string name = ReadString(stream); + int pos = ReadInt(stream); + int size = ReadInt(stream); + _archive[name] = ReadBytesFromPosition(stream, size, pos); } - - foreach(ConsoleArchiveItem citem in items) - { - if (!archive.Files.ContainsKey(citem.Name)) - archive.Files.Add(citem.Name, ReadBytesFromPosition(s, citem.Size, citem.Position)); - else - { - System.Diagnostics.Debug.WriteLine("Copy of: " + citem.Name + " | size:" + citem.Size + " | position:" + citem.Position); - } - s.Flush(); - } - items.Clear(); - s.Close(); - s.Dispose(); - - return archive; + return _archive; } + private string ReadString(Stream stream) { - int length = ReadShort(stream); + short length = ReadShort(stream); return ReadString(stream, length, Encoding.UTF8); } - private byte[] ReadBytesFromPosition(Stream s, int length, int position) + private byte[] ReadBytesFromPosition(Stream stream, int size, int position) { - long originalPOS = s.Position; - s.Position = position; - byte[] ByteArray = ReadBytes(s, length); - s.Position = originalPOS; - return ByteArray; + long originalPOS = stream.Position; + if (stream.Seek(position, SeekOrigin.Begin) != position) throw new Exception(); + byte[] bytes = ReadBytes(stream, size); + if (stream.Seek(originalPOS, SeekOrigin.Begin) != originalPOS) throw new Exception(); + return bytes; } } diff --git a/PCK-Studio/Classes/IO/ARC/ARCFileWriter.cs b/PCK-Studio/Classes/IO/ARC/ARCFileWriter.cs index 2835f9c6..f3d12752 100644 --- a/PCK-Studio/Classes/IO/ARC/ARCFileWriter.cs +++ b/PCK-Studio/Classes/IO/ARC/ARCFileWriter.cs @@ -10,51 +10,36 @@ namespace PckStudio.Classes.IO.ARC { internal class ARCFileWriter : StreamDataWriter { + private ConsoleArchive _archive; - private ARCFileWriter() : base(true) - {} - - public byte[] Build(ConsoleArchive ConsoleArc, string Filename) + public static void Write(Stream stream, ConsoleArchive archive) { - MemoryStream f = new MemoryStream(); - WriteInt(f, ConsoleArc.Files.Count); - foreach(ConsoleArchiveItem item in BuildTable(ConsoleArc)) - { - WriteString(f, item.Name); - WriteInt(f, item.Position); - WriteInt(f, item.Size); - } - foreach (KeyValuePair pair in ConsoleArc.Files) - { - WriteBytes(f, pair.Value); - } - f.Close(); - f.Dispose(); - return f.ToArray(); + new ARCFileWriter(archive).WriteToStream(stream); } - private List BuildTable(ConsoleArchive ConsoleArc) + public ARCFileWriter(ConsoleArchive archive) : base(true) { - List l = new List(); - int HeaderSize = 4; - int currentFileOffset = 0; - foreach(KeyValuePair pair in ConsoleArc.Files) + _archive = archive; + } + + private void WriteToStream(Stream stream) + { + WriteInt(stream, _archive.Count); + int currentOffset = 4 + _archive.Keys.ToArray().Sum(key => 10 + key.Length); + foreach (var pair in _archive) { - HeaderSize += pair.Key.Length; - HeaderSize += 10; - string name = pair.Key; int size = pair.Value.Length; - int position = currentFileOffset; - ConsoleArchiveItem citem = new ConsoleArchiveItem(name, size, position); - l.Add(citem); - currentFileOffset += size; + WriteString(stream, pair.Key); + WriteInt(stream, currentOffset); + WriteInt(stream, size); + currentOffset += size; } - foreach (ConsoleArchiveItem item in l) + foreach (byte[] data in _archive.Values) { - item.Position += HeaderSize; + WriteBytes(stream, data); } - return l; } + private void WriteString(Stream stream, string String) { WriteShort(stream, (short)String.Length); diff --git a/PCK-Studio/Classes/Utils/ARC/ARCUtil.cs b/PCK-Studio/Classes/Utils/ARC/ARCUtil.cs new file mode 100644 index 00000000..afbee456 --- /dev/null +++ b/PCK-Studio/Classes/Utils/ARC/ARCUtil.cs @@ -0,0 +1,23 @@ +using PckStudio.Classes.IO.ARC; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PckStudio.Classes.Utils.ARC +{ + public static class ARCUtil + { + public static void Inject(string filepath, (string filepath, byte[] data) entry) + { + using (var fs = File.Open(filepath, FileMode.Open, FileAccess.ReadWrite)) + { + var archive = ARCFileReader.Read(fs); + archive.Add(entry.filepath, entry.data); + ARCFileWriter.Write(fs, archive); + } + } + } +} \ No newline at end of file diff --git a/PCK-Studio/PckStudio.csproj b/PCK-Studio/PckStudio.csproj index 667ed559..112b32fa 100644 --- a/PCK-Studio/PckStudio.csproj +++ b/PCK-Studio/PckStudio.csproj @@ -154,6 +154,7 @@ +