예제 #1
0
        public void Initialize()
        {
            _startupPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

            _getUOFilePath   = GetUOFilePath;
            _getPacketLength = GetPacketLength;
            _sendPacket      = SendPacket;
            _receivePacket   = ReceivePacket;
            _requestMove     = (dir, run) => true;
            _setTitle        = SetTitle;

            _pluginHeader = new PluginHeader
            {
                GetPacketLength = Marshal.GetFunctionPointerForDelegate(_getPacketLength),
                GetUOFilePath   = Marshal.GetFunctionPointerForDelegate(_getUOFilePath),
                Recv            = Marshal.GetFunctionPointerForDelegate(_receivePacket),
                Send            = Marshal.GetFunctionPointerForDelegate(_sendPacket),
                RequestMove     = Marshal.GetFunctionPointerForDelegate(_requestMove),
                SetTitle        = Marshal.GetFunctionPointerForDelegate(_setTitle)
            };

            Engine.StartupPath = _startupPath;

            _packetLengths = new int[byte.MaxValue];

            string json = File.ReadAllText(Path.Combine(_startupPath ?? throw new InvalidOperationException(),
                                                        "packetlengths.json"));

            JObject jsonObj = JObject.Parse(json);

            foreach (JProperty token in jsonObj["PacketLengths"].Children <JProperty>())
            {
                int key = int.Parse(token.Name);
                int val = token.Value.ToObject <int>();

                if (val == 0x8000)
                {
                    val = 0;
                }

                _packetLengths[key] = val;
            }
        }
예제 #2
0
        public void Load()
        {
            _recv              = OnPluginRecv;
            _send              = OnPluginSend;
            _recv_new          = OnPluginRecv_new;
            _send_new          = OnPluginSend_new;
            _getPacketLength   = PacketsTable.GetPacketLength;
            _getPlayerPosition = GetPlayerPosition;
            _castSpell         = GameActions.CastSpell;
            _getStaticImage    = GetStaticImage;
            _getUoFilePath     = GetUOFilePath;
            _requestMove       = RequestMove;
            _setTitle          = SetWindowTitle;

            SDL.SDL_SysWMinfo info = new SDL.SDL_SysWMinfo();
            SDL.SDL_VERSION(out info.version);
            SDL.SDL_GetWindowWMInfo(SDL.SDL_GL_GetCurrentWindow(), ref info);

            IntPtr hwnd = IntPtr.Zero;

            if (info.subsystem == SDL.SDL_SYSWM_TYPE.SDL_SYSWM_WINDOWS)
            {
                hwnd = info.info.win.window;
            }

            PluginHeader header = new PluginHeader
            {
                ClientVersion     = (int)Client.Version,
                Recv              = Marshal.GetFunctionPointerForDelegate(_recv),
                Send              = Marshal.GetFunctionPointerForDelegate(_send),
                GetPacketLength   = Marshal.GetFunctionPointerForDelegate(_getPacketLength),
                GetPlayerPosition = Marshal.GetFunctionPointerForDelegate(_getPlayerPosition),
                CastSpell         = Marshal.GetFunctionPointerForDelegate(_castSpell),
                GetStaticImage    = Marshal.GetFunctionPointerForDelegate(_getStaticImage),
                HWND              = hwnd,
                GetUOFilePath     = Marshal.GetFunctionPointerForDelegate(_getUoFilePath),
                RequestMove       = Marshal.GetFunctionPointerForDelegate(_requestMove),
                SetTitle          = Marshal.GetFunctionPointerForDelegate(_setTitle),
                Recv_new          = Marshal.GetFunctionPointerForDelegate(_recv_new),
                Send_new          = Marshal.GetFunctionPointerForDelegate(_send_new),

                SDL_Window = Client.Game.Window.Handle
            };

            void *func = &header;

            if (Environment.OSVersion.Platform != PlatformID.Unix && Environment.OSVersion.Platform != PlatformID.MacOSX)
            {
                UnblockPath(Path.GetDirectoryName(_path));
            }

            try
            {
                IntPtr assptr = Native.LoadLibrary(_path);

                Log.Trace($"assembly: {assptr}");

                if (assptr == IntPtr.Zero)
                {
                    throw new Exception("Invalid Assembly, Attempting managed load.");
                }

                Log.Trace($"Searching for 'Install' entry point  -  {assptr}");

                IntPtr installPtr = Native.GetProcessAddress(assptr, "Install");

                Log.Trace($"Entry point: {installPtr}");

                if (installPtr == IntPtr.Zero)
                {
                    throw new Exception("Invalid Entry Point, Attempting managed load.");
                }

                Marshal.GetDelegateForFunctionPointer <OnInstall>(installPtr)(func);

                Console.WriteLine(">>> ADDRESS {0}", header.OnInitialize);
            }
            catch
            {
                try
                {
                    var asm  = Assembly.LoadFile(_path);
                    var type = asm.GetType("Assistant.Engine");

                    if (type == null)
                    {
                        Log.Error(
                            "Unable to find Plugin Type, API requires the public class Engine in namespace Assistant.");

                        return;
                    }

                    var meth = type.GetMethod("Install", BindingFlags.Public | BindingFlags.Static);

                    if (meth == null)
                    {
                        Log.Error("Engine class missing public static Install method Needs 'public static unsafe void Install(PluginHeader *plugin)' ");

                        return;
                    }

                    meth.Invoke(null, new object[] { (IntPtr)func });
                }
                catch (Exception err)
                {
                    Log.Error(
                        $"Plugin threw an error during Initialization. {err.Message} {err.StackTrace} {err.InnerException?.Message} {err.InnerException?.StackTrace}");

                    return;
                }
            }


            if (header.OnRecv != IntPtr.Zero)
            {
                _onRecv = Marshal.GetDelegateForFunctionPointer <OnPacketSendRecv>(header.OnRecv);
            }

            if (header.OnSend != IntPtr.Zero)
            {
                _onSend = Marshal.GetDelegateForFunctionPointer <OnPacketSendRecv>(header.OnSend);
            }

            if (header.OnHotkeyPressed != IntPtr.Zero)
            {
                _onHotkeyPressed = Marshal.GetDelegateForFunctionPointer <OnHotkey>(header.OnHotkeyPressed);
            }

            if (header.OnMouse != IntPtr.Zero)
            {
                _onMouse = Marshal.GetDelegateForFunctionPointer <OnMouse>(header.OnMouse);
            }

            if (header.OnPlayerPositionChanged != IntPtr.Zero)
            {
                _onUpdatePlayerPosition = Marshal.GetDelegateForFunctionPointer <OnUpdatePlayerPosition>(header.OnPlayerPositionChanged);
            }

            if (header.OnClientClosing != IntPtr.Zero)
            {
                _onClientClose = Marshal.GetDelegateForFunctionPointer <OnClientClose>(header.OnClientClosing);
            }

            if (header.OnInitialize != IntPtr.Zero)
            {
                _onInitialize = Marshal.GetDelegateForFunctionPointer <OnInitialize>(header.OnInitialize);
            }

            if (header.OnConnected != IntPtr.Zero)
            {
                _onConnected = Marshal.GetDelegateForFunctionPointer <OnConnected>(header.OnConnected);
            }

            if (header.OnDisconnected != IntPtr.Zero)
            {
                _onDisconnected = Marshal.GetDelegateForFunctionPointer <OnDisconnected>(header.OnDisconnected);
            }

            if (header.OnFocusGained != IntPtr.Zero)
            {
                _onFocusGained = Marshal.GetDelegateForFunctionPointer <OnFocusGained>(header.OnFocusGained);
            }

            if (header.OnFocusLost != IntPtr.Zero)
            {
                _onFocusLost = Marshal.GetDelegateForFunctionPointer <OnFocusLost>(header.OnFocusLost);
            }

            if (header.Tick != IntPtr.Zero)
            {
                _tick = Marshal.GetDelegateForFunctionPointer <OnTick>(header.Tick);
            }


            if (header.OnRecv_new != IntPtr.Zero)
            {
                _onRecv_new = Marshal.GetDelegateForFunctionPointer <OnPacketSendRecv_new>(header.OnRecv_new);
            }
            if (header.OnSend_new != IntPtr.Zero)
            {
                _onSend_new = Marshal.GetDelegateForFunctionPointer <OnPacketSendRecv_new>(header.OnSend_new);
            }

            if (header.OnDrawCmdList != IntPtr.Zero)
            {
                _draw_cmd_list = Marshal.GetDelegateForFunctionPointer <OnDrawCmdList>(header.OnDrawCmdList);
            }
            if (header.OnWndProc != IntPtr.Zero)
            {
                _on_wnd_proc = Marshal.GetDelegateForFunctionPointer <OnWndProc>(header.OnWndProc);
            }


            IsValid = true;

            _onInitialize?.Invoke();
        }
예제 #3
0
        public void Load()
        {
            _recv              = OnPluginRecv;
            _send              = OnPluginSend;
            _getPacketLength   = PacketsTable.GetPacketLength;
            _getPlayerPosition = GetPlayerPosition;
            _castSpell         = GameActions.CastSpell;
            _getStaticImage    = GetStaticImage;
            _getUoFilePath     = GetUOFilePath;

            IntPtr assptr = SDL2EX.SDL_LoadObject(_path);

            Log.Message(LogTypes.Trace, $"assembly: {assptr}");

            if (assptr == IntPtr.Zero)
            {
                Log.Message(LogTypes.Error, "Invalid assemlby.");
                return;
            }

            Log.Message(LogTypes.Trace, $"Searching for 'Install' entry point  -  {assptr}");

            IntPtr installPtr = SDL2EX.SDL_LoadFunction(assptr, "Install");

            Log.Message(LogTypes.Trace, $"Entry point: {installPtr}");

            if (installPtr == IntPtr.Zero)
            {
                Log.Message(LogTypes.Error, "Invalid entry point.");
                return;
            }


            //IntPtr headerPtr = Marshal.AllocHGlobal(4 + 8 * 18); // 256 ?
            //Marshal.WriteInt32(headerPtr, (int)FileManager.ClientVersion);
            //Marshal.WriteIntPtr(headerPtr, Marshal.GetFunctionPointerForDelegate(_recv));
            //Marshal.WriteIntPtr(headerPtr, Marshal.GetFunctionPointerForDelegate(_send));
            //Marshal.WriteIntPtr(headerPtr, Marshal.GetFunctionPointerForDelegate(_getPacketLength));
            //Marshal.WriteIntPtr(headerPtr, Marshal.GetFunctionPointerForDelegate(_getPlayerPosition));
            //Marshal.WriteIntPtr(headerPtr, Marshal.GetFunctionPointerForDelegate(_castSpell));
            //Marshal.WriteIntPtr(headerPtr, Marshal.GetFunctionPointerForDelegate(_getStaticImage));
            //Marshal.WriteIntPtr(headerPtr, SDL.SDL_GL_GetCurrentWindow());
            //Marshal.WriteIntPtr(headerPtr, Marshal.GetFunctionPointerForDelegate(_getUoFilePath));

            SDL.SDL_SysWMinfo info = new SDL.SDL_SysWMinfo();
            SDL.SDL_VERSION(out info.version);
            SDL.SDL_GetWindowWMInfo(SDL.SDL_GL_GetCurrentWindow(), ref info);

            IntPtr hwnd = IntPtr.Zero;

            if (info.subsystem == SDL.SDL_SYSWM_TYPE.SDL_SYSWM_WINDOWS)
            {
                hwnd = info.info.win.window;
            }

            PluginHeader header = new PluginHeader
            {
                ClientVersion     = (int)FileManager.ClientVersion,
                Recv              = Marshal.GetFunctionPointerForDelegate(_recv),
                Send              = Marshal.GetFunctionPointerForDelegate(_send),
                GetPacketLength   = Marshal.GetFunctionPointerForDelegate(_getPacketLength),
                GetPlayerPosition = Marshal.GetFunctionPointerForDelegate(_getPlayerPosition),
                CastSpell         = Marshal.GetFunctionPointerForDelegate(_castSpell),
                GetStaticImage    = Marshal.GetFunctionPointerForDelegate(_getStaticImage),
                HWND              = hwnd,
                GetUOFilePath     = Marshal.GetFunctionPointerForDelegate(_getUoFilePath)
            };

            void *func = &header;

            Marshal.GetDelegateForFunctionPointer <OnInstall>(installPtr)(ref func);

            if (header.OnRecv != IntPtr.Zero)
            {
                _onRecv = Marshal.GetDelegateForFunctionPointer <OnPacketSendRecv>(header.OnRecv);
            }
            if (header.OnSend != IntPtr.Zero)
            {
                _onSend = Marshal.GetDelegateForFunctionPointer <OnPacketSendRecv>(header.OnSend);
            }
            if (header.OnHotkeyPressed != IntPtr.Zero)
            {
                _onHotkeyPressed = Marshal.GetDelegateForFunctionPointer <OnHotkey>(header.OnHotkeyPressed);
            }
            if (header.OnMouse != IntPtr.Zero)
            {
                _onMouse = Marshal.GetDelegateForFunctionPointer <OnMouse>(header.OnMouse);
            }
            if (header.OnPlayerPositionChanged != IntPtr.Zero)
            {
                _onUpdatePlayerPosition = Marshal.GetDelegateForFunctionPointer <OnUpdatePlayerPosition>(header.OnPlayerPositionChanged);
            }
            if (header.OnClientClosing != IntPtr.Zero)
            {
                _onClientClose = Marshal.GetDelegateForFunctionPointer <OnClientClose>(header.OnClientClosing);
            }
            if (header.OnInitialize != IntPtr.Zero)
            {
                _onInitialize = Marshal.GetDelegateForFunctionPointer <OnInitialize>(header.OnInitialize);
            }
            if (header.OnConnected != IntPtr.Zero)
            {
                _onConnected = Marshal.GetDelegateForFunctionPointer <OnConnected>(header.OnConnected);
            }
            if (header.OnDisconnected != IntPtr.Zero)
            {
                _onDisconnected = Marshal.GetDelegateForFunctionPointer <OnDisconnected>(header.OnDisconnected);
            }
            if (header.OnFocusGained != IntPtr.Zero)
            {
                _onFocusGained = Marshal.GetDelegateForFunctionPointer <OnFocusGained>(header.OnFocusGained);
            }
            if (header.OnFocusLost != IntPtr.Zero)
            {
                _onFocusLost = Marshal.GetDelegateForFunctionPointer <OnFocusLost>(header.OnFocusLost);
            }

            IsValid = true;

            //Marshal.FreeHGlobal(headerPtr);

            _onInitialize?.Invoke();
        }
예제 #4
0
        public void Load()
        {
            _recv              = OnPluginRecv;
            _send              = OnPluginSend;
            _getPacketLength   = PacketsTable.GetPacketLength;
            _getPlayerPosition = GetPlayerPosition;
            _castSpell         = GameActions.CastSpell;
            _getStaticImage    = GetStaticImage;
            _getUoFilePath     = GetUOFilePath;
            _requestMove       = RequestMove;
            _setTitle          = SetWindowTitle;

            //IntPtr headerPtr = Marshal.AllocHGlobal(4 + 8 * 18); // 256 ?
            //Marshal.WriteInt32(headerPtr, (int)FileManager.ClientVersion);
            //Marshal.WriteIntPtr(headerPtr, Marshal.GetFunctionPointerForDelegate(_recv));
            //Marshal.WriteIntPtr(headerPtr, Marshal.GetFunctionPointerForDelegate(_send));
            //Marshal.WriteIntPtr(headerPtr, Marshal.GetFunctionPointerForDelegate(_getPacketLength));
            //Marshal.WriteIntPtr(headerPtr, Marshal.GetFunctionPointerForDelegate(_getPlayerPosition));
            //Marshal.WriteIntPtr(headerPtr, Marshal.GetFunctionPointerForDelegate(_castSpell));
            //Marshal.WriteIntPtr(headerPtr, Marshal.GetFunctionPointerForDelegate(_getStaticImage));
            //Marshal.WriteIntPtr(headerPtr, SDL.SDL_GL_GetCurrentWindow());
            //Marshal.WriteIntPtr(headerPtr, Marshal.GetFunctionPointerForDelegate(_getUoFilePath));

            SDL.SDL_SysWMinfo info = new SDL.SDL_SysWMinfo();
            SDL.SDL_VERSION(out info.version);
            SDL.SDL_GetWindowWMInfo(SDL.SDL_GL_GetCurrentWindow(), ref info);

            IntPtr hwnd = IntPtr.Zero;

            if (info.subsystem == SDL.SDL_SYSWM_TYPE.SDL_SYSWM_WINDOWS)
            {
                hwnd = info.info.win.window;
            }

            PluginHeader header = new PluginHeader
            {
                ClientVersion     = (int)FileManager.ClientVersion,
                Recv              = Marshal.GetFunctionPointerForDelegate(_recv),
                Send              = Marshal.GetFunctionPointerForDelegate(_send),
                GetPacketLength   = Marshal.GetFunctionPointerForDelegate(_getPacketLength),
                GetPlayerPosition = Marshal.GetFunctionPointerForDelegate(_getPlayerPosition),
                CastSpell         = Marshal.GetFunctionPointerForDelegate(_castSpell),
                GetStaticImage    = Marshal.GetFunctionPointerForDelegate(_getStaticImage),
                HWND              = hwnd,
                GetUOFilePath     = Marshal.GetFunctionPointerForDelegate(_getUoFilePath),
                RequestMove       = Marshal.GetFunctionPointerForDelegate(_requestMove),
                SetTitle          = Marshal.GetFunctionPointerForDelegate(_setTitle)
            };

            void *func = &header;

            try
            {
                IntPtr assptr = SDL2EX.SDL_LoadObject(_path);

                Log.Message(LogTypes.Trace, $"assembly: {assptr}");

                if (assptr == IntPtr.Zero)
                {
                    throw new Exception("Invalid Assembly, Attempting managed load.");
                }

                Log.Message(LogTypes.Trace, $"Searching for 'Install' entry point  -  {assptr}");

                IntPtr installPtr = SDL2EX.SDL_LoadFunction(assptr, "Install");

                Log.Message(LogTypes.Trace, $"Entry point: {installPtr}");

                if (installPtr == IntPtr.Zero)
                {
                    throw new Exception("Invalid Entry Point, Attempting managed load.");
                }
                Marshal.GetDelegateForFunctionPointer <OnInstall>(installPtr)(ref func);
            }
            catch
            {
                try
                {
                    var asm  = Assembly.LoadFile(_path);
                    var type = asm.GetType("Assistant.Engine");

                    if (type == null)
                    {
                        Log.Message(LogTypes.Error,
                                    $"Unable to find Plugin Type, API requires the public class Engine in namespace Assistant.");
                        return;
                    }

                    var meth = type.GetMethod("Install", BindingFlags.Public | BindingFlags.Static);
                    if (meth == null)
                    {
                        Log.Message(LogTypes.Error, $"Engine class missing public static Install method Needs 'public static unsafe void Install(PluginHeader *plugin)' ");
                        return;
                    }

                    meth.Invoke(null, new object[] { (IntPtr)func });
                }
                catch (Exception err)
                {
                    Log.Message(LogTypes.Error,
                                $"Invalid plugin specified. {err} {err.StackTrace}");
                    return;
                }
            }


            if (header.OnRecv != IntPtr.Zero)
            {
                _onRecv = Marshal.GetDelegateForFunctionPointer <OnPacketSendRecv>(header.OnRecv);
            }
            if (header.OnSend != IntPtr.Zero)
            {
                _onSend = Marshal.GetDelegateForFunctionPointer <OnPacketSendRecv>(header.OnSend);
            }
            if (header.OnHotkeyPressed != IntPtr.Zero)
            {
                _onHotkeyPressed = Marshal.GetDelegateForFunctionPointer <OnHotkey>(header.OnHotkeyPressed);
            }
            if (header.OnMouse != IntPtr.Zero)
            {
                _onMouse = Marshal.GetDelegateForFunctionPointer <OnMouse>(header.OnMouse);
            }
            if (header.OnPlayerPositionChanged != IntPtr.Zero)
            {
                _onUpdatePlayerPosition = Marshal.GetDelegateForFunctionPointer <OnUpdatePlayerPosition>(header.OnPlayerPositionChanged);
            }
            if (header.OnClientClosing != IntPtr.Zero)
            {
                _onClientClose = Marshal.GetDelegateForFunctionPointer <OnClientClose>(header.OnClientClosing);
            }
            if (header.OnInitialize != IntPtr.Zero)
            {
                _onInitialize = Marshal.GetDelegateForFunctionPointer <OnInitialize>(header.OnInitialize);
            }
            if (header.OnConnected != IntPtr.Zero)
            {
                _onConnected = Marshal.GetDelegateForFunctionPointer <OnConnected>(header.OnConnected);
            }
            if (header.OnDisconnected != IntPtr.Zero)
            {
                _onDisconnected = Marshal.GetDelegateForFunctionPointer <OnDisconnected>(header.OnDisconnected);
            }
            if (header.OnFocusGained != IntPtr.Zero)
            {
                _onFocusGained = Marshal.GetDelegateForFunctionPointer <OnFocusGained>(header.OnFocusGained);
            }
            if (header.OnFocusLost != IntPtr.Zero)
            {
                _onFocusLost = Marshal.GetDelegateForFunctionPointer <OnFocusLost>(header.OnFocusLost);
            }
            if (header.Tick != IntPtr.Zero)
            {
                _tick = Marshal.GetDelegateForFunctionPointer <OnTick>(header.Tick);
            }
            IsValid = true;

            //Marshal.FreeHGlobal(headerPtr);

            _onInitialize?.Invoke();
        }
예제 #5
0
        public override void ReadData(ESPReader reader, long dataEnd)
        {
            while (reader.BaseStream.Position < dataEnd)
            {
                string subTag = reader.PeekTag();

                switch (subTag)
                {
                case "HEDR":
                    if (FileHeader == null)
                    {
                        FileHeader = new PluginHeader();
                    }

                    FileHeader.ReadBinary(reader);
                    break;

                case "OFST":
                    if (OffsetData == null)
                    {
                        OffsetData = new SimpleSubrecord <Byte[]>();
                    }

                    OffsetData.ReadBinary(reader);
                    break;

                case "DELE":
                    if (DeletionsData == null)
                    {
                        DeletionsData = new SimpleSubrecord <Byte[]>();
                    }

                    DeletionsData.ReadBinary(reader);
                    break;

                case "CNAM":
                    if (Author == null)
                    {
                        Author = new SimpleSubrecord <String>();
                    }

                    Author.ReadBinary(reader);
                    break;

                case "SNAM":
                    if (Description == null)
                    {
                        Description = new SimpleSubrecord <String>();
                    }

                    Description.ReadBinary(reader);
                    break;

                case "MAST":
                    if (MasterFiles == null)
                    {
                        MasterFiles = new List <MasterFileData>();
                    }

                    MasterFileData tempMAST = new MasterFileData();
                    tempMAST.ReadBinary(reader);
                    MasterFiles.Add(tempMAST);
                    break;

                case "ONAM":
                    if (OverriddenRecords == null)
                    {
                        OverriddenRecords = new FormArray();
                    }

                    OverriddenRecords.ReadBinary(reader);
                    break;

                case "SCRN":
                    if (ScreenshotData == null)
                    {
                        ScreenshotData = new SimpleSubrecord <Byte[]>();
                    }

                    ScreenshotData.ReadBinary(reader);
                    break;

                default:
                    throw new Exception();
                }
            }
        }
예제 #6
0
 public Header(PluginHeader FileHeader, SimpleSubrecord <Byte[]> OffsetData, SimpleSubrecord <Byte[]> DeletionsData, SimpleSubrecord <String> Author, SimpleSubrecord <String> Description, List <MasterFileData> MasterFiles, FormArray OverriddenRecords, SimpleSubrecord <Byte[]> ScreenshotData)
 {
     this.FileHeader = FileHeader;
     this.Author     = Author;
 }
예제 #7
0
 public Header()
 {
     FileHeader = new PluginHeader("HEDR");
     Author     = new SimpleSubrecord <String>("CNAM");
 }
예제 #8
0
        public override void ReadDataXML(XElement ele, ElderScrollsPlugin master)
        {
            XElement subEle;

            if (ele.TryPathTo("FileHeader", false, out subEle))
            {
                if (FileHeader == null)
                {
                    FileHeader = new PluginHeader();
                }

                FileHeader.ReadXML(subEle, master);
            }
            if (ele.TryPathTo("OffsetData", false, out subEle))
            {
                if (OffsetData == null)
                {
                    OffsetData = new SimpleSubrecord <Byte[]>();
                }

                OffsetData.ReadXML(subEle, master);
            }
            if (ele.TryPathTo("DeletionsData", false, out subEle))
            {
                if (DeletionsData == null)
                {
                    DeletionsData = new SimpleSubrecord <Byte[]>();
                }

                DeletionsData.ReadXML(subEle, master);
            }
            if (ele.TryPathTo("Author", false, out subEle))
            {
                if (Author == null)
                {
                    Author = new SimpleSubrecord <String>();
                }

                Author.ReadXML(subEle, master);
            }
            if (ele.TryPathTo("Description", false, out subEle))
            {
                if (Description == null)
                {
                    Description = new SimpleSubrecord <String>();
                }

                Description.ReadXML(subEle, master);
            }
            if (ele.TryPathTo("MasterFiles", false, out subEle))
            {
                if (MasterFiles == null)
                {
                    MasterFiles = new List <MasterFileData>();
                }

                foreach (XElement e in subEle.Elements())
                {
                    MasterFileData tempMAST = new MasterFileData();
                    tempMAST.ReadXML(e, master);
                    MasterFiles.Add(tempMAST);
                }
            }
            if (ele.TryPathTo("OverriddenRecords", false, out subEle))
            {
                if (OverriddenRecords == null)
                {
                    OverriddenRecords = new FormArray();
                }

                OverriddenRecords.ReadXML(subEle, master);
            }
            if (ele.TryPathTo("ScreenshotData", false, out subEle))
            {
                if (ScreenshotData == null)
                {
                    ScreenshotData = new SimpleSubrecord <Byte[]>();
                }

                ScreenshotData.ReadXML(subEle, master);
            }
        }