示例#1
0
        /**
         * We use reflection to calculate the field offsets since there's no public Machina DLL we could link
         * against. I want to avoid copying the relevant structures so reflection is the last option left.
         *
         * IMPORTANT: Remove the parsing code, once the parser parses the network packet and provides
         * an event or log line for it.
         */

        public static void Init()
        {
            try
            {
                var mach = Assembly.Load("Machina.FFXIV");
                MessageType = mach.GetType("Machina.FFXIV.Headers.Server_MessageType");

                var ActorControl142 = mach.GetType("Machina.FFXIV.Headers.Server_ActorControl142");
                ActorControl142_Size = Marshal.SizeOf(ActorControl142);

                var headerOffset = GetOffset(ActorControl142, "MessageHeader");
                var msgHeader    = ActorControl142.GetField("MessageHeader").FieldType;

                MessageType_Offset = headerOffset + GetOffset(msgHeader, "MessageType");
                ActorID_Offset     = headerOffset + GetOffset(msgHeader, "ActorID");

                Category_Offset = GetOffset(ActorControl142, "category");
                Param1_Offset   = GetOffset(ActorControl142, "param1");

                ActorControl142_Opcode = GetOpcode("ActorControl142");

#if DEBUG
                Registry.Resolve <ILogger>().Log(LogLevel.Debug, $"ActorControl142 = {ActorControl142_Opcode.ToString("x")}");
#endif

                FFXIVRepository.RegisterNetworkParser(Parse);
            } catch (Exception e)
            {
                Registry.Resolve <ILogger>().Log(LogLevel.Error, Resources.NetworkParserInitException, e);
            }
        }
示例#2
0
        public OverlayHider(TinyIoCContainer container)
        {
            this.config     = container.Resolve <IPluginConfig>();
            this.logger     = container.Resolve <ILogger>();
            this.main       = container.Resolve <PluginMain>();
            this.repository = container.Resolve <FFXIVRepository>();

            container.Resolve <NativeMethods>().ActiveWindowChanged   += ActiveWindowChangedHandler;
            container.Resolve <NetworkParser>().OnOnlineStatusChanged += OnlineStatusChanged;
            container.Resolve <EventSources.EnmityEventSource>().CombatStatusChanged += CombatStatusChanged;

            try
            {
                repository.RegisterProcessChangedHandler(UpdateFFXIVProcess);
            } catch (Exception ex)
            {
                logger.Log(LogLevel.Error, "Failed to register process watcher for FFXIV; this is only an issue if you're playing FFXIV. As a consequence, OverlayPlugin won't be able to hide overlays if you're not in-game.");
                logger.Log(LogLevel.Error, "Details: " + ex.ToString());
            }

            focusTimer          = new Timer();
            focusTimer.Tick    += (o, e) => ActiveWindowChangedHandler(this, IntPtr.Zero);
            focusTimer.Interval = 10000;  // 10 seconds
            focusTimer.Start();
        }
示例#3
0
        /**
         * We use reflection to calculate the field offsets since there's no public Machina DLL we could link
         * against. I want to avoid copying the relevant structures so reflection is the last option left.
         *
         * IMPORTANT: Remove the parsing code, once the parser parses the network packet and provides
         * an event or log line for it.
         */

        public static void Init()
        {
            try
            {
                var mach            = Assembly.Load("Machina.FFXIV");
                var ActorControl142 = mach.GetType("Machina.FFXIV.Headers.Server_ActorControl142");
                ActorControl142_Size = Marshal.SizeOf(ActorControl142);

                var headerOffset = GetOffset(ActorControl142, "MessageHeader");
                var msgHeader    = ActorControl142.GetField("MessageHeader").FieldType;

                MessageType_Offset = headerOffset + GetOffset(msgHeader, "MessageType");
                ActorID_Offset     = headerOffset + GetOffset(msgHeader, "ActorID");

                Category_Offset = GetOffset(ActorControl142, "category");
                Param1_Offset   = GetOffset(ActorControl142, "param1");

                ActorControl142_Type = (ushort)GetEnumValue(msgHeader.GetField("MessageType").FieldType, "ActorControl142");

                FFXIVRepository.RegisterNetworkParser(Parse);
            } catch (Exception e)
            {
                Registry.Resolve <ILogger>().Log(LogLevel.Error, Resources.NetworkParserInitException, e);
            }
        }
示例#4
0
        public OverlayZCorrector(TinyIoCContainer container)
        {
            main       = container.Resolve <PluginMain>();
            logger     = container.Resolve <ILogger>();
            repository = container.Resolve <FFXIVRepository>();

            var span = TimeSpan.FromSeconds(3);

            timer = new Timer(EnsureOverlaysAreOverGame, null, span, span);
        }
示例#5
0
        static void OnlineStatusChanged(object sender, OnlineStatusChangedArgs e)
        {
            if (!config.HideOverlayDuringCutscene || e.Target != FFXIVRepository.GetPlayerID())
            {
                return;
            }

            inCutscene = e.Status == 15;
            UpdateOverlays();
        }
示例#6
0
        public OverlayHider(TinyIoCContainer container)
        {
            this.config     = container.Resolve <IPluginConfig>();
            this.logger     = container.Resolve <ILogger>();
            this.main       = container.Resolve <PluginMain>();
            this.repository = container.Resolve <FFXIVRepository>();

            container.Resolve <NativeMethods>().ActiveWindowChanged   += ActiveWindowChangedHandler;
            container.Resolve <NetworkParser>().OnOnlineStatusChanged += OnlineStatusChanged;
        }
示例#7
0
        public OverlayHider(TinyIoCContainer container)
        {
            this.config     = container.Resolve <IPluginConfig>();
            this.logger     = container.Resolve <ILogger>();
            this.main       = container.Resolve <PluginMain>();
            this.repository = container.Resolve <FFXIVRepository>();

            container.Resolve <NativeMethods>().ActiveWindowChanged   += ActiveWindowChangedHandler;
            container.Resolve <NetworkParser>().OnOnlineStatusChanged += OnlineStatusChanged;
            repository.RegisterProcessChangedHandler(UpdateFFXIVProcess);

            focusTimer          = new Timer();
            focusTimer.Tick    += (o, e) => ActiveWindowChangedHandler(this, IntPtr.Zero);
            focusTimer.Interval = 10000;  // 10 seconds
            focusTimer.Start();
        }
示例#8
0
            protected override void OnOpen()
            {
                base.OnOpen();

                EventDispatcher.Subscribe("CombatData", this);
                EventDispatcher.Subscribe("LogLine", this);
                EventDispatcher.Subscribe("ChangeZone", this);
                EventDispatcher.Subscribe("ChangePrimaryPlayer", this);

                Send(JsonConvert.SerializeObject(new
                {
                    type    = "broadcast",
                    msgtype = "SendCharName",
                    msg     = new
                    {
                        charName = FFXIVRepository.GetPlayerName() ?? "YOU",
                        charID   = FFXIVRepository.GetPlayerID()
                    }
                }));
            }
示例#9
0
        private static void EnsureOverlaysAreOverGame(object _)
        {
            var watch = new Stopwatch();

            watch.Start();

            var xivProc = FFXIVRepository.GetCurrentFFXIVProcess();

            if (xivProc == null || xivProc.HasExited)
            {
                return;
            }

            var xivHandle      = xivProc.MainWindowHandle;
            var overlayWindows = new List <IntPtr>();

            var handle = xivHandle;

            while (handle != IntPtr.Zero)
            {
                handle = NativeMethods.GetWindow(handle, NativeMethods.GW_HWNDPREV);
                overlayWindows.Add(handle);
            }

            foreach (var overlay in main.Overlays)
            {
                if (!overlayWindows.Contains(overlay.Handle))
                {
                    // The overlay is behind the game. Let's fix that.
                    NativeMethods.SetWindowPos(
                        overlay.Handle,
                        NativeMethods.HWND_TOPMOST,
                        0, 0, 0, 0,
                        NativeMethods.SWP_NOSIZE | NativeMethods.SWP_NOMOVE | NativeMethods.SWP_NOACTIVATE);

                    logger.Log(LogLevel.Info, $"ZReorder: Fixed {overlay.Name}.");
                }
            }

            // logger.Log(LogLevel.Debug, $"ZReorder: Took {watch.Elapsed.TotalSeconds}s.");
        }
示例#10
0
            public LegacyHandler(TinyIoCContainer container, IWebSocketConnection conn, WSServer server) : base()
            {
                _logger     = container.Resolve <ILogger>();
                _dispatcher = container.Resolve <EventDispatcher>();
                _repository = container.Resolve <FFXIVRepository>();
                _conn       = conn;

                conn.OnOpen    = OnOpen;
                conn.OnMessage = OnMessage;
                conn.OnClose   = () =>
                {
                    try
                    {
                        _dispatcher.UnsubscribeAll(this);
                        server._connections.Remove(this);
                    }
                    catch (Exception ex)
                    {
                        _logger.Log(LogLevel.Error, $"Failed to unsubscribe WebSocket connection: {ex}");
                    }
                };
            }
示例#11
0
            public LegacyHandler(TinyIoCContainer container, IWebSocketConnection conn, WSServer server) : base()
            {
                _logger     = container.Resolve <ILogger>();
                _dispatcher = container.Resolve <EventDispatcher>();
                _repository = container.Resolve <FFXIVRepository>();
                _conn       = conn;

                var open = true;

                conn.OnOpen    = OnOpen;
                conn.OnMessage = OnMessage;
                conn.OnClose   = () =>
                {
                    if (!open)
                    {
                        return;
                    }
                    open = false;

                    try
                    {
                        _dispatcher.UnsubscribeAll(this);
                        server._connections.Remove(this);
                    }
                    catch (Exception ex)
                    {
                        _logger.Log(LogLevel.Error, $"Failed to unsubscribe WebSocket connection: {ex}");
                    }
                };
                conn.OnError = (ex) =>
                {
                    // Fleck will close the connection; make sure we always clean up even if Fleck doesn't call OnClose().
                    conn.OnClose();

                    _logger.Log(LogLevel.Info, $"WebSocket connection was closed with error: {ex}");
                };
            }
示例#12
0
        /// <summary>
        /// コンフィグのオーバーレイ設定を基に、オーバーレイを初期化・登録します。
        /// </summary>
        private void InitializeOverlays()
        {
            Registry.Register(new KeyboardHook());

            // オーバーレイ初期化
            this.Overlays = new List <IOverlay>();
            foreach (var overlayConfig in this.Config.Overlays)
            {
                var parameters = new NamedParameterOverloads();
                parameters["config"] = overlayConfig;
                parameters["name"]   = overlayConfig.Name;

                var overlay = (IOverlay)Registry.Container.Resolve(overlayConfig.OverlayType, parameters);
                if (overlay != null)
                {
                    RegisterOverlay(overlay);
                }
                else
                {
                    Logger.Log(LogLevel.Error, "InitPlugin: Could not find addon for {0}.", overlayConfig.Name);
                }
            }

            var gameActive = true;
            var inCutscene = false;

            NativeMethods.ActiveWindowChanged += (sender, hWndFg) =>
            {
                if (!Config.HideOverlaysWhenNotActive || hWndFg == IntPtr.Zero)
                {
                    return;
                }
                try
                {
                    try
                    {
                        NativeMethods.GetWindowThreadProcessId(hWndFg, out uint pid);

                        if (pid == 0)
                        {
                            return;
                        }

                        var exePath  = Process.GetProcessById((int)pid).MainModule.FileName;
                        var fileName = Path.GetFileName(exePath.ToString());
                        gameActive = (fileName == "ffxiv.exe" || fileName == "ffxiv_dx11.exe" ||
                                      exePath.ToString() == Process.GetCurrentProcess().MainModule.FileName);
                    }
                    catch (System.ComponentModel.Win32Exception ex)
                    {
                        // Ignore access denied errors. Those usually happen if the foreground window is running with
                        // admin permissions but we are not.
                        if (ex.ErrorCode == -2147467259)  // 0x80004005
                        {
                            gameActive = false;
                        }
                        else
                        {
                            Logger.Log(LogLevel.Error, "XivWindowWatcher: {0}", ex.ToString());
                        }
                    }

                    foreach (var overlay in this.Overlays)
                    {
                        if (overlay.Config.IsVisible)
                        {
                            overlay.Visible = gameActive && !inCutscene;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logger.Log(LogLevel.Error, "XivWindowWatcher: {0}", ex.ToString());
                }
            };

            NetworkParser.OnOnlineStatusChanged += (o, e) =>
            {
                if (!Config.HideOverlayDuringCutscene || e.Target != FFXIVRepository.GetPlayerID())
                {
                    return;
                }

                inCutscene = e.Status == 15;
                foreach (var overlay in Overlays)
                {
                    if (overlay.Config.IsVisible)
                    {
                        overlay.Visible = gameActive && !inCutscene;
                    }
                }
            };
        }
示例#13
0
 public LegacyHandler(TinyIoCContainer container) : base()
 {
     _logger     = container.Resolve <ILogger>();
     _dispatcher = container.Resolve <EventDispatcher>();
     _repository = container.Resolve <FFXIVRepository>();
 }