2016-11-12 19:02:48 +03:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
|
|
|
|
using SonicAudioLib.IO;
|
|
|
|
|
using SonicAudioLib.Module;
|
|
|
|
|
|
|
|
|
|
namespace SonicAudioLib.Archive
|
|
|
|
|
{
|
|
|
|
|
public class HeroesPacEntry : EntryBase
|
|
|
|
|
{
|
2016-12-31 15:56:10 +03:00
|
|
|
|
public uint Id { get; set; }
|
2016-11-12 19:02:48 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class HeroesPacArchive : ArchiveBase<HeroesPacEntry>
|
|
|
|
|
{
|
|
|
|
|
public override void Read(Stream source)
|
|
|
|
|
{
|
|
|
|
|
uint entryCount = EndianStream.ReadUInt32(source);
|
|
|
|
|
uint tablePosition = EndianStream.ReadUInt32(source);
|
|
|
|
|
uint vldPoolLength = EndianStream.ReadUInt32(source);
|
|
|
|
|
uint vldPoolPosition = EndianStream.ReadUInt32(source);
|
|
|
|
|
|
|
|
|
|
source.Seek(tablePosition, SeekOrigin.Begin);
|
|
|
|
|
|
|
|
|
|
HeroesPacEntry previousEntry = null;
|
|
|
|
|
for (uint i = 0; i < entryCount; i++)
|
|
|
|
|
{
|
|
|
|
|
HeroesPacEntry pacEntry = new HeroesPacEntry();
|
|
|
|
|
|
2016-12-31 15:56:10 +03:00
|
|
|
|
pacEntry.Id = EndianStream.ReadUInt32(source);
|
2016-11-12 19:02:48 +03:00
|
|
|
|
pacEntry.Position = vldPoolPosition + EndianStream.ReadUInt32(source);
|
|
|
|
|
|
|
|
|
|
if (previousEntry != null)
|
|
|
|
|
{
|
|
|
|
|
previousEntry.Length = pacEntry.Position - previousEntry.Position;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (i == entryCount - 1)
|
|
|
|
|
{
|
|
|
|
|
pacEntry.Length = (uint)source.Length - pacEntry.Position;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
entries.Add(pacEntry);
|
|
|
|
|
previousEntry = pacEntry;
|
|
|
|
|
|
|
|
|
|
source.Seek(8, SeekOrigin.Current);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void Write(Stream destination)
|
|
|
|
|
{
|
|
|
|
|
long headerPosition = destination.Position;
|
|
|
|
|
|
|
|
|
|
uint headerLength = 16;
|
|
|
|
|
for (uint i = 0; i < headerLength; i++)
|
|
|
|
|
{
|
|
|
|
|
destination.WriteByte(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while ((destination.Position % 32) != 0)
|
|
|
|
|
{
|
|
|
|
|
destination.WriteByte(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint tableLength = (uint)(entries.Count * 16);
|
|
|
|
|
uint tablePosition = (uint)destination.Position;
|
|
|
|
|
|
|
|
|
|
VldPool vldPool = new VldPool();
|
|
|
|
|
|
|
|
|
|
foreach (HeroesPacEntry pacEntry in entries)
|
|
|
|
|
{
|
|
|
|
|
uint entryPosition = (uint)vldPool.Put(pacEntry.FilePath);
|
|
|
|
|
|
2016-12-31 15:56:10 +03:00
|
|
|
|
EndianStream.WriteUInt32(destination, pacEntry.Id);
|
2016-11-12 19:02:48 +03:00
|
|
|
|
EndianStream.WriteUInt32(destination, entryPosition);
|
|
|
|
|
|
|
|
|
|
while ((destination.Position % 16) != 0)
|
|
|
|
|
{
|
|
|
|
|
destination.WriteByte(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pacEntry.Position = tablePosition + tableLength + entryPosition;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vldPool.Write(destination);
|
|
|
|
|
vldPool.Clear();
|
|
|
|
|
|
|
|
|
|
destination.Seek(0, SeekOrigin.Begin);
|
|
|
|
|
EndianStream.WriteUInt32(destination, (uint)entries.Count);
|
|
|
|
|
EndianStream.WriteUInt32(destination, tablePosition);
|
|
|
|
|
EndianStream.WriteUInt32(destination, (uint)vldPool.Length);
|
|
|
|
|
EndianStream.WriteUInt32(destination, (uint)vldPool.Position);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|