public uint GetStructMemberAddress(ORNames Struct, ORNames Member, uint Address = 0)
 {
     if (Address <= 0)
     {
         Address = GetStructAddress(Struct);
     }
     return((uint)(Address + GetStructMemberOffset(Struct, Member)));
 }
        public int GetStructMemberSize(ORNames Struct, ORNames Member)
        {
            int Size = _Structs[Struct].members[Member].size;

            if (_Structs[Struct].members[Member].count > 0)
            {
                return(Size * _Structs[Struct].members[Member].count);
            }
            return(Size);
        }
        public Object ReadStructMember(ORNames Struct, ORNames Member, byte[] Data)
        {
            int  Offset = GetStructMemberOffset(Struct, Member);
            int  Size   = GetStructMemberSize(Struct, Member);
            int  Count  = GetStructMemberCount(Struct, Member);
            Type type   = GetStructMemberType(Struct, Member);

            if (Data == null)
            {
                throw new NullReferenceException("OffsetReader.ReadStructMember: Data was null. Struct: " + Struct
                                                 + " Member: " + Member);
            }

            if (Data.Length < Offset + Size)
            {
                char[] hex = new char[16] {
                    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
                };
                string HexData = string.Empty;
                foreach (byte b in Data)
                {
                    HexData += hex[b >> 4];
                    HexData += hex[b & 0x0F] + " ";
                }

                throw new IndexOutOfRangeException("OffsetReader.ReadStructMember: Data was too small to read all data.\nData.Length: "
                                                   + Data.Length.ToString() + " Offset: " + Offset.ToString() + " Size: " + Size.ToString() + " Struct: " + Struct.ToString()
                                                   + " Member: " + Member.ToString() + "\n Data: " + HexData);
            }

            if (type == StringType)
            {
                string ReturnValS = Encoding.UTF8.GetString(Data, Offset, Size);
                int    NullPos    = ReturnValS.IndexOf('\0');
                if (NullPos >= 0)
                {
                    ReturnValS = ReturnValS.Remove(NullPos);
                }
                return(ReturnValS);
            }
            if (Count <= 0)
            {
                return(ReadWriteMemory.RawDeserialize(Data, Offset, type));
            }

            Array ReturnVal = Array.CreateInstance(type, Count);

            for (int i = 0; i < Count; i++)
            {
                ReturnVal.SetValue(ReadWriteMemory.RawDeserialize(Data, Offset + i * Size / Count, type), i);
            }
            return(ReturnVal);
        }
        public bool WriteStruct(ORNames Struct, byte[] Data, uint Address = 0)
        {
            if (Address <= 0)
            {
                Address = GetStructAddress(Struct);
            }
            int Size = GetStructSize(Struct);

            if (Data.Length != Size)
            {
                throw new OverflowException("OffsetReader.WriteStruct: Data.Length != Size. Data.Length: " + Data.Length.ToString() + " Size: " + Size.ToString());
            }

            return(mem.WriteMemory(Address, Data.Length, ref Data));
        }
        public Object ReadStructMember(ORNames Struct, ORNames Member, uint Address = 0)
        {
            if (Address <= 0)
            {
                Address = GetStructAddress(Struct);
            }


            Type type = GetStructMemberType(Struct, Member);

            if (type == StringType)
            {
                int    Length = GetStructMemberSize(Struct, Member);
                byte[] buffer = new byte[Length];
                mem.ReadMemory((uint)(GetStructMemberOffset(Struct, Member) + Address), buffer.Length, out buffer);
                string ReturnValS = Encoding.UTF8.GetString(buffer);
                int    NullPos    = ReturnValS.IndexOf('\0');
                if (NullPos >= 0)
                {
                    ReturnValS = ReturnValS.Remove(NullPos);
                }
                return(ReturnValS);
            }

            int Count = GetStructMemberCount(Struct, Member);

            if (Count <= 0)
            {
                return(mem.ReadMemory((uint)(GetStructMemberOffset(Struct, Member) + Address), GetStructMemberType(Struct, Member)));
            }

            int Size = GetStructMemberSize(Struct, Member);

            byte[] Data = new byte[Size];
            mem.ReadMemory(Address, Data.Length, out Data);
            Array ReturnVal = Array.CreateInstance(type, Count);

            for (int i = 0; i < Count; i++)
            {
                ReturnVal.SetValue(ReadWriteMemory.RawDeserialize(Data, i * Size, type), i);
            }
            return(ReturnVal);
        }
        public ORArray(XElement data)
        {
            name = (ORNames)Enum.Parse(typeof(ORNames), data.Attribute("Name").Value);
            size = (int)ImprovedParse.Parse(data.Attribute("Size").Value);
            type = (ORNames)Enum.Parse(typeof(ORNames), data.Attribute("Type").Value);

            string temp    = data.Attribute("Address").Value;
            int    PlusPos = -1;

            if ((PlusPos = temp.LastIndexOf('+')) >= 0)
            {
                address = (uint)ImprovedParse.Parse(temp.Substring(PlusPos + 1));

                string ModuleName = temp.Substring(0, PlusPos);

                for (int i = 0; i < GameData.SC2Modules.Count; i++)
                {
                    try
                    {
                        if (GameData.SC2Modules[i].ModuleName.Equals(ModuleName, StringComparison.OrdinalIgnoreCase))
                        {
                            address += (uint)GameData.SC2Modules[i].BaseAddress;
                            break;
                        }
                    }
                    catch (System.ComponentModel.Win32Exception)
                    {
                        //Let's wait a tiny bit of time and try this one more time in case it was just a temporary error.
                        System.Threading.Thread.Sleep(0);
                        if (GameData.SC2Process.Modules[i].ModuleName.Equals(ModuleName, StringComparison.OrdinalIgnoreCase))
                        {
                            address += (uint)GameData.SC2Modules[i].BaseAddress;
                            break;
                        }
                    }
                }
            }
            else
            {
                address = (uint)ImprovedParse.Parse(data.Attribute("Address").Value);
            }
        }
        public byte[] ReadStruct(ORNames Struct, uint Address = 0)
        {
            if (Address <= 0)
            {
                Address = GetStructAddress(Struct);
            }
            int StartOffset = GetStructStartOffset(Struct);
            int EndOffset   = GetStructEndOffset(Struct);
            int TotalSize   = GetStructSize(Struct);
            int UsedSize    = EndOffset - StartOffset;

            if (TotalSize < UsedSize + StartOffset)
            {
                TotalSize = UsedSize + StartOffset;
            }

            byte[] buffer;
            mem.ReadMemory(Address, TotalSize, out buffer);
            return(buffer);
        }
        public bool WriteStructMember(ORNames Struct, ORNames Member, Object NewValue, uint Address = 0)
        {
            if (Address <= 0)
            {
                Address = GetStructAddress(Struct);
            }
            int  Offset = GetStructMemberOffset(Struct, Member);
            int  Size   = GetStructMemberSize(Struct, Member);
            int  Count  = GetStructMemberCount(Struct, Member);
            Type type   = GetStructMemberType(Struct, Member);

            if (Count <= 0 && NewValue.GetType() != type)
            {
                throw new InvalidCastException("OffsetReader.WriteStructMember: NewValue is not of the expected type. NewValue type: " + NewValue.GetType().ToString() + " Expected type: " + type.ToString());
            }

            if (type == StringType)
            {
                int    Length        = Size;
                byte[] StringAsBytes = Encoding.UTF8.GetBytes((string)NewValue);
                byte[] buffer        = new byte[Length];
                Array.Copy(StringAsBytes, buffer, StringAsBytes.Length < buffer.Length - 1 ? StringAsBytes.Length : buffer.Length - 1);
                buffer[buffer.Length - 1] = 0;
                return(mem.WriteMemory((uint)(Offset + Address), buffer.Length, ref buffer));
            }
            if (Count <= 0)
            {
                byte[] buffer = ReadWriteMemory.RawSerialize(NewValue);
                return(mem.WriteMemory((uint)(Offset + Address), buffer.Length, ref buffer));
            }
            else
            {
                Array  NewArray = (Array)NewValue;
                byte[] buffer   = new byte[Size];
                for (int i = 0; i < Count && i < NewArray.Length; i++)
                {
                    ReadWriteMemory.RawSerialize(NewArray.GetValue(i)).CopyTo(buffer, i * Size / Count);
                }
                return(mem.WriteMemory((uint)(Offset + Address), buffer.Length, ref buffer));
            }
        }
        public void WriteStructMember(ORNames Struct, ORNames Member, Object NewValue, ref byte[] Data)
        {
            int  Offset = GetStructMemberOffset(Struct, Member);
            int  Size   = GetStructMemberSize(Struct, Member);
            int  Count  = GetStructMemberCount(Struct, Member);
            Type type   = GetStructMemberType(Struct, Member);

            if (Count <= 0 && NewValue.GetType() != type)
            {
                throw new InvalidCastException("OffsetReader.WriteStructMember: NewValue is not of the expected type. NewValue type: " + NewValue.GetType().ToString() + " Expected type: " + type.ToString());
            }

            if (type == StringType)
            {
                int    Length        = Size;
                byte[] StringAsBytes = Encoding.UTF8.GetBytes((string)NewValue);
                int    CopyLength    = StringAsBytes.Length < Length - 1 ? StringAsBytes.Length : Length - 1;
                Array.Copy(StringAsBytes, 0, Data, Offset, CopyLength);
                Data[Offset + CopyLength] = 0;
                return;
            }
            if (Count <= 0)
            {
                byte[] buffer = ReadWriteMemory.RawSerialize(NewValue);
                buffer.CopyTo(Data, Offset);
                return;
            }
            else
            {
                Array  NewArray = (Array)NewValue;
                byte[] buffer   = new byte[Size];
                for (int i = 0; i < Count && i < NewArray.Length; i++)
                {
                    ReadWriteMemory.RawSerialize(NewArray.GetValue(i)).CopyTo(buffer, i * Size / Count);
                }
                buffer.CopyTo(Data, Offset);
                return;
            }
        }
 public int GetStructMemberOffset(ORNames Struct, ORNames Member)
 {
     return(_Structs[Struct].members[Member].offset);
 }
 public bool WriteArrayElementMember(ORNames Array, int Index, ORNames Member, Object NewValue)
 {
     return(WriteStructMember(GetArrayType(Array), Member, NewValue, GetArrayElementAddress(Array, Index)));
 }
 public Object ReadArrayElementMember(ORNames Array, int Index, ORNames Member)
 {
     return(ReadStructMember(GetArrayType(Array), Member, GetArrayElementAddress(Array, Index)));
 }
 public bool WriteArrayElement(ORNames Array, int Index, byte[] Data)
 {
     return(WriteStruct(GetArrayType(Array), Data, GetArrayElementAddress(Array, Index)));
 }
 public byte[] ReadArrayElement(ORNames Array, int Index)
 {
     return(ReadStruct(GetArrayType(Array), GetArrayElementAddress(Array, Index)));
 }
 public ORNames GetArrayType(ORNames Array)
 {
     return(_Arrays[Array].type);
 }
 public int GetStructStartOffset(ORNames Struct)
 {
     return(_Structs[Struct].startOffset);
 }
 public uint GetArrayElementMemberAddress(ORNames Array, int Index, ORNames Member)
 {
     return((uint)(GetArrayElementAddress(Array, Index) + GetStructMemberOffset(GetArrayType(Array), Member)));
 }
 public uint GetStructAddress(ORNames Struct)
 {
     return(_Structs[Struct].address);
 }
 public uint GetArrayAddress(ORNames Array)
 {
     return(_Arrays[Array].address);
 }
 public int GetArrayTotalSize(ORNames Array)
 {
     return(GetArrayCount(Array) * GetArrayElementSize(Array));
 }
 public int GetArrayCount(ORNames Array)
 {
     return(_Arrays[Array].size);
 }
 public Type GetStructMemberType(ORNames Struct, ORNames Member)
 {
     return(_Structs[Struct].members[Member].type);
 }
 public Type GetArrayElementMemberType(ORNames Array, ORNames Member)
 {
     return(GetStructMemberType(GetArrayType(Array), Member));
 }
 public int GetStructEndOffset(ORNames Struct)
 {
     return(_Structs[Struct].endOffset);
 }
 public int GetArrayElementMemberCount(ORNames Array, ORNames Member)
 {
     return(GetStructMemberCount(GetArrayType(Array), Member));
 }
 public uint GetArrayElementAddress(ORNames Array, int Index)
 {
     return((uint)(_Arrays[Array].address + Index * _Structs[GetArrayType(Array)].size));
 }
 public int GetStructMemberCount(ORNames Struct, ORNames Member)
 {
     return(_Structs[Struct].members[Member].count);
 }
 public int GetArrayElementSize(ORNames Array)
 {
     return(_Structs[GetArrayType(Array)].size);
 }
 public int GetStructSize(ORNames Struct)
 {
     return(_Structs[Struct].size);
 }