Skip to content

Commit

Permalink
Merge pull request #13 from WoW-Tools/cli
Browse files Browse the repository at this point in the history
merge
  • Loading branch information
tomrus88 committed Jun 3, 2016
2 parents e29cd50 + 08b5ad9 commit 213f194
Show file tree
Hide file tree
Showing 8 changed files with 261 additions and 27 deletions.
14 changes: 7 additions & 7 deletions CASCExplorer/CASCViewHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,31 +119,31 @@ await Task.Run(() =>
}
}

if (false && _casc.FileExists("DBFilesClient\\SoundKit.db2") && _casc.FileExists("DBFilesClient\\SoundKitEntry.db2"))
if (_casc.FileExists("DBFilesClient\\SoundKit.db2") && _casc.FileExists("DBFilesClient\\SoundKitEntry.db2"))
{
using (Stream skStream = _casc.OpenFile("DBFilesClient\\SoundKit.db2"))
using (Stream skeStream = _casc.OpenFile("DBFilesClient\\SoundKitEntry.db2"))
{
DB3Reader sk = new DB3Reader(skStream);
DB3Reader ske = new DB3Reader(skeStream);
DB5Reader sk = new DB5Reader(skStream);
DB5Reader ske = new DB5Reader(skeStream);

Dictionary<int, List<int>> lookup = new Dictionary<int, List<int>>();

foreach (var row in ske)
{
int soundKitId = row.Value.GetField<ushort>(0xC);
int soundKitId = row.Value.GetField<int>(3);

if (!lookup.ContainsKey(soundKitId))
lookup[soundKitId] = new List<int>();

lookup[soundKitId].Add(row.Value.GetField<int>(0x4));
lookup[soundKitId].Add(row.Value.GetField<int>(0));
}

foreach (var row in sk)
{
string name = row.Value.GetField<string>(0x4).Replace(':', '_');
string name = row.Value.GetField<string>(0).Replace(':', '_');

int type = row.Value.GetField<byte>(0x2C);
int type = row.Value.GetField<byte>(12);

List<int> ske_entries;

Expand Down
4 changes: 2 additions & 2 deletions CascLib/BLTEHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,10 @@ private static void Decompress(byte[] data, Stream outStream)

public void Dispose()
{
_reader.Close();
_reader.Dispose();

if (!_leaveOpen)
_memStream.Close();
_memStream.Dispose();
}
}
}
4 changes: 2 additions & 2 deletions CascLib/CASCHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ protected override Stream GetLocalDataStream(MD5Hash key)
IndexEntry idxInfo = LocalIndex.GetIndexInfo(key);
if (idxInfo == null)
{
Debug.Print("Local index missing: {0}", key.ToHexString());
Logger.WriteLine("Local index missing: {0}", key.ToHexString());
}
return GetLocalDataStreamInternal(idxInfo, key);
}
Expand All @@ -261,7 +261,7 @@ public void Clear()
CDNIndex = null;

foreach (var stream in DataStreams)
stream.Value.Close();
stream.Value.Dispose();

DataStreams.Clear();

Expand Down
1 change: 1 addition & 0 deletions CascLib/CascLib.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
<Compile Include="CASCHandlerLite.cs" />
<Compile Include="DB2Reader.cs" />
<Compile Include="DB3Reader.cs" />
<Compile Include="DB5Reader.cs" />
<Compile Include="DBCReader.cs" />
<Compile Include="DownloadHandler.cs" />
<Compile Include="FastStruct.cs" />
Expand Down
13 changes: 2 additions & 11 deletions CascLib/DB3Reader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ public class DB3Reader : IEnumerable<KeyValuePair<int, DB3Row>>
private readonly int HeaderSize;
private const uint DB3FmtSig = 0x33424457; // WDB3
private const uint DB4FmtSig = 0x34424457; // WDB4
private const uint DB5FmtSig = 0x35424457; // WDB5

public int RecordsCount { get; private set; }
public int FieldsCount { get; private set; }
Expand All @@ -94,7 +93,7 @@ public DB3Reader(Stream stream)

uint magic = reader.ReadUInt32();

if (magic != DB3FmtSig && magic != DB4FmtSig && magic != DB5FmtSig)
if (magic != DB3FmtSig && magic != DB4FmtSig)
{
throw new InvalidDataException(string.Format("DB3 file is corrupted!"));
}
Expand All @@ -114,10 +113,7 @@ public DB3Reader(Stream stream)
uint tableHash = reader.ReadUInt32();
uint build = reader.ReadUInt32();

if (magic != DB5FmtSig)
{
uint unk1 = reader.ReadUInt32(); // timemodified
}
uint unk1 = reader.ReadUInt32(); // timemodified

int MinId = reader.ReadInt32();
int MaxId = reader.ReadInt32();
Expand All @@ -129,11 +125,6 @@ public DB3Reader(Stream stream)
int metaFlags = reader.ReadInt32();
}

if (magic == DB5FmtSig)
{
reader.BaseStream.Position += FieldsCount * 4;
}

int stringTableStart = HeaderSize + RecordsCount * RecordSize;
int stringTableEnd = stringTableStart + StringTableSize;

Expand Down
241 changes: 241 additions & 0 deletions CascLib/DB5Reader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace CASCExplorer
{
public class DB5Row
{
private byte[] m_data;
private DB5Reader m_reader;

public byte[] Data { get { return m_data; } }

public DB5Row(DB5Reader reader, byte[] data)
{
m_reader = reader;
m_data = data;
}

public T GetField<T>(int field, int arrayIndex = 0)
{
DB2Meta meta = m_reader.Meta[field];

if (meta.Bits != 0x00 && meta.Bits != 0x08 && meta.Bits != 0x10 && meta.Bits != 0x18 && meta.Bits != -32)
throw new Exception("Unknown meta.Flags");

int bytesCount = (32 - meta.Bits) >> 3;

TypeCode code = Type.GetTypeCode(typeof(T));

object value = null;

switch (code)
{
case TypeCode.Byte:
if (meta.Bits != 0x18)
throw new Exception("TypeCode.Byte Unknown meta.Bits");
value = m_data[meta.Offset + bytesCount * arrayIndex];
break;
case TypeCode.SByte:
if (meta.Bits != 0x18)
throw new Exception("TypeCode.SByte Unknown meta.Bits");
value = (sbyte)m_data[meta.Offset + bytesCount * arrayIndex];
break;
case TypeCode.Int16:
if (meta.Bits != 0x10)
throw new Exception("TypeCode.Int16 Unknown meta.Bits");
value = BitConverter.ToInt16(m_data, meta.Offset + bytesCount * arrayIndex);
break;
case TypeCode.UInt16:
if (meta.Bits != 0x10)
throw new Exception("TypeCode.UInt16 Unknown meta.Bits");
value = BitConverter.ToUInt16(m_data, meta.Offset + bytesCount * arrayIndex);
break;
case TypeCode.Int32:
byte[] b1 = new byte[4];
Array.Copy(m_data, meta.Offset + bytesCount * arrayIndex, b1, 0, bytesCount);
value = BitConverter.ToInt32(b1, 0);
break;
case TypeCode.UInt32:
byte[] b2 = new byte[4];
Array.Copy(m_data, meta.Offset + bytesCount * arrayIndex, b2, 0, bytesCount);
value = BitConverter.ToUInt32(b2, 0);
break;
case TypeCode.Int64:
byte[] b3 = new byte[8];
Array.Copy(m_data, meta.Offset + bytesCount * arrayIndex, b3, 0, bytesCount);
value = BitConverter.ToInt64(b3, 0);
break;
case TypeCode.UInt64:
byte[] b4 = new byte[8];
Array.Copy(m_data, meta.Offset + bytesCount * arrayIndex, b4, 0, bytesCount);
value = BitConverter.ToUInt64(b4, 0);
break;
case TypeCode.String:
if (meta.Bits != 0x00)
throw new Exception("TypeCode.String Unknown meta.Bits");
byte[] b5 = new byte[4];
Array.Copy(m_data, meta.Offset + bytesCount * arrayIndex, b5, 0, bytesCount);
int start = BitConverter.ToInt32(b5, 0), len = 0;
while (m_reader.StringTable[start + len] != 0)
len++;
value = Encoding.UTF8.GetString(m_reader.StringTable, start, len);
break;
case TypeCode.Single:
if (meta.Bits != 0x00)
throw new Exception("TypeCode.Single Unknown meta.Bits");
value = BitConverter.ToSingle(m_data, meta.Offset + bytesCount * arrayIndex);
break;
default:
throw new Exception("Unknown TypeCode " + code);
}

return (T)value;
}
}

public class DB2Meta
{
public short Bits { get; set; }
public short Offset { get; set; }
}

public class DB5Reader : IEnumerable<KeyValuePair<int, DB5Row>>
{
private const int HeaderSize = 48;
private const uint DB5FmtSig = 0x35424457; // WDB5

public int RecordsCount { get; private set; }
public int FieldsCount { get; private set; }
public int RecordSize { get; private set; }
public int StringTableSize { get; private set; }
public int MinIndex { get; private set; }
public int MaxIndex { get; private set; }

private readonly byte[] m_stringTable;
private readonly DB2Meta[] m_meta;

public byte[] StringTable => m_stringTable;
public DB2Meta[] Meta => m_meta;

private Dictionary<int, DB5Row> m_index = new Dictionary<int, DB5Row>();

public DB5Reader(string dbcFile) : this(new FileStream(dbcFile, FileMode.Open)) { }

public DB5Reader(Stream stream)
{
using (var reader = new BinaryReader(stream, Encoding.UTF8))
{
if (reader.BaseStream.Length < HeaderSize)
{
throw new InvalidDataException(String.Format("DB5 file is corrupted!"));
}

uint magic = reader.ReadUInt32();

if (magic != DB5FmtSig)
{
throw new InvalidDataException(String.Format("DB5 file is corrupted!"));
}

RecordsCount = reader.ReadInt32();
FieldsCount = reader.ReadInt32();
RecordSize = reader.ReadInt32();
StringTableSize = reader.ReadInt32();

uint tableHash = reader.ReadUInt32();
uint layoutHash = reader.ReadUInt32();
MinIndex = reader.ReadInt32();
MaxIndex = reader.ReadInt32();
int locale = reader.ReadInt32();
int copyTableSize = reader.ReadInt32();
int flags = reader.ReadUInt16();
int idIndex = reader.ReadUInt16();

bool isSparse = (flags & 0x1) != 0;
bool hasIndex = (flags & 0x4) != 0;

m_meta = new DB2Meta[FieldsCount];

for (int i = 0; i < m_meta.Length; i++)
{
m_meta[i] = new DB2Meta();
m_meta[i].Bits = reader.ReadInt16();
m_meta[i].Offset = reader.ReadInt16();
}

DB5Row[] m_rows = new DB5Row[RecordsCount];

for (int i = 0; i < RecordsCount; i++)
{
m_rows[i] = new DB5Row(this, reader.ReadBytes(RecordSize));
}

m_stringTable = reader.ReadBytes(StringTableSize);

if (isSparse)
{
// code...
throw new Exception("can't do sparse table");
}

if (hasIndex)
{
for (int i = 0; i < RecordsCount; i++)
{
int id = reader.ReadInt32();
m_index[id] = m_rows[i];
}
}
else
{
for (int i = 0; i < RecordsCount; i++)
{
int id = m_rows[i].Data.Skip(m_meta[idIndex].Offset).Take((32 - m_meta[idIndex].Bits) >> 3).Select((b, k) => b << k * 8).Sum();
m_index[id] = m_rows[i];
}
}

if (copyTableSize > 0)
{
int copyCount = copyTableSize / 8;

for (int i = 0; i < copyCount; i++)
{
int newId = reader.ReadInt32();
int oldId = reader.ReadInt32();

m_index[newId] = m_index[oldId];
}
}
}
}

public bool HasRow(int id)
{
return m_index.ContainsKey(id);
}

public DB5Row GetRow(int id)
{
if (!m_index.ContainsKey(id))
return null;

return m_index[id];
}

public IEnumerator<KeyValuePair<int, DB5Row>> GetEnumerator()
{
return m_index.GetEnumerator();
}

IEnumerator IEnumerable.GetEnumerator()
{
return m_index.GetEnumerator();
}
}
}
2 changes: 1 addition & 1 deletion CascLib/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public static string ToBinaryString(this BitArray bits)
{
StringBuilder sb = new StringBuilder(bits.Length);

for (int i = 0; i < bits.Count; ++i)
for (int i = 0; i < bits.Length; ++i)
{
sb.Append(bits[i] ? "1" : "0");
}
Expand Down
9 changes: 5 additions & 4 deletions CascLib/WowRootHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -263,12 +263,12 @@ public void LoadFileDataComplete(CASCHandler casc)

using (var s = casc.OpenFile("DBFilesClient\\FileDataComplete.db2"))
{
DB3Reader fd = new DB3Reader(s);
DB5Reader fd = new DB5Reader(s);

foreach (var row in fd)
{
string path = row.Value.GetField<string>(4);
string name = row.Value.GetField<string>(8);
string path = row.Value.GetField<string>(0);
string name = row.Value.GetField<string>(1);

string fullname = path + name;

Expand Down Expand Up @@ -308,7 +308,8 @@ public override void LoadListFile(string path, BackgroundWorkerEx worker = null)

using (var fs = new FileStream("listfile.bin", FileMode.Create))
using (var bw = new BinaryWriter(fs))
using (var sr = new StreamReader(path))
using (var fs2 = File.Open(path, FileMode.Open))
using (var sr = new StreamReader(fs2))
{
string file;

Expand Down

0 comments on commit 213f194

Please sign in to comment.