Initial commit
This commit is contained in:
commit
0f86b0434b
38 changed files with 2370 additions and 0 deletions
14
LibDgf/Aqualead/Archive/AlAarArchiveFlags.cs
Normal file
14
LibDgf/Aqualead/Archive/AlAarArchiveFlags.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace LibDgf.Aqualead.Archive
|
||||
{
|
||||
[Flags]
|
||||
public enum AlAarArchiveFlags : byte
|
||||
{
|
||||
IsValid = 1 << 0,
|
||||
IsSorted = 1 << 5,
|
||||
IsUseNameHash = 1 << 6
|
||||
}
|
||||
}
|
15
LibDgf/Aqualead/Archive/AlAarEntryFlags.cs
Normal file
15
LibDgf/Aqualead/Archive/AlAarEntryFlags.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace LibDgf.Aqualead.Archive
|
||||
{
|
||||
[Flags]
|
||||
public enum AlAarEntryFlags : byte
|
||||
{
|
||||
IsResident = 1 << 0,
|
||||
IsPrepare = 1 << 1,
|
||||
Unknown2 = 1 << 6,
|
||||
IsUseName = 1 << 7
|
||||
}
|
||||
}
|
49
LibDgf/Aqualead/Archive/AlAarEntryV2.cs
Normal file
49
LibDgf/Aqualead/Archive/AlAarEntryV2.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace LibDgf.Aqualead.Archive
|
||||
{
|
||||
public class AlAarEntryV2
|
||||
{
|
||||
uint rest;
|
||||
|
||||
public uint Id { get; set; }
|
||||
public uint Offset { get; set; }
|
||||
public uint Length { get; set; }
|
||||
public uint Range
|
||||
{
|
||||
get
|
||||
{
|
||||
return rest & 0xffffff;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value > 0xffffff) throw new ArgumentOutOfRangeException(nameof(value));
|
||||
rest = value | (rest & 0xff000000);
|
||||
}
|
||||
}
|
||||
public AlAarEntryFlags Flags
|
||||
{
|
||||
get
|
||||
{
|
||||
return (AlAarEntryFlags)((rest >> 24) & 0xff);
|
||||
}
|
||||
set
|
||||
{
|
||||
if ((uint)value > 0xff) throw new ArgumentOutOfRangeException(nameof(value));
|
||||
rest = ((uint)value << 24) | (rest & 0xffffff);
|
||||
}
|
||||
}
|
||||
public string Name { get; set; }
|
||||
|
||||
public void Read(BinaryReader br)
|
||||
{
|
||||
Id = br.ReadUInt32();
|
||||
Offset = br.ReadUInt32();
|
||||
Length = br.ReadUInt32();
|
||||
rest = br.ReadUInt32();
|
||||
}
|
||||
}
|
||||
}
|
24
LibDgf/Aqualead/Archive/AlAarHeaderV2.cs
Normal file
24
LibDgf/Aqualead/Archive/AlAarHeaderV2.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace LibDgf.Aqualead.Archive
|
||||
{
|
||||
public class AlAarHeaderV2
|
||||
{
|
||||
// Magic and version omitted, handled in archive class
|
||||
public AlAarArchiveFlags Flags { get; set; }
|
||||
public ushort Count { get; set; }
|
||||
public uint LowId { get; set; }
|
||||
public uint HighId { get; set; }
|
||||
|
||||
public void Read(BinaryReader br)
|
||||
{
|
||||
Flags = (AlAarArchiveFlags)br.ReadByte();
|
||||
Count = br.ReadUInt16();
|
||||
LowId = br.ReadUInt32();
|
||||
HighId = br.ReadUInt32();
|
||||
}
|
||||
}
|
||||
}
|
108
LibDgf/Aqualead/Archive/AlArchiveV2.cs
Normal file
108
LibDgf/Aqualead/Archive/AlArchiveV2.cs
Normal file
|
@ -0,0 +1,108 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using GMWare.IO;
|
||||
|
||||
namespace LibDgf.Aqualead.Archive
|
||||
{
|
||||
public class AlArchiveV2 : IDisposable
|
||||
{
|
||||
AlAarHeaderV2 header;
|
||||
List<AlAarEntryV2> entries;
|
||||
Stream stream;
|
||||
private bool disposedValue;
|
||||
|
||||
public AlArchiveV2(Stream stream)
|
||||
{
|
||||
this.stream = stream ?? throw new ArgumentNullException(nameof(stream));
|
||||
Load();
|
||||
}
|
||||
|
||||
public IList<AlAarEntryV2> Entries
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDisposed();
|
||||
return new ReadOnlyCollection<AlAarEntryV2>(entries);
|
||||
}
|
||||
}
|
||||
|
||||
void Load()
|
||||
{
|
||||
BinaryReader br = new BinaryReader(stream);
|
||||
if (new string(br.ReadChars(4)) != "ALAR")
|
||||
throw new InvalidDataException("Not an AquaLead archive.");
|
||||
if (br.ReadByte() != 2)
|
||||
throw new NotSupportedException("Not version 2 archive.");
|
||||
|
||||
header = new AlAarHeaderV2();
|
||||
header.Read(br);
|
||||
|
||||
entries = new List<AlAarEntryV2>();
|
||||
for (int i = 0; i < header.Count; ++i)
|
||||
{
|
||||
var entry = new AlAarEntryV2();
|
||||
entry.Read(br);
|
||||
entries.Add(entry);
|
||||
}
|
||||
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
if ((entry.Flags & AlAarEntryFlags.IsUseName) != 0)
|
||||
{
|
||||
stream.Seek(entry.Offset - 0x22, SeekOrigin.Begin);
|
||||
entry.Name = StringReadingHelper.ReadNullTerminatedStringFromFixedSizeBlock(br, 0x20, Encoding.UTF8);
|
||||
}
|
||||
|
||||
if ((entry.Flags & ~AlAarEntryFlags.IsUseName) != 0)
|
||||
{
|
||||
Console.WriteLine($"Entry {entry.Name} has other flags set: {entry.Flags}");
|
||||
//Debugger.Break();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Stream GetFile(AlAarEntryV2 entry)
|
||||
{
|
||||
if (!entries.Contains(entry))
|
||||
throw new ArgumentException("Entry not from this archive.", nameof(entry));
|
||||
if (stream == null) throw new InvalidOperationException("Archive is not opened from existing.");
|
||||
CheckDisposed();
|
||||
|
||||
stream.Seek(entry.Offset, SeekOrigin.Begin);
|
||||
MemoryStream ms = new MemoryStream();
|
||||
StreamUtils.StreamCopy(stream, ms, entry.Length);
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
return Utils.CheckDecompress(ms);
|
||||
}
|
||||
|
||||
void CheckDisposed()
|
||||
{
|
||||
if (disposedValue) throw new ObjectDisposedException(GetType().FullName);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
stream.Close();
|
||||
}
|
||||
|
||||
entries = null;
|
||||
disposedValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue