Update ARCFile.cs, ARCFileReader.cs and ARCFileWriter and add ARCUtil.cs

This commit is contained in:
miku-666
2022-08-30 18:55:43 +02:00
parent 6408d33125
commit 91b89780d5
5 changed files with 68 additions and 131 deletions

View File

@@ -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<string, byte[]>
{
public ConsoleArchive()
{
}
public Dictionary<string, byte[]> Files = new Dictionary<string, byte[]>();
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;
}
}
}
}

View File

@@ -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<ConsoleArchiveItem> items = new List<ConsoleArchiveItem>();
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;
}
}

View File

@@ -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<string, byte[]> pair in ConsoleArc.Files)
{
WriteBytes(f, pair.Value);
}
f.Close();
f.Dispose();
return f.ToArray();
new ARCFileWriter(archive).WriteToStream(stream);
}
private List<ConsoleArchiveItem> BuildTable(ConsoleArchive ConsoleArc)
public ARCFileWriter(ConsoleArchive archive) : base(true)
{
List<ConsoleArchiveItem> l = new List<ConsoleArchiveItem>();
int HeaderSize = 4;
int currentFileOffset = 0;
foreach(KeyValuePair<string, byte[]> 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);

View File

@@ -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);
}
}
}
}

View File

@@ -154,6 +154,7 @@
<Compile Include="Classes\IO\COL\COLFileWriter.cs" />
<Compile Include="Classes\IO\Sounds\SoundIO.cs" />
<Compile Include="Classes\IO\Sounds\Sounds.cs" />
<Compile Include="Classes\Utils\ARC\ARCUtil.cs" />
<Compile Include="Classes\Utils\SkinANIM.cs" />
<Compile Include="Classes\FileTypes\PCKProperties.cs" />
<Compile Include="Classes\FileTypes\PCKFile.cs" />