Initial commit: Complete open-source Decal rebuild
All 5 phases of the open-source Decal rebuild: Phase 1: 14 decompiled .NET projects (Interop.*, Adapter, FileService, DecalUtil) Phase 2: 10 native DLLs rewritten as C# COM servers with matching GUIDs - DecalDat, DHS, SpellFilter, DecalInput, DecalNet, DecalFilters - Decal.Core, DecalControls, DecalRender, D3DService Phase 3: C++ shims for Inject.DLL (D3D9 hooking) and LauncherHook.DLL Phase 4: DenAgent WinForms tray application Phase 5: WiX installer and build script 25 C# projects building with 0 errors. Native C++ projects require VS 2022 + Windows SDK (x86). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
commit
d1442e3747
1382 changed files with 170725 additions and 0 deletions
46
Managed/Decal.FileService/Decal.Filters/Attrib.cs
Normal file
46
Managed/Decal.FileService/Decal.Filters/Attrib.cs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public class Attrib : IIdNameTableEntry
|
||||
{
|
||||
private int mID;
|
||||
|
||||
private string mName;
|
||||
|
||||
private int mIconId;
|
||||
|
||||
public int Id => mID;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int IconId
|
||||
{
|
||||
get
|
||||
{
|
||||
return mIconId;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mIconId = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal Attrib(int ID)
|
||||
{
|
||||
mID = ID;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
}
|
||||
35
Managed/Decal.FileService/Decal.Filters/AttributeTable.cs
Normal file
35
Managed/Decal.FileService/Decal.Filters/AttributeTable.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public sealed class AttributeTable : IdNameTable<Attrib>
|
||||
{
|
||||
internal AttributeTable(byte[] Data)
|
||||
{
|
||||
LoadFrom(Data);
|
||||
}
|
||||
|
||||
internal override bool LoadFrom(byte[] Data)
|
||||
{
|
||||
int Index = 0;
|
||||
if (Get.DWord(Data, ref Index) != 620756998)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Index++;
|
||||
int num = Get.Byte(Data, ref Index);
|
||||
InitializeTable(num);
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
Attrib attrib = new Attrib(Get.DWord(Data, ref Index));
|
||||
attrib.IconId = Get.DWord(Data, ref Index);
|
||||
Add(attrib);
|
||||
}
|
||||
Index++;
|
||||
num = Get.Byte(Data, ref Index);
|
||||
for (int j = 0; j < num; j++)
|
||||
{
|
||||
int id = Get.DWord(Data, ref Index);
|
||||
GetById(id).Name = Get.PString(Data, ref Index);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
19
Managed/Decal.FileService/Decal.Filters/AttributeXPTable.cs
Normal file
19
Managed/Decal.FileService/Decal.Filters/AttributeXPTable.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public sealed class AttributeXPTable : RawTable<long>
|
||||
{
|
||||
internal AttributeXPTable(int Length)
|
||||
{
|
||||
InitializeTable(Length);
|
||||
}
|
||||
|
||||
internal override bool LoadFrom(byte[] Data)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
internal new void Add(long Entry)
|
||||
{
|
||||
base.Add(Entry);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public sealed class CharacterSkillCreditsTable : RawTable<byte>
|
||||
{
|
||||
internal CharacterSkillCreditsTable(int Length)
|
||||
{
|
||||
InitializeTable(Length);
|
||||
}
|
||||
|
||||
internal override bool LoadFrom(byte[] Data)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
internal new void Add(byte Entry)
|
||||
{
|
||||
base.Add(Entry);
|
||||
}
|
||||
}
|
||||
19
Managed/Decal.FileService/Decal.Filters/CharacterXPTable.cs
Normal file
19
Managed/Decal.FileService/Decal.Filters/CharacterXPTable.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public sealed class CharacterXPTable : RawTable<long>
|
||||
{
|
||||
internal CharacterXPTable(int Length)
|
||||
{
|
||||
InitializeTable(Length);
|
||||
}
|
||||
|
||||
internal override bool LoadFrom(byte[] Data)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
internal new void Add(long Entry)
|
||||
{
|
||||
base.Add(Entry);
|
||||
}
|
||||
}
|
||||
130
Managed/Decal.FileService/Decal.Filters/Component.cs
Normal file
130
Managed/Decal.FileService/Decal.Filters/Component.cs
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public class Component : IIdNameTableEntry
|
||||
{
|
||||
private int mID;
|
||||
|
||||
private string mName;
|
||||
|
||||
private ComponentType mType;
|
||||
|
||||
private int mIconId;
|
||||
|
||||
private int mSort;
|
||||
|
||||
private int mGestureID;
|
||||
|
||||
private float mGestureSpeed;
|
||||
|
||||
private string mWord;
|
||||
|
||||
private float mBurnRate;
|
||||
|
||||
public int Id => mID;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public ComponentType Type
|
||||
{
|
||||
get
|
||||
{
|
||||
return mType;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mType = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int IconId
|
||||
{
|
||||
get
|
||||
{
|
||||
return mIconId;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mIconId = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int SortKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return mSort;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mSort = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int GestureId
|
||||
{
|
||||
get
|
||||
{
|
||||
return mGestureID;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mGestureID = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float GestureSpeed
|
||||
{
|
||||
get
|
||||
{
|
||||
return mGestureSpeed;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mGestureSpeed = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string Word
|
||||
{
|
||||
get
|
||||
{
|
||||
return mWord;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mWord = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float BurnRate
|
||||
{
|
||||
get
|
||||
{
|
||||
return mBurnRate;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mBurnRate = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal Component(int ID)
|
||||
{
|
||||
mID = ID;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
}
|
||||
35
Managed/Decal.FileService/Decal.Filters/ComponentTable.cs
Normal file
35
Managed/Decal.FileService/Decal.Filters/ComponentTable.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public sealed class ComponentTable : IdNameTable<Component>
|
||||
{
|
||||
internal ComponentTable(byte[] Data)
|
||||
{
|
||||
LoadFrom(Data);
|
||||
}
|
||||
|
||||
internal override bool LoadFrom(byte[] Data)
|
||||
{
|
||||
int Index = 0;
|
||||
if (Get.DWord(Data, ref Index) != 234881039)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int num = Get.Word(Data, ref Index);
|
||||
InitializeTable(num);
|
||||
Index += 2;
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
Component component = new Component(Get.DWord(Data, ref Index));
|
||||
component.Name = Get.EncString(Data, ref Index);
|
||||
component.Type = ComponentType.GetById(Get.DWord(Data, ref Index));
|
||||
component.IconId = Get.DWord(Data, ref Index);
|
||||
component.SortKey = Get.DWord(Data, ref Index);
|
||||
component.GestureId = Get.DWord(Data, ref Index);
|
||||
component.GestureSpeed = Get.Float(Data, ref Index);
|
||||
component.Word = Get.EncString(Data, ref Index);
|
||||
component.BurnRate = Get.Float(Data, ref Index);
|
||||
Add(component);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
60
Managed/Decal.FileService/Decal.Filters/ComponentType.cs
Normal file
60
Managed/Decal.FileService/Decal.Filters/ComponentType.cs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
using System.Globalization;
|
||||
|
||||
namespace Decal.Filters;
|
||||
|
||||
public class ComponentType
|
||||
{
|
||||
private static ComponentType[] sTypes = new ComponentType[7]
|
||||
{
|
||||
new ComponentType(0, "Scarab"),
|
||||
new ComponentType(1, "Herb"),
|
||||
new ComponentType(2, "Powder"),
|
||||
new ComponentType(3, "Potion"),
|
||||
new ComponentType(4, "Talisman"),
|
||||
new ComponentType(5, "Taper"),
|
||||
new ComponentType(6, "Pea")
|
||||
};
|
||||
|
||||
private int mId;
|
||||
|
||||
private string mName;
|
||||
|
||||
public int Id => mId;
|
||||
|
||||
public string Name => mName;
|
||||
|
||||
public static ComponentType GetById(int id)
|
||||
{
|
||||
for (int i = 0; i < sTypes.Length; i++)
|
||||
{
|
||||
if (sTypes[i].Id == id)
|
||||
{
|
||||
return sTypes[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ComponentType GetByName(string name)
|
||||
{
|
||||
for (int i = 0; i < sTypes.Length; i++)
|
||||
{
|
||||
if (string.Compare(sTypes[i].Name, name, ignoreCase: true, CultureInfo.InvariantCulture) == 0)
|
||||
{
|
||||
return sTypes[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private ComponentType(int id, string Name)
|
||||
{
|
||||
mId = id;
|
||||
mName = Name;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
}
|
||||
179
Managed/Decal.FileService/Decal.Filters/FileService.cs
Normal file
179
Managed/Decal.FileService/Decal.Filters/FileService.cs
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
using System;
|
||||
using Decal.Adapter;
|
||||
using Decal.Interop.Dat;
|
||||
|
||||
namespace Decal.Filters;
|
||||
|
||||
public sealed class FileService : FilterBase
|
||||
{
|
||||
private AttributeTable mAttributeTable;
|
||||
|
||||
private VitalTable mVitalTable;
|
||||
|
||||
private VitalFormulaTable mVitalFormulaTable;
|
||||
|
||||
private SkillTable mSkillTable;
|
||||
|
||||
private ComponentTable mComponentTable;
|
||||
|
||||
private SpellTable mSpellTable;
|
||||
|
||||
private LevelTables mLevelTables;
|
||||
|
||||
private GenderTable mGenderTable;
|
||||
|
||||
private HeritageTable mHeritageTable;
|
||||
|
||||
private SpeciesTable mSpeciesTable;
|
||||
|
||||
private MaterialTable mMaterialTable;
|
||||
|
||||
public override string ReferenceName => "Decal.FileService";
|
||||
|
||||
public AttributeTable AttributeTable => mAttributeTable;
|
||||
|
||||
public VitalTable VitalTable => mVitalTable;
|
||||
|
||||
public VitalFormulaTable VitalFormulaTable => mVitalFormulaTable;
|
||||
|
||||
public SkillTable SkillTable => mSkillTable;
|
||||
|
||||
public ComponentTable ComponentTable => mComponentTable;
|
||||
|
||||
public SpellTable SpellTable => mSpellTable;
|
||||
|
||||
public LevelTables LevelTables => mLevelTables;
|
||||
|
||||
public GenderTable GenderTable => mGenderTable;
|
||||
|
||||
public HeritageTable HeritageTable => mHeritageTable;
|
||||
|
||||
public SpeciesTable SpeciesTable => mSpeciesTable;
|
||||
|
||||
public MaterialTable MaterialTable => mMaterialTable;
|
||||
|
||||
public event EventHandler<UpdateEventArgs> OnUpdatePortal;
|
||||
|
||||
public event EventHandler<UpdateEventArgs> OnUpdateCell;
|
||||
|
||||
protected override void Startup()
|
||||
{
|
||||
base.ServerDispatch += OnServerDispatch;
|
||||
mAttributeTable = new AttributeTable(GetPortalFile(620756998));
|
||||
mVitalTable = new VitalTable(GetPortalFile(620756999));
|
||||
mVitalFormulaTable = new VitalFormulaTable(GetPortalFile(234881027));
|
||||
mSkillTable = new SkillTable(GetPortalFile(234881028));
|
||||
mComponentTable = new ComponentTable(GetPortalFile(234881039));
|
||||
mSpellTable = new SpellTable(GetPortalFile(234881038));
|
||||
mLevelTables = new LevelTables(GetPortalFile(234881048));
|
||||
mGenderTable = new GenderTable(GetPortalFile(570425354));
|
||||
mHeritageTable = new HeritageTable(GetPortalFile(570425355));
|
||||
mSpeciesTable = new SpeciesTable(GetPortalFile(570425358));
|
||||
mMaterialTable = new MaterialTable(GetPortalFile(654311424));
|
||||
}
|
||||
|
||||
protected override void Shutdown()
|
||||
{
|
||||
base.ServerDispatch -= OnServerDispatch;
|
||||
mAttributeTable = null;
|
||||
mVitalTable = null;
|
||||
mVitalFormulaTable = null;
|
||||
mSkillTable = null;
|
||||
mComponentTable = null;
|
||||
mSpellTable = null;
|
||||
mLevelTables = null;
|
||||
mGenderTable = null;
|
||||
mHeritageTable = null;
|
||||
mSpeciesTable = null;
|
||||
mMaterialTable = null;
|
||||
}
|
||||
|
||||
private void OnServerDispatch(object sender, NetworkMessageEventArgs e)
|
||||
{
|
||||
Message message = e.Message;
|
||||
if (message.Type != 63458)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int num = message.Value<int>("type");
|
||||
if (num == 1 || num == 2)
|
||||
{
|
||||
int num2 = message.Value<int>("resource");
|
||||
byte[] data = message.Value<byte>("compression") switch
|
||||
{
|
||||
0 => message.RawValue("data"),
|
||||
1 => zlib.Inflate(message.RawValue("data"), message.Value<int>("fileSize")),
|
||||
_ => null,
|
||||
};
|
||||
switch (num2)
|
||||
{
|
||||
case 620756998:
|
||||
mAttributeTable.UpdateFrom(data);
|
||||
break;
|
||||
case 620756999:
|
||||
mVitalTable.UpdateFrom(data);
|
||||
break;
|
||||
case 234881027:
|
||||
mVitalFormulaTable.UpdateFrom(data);
|
||||
break;
|
||||
case 234881028:
|
||||
mSkillTable.UpdateFrom(data);
|
||||
break;
|
||||
case 234881039:
|
||||
mComponentTable.UpdateFrom(data);
|
||||
break;
|
||||
case 234881038:
|
||||
mSpellTable.UpdateFrom(data);
|
||||
break;
|
||||
case 234881048:
|
||||
mLevelTables.UpdateFrom(data);
|
||||
break;
|
||||
case 570425354:
|
||||
mGenderTable.UpdateFrom(data);
|
||||
break;
|
||||
case 570425355:
|
||||
mHeritageTable.UpdateFrom(data);
|
||||
break;
|
||||
case 570425358:
|
||||
mSpeciesTable.UpdateFrom(data);
|
||||
break;
|
||||
case 654311424:
|
||||
mMaterialTable.UpdateFrom(data);
|
||||
break;
|
||||
}
|
||||
switch (num)
|
||||
{
|
||||
case 1:
|
||||
this.OnUpdatePortal(this, new UpdateEventArgs(num2));
|
||||
break;
|
||||
case 2:
|
||||
this.OnUpdateCell(this, new UpdateEventArgs(num2));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] GetPortalFile(int fileId)
|
||||
{
|
||||
return GetFile("services\\DecalDat.DatService\\portal\\" + fileId.ToString("X8"));
|
||||
}
|
||||
|
||||
public byte[] GetCellFile(int fileId)
|
||||
{
|
||||
return GetFile("services\\DecalDat.DatService\\cell\\" + fileId.ToString("X8"));
|
||||
}
|
||||
|
||||
private byte[] GetFile(string decalObject)
|
||||
{
|
||||
IDatStream datStream = (IDatStream)base.Host.Decal.GetObject(decalObject, "{B27D3F72-2640-432F-BAE4-175E1AA0CA39}");
|
||||
if (datStream == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
int size = datStream.Size;
|
||||
byte[] array = (byte[])Array.CreateInstance(typeof(byte), size);
|
||||
datStream.Restart();
|
||||
datStream.ReadBinary(size, ref array[0]);
|
||||
return array;
|
||||
}
|
||||
}
|
||||
32
Managed/Decal.FileService/Decal.Filters/Gender.cs
Normal file
32
Managed/Decal.FileService/Decal.Filters/Gender.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public class Gender : IIdNameTableEntry
|
||||
{
|
||||
private int mID;
|
||||
|
||||
private string mName;
|
||||
|
||||
public int Id => mID;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mName = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal Gender(int ID)
|
||||
{
|
||||
mID = ID;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
}
|
||||
28
Managed/Decal.FileService/Decal.Filters/GenderTable.cs
Normal file
28
Managed/Decal.FileService/Decal.Filters/GenderTable.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public sealed class GenderTable : IdNameTable<Gender>
|
||||
{
|
||||
internal GenderTable(byte[] Data)
|
||||
{
|
||||
LoadFrom(Data);
|
||||
}
|
||||
|
||||
internal override bool LoadFrom(byte[] Data)
|
||||
{
|
||||
int Index = 0;
|
||||
if (Get.DWord(Data, ref Index) != 570425354)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Index += 5;
|
||||
int num = Get.Byte(Data, ref Index);
|
||||
InitializeTable(num);
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
Gender gender = new Gender(Get.DWord(Data, ref Index));
|
||||
gender.Name = Get.PString(Data, ref Index);
|
||||
Add(gender);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
102
Managed/Decal.FileService/Decal.Filters/Get.cs
Normal file
102
Managed/Decal.FileService/Decal.Filters/Get.cs
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Decal.Filters;
|
||||
|
||||
internal static class Get
|
||||
{
|
||||
internal static byte Byte(byte[] Data, ref int Index)
|
||||
{
|
||||
return Data[Index++];
|
||||
}
|
||||
|
||||
internal static int Word(byte[] Data, ref int Index)
|
||||
{
|
||||
ushort result = BitConverter.ToUInt16(Data, Index);
|
||||
Index += 2;
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static int DWord(byte[] Data, ref int Index)
|
||||
{
|
||||
int result = BitConverter.ToInt32(Data, Index);
|
||||
Index += 4;
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static long QWord(byte[] Data, ref int Index)
|
||||
{
|
||||
long result = BitConverter.ToInt64(Data, Index);
|
||||
Index += 8;
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static float Float(byte[] Data, ref int Index)
|
||||
{
|
||||
float result = BitConverter.ToSingle(Data, Index);
|
||||
Index += 4;
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static double Double(byte[] Data, ref int Index)
|
||||
{
|
||||
double result = BitConverter.ToDouble(Data, Index);
|
||||
Index += 8;
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static string String(byte[] Data, ref int Index)
|
||||
{
|
||||
int num = Word(Data, ref Index);
|
||||
if (num == 65535)
|
||||
{
|
||||
num = DWord(Data, ref Index);
|
||||
}
|
||||
StringBuilder stringBuilder = new StringBuilder(num);
|
||||
Encoding encoding = Encoding.GetEncoding(1252);
|
||||
byte[] array = (byte[])Array.CreateInstance(typeof(byte), 1);
|
||||
while (num-- > 0)
|
||||
{
|
||||
array[0] = Byte(Data, ref Index);
|
||||
stringBuilder.Append(encoding.GetChars(array));
|
||||
}
|
||||
Index += 3;
|
||||
Index &= -4;
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
internal static string EncString(byte[] Data, ref int Index)
|
||||
{
|
||||
int num = Word(Data, ref Index);
|
||||
if (num == 65535)
|
||||
{
|
||||
num = DWord(Data, ref Index);
|
||||
}
|
||||
StringBuilder stringBuilder = new StringBuilder(num);
|
||||
Encoding encoding = Encoding.GetEncoding(1252);
|
||||
byte[] array = (byte[])Array.CreateInstance(typeof(byte), 1);
|
||||
while (num-- > 0)
|
||||
{
|
||||
byte b = Byte(Data, ref Index);
|
||||
array[0] = (byte)((b >> 4) | (b << 4));
|
||||
stringBuilder.Append(encoding.GetChars(array));
|
||||
}
|
||||
Index += 3;
|
||||
Index &= -4;
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
internal static string PString(byte[] Data, ref int Index)
|
||||
{
|
||||
int capacity = Byte(Data, ref Index);
|
||||
StringBuilder stringBuilder = new StringBuilder(capacity);
|
||||
Encoding encoding = Encoding.GetEncoding(1252);
|
||||
byte[] array = (byte[])Array.CreateInstance(typeof(byte), 1);
|
||||
while (capacity-- > 0)
|
||||
{
|
||||
array[0] = Byte(Data, ref Index);
|
||||
stringBuilder.Append(encoding.GetChars(array));
|
||||
}
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
32
Managed/Decal.FileService/Decal.Filters/Heritage.cs
Normal file
32
Managed/Decal.FileService/Decal.Filters/Heritage.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public class Heritage : IIdNameTableEntry
|
||||
{
|
||||
private int mID;
|
||||
|
||||
private string mName;
|
||||
|
||||
public int Id => mID;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mName = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal Heritage(int ID)
|
||||
{
|
||||
mID = ID;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
}
|
||||
28
Managed/Decal.FileService/Decal.Filters/HeritageTable.cs
Normal file
28
Managed/Decal.FileService/Decal.Filters/HeritageTable.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public sealed class HeritageTable : IdNameTable<Heritage>
|
||||
{
|
||||
internal HeritageTable(byte[] Data)
|
||||
{
|
||||
LoadFrom(Data);
|
||||
}
|
||||
|
||||
internal override bool LoadFrom(byte[] Data)
|
||||
{
|
||||
int Index = 0;
|
||||
if (Get.DWord(Data, ref Index) != 570425355)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Index += 5;
|
||||
int num = Get.Byte(Data, ref Index);
|
||||
InitializeTable(num);
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
Heritage heritage = new Heritage(Get.DWord(Data, ref Index));
|
||||
heritage.Name = Get.PString(Data, ref Index);
|
||||
Add(heritage);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public interface IIdNameTableEntry
|
||||
{
|
||||
int Id { get; }
|
||||
|
||||
string Name { get; }
|
||||
}
|
||||
104
Managed/Decal.FileService/Decal.Filters/IdNameTable.cs
Normal file
104
Managed/Decal.FileService/Decal.Filters/IdNameTable.cs
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
using System;
|
||||
|
||||
namespace Decal.Filters;
|
||||
|
||||
public abstract class IdNameTable<EntryType> where EntryType : IIdNameTableEntry
|
||||
{
|
||||
private int mCount;
|
||||
|
||||
private EntryType[] mTable;
|
||||
|
||||
public EntryType this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (index >= 0 && index < mCount)
|
||||
{
|
||||
return mTable[index];
|
||||
}
|
||||
return default(EntryType);
|
||||
}
|
||||
}
|
||||
|
||||
public int Length => mCount;
|
||||
|
||||
public event EventHandler Update;
|
||||
|
||||
internal abstract bool LoadFrom(byte[] data);
|
||||
|
||||
internal bool UpdateFrom(byte[] data)
|
||||
{
|
||||
bool num = LoadFrom(data);
|
||||
if (num)
|
||||
{
|
||||
this.Update(this, null);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
protected void InitializeTable(int n)
|
||||
{
|
||||
mCount = 0;
|
||||
mTable = (EntryType[])Array.CreateInstance(typeof(EntryType), n);
|
||||
}
|
||||
|
||||
protected void Add(EntryType entry)
|
||||
{
|
||||
if (mCount < mTable.Length)
|
||||
{
|
||||
int num = mCount++;
|
||||
while (num > 0 && mTable[num - 1].Id > entry.Id)
|
||||
{
|
||||
mTable[num] = mTable[num - 1];
|
||||
num--;
|
||||
}
|
||||
mTable[num] = entry;
|
||||
}
|
||||
}
|
||||
|
||||
public int IndexFromId(int id)
|
||||
{
|
||||
int num = 0;
|
||||
int num2 = mCount - 1;
|
||||
while (num <= num2)
|
||||
{
|
||||
int num3 = (num2 - num >> 1) + num;
|
||||
int id2 = mTable[num3].Id;
|
||||
if (id == id2)
|
||||
{
|
||||
return num3;
|
||||
}
|
||||
if (id < id2)
|
||||
{
|
||||
num2 = num3 - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
num = num3 + 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int IndexFromName(string name)
|
||||
{
|
||||
for (int i = 0; i < mCount; i++)
|
||||
{
|
||||
if (string.Compare(mTable[i].Name, name, ignoreCase: true) == 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public EntryType GetById(int id)
|
||||
{
|
||||
return this[IndexFromId(id)];
|
||||
}
|
||||
|
||||
public EntryType GetByName(string name)
|
||||
{
|
||||
return this[IndexFromName(name)];
|
||||
}
|
||||
}
|
||||
78
Managed/Decal.FileService/Decal.Filters/LevelTables.cs
Normal file
78
Managed/Decal.FileService/Decal.Filters/LevelTables.cs
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public sealed class LevelTables : RawTable<object>
|
||||
{
|
||||
private AttributeXPTable mAttrXP;
|
||||
|
||||
private VitalXPTable mVitalXP;
|
||||
|
||||
private TrainedSkillXPTable mTrainXP;
|
||||
|
||||
private SpecializedSkillXPTable mSpecXP;
|
||||
|
||||
private CharacterXPTable mLevelXP;
|
||||
|
||||
private CharacterSkillCreditsTable mSkillCredits;
|
||||
|
||||
public AttributeXPTable AttributeXP => mAttrXP;
|
||||
|
||||
public VitalXPTable VitalXP => mVitalXP;
|
||||
|
||||
public TrainedSkillXPTable TrainedSkillXP => mTrainXP;
|
||||
|
||||
public SpecializedSkillXPTable SpecializedSkillXP => mSpecXP;
|
||||
|
||||
public CharacterXPTable CharacterXP => mLevelXP;
|
||||
|
||||
public CharacterSkillCreditsTable CharacterSkillCredits => mSkillCredits;
|
||||
|
||||
internal LevelTables(byte[] Data)
|
||||
{
|
||||
LoadFrom(Data);
|
||||
}
|
||||
|
||||
internal override bool LoadFrom(byte[] Data)
|
||||
{
|
||||
int Index = 0;
|
||||
if (Get.DWord(Data, ref Index) != 234881048)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int num = Get.DWord(Data, ref Index) + 1;
|
||||
int num2 = Get.DWord(Data, ref Index) + 1;
|
||||
int num3 = Get.DWord(Data, ref Index) + 1;
|
||||
int num4 = Get.DWord(Data, ref Index) + 1;
|
||||
int num5 = Get.DWord(Data, ref Index) + 1;
|
||||
mAttrXP = new AttributeXPTable(num);
|
||||
mVitalXP = new VitalXPTable(num2);
|
||||
mTrainXP = new TrainedSkillXPTable(num3);
|
||||
mSpecXP = new SpecializedSkillXPTable(num4);
|
||||
mLevelXP = new CharacterXPTable(num5);
|
||||
mSkillCredits = new CharacterSkillCreditsTable(num5);
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
mAttrXP.Add(Get.DWord(Data, ref Index) & 0xFFFFFFFFu);
|
||||
}
|
||||
for (int j = 0; j < num2; j++)
|
||||
{
|
||||
mVitalXP.Add(Get.DWord(Data, ref Index) & 0xFFFFFFFFu);
|
||||
}
|
||||
for (int k = 0; k < num3; k++)
|
||||
{
|
||||
mTrainXP.Add(Get.DWord(Data, ref Index) & 0xFFFFFFFFu);
|
||||
}
|
||||
for (int l = 0; l < num4; l++)
|
||||
{
|
||||
mSpecXP.Add(Get.DWord(Data, ref Index) & 0xFFFFFFFFu);
|
||||
}
|
||||
for (int m = 0; m < num5; m++)
|
||||
{
|
||||
mLevelXP.Add(Get.QWord(Data, ref Index));
|
||||
}
|
||||
for (int n = 0; n < num5; n++)
|
||||
{
|
||||
mSkillCredits.Add(Get.Byte(Data, ref Index));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
46
Managed/Decal.FileService/Decal.Filters/Material.cs
Normal file
46
Managed/Decal.FileService/Decal.Filters/Material.cs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public class Material : IIdNameTableEntry
|
||||
{
|
||||
private int mID;
|
||||
|
||||
private string mName;
|
||||
|
||||
private int mUnk;
|
||||
|
||||
public int Id => mID;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Unknown
|
||||
{
|
||||
get
|
||||
{
|
||||
return mUnk;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mUnk = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal Material(int ID)
|
||||
{
|
||||
mID = ID;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
}
|
||||
35
Managed/Decal.FileService/Decal.Filters/MaterialTable.cs
Normal file
35
Managed/Decal.FileService/Decal.Filters/MaterialTable.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public sealed class MaterialTable : IdNameTable<Material>
|
||||
{
|
||||
internal MaterialTable(byte[] Data)
|
||||
{
|
||||
LoadFrom(Data);
|
||||
}
|
||||
|
||||
internal override bool LoadFrom(byte[] Data)
|
||||
{
|
||||
int Index = 0;
|
||||
if (Get.DWord(Data, ref Index) != 654311424)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Index++;
|
||||
int num = Get.Byte(Data, ref Index);
|
||||
InitializeTable(num);
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
Material material = new Material(Get.DWord(Data, ref Index));
|
||||
material.Unknown = Get.DWord(Data, ref Index);
|
||||
Add(material);
|
||||
}
|
||||
Index++;
|
||||
num = Get.Byte(Data, ref Index);
|
||||
for (int j = 0; j < num; j++)
|
||||
{
|
||||
int id = Get.DWord(Data, ref Index);
|
||||
GetById(id).Name = Get.PString(Data, ref Index).Replace('_', ' ');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
59
Managed/Decal.FileService/Decal.Filters/RawTable.cs
Normal file
59
Managed/Decal.FileService/Decal.Filters/RawTable.cs
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
using System;
|
||||
|
||||
namespace Decal.Filters;
|
||||
|
||||
public abstract class RawTable<EntryType>
|
||||
{
|
||||
private int mCount;
|
||||
|
||||
private EntryType[] mTable;
|
||||
|
||||
public EntryType this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (index >= 0 && index < mCount)
|
||||
{
|
||||
return mTable[index];
|
||||
}
|
||||
return default(EntryType);
|
||||
}
|
||||
protected set
|
||||
{
|
||||
if (index >= 0 && index < mCount)
|
||||
{
|
||||
mTable[index] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int Length => mCount;
|
||||
|
||||
public event EventHandler Update;
|
||||
|
||||
internal abstract bool LoadFrom(byte[] Data);
|
||||
|
||||
internal bool UpdateFrom(byte[] Data)
|
||||
{
|
||||
bool num = LoadFrom(Data);
|
||||
if (num)
|
||||
{
|
||||
this.Update(this, null);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
protected void InitializeTable(int n)
|
||||
{
|
||||
mCount = 0;
|
||||
mTable = (EntryType[])Array.CreateInstance(typeof(EntryType), n);
|
||||
}
|
||||
|
||||
protected void Add(EntryType entry)
|
||||
{
|
||||
if (mCount < mTable.Length)
|
||||
{
|
||||
mTable[mCount++] = entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
256
Managed/Decal.FileService/Decal.Filters/Skill.cs
Normal file
256
Managed/Decal.FileService/Decal.Filters/Skill.cs
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public class Skill : IIdNameTableEntry
|
||||
{
|
||||
private int mID;
|
||||
|
||||
private string mName;
|
||||
|
||||
private string mDesc;
|
||||
|
||||
private int mIconId;
|
||||
|
||||
private int mTrainCost;
|
||||
|
||||
private int mSpecCost;
|
||||
|
||||
private SkillType mType;
|
||||
|
||||
private int mUnk1;
|
||||
|
||||
private SkillState mUsability;
|
||||
|
||||
private int mUnk2;
|
||||
|
||||
private bool mAttr1Valid;
|
||||
|
||||
private bool mAttr2Valid;
|
||||
|
||||
private int mDivisor;
|
||||
|
||||
private int mAttr1ID;
|
||||
|
||||
private int mAttr2ID;
|
||||
|
||||
private double mTimerLimit;
|
||||
|
||||
private double mTimerStart;
|
||||
|
||||
private double mUnk3;
|
||||
|
||||
public int Id => mID;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string Description
|
||||
{
|
||||
get
|
||||
{
|
||||
return mDesc;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mDesc = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int IconId
|
||||
{
|
||||
get
|
||||
{
|
||||
return mIconId;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mIconId = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int CreditsToTrain
|
||||
{
|
||||
get
|
||||
{
|
||||
return mTrainCost;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mTrainCost = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int CreditsToSpecialize
|
||||
{
|
||||
get
|
||||
{
|
||||
return mSpecCost;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mSpecCost = value;
|
||||
}
|
||||
}
|
||||
|
||||
public SkillType Type
|
||||
{
|
||||
get
|
||||
{
|
||||
return mType;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mType = value;
|
||||
}
|
||||
}
|
||||
|
||||
public SkillState Usability
|
||||
{
|
||||
get
|
||||
{
|
||||
return mUsability;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mUsability = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAttribute1Valid
|
||||
{
|
||||
get
|
||||
{
|
||||
return mAttr1Valid;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mAttr1Valid = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAttribute2Valid
|
||||
{
|
||||
get
|
||||
{
|
||||
return mAttr2Valid;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mAttr2Valid = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Attribute1Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return mAttr1ID;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mAttr1ID = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Attribute2Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return mAttr2ID;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mAttr2ID = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int AttributeDivisor
|
||||
{
|
||||
get
|
||||
{
|
||||
return mDivisor;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mDivisor = value;
|
||||
}
|
||||
}
|
||||
|
||||
public double XPTimerStart
|
||||
{
|
||||
get
|
||||
{
|
||||
return mTimerStart;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mTimerStart = value;
|
||||
}
|
||||
}
|
||||
|
||||
public double XPTimerLimit
|
||||
{
|
||||
get
|
||||
{
|
||||
return mTimerLimit;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mTimerLimit = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Unknown1
|
||||
{
|
||||
get
|
||||
{
|
||||
return mUnk1;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mUnk1 = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Unknown2
|
||||
{
|
||||
get
|
||||
{
|
||||
return mUnk2;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mUnk2 = value;
|
||||
}
|
||||
}
|
||||
|
||||
public double Unknown3
|
||||
{
|
||||
get
|
||||
{
|
||||
return mUnk3;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mUnk3 = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal Skill(int ID)
|
||||
{
|
||||
mID = ID;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
}
|
||||
56
Managed/Decal.FileService/Decal.Filters/SkillState.cs
Normal file
56
Managed/Decal.FileService/Decal.Filters/SkillState.cs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
using System.Globalization;
|
||||
|
||||
namespace Decal.Filters;
|
||||
|
||||
public class SkillState
|
||||
{
|
||||
private static SkillState[] sStates = new SkillState[3]
|
||||
{
|
||||
new SkillState(1, "Untrained"),
|
||||
new SkillState(2, "Trained"),
|
||||
new SkillState(3, "Specialized")
|
||||
};
|
||||
|
||||
private int mId;
|
||||
|
||||
private string mName;
|
||||
|
||||
public int Id => mId;
|
||||
|
||||
public string Name => mName;
|
||||
|
||||
public static SkillState GetById(int id)
|
||||
{
|
||||
for (int i = 0; i < sStates.Length; i++)
|
||||
{
|
||||
if (sStates[i].Id == id)
|
||||
{
|
||||
return sStates[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static SkillState GetByName(string name)
|
||||
{
|
||||
for (int i = 0; i < sStates.Length; i++)
|
||||
{
|
||||
if (string.Compare(sStates[i].Name, name, ignoreCase: true, CultureInfo.InvariantCulture) == 0)
|
||||
{
|
||||
return sStates[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private SkillState(int id, string name)
|
||||
{
|
||||
mId = id;
|
||||
mName = name;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
}
|
||||
44
Managed/Decal.FileService/Decal.Filters/SkillTable.cs
Normal file
44
Managed/Decal.FileService/Decal.Filters/SkillTable.cs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public sealed class SkillTable : IdNameTable<Skill>
|
||||
{
|
||||
internal SkillTable(byte[] Data)
|
||||
{
|
||||
LoadFrom(Data);
|
||||
}
|
||||
|
||||
internal override bool LoadFrom(byte[] Data)
|
||||
{
|
||||
int Index = 0;
|
||||
if (Get.DWord(Data, ref Index) != 234881028)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int num = Get.Word(Data, ref Index);
|
||||
InitializeTable(num);
|
||||
Index += 2;
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
Skill skill = new Skill(Get.DWord(Data, ref Index));
|
||||
skill.Description = Get.String(Data, ref Index);
|
||||
skill.Name = Get.String(Data, ref Index);
|
||||
skill.IconId = Get.DWord(Data, ref Index);
|
||||
skill.CreditsToTrain = Get.DWord(Data, ref Index);
|
||||
skill.CreditsToSpecialize = Get.DWord(Data, ref Index);
|
||||
skill.Type = SkillType.GetById(Get.DWord(Data, ref Index));
|
||||
skill.Unknown1 = Get.DWord(Data, ref Index);
|
||||
skill.Usability = SkillState.GetById(Get.DWord(Data, ref Index));
|
||||
skill.Unknown2 = Get.DWord(Data, ref Index);
|
||||
skill.IsAttribute1Valid = Get.DWord(Data, ref Index) == 1;
|
||||
skill.IsAttribute2Valid = Get.DWord(Data, ref Index) == 1;
|
||||
skill.AttributeDivisor = Get.DWord(Data, ref Index);
|
||||
skill.Attribute1Id = Get.DWord(Data, ref Index);
|
||||
skill.Attribute2Id = Get.DWord(Data, ref Index);
|
||||
skill.XPTimerLimit = Get.Double(Data, ref Index);
|
||||
skill.XPTimerStart = Get.Double(Data, ref Index);
|
||||
skill.Unknown3 = Get.Double(Data, ref Index);
|
||||
Add(skill);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
56
Managed/Decal.FileService/Decal.Filters/SkillType.cs
Normal file
56
Managed/Decal.FileService/Decal.Filters/SkillType.cs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
using System.Globalization;
|
||||
|
||||
namespace Decal.Filters;
|
||||
|
||||
public class SkillType
|
||||
{
|
||||
private static SkillType[] sTypes = new SkillType[3]
|
||||
{
|
||||
new SkillType(1, "Combat"),
|
||||
new SkillType(2, "Other"),
|
||||
new SkillType(3, "Magic")
|
||||
};
|
||||
|
||||
private int mId;
|
||||
|
||||
private string mName;
|
||||
|
||||
public int Id => mId;
|
||||
|
||||
public string Name => mName;
|
||||
|
||||
public static SkillType GetById(int id)
|
||||
{
|
||||
for (int i = 0; i < sTypes.Length; i++)
|
||||
{
|
||||
if (sTypes[i].Id == id)
|
||||
{
|
||||
return sTypes[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static SkillType GetByName(string name)
|
||||
{
|
||||
for (int i = 0; i < sTypes.Length; i++)
|
||||
{
|
||||
if (string.Compare(sTypes[i].Name, name, ignoreCase: true, CultureInfo.InvariantCulture) == 0)
|
||||
{
|
||||
return sTypes[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private SkillType(int id, string name)
|
||||
{
|
||||
mId = id;
|
||||
mName = name;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public sealed class SpecializedSkillXPTable : RawTable<long>
|
||||
{
|
||||
internal SpecializedSkillXPTable(int Length)
|
||||
{
|
||||
InitializeTable(Length);
|
||||
}
|
||||
|
||||
internal override bool LoadFrom(byte[] Data)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
internal new void Add(long Entry)
|
||||
{
|
||||
base.Add(Entry);
|
||||
}
|
||||
}
|
||||
32
Managed/Decal.FileService/Decal.Filters/Species.cs
Normal file
32
Managed/Decal.FileService/Decal.Filters/Species.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public class Species : IIdNameTableEntry
|
||||
{
|
||||
private int mID;
|
||||
|
||||
private string mName;
|
||||
|
||||
public int Id => mID;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mName = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal Species(int ID)
|
||||
{
|
||||
mID = ID;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
}
|
||||
28
Managed/Decal.FileService/Decal.Filters/SpeciesTable.cs
Normal file
28
Managed/Decal.FileService/Decal.Filters/SpeciesTable.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public sealed class SpeciesTable : IdNameTable<Species>
|
||||
{
|
||||
internal SpeciesTable(byte[] Data)
|
||||
{
|
||||
LoadFrom(Data);
|
||||
}
|
||||
|
||||
internal override bool LoadFrom(byte[] Data)
|
||||
{
|
||||
int Index = 0;
|
||||
if (Get.DWord(Data, ref Index) != 570425358)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Index += 5;
|
||||
int num = Get.Byte(Data, ref Index);
|
||||
InitializeTable(num);
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
Species species = new Species(Get.DWord(Data, ref Index));
|
||||
species.Name = Get.PString(Data, ref Index);
|
||||
Add(species);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
427
Managed/Decal.FileService/Decal.Filters/Spell.cs
Normal file
427
Managed/Decal.FileService/Decal.Filters/Spell.cs
Normal file
|
|
@ -0,0 +1,427 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public class Spell : IIdNameTableEntry
|
||||
{
|
||||
private int mID;
|
||||
|
||||
private string mName;
|
||||
|
||||
private string mDesc;
|
||||
|
||||
private int mIconId;
|
||||
|
||||
private int mFamily;
|
||||
|
||||
private int mType;
|
||||
|
||||
private int mFlags;
|
||||
|
||||
private SpellSchool mSchool;
|
||||
|
||||
private int mDiff;
|
||||
|
||||
private int mMana;
|
||||
|
||||
private SpellComponentIDs mComps;
|
||||
|
||||
private float mSpeed;
|
||||
|
||||
private double mDuration;
|
||||
|
||||
private int mCasterEffect;
|
||||
|
||||
private int mTargetEffect;
|
||||
|
||||
private int mTargetMask;
|
||||
|
||||
private int mGen;
|
||||
|
||||
private int mSort;
|
||||
|
||||
private float mUnk1;
|
||||
|
||||
private float mUnk2;
|
||||
|
||||
private float mUnk3;
|
||||
|
||||
private int mUnk4;
|
||||
|
||||
private double mUnk5;
|
||||
|
||||
private int mUnk6;
|
||||
|
||||
private int mUnk7;
|
||||
|
||||
private int mUnk8;
|
||||
|
||||
private int mUnk9;
|
||||
|
||||
private int mUnk10;
|
||||
|
||||
public int Id => mID;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string Description
|
||||
{
|
||||
get
|
||||
{
|
||||
return mDesc;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mDesc = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int IconId
|
||||
{
|
||||
get
|
||||
{
|
||||
return mIconId;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mIconId = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Family
|
||||
{
|
||||
get
|
||||
{
|
||||
return mFamily;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mFamily = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Type
|
||||
{
|
||||
get
|
||||
{
|
||||
return mType;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mType = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Flags
|
||||
{
|
||||
get
|
||||
{
|
||||
return mFlags;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mFlags = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsOffensive => (mFlags & 1) != 0;
|
||||
|
||||
public bool IsIrresistible => (mFlags & 4) != 0;
|
||||
|
||||
public bool IsUntargetted => (mFlags & 8) != 0;
|
||||
|
||||
public bool IsDebuff => (mFlags & 0x10) != 0;
|
||||
|
||||
public bool IsFellowship => (mFlags & 0x2000) != 0;
|
||||
|
||||
public bool IsFastWindup => (mFlags & 0x4000) != 0;
|
||||
|
||||
public SpellSchool School
|
||||
{
|
||||
get
|
||||
{
|
||||
return mSchool;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mSchool = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Difficulty
|
||||
{
|
||||
get
|
||||
{
|
||||
return mDiff;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mDiff = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Mana
|
||||
{
|
||||
get
|
||||
{
|
||||
return mMana;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mMana = value;
|
||||
}
|
||||
}
|
||||
|
||||
public SpellComponentIDs ComponentIDs
|
||||
{
|
||||
get
|
||||
{
|
||||
return mComps;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mComps = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float Speed
|
||||
{
|
||||
get
|
||||
{
|
||||
return mSpeed;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mSpeed = value;
|
||||
}
|
||||
}
|
||||
|
||||
public double Duration
|
||||
{
|
||||
get
|
||||
{
|
||||
return mDuration;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mDuration = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int CasterEffect
|
||||
{
|
||||
get
|
||||
{
|
||||
return mCasterEffect;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mCasterEffect = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int TargetEffect
|
||||
{
|
||||
get
|
||||
{
|
||||
return mTargetEffect;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mTargetEffect = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int TargetMask
|
||||
{
|
||||
get
|
||||
{
|
||||
return mTargetMask;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mTargetMask = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Generation
|
||||
{
|
||||
get
|
||||
{
|
||||
return mGen;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mGen = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int SortKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return mSort;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mSort = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float Unknown1
|
||||
{
|
||||
get
|
||||
{
|
||||
return mUnk1;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mUnk1 = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float Unknown2
|
||||
{
|
||||
get
|
||||
{
|
||||
return mUnk2;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mUnk2 = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float Unknown3
|
||||
{
|
||||
get
|
||||
{
|
||||
return mUnk3;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mUnk3 = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Unknown4
|
||||
{
|
||||
get
|
||||
{
|
||||
return mUnk4;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mUnk4 = value;
|
||||
}
|
||||
}
|
||||
|
||||
public double Unknown5
|
||||
{
|
||||
get
|
||||
{
|
||||
return mUnk5;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mUnk5 = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Unknown6
|
||||
{
|
||||
get
|
||||
{
|
||||
return mUnk6;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mUnk6 = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Unknown7
|
||||
{
|
||||
get
|
||||
{
|
||||
return mUnk7;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mUnk7 = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Unknown8
|
||||
{
|
||||
get
|
||||
{
|
||||
return mUnk8;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mUnk8 = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Unknown9
|
||||
{
|
||||
get
|
||||
{
|
||||
return mUnk9;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mUnk9 = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Unknown10
|
||||
{
|
||||
get
|
||||
{
|
||||
return mUnk10;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mUnk10 = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal Spell(int ID)
|
||||
{
|
||||
mID = ID;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
internal static int Hash(string Name, string Description)
|
||||
{
|
||||
return Hash(Name, 303068800u) + Hash(Description, 3199061829u);
|
||||
}
|
||||
|
||||
internal static int Hash(string Buffer, uint Seed)
|
||||
{
|
||||
int num = 0;
|
||||
for (int i = 0; i < Buffer.Length; i++)
|
||||
{
|
||||
num = (num << 4) + (byte)Buffer[i];
|
||||
if ((num & 0xF0000000u) != 0L)
|
||||
{
|
||||
num = (num & 0xFFFFFFF) ^ ((num >> 24) & 0xF0);
|
||||
}
|
||||
}
|
||||
return (int)(num % Seed);
|
||||
}
|
||||
}
|
||||
25
Managed/Decal.FileService/Decal.Filters/SpellComponentIDs.cs
Normal file
25
Managed/Decal.FileService/Decal.Filters/SpellComponentIDs.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public sealed class SpellComponentIDs : RawTable<int>
|
||||
{
|
||||
private int mHash;
|
||||
|
||||
internal SpellComponentIDs(int length, int hash)
|
||||
{
|
||||
InitializeTable(length);
|
||||
mHash = hash;
|
||||
}
|
||||
|
||||
internal override bool LoadFrom(byte[] data)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
internal new void Add(int entry)
|
||||
{
|
||||
if (entry != 0 && entry - mHash != 0)
|
||||
{
|
||||
base.Add(entry - mHash);
|
||||
}
|
||||
}
|
||||
}
|
||||
58
Managed/Decal.FileService/Decal.Filters/SpellSchool.cs
Normal file
58
Managed/Decal.FileService/Decal.Filters/SpellSchool.cs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
using System.Globalization;
|
||||
|
||||
namespace Decal.Filters;
|
||||
|
||||
public sealed class SpellSchool
|
||||
{
|
||||
private static SpellSchool[] sSchools = new SpellSchool[5]
|
||||
{
|
||||
new SpellSchool(1, "War Magic"),
|
||||
new SpellSchool(2, "Life Magic"),
|
||||
new SpellSchool(3, "Item Enchantment"),
|
||||
new SpellSchool(4, "Creature Enchantment"),
|
||||
new SpellSchool(5, "Void Magic")
|
||||
};
|
||||
|
||||
private int mId;
|
||||
|
||||
private string mName;
|
||||
|
||||
public int Id => mId;
|
||||
|
||||
public string Name => mName;
|
||||
|
||||
public static SpellSchool GetById(int id)
|
||||
{
|
||||
for (int i = 0; i < sSchools.Length; i++)
|
||||
{
|
||||
if (sSchools[i].Id == id)
|
||||
{
|
||||
return sSchools[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static SpellSchool GetByName(string name)
|
||||
{
|
||||
for (int i = 0; i < sSchools.Length; i++)
|
||||
{
|
||||
if (string.Compare(sSchools[i].Name, name, ignoreCase: true, CultureInfo.InvariantCulture) == 0)
|
||||
{
|
||||
return sSchools[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private SpellSchool(int id, string name)
|
||||
{
|
||||
mId = id;
|
||||
mName = name;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
}
|
||||
58
Managed/Decal.FileService/Decal.Filters/SpellTable.cs
Normal file
58
Managed/Decal.FileService/Decal.Filters/SpellTable.cs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public sealed class SpellTable : IdNameTable<Spell>
|
||||
{
|
||||
internal SpellTable(byte[] Data)
|
||||
{
|
||||
LoadFrom(Data);
|
||||
}
|
||||
|
||||
internal override bool LoadFrom(byte[] Data)
|
||||
{
|
||||
int Index = 0;
|
||||
if (Get.DWord(Data, ref Index) != 234881038)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int num = Get.Word(Data, ref Index);
|
||||
InitializeTable(num);
|
||||
Index += 2;
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
Spell spell = new Spell(Get.DWord(Data, ref Index));
|
||||
spell.Name = Get.EncString(Data, ref Index);
|
||||
spell.Description = Get.EncString(Data, ref Index);
|
||||
spell.School = SpellSchool.GetById(Get.DWord(Data, ref Index));
|
||||
spell.IconId = Get.DWord(Data, ref Index);
|
||||
spell.Family = Get.DWord(Data, ref Index);
|
||||
spell.Flags = Get.DWord(Data, ref Index);
|
||||
spell.Mana = Get.DWord(Data, ref Index);
|
||||
spell.Unknown1 = Get.Float(Data, ref Index);
|
||||
spell.Unknown2 = Get.Float(Data, ref Index);
|
||||
spell.Difficulty = Get.DWord(Data, ref Index);
|
||||
spell.Unknown3 = Get.Float(Data, ref Index);
|
||||
spell.Generation = Get.DWord(Data, ref Index);
|
||||
spell.Speed = Get.Float(Data, ref Index);
|
||||
spell.Type = Get.DWord(Data, ref Index);
|
||||
spell.Unknown4 = Get.DWord(Data, ref Index);
|
||||
spell.Duration = ((spell.Type == 1 || spell.Type == 7 || spell.Type == 12) ? Get.Double(Data, ref Index) : (-1.0));
|
||||
spell.Unknown5 = ((spell.Type == 1 || spell.Type == 12) ? Get.Double(Data, ref Index) : (-1.0));
|
||||
spell.ComponentIDs = new SpellComponentIDs(8, Spell.Hash(spell.Name, spell.Description));
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
spell.ComponentIDs.Add(Get.DWord(Data, ref Index));
|
||||
}
|
||||
spell.CasterEffect = Get.DWord(Data, ref Index);
|
||||
spell.TargetEffect = Get.DWord(Data, ref Index);
|
||||
spell.Unknown6 = Get.DWord(Data, ref Index);
|
||||
spell.Unknown7 = Get.DWord(Data, ref Index);
|
||||
spell.Unknown8 = Get.DWord(Data, ref Index);
|
||||
spell.Unknown9 = Get.DWord(Data, ref Index);
|
||||
spell.SortKey = Get.DWord(Data, ref Index);
|
||||
spell.TargetMask = Get.DWord(Data, ref Index);
|
||||
spell.Unknown10 = Get.DWord(Data, ref Index);
|
||||
Add(spell);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public sealed class TrainedSkillXPTable : RawTable<long>
|
||||
{
|
||||
internal TrainedSkillXPTable(int Length)
|
||||
{
|
||||
InitializeTable(Length);
|
||||
}
|
||||
|
||||
internal override bool LoadFrom(byte[] Data)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
internal new void Add(long Entry)
|
||||
{
|
||||
base.Add(Entry);
|
||||
}
|
||||
}
|
||||
25
Managed/Decal.FileService/Decal.Filters/UpdateEventArgs.cs
Normal file
25
Managed/Decal.FileService/Decal.Filters/UpdateEventArgs.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
using System;
|
||||
|
||||
namespace Decal.Filters;
|
||||
|
||||
public class UpdateEventArgs : EventArgs
|
||||
{
|
||||
private int mFileId;
|
||||
|
||||
public int FileId
|
||||
{
|
||||
get
|
||||
{
|
||||
return mFileId;
|
||||
}
|
||||
set
|
||||
{
|
||||
mFileId = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal UpdateEventArgs(int fileId)
|
||||
{
|
||||
mFileId = fileId;
|
||||
}
|
||||
}
|
||||
46
Managed/Decal.FileService/Decal.Filters/Vital.cs
Normal file
46
Managed/Decal.FileService/Decal.Filters/Vital.cs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public class Vital : IIdNameTableEntry
|
||||
{
|
||||
private int mID;
|
||||
|
||||
private string mName;
|
||||
|
||||
private int mIconId;
|
||||
|
||||
public int Id => mID;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int IconId
|
||||
{
|
||||
get
|
||||
{
|
||||
return mIconId;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mIconId = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal Vital(int ID)
|
||||
{
|
||||
mID = ID;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
}
|
||||
92
Managed/Decal.FileService/Decal.Filters/VitalFormula.cs
Normal file
92
Managed/Decal.FileService/Decal.Filters/VitalFormula.cs
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public class VitalFormula
|
||||
{
|
||||
private bool mAttr1Valid;
|
||||
|
||||
private bool mAttr2Valid;
|
||||
|
||||
private int mAttr1Id;
|
||||
|
||||
private int mAttr2Id;
|
||||
|
||||
private int mDivisor;
|
||||
|
||||
private int mUnk;
|
||||
|
||||
public bool IsAttribute1Valid
|
||||
{
|
||||
get
|
||||
{
|
||||
return mAttr1Valid;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mAttr1Valid = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAttribute2Valid
|
||||
{
|
||||
get
|
||||
{
|
||||
return mAttr2Valid;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mAttr2Valid = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Attribute1Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return mAttr1Id;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mAttr1Id = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Attribute2Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return mAttr2Id;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mAttr2Id = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int AttributeDivisor
|
||||
{
|
||||
get
|
||||
{
|
||||
return mDivisor;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mDivisor = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Unknown
|
||||
{
|
||||
get
|
||||
{
|
||||
return mUnk;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
mUnk = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal VitalFormula()
|
||||
{
|
||||
}
|
||||
}
|
||||
36
Managed/Decal.FileService/Decal.Filters/VitalFormulaTable.cs
Normal file
36
Managed/Decal.FileService/Decal.Filters/VitalFormulaTable.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public sealed class VitalFormulaTable : RawTable<VitalFormula>
|
||||
{
|
||||
internal VitalFormulaTable(byte[] Data)
|
||||
{
|
||||
LoadFrom(Data);
|
||||
}
|
||||
|
||||
internal override bool LoadFrom(byte[] Data)
|
||||
{
|
||||
int Index = 0;
|
||||
if (Get.DWord(Data, ref Index) != 234881027)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ((Data.Length - Index) % 24 != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int num = (Data.Length - 4) / 24;
|
||||
InitializeTable(num);
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
VitalFormula vitalFormula = new VitalFormula();
|
||||
vitalFormula.Unknown = Get.DWord(Data, ref Index);
|
||||
vitalFormula.IsAttribute1Valid = Get.DWord(Data, ref Index) == 1;
|
||||
vitalFormula.IsAttribute2Valid = Get.DWord(Data, ref Index) == 1;
|
||||
vitalFormula.AttributeDivisor = Get.DWord(Data, ref Index);
|
||||
vitalFormula.Attribute1Id = Get.DWord(Data, ref Index);
|
||||
vitalFormula.Attribute2Id = Get.DWord(Data, ref Index);
|
||||
Add(vitalFormula);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
35
Managed/Decal.FileService/Decal.Filters/VitalTable.cs
Normal file
35
Managed/Decal.FileService/Decal.Filters/VitalTable.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public sealed class VitalTable : IdNameTable<Vital>
|
||||
{
|
||||
internal VitalTable(byte[] Data)
|
||||
{
|
||||
LoadFrom(Data);
|
||||
}
|
||||
|
||||
internal override bool LoadFrom(byte[] Data)
|
||||
{
|
||||
int Index = 0;
|
||||
if (Get.DWord(Data, ref Index) != 620756999)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Index++;
|
||||
int num = Get.Byte(Data, ref Index);
|
||||
InitializeTable(num);
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
Vital vital = new Vital(Get.DWord(Data, ref Index));
|
||||
vital.IconId = Get.DWord(Data, ref Index);
|
||||
Add(vital);
|
||||
}
|
||||
Index++;
|
||||
num = Get.Byte(Data, ref Index);
|
||||
for (int j = 0; j < num; j++)
|
||||
{
|
||||
int id = Get.DWord(Data, ref Index);
|
||||
GetById(id).Name = Get.PString(Data, ref Index);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
19
Managed/Decal.FileService/Decal.Filters/VitalXPTable.cs
Normal file
19
Managed/Decal.FileService/Decal.Filters/VitalXPTable.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
namespace Decal.Filters;
|
||||
|
||||
public sealed class VitalXPTable : RawTable<long>
|
||||
{
|
||||
internal VitalXPTable(int Length)
|
||||
{
|
||||
InitializeTable(Length);
|
||||
}
|
||||
|
||||
internal override bool LoadFrom(byte[] Data)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
internal new void Add(long Entry)
|
||||
{
|
||||
base.Add(Entry);
|
||||
}
|
||||
}
|
||||
434
Managed/Decal.FileService/Decal.Filters/zlib.cs
Normal file
434
Managed/Decal.FileService/Decal.Filters/zlib.cs
Normal file
|
|
@ -0,0 +1,434 @@
|
|||
#define TRACE
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
namespace Decal.Filters;
|
||||
|
||||
internal class zlib
|
||||
{
|
||||
private byte[] mInData;
|
||||
|
||||
private int mInIndex;
|
||||
|
||||
private int mInCount;
|
||||
|
||||
private int mInBuf;
|
||||
|
||||
private int mInBufSize;
|
||||
|
||||
private byte[] mOutData;
|
||||
|
||||
private int mOutIndex;
|
||||
|
||||
private int mOutCount;
|
||||
|
||||
private short[] mDynLCodeTree;
|
||||
|
||||
private short[] mDynDCodeTree;
|
||||
|
||||
private static short[] mFixLCodeTree;
|
||||
|
||||
private static short[] mFixDCodeTree;
|
||||
|
||||
public static byte[] Inflate(byte[] CompressedData, int UncompressedSize)
|
||||
{
|
||||
byte[] array = (byte[])Array.CreateInstance(typeof(byte), UncompressedSize);
|
||||
new zlib(CompressedData, 0, CompressedData.Length, array, 0, UncompressedSize).Inflate();
|
||||
return array;
|
||||
}
|
||||
|
||||
internal zlib(byte[] InData, int InIndex, int InCount, byte[] OutData, int OutIndex, int OutCount)
|
||||
{
|
||||
mInData = InData;
|
||||
mInIndex = InIndex;
|
||||
mInCount = InCount;
|
||||
mOutData = OutData;
|
||||
mOutIndex = OutIndex;
|
||||
mOutCount = OutCount;
|
||||
}
|
||||
|
||||
internal bool Inflate()
|
||||
{
|
||||
byte b = Get.Byte(mInData, ref mInIndex);
|
||||
mInCount--;
|
||||
byte b2 = Get.Byte(mInData, ref mInIndex);
|
||||
mInCount--;
|
||||
int num = 0;
|
||||
if ((b2 & 0x20) != 0)
|
||||
{
|
||||
num = Get.DWord(mInData, ref mInIndex);
|
||||
mInCount -= 4;
|
||||
}
|
||||
if ((b & 0xF) != 8)
|
||||
{
|
||||
Trace.WriteLine(new StringBuilder(64).AppendFormat("zlib.Inflate() Warning: unknown compression method 0x{0:x1}", b & 0xF).ToString());
|
||||
return false;
|
||||
}
|
||||
if (b >> 4 != 7)
|
||||
{
|
||||
Trace.WriteLine("zlib.Inflate() Warning: window size other than 32K");
|
||||
return false;
|
||||
}
|
||||
if ((b2 & 0x20) != 0)
|
||||
{
|
||||
Trace.WriteLine(new StringBuilder(64).AppendFormat("zlib.Inflate() Warning: unknown DICTID 0x{0:x8}", num).ToString());
|
||||
return false;
|
||||
}
|
||||
int bits;
|
||||
do
|
||||
{
|
||||
bits = GetBits(1);
|
||||
switch (GetBits(2))
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
GetBits(0);
|
||||
int bits2 = GetBits(16);
|
||||
int bits3 = GetBits(16);
|
||||
if (bits2 != (~bits3 & 0xFFFF))
|
||||
{
|
||||
Trace.WriteLine("zlib.Inflate() Warning: LEN != ~NLEN");
|
||||
}
|
||||
Buffer.BlockCopy(mInData, mInIndex, mOutData, mOutIndex, bits2);
|
||||
mInIndex += bits2;
|
||||
mOutIndex += bits2;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
if ((mFixLCodeTree == null || mFixDCodeTree == null) && !InitFixedCodes())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!Decompress(mFixLCodeTree, mFixDCodeTree))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (!InitDynamicCodes())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!Decompress(mDynLCodeTree, mDynDCodeTree))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
Trace.WriteLine("zlib.Inflate() Warning: unhandled block type 3");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
while (bits != 1);
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
GetBits(8);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool InitFixedCodes()
|
||||
{
|
||||
int[] array = (int[])Array.CreateInstance(typeof(int), 288);
|
||||
int[] array2 = (int[])Array.CreateInstance(typeof(int), 32);
|
||||
int i;
|
||||
for (i = 0; i < 144; i++)
|
||||
{
|
||||
array[i] = 8;
|
||||
}
|
||||
for (; i < 256; i++)
|
||||
{
|
||||
array[i] = 9;
|
||||
}
|
||||
for (; i < 280; i++)
|
||||
{
|
||||
array[i] = 7;
|
||||
}
|
||||
for (; i < 288; i++)
|
||||
{
|
||||
array[i] = 8;
|
||||
}
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
array2[i] = 5;
|
||||
}
|
||||
mFixLCodeTree = BuildCodeTree(array, 0, 288, 65536);
|
||||
mFixDCodeTree = BuildCodeTree(array2, 0, 32, 65536);
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool InitDynamicCodes()
|
||||
{
|
||||
int[] array = new int[19]
|
||||
{
|
||||
16, 17, 18, 0, 8, 7, 9, 6, 10, 5,
|
||||
11, 4, 12, 3, 13, 2, 14, 1, 15
|
||||
};
|
||||
int num = GetBits(5) + 257;
|
||||
int num2 = GetBits(5) + 1;
|
||||
int num3 = GetBits(4) + 4;
|
||||
int[] array2 = (int[])Array.CreateInstance(typeof(int), 19);
|
||||
for (int i = 0; i < num3; i++)
|
||||
{
|
||||
array2[array[i]] = GetBits(3);
|
||||
}
|
||||
short[] codeTree = BuildCodeTree(array2, 0, 19, 256);
|
||||
int num4 = num + num2;
|
||||
int[] array3 = (int[])Array.CreateInstance(typeof(int), num4);
|
||||
int num5 = 0;
|
||||
while (num5 < num4)
|
||||
{
|
||||
int code = GetCode(codeTree);
|
||||
if (code >= 0 && code < 16)
|
||||
{
|
||||
array3[num5++] = code;
|
||||
continue;
|
||||
}
|
||||
switch (code)
|
||||
{
|
||||
case 16:
|
||||
{
|
||||
int num7 = GetBits(2) + 3;
|
||||
while (num7-- > 0)
|
||||
{
|
||||
array3[num5] = array3[num5 - 1];
|
||||
num5++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 17:
|
||||
{
|
||||
int num8 = GetBits(3) + 3;
|
||||
while (num8-- > 0)
|
||||
{
|
||||
array3[num5++] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 18:
|
||||
{
|
||||
int num6 = GetBits(7) + 11;
|
||||
while (num6-- > 0)
|
||||
{
|
||||
array3[num5++] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Trace.WriteLine(new StringBuilder(64).AppendFormat("Deflate.InitDynamicCodes Warning: invalid code 0x{0:x4}", code).ToString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
mDynLCodeTree = BuildCodeTree(array3, 0, num, 65536);
|
||||
mDynDCodeTree = BuildCodeTree(array3, num, num2, 65536);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static short[] BuildCodeTree(int[] CodeLens, int Start, int Count, int CodeTreeLength)
|
||||
{
|
||||
short[] array = (short[])Array.CreateInstance(typeof(short), CodeTreeLength);
|
||||
int[] array2 = (int[])Array.CreateInstance(typeof(int), 16);
|
||||
int[] array3 = (int[])Array.CreateInstance(typeof(int), 16);
|
||||
for (int i = Start; i < Start + Count; i++)
|
||||
{
|
||||
array2[CodeLens[i]]++;
|
||||
}
|
||||
array2[0] = 0;
|
||||
int num = 0;
|
||||
for (int j = 1; j < 16; j++)
|
||||
{
|
||||
num = (array3[j] = num + array2[j - 1] << 1);
|
||||
}
|
||||
for (int k = 0; k < CodeTreeLength; k++)
|
||||
{
|
||||
array[k] = -1;
|
||||
}
|
||||
for (int l = 0; l < Count; l++)
|
||||
{
|
||||
int num2 = CodeLens[Start + l];
|
||||
if (num2 > 0)
|
||||
{
|
||||
int num3 = Reverse(array3[num2]++, num2);
|
||||
int num4 = 1;
|
||||
while (num2-- > 0)
|
||||
{
|
||||
num4 <<= 1;
|
||||
num4 += num3 & 1;
|
||||
num3 >>= 1;
|
||||
}
|
||||
array[num4] = (short)l;
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
private bool Decompress(short[] LCodeTree, short[] DCodeTree)
|
||||
{
|
||||
int[,] array = new int[29, 2]
|
||||
{
|
||||
{ 0, 3 },
|
||||
{ 0, 4 },
|
||||
{ 0, 5 },
|
||||
{ 0, 6 },
|
||||
{ 0, 7 },
|
||||
{ 0, 8 },
|
||||
{ 0, 9 },
|
||||
{ 0, 10 },
|
||||
{ 1, 11 },
|
||||
{ 1, 13 },
|
||||
{ 1, 15 },
|
||||
{ 1, 17 },
|
||||
{ 2, 19 },
|
||||
{ 2, 23 },
|
||||
{ 2, 27 },
|
||||
{ 2, 31 },
|
||||
{ 3, 35 },
|
||||
{ 3, 43 },
|
||||
{ 3, 51 },
|
||||
{ 3, 59 },
|
||||
{ 4, 67 },
|
||||
{ 4, 83 },
|
||||
{ 4, 99 },
|
||||
{ 4, 115 },
|
||||
{ 5, 131 },
|
||||
{ 5, 163 },
|
||||
{ 5, 195 },
|
||||
{ 5, 227 },
|
||||
{ 0, 258 }
|
||||
};
|
||||
int[,] array2 = new int[30, 2]
|
||||
{
|
||||
{ 0, 1 },
|
||||
{ 0, 2 },
|
||||
{ 0, 3 },
|
||||
{ 0, 4 },
|
||||
{ 1, 5 },
|
||||
{ 1, 7 },
|
||||
{ 2, 9 },
|
||||
{ 2, 13 },
|
||||
{ 3, 17 },
|
||||
{ 3, 25 },
|
||||
{ 4, 33 },
|
||||
{ 4, 49 },
|
||||
{ 5, 65 },
|
||||
{ 5, 97 },
|
||||
{ 6, 129 },
|
||||
{ 6, 193 },
|
||||
{ 7, 257 },
|
||||
{ 7, 385 },
|
||||
{ 8, 513 },
|
||||
{ 8, 769 },
|
||||
{ 9, 1025 },
|
||||
{ 9, 1537 },
|
||||
{ 10, 2049 },
|
||||
{ 10, 3073 },
|
||||
{ 11, 4097 },
|
||||
{ 11, 6145 },
|
||||
{ 12, 8193 },
|
||||
{ 12, 12289 },
|
||||
{ 13, 16385 },
|
||||
{ 13, 24577 }
|
||||
};
|
||||
int code;
|
||||
while ((code = GetCode(LCodeTree)) != 256)
|
||||
{
|
||||
if (code >= 0 && code < 256)
|
||||
{
|
||||
mOutData[mOutIndex++] = (byte)code;
|
||||
mOutCount--;
|
||||
continue;
|
||||
}
|
||||
if (code > 256)
|
||||
{
|
||||
code -= 257;
|
||||
int numBits;
|
||||
int num = (((numBits = array[code, 0]) > 0) ? GetBits(numBits) : 0);
|
||||
num += array[code, 1];
|
||||
code = GetCode(DCodeTree);
|
||||
int num2 = (((numBits = array2[code, 0]) > 0) ? GetBits(numBits) : 0);
|
||||
num2 += array2[code, 1];
|
||||
while (num-- > 0)
|
||||
{
|
||||
mOutData[mOutIndex] = mOutData[mOutIndex - num2];
|
||||
mOutIndex++;
|
||||
mOutCount--;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
Trace.WriteLine(new StringBuilder(64).AppendFormat("Deflate.Decompress Warning: invalid code 0x{0:x4}", code).ToString());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private short GetCode(short[] CodeTree)
|
||||
{
|
||||
int num = CodeTree.Length;
|
||||
int num2 = 1;
|
||||
while (CodeTree[num2] == -1)
|
||||
{
|
||||
num2 <<= 1;
|
||||
num2 += GetBits(1);
|
||||
if (num2 >= num)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return CodeTree[num2];
|
||||
}
|
||||
|
||||
private int GetBits(int NumBits)
|
||||
{
|
||||
int num;
|
||||
switch (NumBits)
|
||||
{
|
||||
default:
|
||||
return -1;
|
||||
case 0:
|
||||
num = mInBufSize & 7;
|
||||
mInBuf >>= num;
|
||||
mInBufSize -= num;
|
||||
return 0;
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 16:
|
||||
break;
|
||||
}
|
||||
while (mInBufSize < NumBits)
|
||||
{
|
||||
int num2 = mInData[mInIndex++];
|
||||
mInCount--;
|
||||
mInBuf |= num2 << mInBufSize;
|
||||
mInBufSize += 8;
|
||||
}
|
||||
num = mInBuf & ((1 << NumBits) - 1);
|
||||
mInBuf >>= NumBits;
|
||||
mInBufSize -= NumBits;
|
||||
return num;
|
||||
}
|
||||
|
||||
private static int Reverse(int Bits, int Length)
|
||||
{
|
||||
int num = 0;
|
||||
while (Length-- > 0)
|
||||
{
|
||||
num = (num << 1) | (Bits & 1);
|
||||
Bits >>= 1;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue