MosswartMassacre/Unused/Decal.Adapter/MessageStruct.cs
2025-06-09 02:03:11 +02:00

676 lines
15 KiB
C#

using System;
using System.Globalization;
using System.Text;
using Decal.Adapter.NetParser;
using Decal.Adapter.Support;
namespace Decal.Adapter;
/// <summary>
/// Represents Message data
/// </summary>
public class MessageStruct : MarshalByRefObject
{
internal struct MessageField
{
internal string Name;
internal MemberParserType Type;
internal object Value;
internal int Offset;
internal int Length;
}
internal byte[] mData;
internal int mOffset;
internal int mLength;
internal MemberParser mParser;
internal MessageStruct mParent;
internal int mIndex;
internal bool mParsed;
internal int mCount;
internal MessageField[] mFields;
/// <summary>
/// Returns the number of fields (or vector length)
/// </summary>
public virtual int Count
{
get
{
if (!mParsed)
{
Parse();
}
return mCount;
}
}
/// <summary>
/// Returns the specified field data
/// </summary>
/// <param name="index">Field index</param>
/// <returns>Field value</returns>
public virtual object this[int index]
{
get
{
if (!mParsed)
{
Parse();
}
if (index >= 0 && index < mCount)
{
return mFields[index].Value;
}
return null;
}
}
/// <summary>
/// Returns the specified field data
/// </summary>
/// <param name="name">Field name</param>
/// <returns>Field value</returns>
public virtual object this[string name]
{
get
{
if (!mParsed)
{
Parse();
}
int num = IndexFromName(name);
if (num >= 0 && num < mCount)
{
return mFields[num].Value;
}
return null;
}
}
/// <summary>
/// Returns the raw bytes for this field
/// </summary>
public virtual byte[] RawData
{
get
{
if (mParent != null)
{
return mParent.RawValue(mIndex);
}
byte[] array = (byte[])Array.CreateInstance(typeof(byte), mData.Length);
Buffer.BlockCopy(mData, 0, array, 0, mData.Length);
return array;
}
}
/// <summary>
/// Returns the next object in the (parent) vector
/// </summary>
public virtual object Next
{
get
{
if (mParent == null)
{
return null;
}
return mParent[mIndex + 1];
}
}
/// <summary>
/// Returns the parent field
/// </summary>
public virtual MessageStruct Parent => mParent;
internal MessageStruct()
{
}
internal MessageStruct(byte[] Data, int Offset, MemberParser Parser)
{
mData = (byte[])Array.CreateInstance(typeof(byte), Data.Length);
Buffer.BlockCopy(Data, 0, mData, 0, mData.Length);
mOffset = Offset;
mParser = Parser;
mCount = -1;
}
internal MessageStruct(byte[] Data, int Offset, MemberParser Parser, MessageStruct Parent, int Index)
{
mData = Data;
mOffset = Offset;
mParser = Parser;
mParent = Parent;
mIndex = Index;
mCount = -1;
}
internal MessageStruct(byte[] Data, int Offset, MemberParser Parser, int Length, MessageStruct Parent, int Index)
{
mData = Data;
mOffset = Offset;
mParser = Parser;
mParent = Parent;
mIndex = Index;
mCount = Length;
}
internal int ObjectToIndex(object vIndex)
{
string text = vIndex as string;
int num = -1;
num = (string.IsNullOrEmpty(text) ? Util.UnboxTo<int>(vIndex) : IndexFromName(text));
if (num >= 0 && num < mCount)
{
return num;
}
return -1;
}
/// <summary>
/// Return the field name for the specified index
/// </summary>
/// <param name="index">Field index</param>
/// <returns>Name of the field</returns>
public virtual string Name(int index)
{
if (!mParsed)
{
Parse();
}
if (index >= 0 && index < mCount)
{
return mFields[index].Name;
}
return null;
}
/// <summary>
/// Returns the passed in value?
/// </summary>
/// <param name="memberName"></param>
/// <returns></returns>
public virtual string Name(string memberName)
{
if (!mParsed)
{
Parse();
}
int num = IndexFromName(memberName);
if (num >= 0 && num < mCount)
{
return mFields[num].Name;
}
return null;
}
/// <summary>
/// Returns the specified child structure
/// </summary>
/// <param name="index">Field index</param>
/// <returns>MessageStruct for the specified field</returns>
public virtual MessageStruct Struct(int index)
{
if (!mParsed)
{
Parse();
}
if (index >= 0 && index < mCount)
{
MemberParserType type = mFields[index].Type;
if (type == MemberParserType.Struct || type == MemberParserType.Vector)
{
return mFields[index].Value as MessageStruct;
}
}
return null;
}
/// <summary>
/// Returns the specified child structure
/// </summary>
/// <param name="name">Field name</param>
/// <returns>MessageStruct for the specified field</returns>
public virtual MessageStruct Struct(string name)
{
if (!mParsed)
{
Parse();
}
int num = IndexFromName(name);
if (num >= 0 && num < mCount)
{
MemberParserType type = mFields[num].Type;
if (type == MemberParserType.Struct || type == MemberParserType.Vector)
{
return mFields[num].Value as MessageStruct;
}
}
return null;
}
/// <summary>
/// Returns the specified field value
/// </summary>
/// <typeparam name="FieldType">Type of the field</typeparam>
/// <param name="index">Field index</param>
/// <returns>Field value cast to the specified FieldType</returns>
public virtual FieldType Value<FieldType>(int index)
{
if (!mParsed)
{
Parse();
}
if (index >= 0 && index < mCount)
{
return Util.UnboxTo<FieldType>(mFields[index].Value);
}
return default(FieldType);
}
/// <summary>
/// Returns the specified field value
/// </summary>
/// <typeparam name="FieldType">Type of the field</typeparam>
/// <param name="name">Field name</param>
/// <returns>Field value cast to the specified FieldType</returns>
public virtual FieldType Value<FieldType>(string name)
{
if (!mParsed)
{
Parse();
}
int num = IndexFromName(name);
if (num >= 0 && num < mCount)
{
return Util.UnboxTo<FieldType>(mFields[num].Value);
}
return default(FieldType);
}
/// <summary>
/// Returns the raw bytes of the specified field
/// </summary>
/// <param name="index">Field index</param>
/// <returns>Raw field value</returns>
public virtual byte[] RawValue(int index)
{
if (!mParsed)
{
Parse();
}
if (index >= 0 && index < mCount)
{
int length = mFields[index].Length;
byte[] array = (byte[])Array.CreateInstance(typeof(byte), length);
Buffer.BlockCopy(mData, mFields[index].Offset, array, 0, length);
return array;
}
return null;
}
/// <summary>
/// Returns the raw bytes of the specified field
/// </summary>
/// <param name="name">Field name</param>
/// <returns>Raw field value</returns>
public virtual byte[] RawValue(string name)
{
if (!mParsed)
{
Parse();
}
int num = IndexFromName(name);
if (num >= 0 && num < mCount)
{
int length = mFields[num].Length;
byte[] array = (byte[])Array.CreateInstance(typeof(byte), length);
Buffer.BlockCopy(mData, mFields[num].Offset, array, 0, length);
return array;
}
return null;
}
internal int IndexFromName(string Name)
{
int num = mCount;
for (int i = 0; i < num; i++)
{
if (string.Compare(Name, mFields[i].Name, ignoreCase: true, CultureInfo.InvariantCulture) == 0)
{
return i;
}
}
return -1;
}
internal void Parse()
{
if (mCount == -1)
{
ParseStruct();
}
else
{
ParseVector();
}
}
internal void ParseStruct()
{
int length = ParseCounter(mParser);
mFields = (MessageField[])Array.CreateInstance(typeof(MessageField), length);
mParsed = true;
int ByteIndex = mOffset;
mCount = 0;
ParseHelper(mParser, ref mCount, ref ByteIndex);
mLength = ByteIndex - mOffset;
MessageField[] sourceArray = mFields;
mFields = (MessageField[])Array.CreateInstance(typeof(MessageField), mCount);
Array.Copy(sourceArray, mFields, mCount);
}
internal void ParseVector()
{
int num = mCount;
mFields = (MessageField[])Array.CreateInstance(typeof(MessageField), num);
mParsed = true;
int num2 = mOffset;
for (int i = 0; i < num; i++)
{
mFields[i].Name = i.ToString();
mFields[i].Offset = num2;
mFields[i].Type = MemberParserType.Struct;
MessageStruct messageStruct = new MessageStruct(mData, num2, mParser, this, i);
messageStruct.ParseStruct();
mFields[i].Value = messageStruct;
mFields[i].Length = messageStruct.mLength;
num2 += messageStruct.mLength;
}
mLength = num2 - mOffset;
}
internal int ParseCounter(MemberParser Parser)
{
int num = 0;
while (Parser != null)
{
num = ((Parser.MemberType != MemberParserType.Case) ? (num + 1) : (num + ParseCounter(Parser.Child)));
Parser = Parser.Next;
}
return num;
}
internal void ParseHelper(MemberParser Parser, ref int FieldIndex, ref int ByteIndex)
{
Encoding encoding = Encoding.GetEncoding(1252);
while (Parser != null)
{
if (Parser.PreAlignment != 0)
{
int num = ByteIndex % Parser.PreAlignment;
if (num != 0)
{
ByteIndex += Parser.PreAlignment - num;
}
}
bool flag = Parser.Condition == MemberParserCondition.None;
if (!flag)
{
MessageStruct messageStruct = this;
object obj;
do
{
obj = messageStruct[Parser.ConditionField];
if (obj != null)
{
break;
}
messageStruct = messageStruct.mParent;
}
while (messageStruct != null);
if (obj != null)
{
long num2 = 0L;
Type type = obj.GetType();
if (type.Equals(typeof(int)))
{
num2 = Convert.ToInt64(obj);
num2 &= 0xFFFFFFFFu;
}
else if (type.Equals(typeof(short)))
{
num2 = Convert.ToInt64(obj);
num2 &= 0xFFFF;
}
else if (type.Equals(typeof(byte)))
{
num2 = Convert.ToInt64(obj);
num2 &= 0xFF;
}
else if (type.Equals(typeof(long)))
{
num2 = Convert.ToInt64(obj);
}
num2 ^= Parser.ConditionXor;
num2 &= Parser.ConditionAnd;
switch (Parser.Condition)
{
case MemberParserCondition.EQ:
flag = num2 == Parser.ConditionResult;
break;
case MemberParserCondition.NE:
flag = num2 != Parser.ConditionResult;
break;
case MemberParserCondition.GE:
flag = num2 >= Parser.ConditionResult;
break;
case MemberParserCondition.GT:
flag = num2 > Parser.ConditionResult;
break;
case MemberParserCondition.LE:
flag = num2 <= Parser.ConditionResult;
break;
case MemberParserCondition.LT:
flag = num2 < Parser.ConditionResult;
break;
}
}
}
if (flag)
{
mFields[FieldIndex].Name = Parser.MemberName;
mFields[FieldIndex].Offset = ByteIndex;
mFields[FieldIndex].Type = Parser.MemberType;
switch (Parser.MemberType)
{
case MemberParserType.BYTE:
mFields[FieldIndex].Value = mData[ByteIndex++];
break;
case MemberParserType.WORD:
mFields[FieldIndex].Value = BitConverter.ToInt16(mData, ByteIndex);
ByteIndex += 2;
break;
case MemberParserType.PackedWORD:
{
int num6 = mData[ByteIndex++];
if ((num6 & 0x80) != 0)
{
num6 = ((num6 & 0x7F) << 8) | mData[ByteIndex++];
}
mFields[FieldIndex].Value = num6;
break;
}
case MemberParserType.DWORD:
mFields[FieldIndex].Value = BitConverter.ToInt32(mData, ByteIndex);
ByteIndex += 4;
break;
case MemberParserType.PackedDWORD:
{
int num6 = BitConverter.ToInt16(mData, ByteIndex);
ByteIndex += 2;
if ((num6 & 0x8000) != 0)
{
num6 = ((num6 & 0x7FFF) << 16) | (BitConverter.ToInt16(mData, ByteIndex) & 0xFFFF);
ByteIndex += 2;
}
mFields[FieldIndex].Value = num6;
break;
}
case MemberParserType.QWORD:
mFields[FieldIndex].Value = BitConverter.ToInt64(mData, ByteIndex);
ByteIndex += 8;
break;
case MemberParserType.@float:
mFields[FieldIndex].Value = BitConverter.ToSingle(mData, ByteIndex);
ByteIndex += 4;
break;
case MemberParserType.@double:
mFields[FieldIndex].Value = BitConverter.ToDouble(mData, ByteIndex);
ByteIndex += 8;
break;
case MemberParserType.String:
{
int num6 = BitConverter.ToInt16(mData, ByteIndex);
ByteIndex += 2;
if (num6 == -1)
{
num6 = BitConverter.ToInt32(mData, ByteIndex);
ByteIndex += 4;
}
StringBuilder stringBuilder = new StringBuilder(num6);
for (int j = 0; j < num6; j++)
{
stringBuilder.Append(encoding.GetChars(mData, ByteIndex++, 1));
}
mFields[FieldIndex].Value = stringBuilder.ToString();
ByteIndex = (ByteIndex + 3) & -4;
break;
}
case MemberParserType.WString:
{
int num6 = mData[ByteIndex++];
if ((num6 & 0x80) != 0)
{
num6 = ((num6 & 0x7F) << 8) | mData[ByteIndex++];
}
StringBuilder stringBuilder = new StringBuilder(num6);
for (int i = 0; i < num6; i++)
{
stringBuilder.Append(BitConverter.ToChar(mData, ByteIndex));
ByteIndex += 2;
}
mFields[FieldIndex].Value = stringBuilder.ToString();
break;
}
case MemberParserType.Struct:
{
MessageStruct messageStruct = new MessageStruct(mData, ByteIndex, Parser.Child, this, FieldIndex);
messageStruct.ParseStruct();
ByteIndex += messageStruct.mLength;
mFields[FieldIndex].Value = messageStruct;
break;
}
case MemberParserType.Vector:
{
MessageStruct messageStruct = this;
object obj;
do
{
obj = messageStruct[Parser.LengthField];
if (obj != null)
{
break;
}
messageStruct = messageStruct.mParent;
}
while (messageStruct != null);
long num4 = 0L;
if (obj != null)
{
Type type2 = obj.GetType();
if (type2.Equals(typeof(int)))
{
num4 = Convert.ToInt64(obj);
num4 &= 0xFFFFFFFFu;
}
else if (type2.Equals(typeof(short)))
{
num4 = Convert.ToInt64(obj);
num4 &= 0xFFFF;
}
else if (type2.Equals(typeof(byte)))
{
num4 = Convert.ToInt64(obj);
num4 &= 0xFF;
}
else if (type2.Equals(typeof(long)))
{
num4 = Convert.ToInt64(obj);
}
}
long num5 = Parser.LengthMask;
num4 &= num5;
if (num5 != 0L)
{
while ((num5 & 1) == 0L)
{
num4 >>= 1;
num5 >>= 1;
}
}
messageStruct = new MessageStruct(mData, ByteIndex, Parser.Child, (int)num4 + Parser.LengthDelta, this, FieldIndex);
messageStruct.ParseVector();
ByteIndex += messageStruct.mLength;
mFields[FieldIndex].Value = messageStruct;
break;
}
case MemberParserType.Case:
{
int num3 = FieldIndex;
ParseHelper(Parser.Child, ref FieldIndex, ref ByteIndex);
if (FieldIndex > num3)
{
FieldIndex--;
}
break;
}
}
mFields[FieldIndex].Length = ByteIndex - mFields[FieldIndex].Offset;
}
if (Parser.PostAlignment != 0)
{
int num7 = ByteIndex % Parser.PostAlignment;
if (num7 != 0)
{
num7 = Parser.PostAlignment - num7;
ByteIndex += num7;
if (flag)
{
mFields[FieldIndex].Length += num7;
}
}
}
if (flag)
{
FieldIndex++;
}
Parser = Parser.Next;
}
}
}