From 8d22fcf20dc958e188b4ba858e9a5a61aee89a86 Mon Sep 17 00:00:00 2001 From: Piotrekol <4990365+Piotrekol@users.noreply.github.com> Date: Mon, 5 Sep 2022 20:58:47 +0200 Subject: [PATCH] Misc: Share injection methods between Text & Browser overlays --- osu!StreamCompanion.sln | 11 + .../BrowserIngameOverlay.csproj | 12 +- .../BrowserOverlay/BrowserOverlay.cs | 27 +- .../BrowserOverlay/Loader/DllInjector.cs | 203 -------------- .../BrowserOverlay/Loader/InjectionResult.cs | 20 -- .../Loader/ProcessExtensions.cs | 74 ----- .../BrowserOverlay/Loader/X64DllInjector.cs | 12 - .../Dlls/X32ProcessOverlayHelper.exe | Bin .../Loader/DllInjectionResult.cs | 2 +- .../Loader/DllInjector.cs | 16 +- .../Loader/InjectionResult.cs | 4 +- .../Loader/KnownOsuModules.cs | 2 +- .../Loader/Loader.cs | 5 +- .../Loader/LoaderWatchdog.cs | 31 +-- .../Loader/ProcessExtensions.cs | 4 +- .../Overlay.Common/Overlay.Common.csproj | 22 ++ .../Overlay.Common/OverlayReport.cs | 14 + .../Overlay.Common/ReportType.cs | 8 + .../Dlls/X32ProcessOverlayHelper.exe | Bin 13824 -> 0 bytes .../Dlls/{osuOverlay.dll => textOverlay.dll} | Bin .../TextOverlay/IngameOverlay.cs | 258 ------------------ .../TextOverlay/Loader/DllInjectionResult.cs | 13 - .../TextOverlay/Loader/Loader.cs | 68 ----- .../TextOverlay/TextIngameOverlay.csproj | 28 +- .../IngameOverlays/TextOverlay/TextOverlay.cs | 107 ++++++++ ...ner.cs => TextOverlaySettings.Designer.cs} | 4 +- ...rlaySettings.cs => TextOverlaySettings.cs} | 10 +- ...Settings.resx => TextOverlaySettings.resx} | 0 28 files changed, 233 insertions(+), 722 deletions(-) delete mode 100644 plugins/IngameOverlays/BrowserOverlay/Loader/DllInjector.cs delete mode 100644 plugins/IngameOverlays/BrowserOverlay/Loader/InjectionResult.cs delete mode 100644 plugins/IngameOverlays/BrowserOverlay/Loader/ProcessExtensions.cs delete mode 100644 plugins/IngameOverlays/BrowserOverlay/Loader/X64DllInjector.cs rename plugins/IngameOverlays/{BrowserOverlay => Overlay.Common}/Dlls/X32ProcessOverlayHelper.exe (100%) rename plugins/IngameOverlays/{BrowserOverlay => Overlay.Common}/Loader/DllInjectionResult.cs (87%) rename plugins/IngameOverlays/{TextOverlay => Overlay.Common}/Loader/DllInjector.cs (93%) rename plugins/IngameOverlays/{TextOverlay => Overlay.Common}/Loader/InjectionResult.cs (88%) rename plugins/IngameOverlays/{BrowserOverlay => Overlay.Common}/Loader/KnownOsuModules.cs (99%) rename plugins/IngameOverlays/{BrowserOverlay => Overlay.Common}/Loader/Loader.cs (95%) rename plugins/IngameOverlays/{BrowserOverlay => Overlay.Common}/Loader/LoaderWatchdog.cs (81%) rename plugins/IngameOverlays/{TextOverlay => Overlay.Common}/Loader/ProcessExtensions.cs (96%) create mode 100644 plugins/IngameOverlays/Overlay.Common/Overlay.Common.csproj create mode 100644 plugins/IngameOverlays/Overlay.Common/OverlayReport.cs create mode 100644 plugins/IngameOverlays/Overlay.Common/ReportType.cs delete mode 100644 plugins/IngameOverlays/TextOverlay/Dlls/X32ProcessOverlayHelper.exe rename plugins/IngameOverlays/TextOverlay/Dlls/{osuOverlay.dll => textOverlay.dll} (100%) delete mode 100644 plugins/IngameOverlays/TextOverlay/IngameOverlay.cs delete mode 100644 plugins/IngameOverlays/TextOverlay/Loader/DllInjectionResult.cs delete mode 100644 plugins/IngameOverlays/TextOverlay/Loader/Loader.cs create mode 100644 plugins/IngameOverlays/TextOverlay/TextOverlay.cs rename plugins/IngameOverlays/TextOverlay/{IngameOverlaySettings.Designer.cs => TextOverlaySettings.Designer.cs} (97%) rename plugins/IngameOverlays/TextOverlay/{IngameOverlaySettings.cs => TextOverlaySettings.cs} (74%) rename plugins/IngameOverlays/TextOverlay/{IngameOverlaySettings.resx => TextOverlaySettings.resx} (100%) diff --git a/osu!StreamCompanion.sln b/osu!StreamCompanion.sln index 98108f34..45f45891 100644 --- a/osu!StreamCompanion.sln +++ b/osu!StreamCompanion.sln @@ -95,6 +95,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "X32ProcessHelper", "plugins EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ingameOverlays", "ingameOverlays", "{7BCF111B-5AC0-4E5F-9C97-B0980C32481F}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Overlay.Common", "plugins\IngameOverlays\Overlay.Common\Overlay.Common.csproj", "{9AE2BF2B-BA42-4551-B553-D11039644B05}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -355,6 +357,14 @@ Global {2CD73747-6AC0-480E-8128-4310DF941A6B}.Debug|x86.ActiveCfg = Debug|Win32 {2CD73747-6AC0-480E-8128-4310DF941A6B}.Release|Any CPU.ActiveCfg = Release|Win32 {2CD73747-6AC0-480E-8128-4310DF941A6B}.Release|x86.ActiveCfg = Release|Win32 + {9AE2BF2B-BA42-4551-B553-D11039644B05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9AE2BF2B-BA42-4551-B553-D11039644B05}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9AE2BF2B-BA42-4551-B553-D11039644B05}.Debug|x86.ActiveCfg = Debug|Any CPU + {9AE2BF2B-BA42-4551-B553-D11039644B05}.Debug|x86.Build.0 = Debug|Any CPU + {9AE2BF2B-BA42-4551-B553-D11039644B05}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9AE2BF2B-BA42-4551-B553-D11039644B05}.Release|Any CPU.Build.0 = Release|Any CPU + {9AE2BF2B-BA42-4551-B553-D11039644B05}.Release|x86.ActiveCfg = Release|Any CPU + {9AE2BF2B-BA42-4551-B553-D11039644B05}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -389,6 +399,7 @@ Global {82B1293E-ED50-4CE7-9EFF-0F66A63801A1} = {7357CB17-E9D7-493F-BC1B-354F717D7AA3} {3CA7BE44-68FA-40A9-8809-7BE650EFA335} = {7357CB17-E9D7-493F-BC1B-354F717D7AA3} {7BCF111B-5AC0-4E5F-9C97-B0980C32481F} = {7357CB17-E9D7-493F-BC1B-354F717D7AA3} + {9AE2BF2B-BA42-4551-B553-D11039644B05} = {7BCF111B-5AC0-4E5F-9C97-B0980C32481F} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {90CD718D-2503-4BBC-867D-E8EF9C9DBC77} diff --git a/plugins/IngameOverlays/BrowserOverlay/BrowserIngameOverlay.csproj b/plugins/IngameOverlays/BrowserOverlay/BrowserIngameOverlay.csproj index d72e4e09..9c7d84e4 100644 --- a/plugins/IngameOverlays/BrowserOverlay/BrowserIngameOverlay.csproj +++ b/plugins/IngameOverlays/BrowserOverlay/BrowserIngameOverlay.csproj @@ -16,25 +16,17 @@ bin\Release_temp\ - - - - - - Always - - - + - + diff --git a/plugins/IngameOverlays/BrowserOverlay/BrowserOverlay.cs b/plugins/IngameOverlays/BrowserOverlay/BrowserOverlay.cs index 09648bad..8f2b7b59 100644 --- a/plugins/IngameOverlays/BrowserOverlay/BrowserOverlay.cs +++ b/plugins/IngameOverlays/BrowserOverlay/BrowserOverlay.cs @@ -7,10 +7,10 @@ using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; -using BrowserOverlay.Loader; using Newtonsoft.Json; +using Overlay.Common; +using Overlay.Common.Loader; using StreamCompanion.Common; -using StreamCompanionTypes; using StreamCompanionTypes.DataTypes; using StreamCompanionTypes.Enums; using StreamCompanionTypes.Interfaces; @@ -149,16 +149,25 @@ private async Task Initialize() return; } - //Check one of the files included in overlay assets - _loaderWatchdog = new LoaderWatchdog(_logger, GetFullDllLocation(_saver)) - { - InjectionProgressReporter = new Progress(s => _logger.Log(s, LogLevel.Debug)) - }; - //_loaderWatchdog.BeforeInjection += async (_, __) => await DownloadAndUnpackOverlay(zipFileLocation, assetsLocation); - _ = _loaderWatchdog.WatchForProcessStart(CancellationToken.None).HandleExceptions(); + _loaderWatchdog = new LoaderWatchdog(_logger, GetFullDllLocation(_saver), new Progress(s => _logger.Log(s, LogLevel.Debug))); + _ = _loaderWatchdog.WatchForProcessStart(CancellationToken.None, new Progress(HandleOverlayReport)).HandleExceptions(); return; } + private void HandleOverlayReport(OverlayReport report) + { + const string messageBoxTitle = "StreamCompanion - Browser overlay"; + switch (report.ReportType) + { + case ReportType.Information: + MessageBox.Show(report.Message, messageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Information); + break; + case ReportType.Error: + MessageBox.Show(report.Message, messageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); + break; + } + } + private async Task DownloadAndUnpackOverlay(string zipFileLocation, string assetsLocation) { _overlayDownloadForm = new OverlayDownload(); diff --git a/plugins/IngameOverlays/BrowserOverlay/Loader/DllInjector.cs b/plugins/IngameOverlays/BrowserOverlay/Loader/DllInjector.cs deleted file mode 100644 index 518603b6..00000000 --- a/plugins/IngameOverlays/BrowserOverlay/Loader/DllInjector.cs +++ /dev/null @@ -1,203 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Text; - -namespace BrowserOverlay.Loader -{ - public class DllInjector - { - - public enum LoadedResult - { - Loaded, - NotLoaded, - Error - } - static readonly IntPtr INTPTR_ZERO = (IntPtr)0; - - [DllImport("kernel32.dll", SetLastError = true)] - static extern IntPtr OpenProcess(uint dwDesiredAccess, int bInheritHandle, uint dwProcessId); - - [DllImport("kernel32.dll", SetLastError = true)] - static extern int CloseHandle(IntPtr hObject); - - [DllImport("kernel32.dll", SetLastError = true)] - static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName); - - [DllImport("kernel32.dll", SetLastError = true)] - static extern IntPtr GetModuleHandle(string lpModuleName); - - [DllImport("kernel32.dll", SetLastError = true)] - static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, IntPtr dwSize, uint flAllocationType, uint flProtect); - - [DllImport("kernel32.dll", SetLastError = true)] - static extern int WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] buffer, uint size, int lpNumberOfBytesWritten); - - [DllImport("kernel32.dll", SetLastError = true)] - static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttribute, IntPtr dwStackSize, IntPtr lpStartAddress, - IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); - - [DllImport("kernel32.dll", SetLastError = true)] - static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds); - const UInt32 WAIT_ABANDONED = 0x00000080; - const UInt32 WAIT_OBJECT_0 = 0x00000000; - const UInt32 WAIT_TIMEOUT = 0x00000102; - - static DllInjector _instance; - - public static DllInjector GetInstance - { - get - { - if (_instance == null) - { - _instance = new DllInjector(); - } - return _instance; - } - } - - protected DllInjector() { } - - public (DllInjectionResult InjectionResult, int errorCode, int Win32Error) Inject(string sProcName, string sDllPath) - { - if (!File.Exists(sDllPath)) - { - return (DllInjectionResult.DllNotFound, 1, 0); - } - - uint _procId = 0; - - Process[] _procs = Process.GetProcesses(); - for (int i = 0; i < _procs.Length; i++) - { - if (_procs[i].ProcessName == sProcName) - { - _procId = (uint)_procs[i].Id; - break; - } - } - - if (_procId == 0) - { - return (DllInjectionResult.GameProcessNotFound, 2, 0); - } - - var loadedResult = IsAlreadyLoaded(sProcName, Path.GetFileName(sDllPath)); - if (loadedResult.LoadedResult == LoadedResult.Loaded) - return (DllInjectionResult.Success, 0, 0); - - if (loadedResult.LoadedResult == LoadedResult.Error) - return (DllInjectionResult.InjectionFailed, -1, 0); - - var libAddress = GetLoadLibraryAAddress(); - if(libAddress == IntPtr.Zero) - return (DllInjectionResult.HelperProcessFailed, -2, 0); - - var injectionResult = BInject(_procId, sDllPath, libAddress); - if (!injectionResult.Success) - { - return (DllInjectionResult.InjectionFailed, injectionResult.ErrorCode, Marshal.GetLastWin32Error()); - } - - return (DllInjectionResult.Success, 0, 0); - } - - private IntPtr GetLoadLibraryAAddress() - { - var file = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "Plugins", "Dlls", "X32ProcessOverlayHelper.exe"); - var process = Process.Start(new ProcessStartInfo - { - CreateNoWindow = true, - UseShellExecute = false, - RedirectStandardOutput = true, - FileName = file, - Arguments = "proc LoadLibraryA" - }); - process.WaitForExit(); - if (process.ExitCode != 0) - return IntPtr.Zero; - - var rawAddress = process.StandardOutput.ReadToEnd().Trim(); - return new IntPtr(Convert.ToInt32(rawAddress, 16)); - } - - public (LoadedResult LoadedResult, int ErrorCode) IsAlreadyLoaded(string procName, string dllName) - { - try - { - var moduleFound = ListModules(procName).Any(moduleName => moduleName == dllName); - if (moduleFound) - return (LoadedResult.Loaded, 0); - } - catch (Exception ex) - { - Console.WriteLine(ex); - return (LoadedResult.Error, 0); - } - - return (LoadedResult.NotLoaded, 0); - } - - public IEnumerable ListModules(string procName) - { - var processes = Process.GetProcessesByName(procName); - var process = processes.FirstOrDefault(p => p.ProcessName == procName); - if (process != null) - { - foreach (var pm in process.X32BitModules()) - yield return Path.GetFileName(pm.szExePath); - } - } - - protected virtual (bool Success, int ErrorCode) BInject(uint pToBeInjected, string sDllPath, IntPtr? LoadLibraryAAddress = null) - { - IntPtr hndProc = OpenProcess((0x2 | 0x8 | 0x10 | 0x20 | 0x400), 1, pToBeInjected); - - if (hndProc == INTPTR_ZERO) - { - return (false, 3); - } - - IntPtr lpLLAddress = LoadLibraryAAddress ?? GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"); - - if (lpLLAddress == INTPTR_ZERO) - { - return (false, 4); - } - - IntPtr lpAddress = VirtualAllocEx(hndProc, (IntPtr)null, (IntPtr)sDllPath.Length, (0x1000 | 0x2000), 0X40); - - if (lpAddress == INTPTR_ZERO) - { - return (false, 5); - } - - byte[] bytes = Encoding.ASCII.GetBytes(sDllPath); - - if (WriteProcessMemory(hndProc, lpAddress, bytes, (uint)bytes.Length, 0) == 0) - { - return (false, 6); - } - - IntPtr threadHandle; - if ((threadHandle = CreateRemoteThread(hndProc, (IntPtr)null, INTPTR_ZERO, lpLLAddress, lpAddress, 0, (IntPtr)null)) == INTPTR_ZERO) - { - return (false, 7); - } - - var objectResult = WaitForSingleObject(threadHandle, 3000); - if (objectResult == WAIT_ABANDONED || objectResult == WAIT_TIMEOUT) - return (false, 100 + (int)objectResult); - - CloseHandle(hndProc); - - return (true, 0); - } - } -} \ No newline at end of file diff --git a/plugins/IngameOverlays/BrowserOverlay/Loader/InjectionResult.cs b/plugins/IngameOverlays/BrowserOverlay/Loader/InjectionResult.cs deleted file mode 100644 index a52f74ad..00000000 --- a/plugins/IngameOverlays/BrowserOverlay/Loader/InjectionResult.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace BrowserOverlay.Loader -{ - public class InjectionResult - { - public DllInjectionResult ResultCode { get; } - public int ErrorCode { get; } - public int Win32ErrorCode { get; } - public string Result { get; } - - public InjectionResult(DllInjectionResult resultCode, int ErrorCode, int Win32ErrorCode, string Result) - { - this.ResultCode = resultCode; - this.ErrorCode = ErrorCode; - this.Win32ErrorCode = Win32ErrorCode; - this.Result = Result; - } - - public override string ToString() => $"{ResultCode},{ErrorCode},{Win32ErrorCode},{Result}"; - } -} \ No newline at end of file diff --git a/plugins/IngameOverlays/BrowserOverlay/Loader/ProcessExtensions.cs b/plugins/IngameOverlays/BrowserOverlay/Loader/ProcessExtensions.cs deleted file mode 100644 index 8bc250a4..00000000 --- a/plugins/IngameOverlays/BrowserOverlay/Loader/ProcessExtensions.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Runtime.InteropServices; - -namespace BrowserOverlay.Loader -{ - static class ProcessExtensions - { - [DllImport("kernel32.dll", SetLastError = true)] - static public extern bool CloseHandle(IntPtr hHandle); - - [DllImport("kernel32.dll")] - static public extern bool Module32First(IntPtr hSnapshot, ref MODULEENTRY32 lpme); - - [DllImport("kernel32.dll")] - static public extern bool Module32Next(IntPtr hSnapshot, ref MODULEENTRY32 lpme); - - [DllImport("kernel32.dll", SetLastError = true)] - static public extern IntPtr CreateToolhelp32Snapshot(SnapshotFlags dwFlags, uint th32ProcessID); - - public const short INVALID_HANDLE_VALUE = -1; - - [Flags] - public enum SnapshotFlags : uint - { - HeapList = 0x00000001, - Process = 0x00000002, - Thread = 0x00000004, - Module = 0x00000008, - Module32 = 0x00000010, - Inherit = 0x80000000, - All = 0x0000001F - } - - [StructLayoutAttribute(LayoutKind.Sequential)] - public struct MODULEENTRY32 - { - public uint dwSize; - public uint th32ModuleID; - public uint th32ProcessID; - public uint GlblcntUsage; - public uint ProccntUsage; - public IntPtr modBaseAddr; - public uint modBaseSize; - public IntPtr hModule; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] - public string szModule; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] - public string szExePath; - } - - public static List X32BitModules(this Process proc) - => X32BitModules((uint)proc.Id); - - public static List X32BitModules(uint procId) - { - var snapshot = CreateToolhelp32Snapshot(SnapshotFlags.Module | SnapshotFlags.Module32, procId); - MODULEENTRY32 mod = new MODULEENTRY32() { dwSize = (uint)Marshal.SizeOf(typeof(MODULEENTRY32)) }; - if (!Module32First(snapshot, ref mod)) - return null; - - List modules = new(); - do - { - var shallowCopy = mod; - modules.Add(shallowCopy); - } - while (Module32Next(snapshot, ref mod)); - - return modules; - } - } -} diff --git a/plugins/IngameOverlays/BrowserOverlay/Loader/X64DllInjector.cs b/plugins/IngameOverlays/BrowserOverlay/Loader/X64DllInjector.cs deleted file mode 100644 index d29c68d6..00000000 --- a/plugins/IngameOverlays/BrowserOverlay/Loader/X64DllInjector.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace BrowserOverlay.Loader -{ - public class X64DllInjector : DllInjector - { - } -} diff --git a/plugins/IngameOverlays/BrowserOverlay/Dlls/X32ProcessOverlayHelper.exe b/plugins/IngameOverlays/Overlay.Common/Dlls/X32ProcessOverlayHelper.exe similarity index 100% rename from plugins/IngameOverlays/BrowserOverlay/Dlls/X32ProcessOverlayHelper.exe rename to plugins/IngameOverlays/Overlay.Common/Dlls/X32ProcessOverlayHelper.exe diff --git a/plugins/IngameOverlays/BrowserOverlay/Loader/DllInjectionResult.cs b/plugins/IngameOverlays/Overlay.Common/Loader/DllInjectionResult.cs similarity index 87% rename from plugins/IngameOverlays/BrowserOverlay/Loader/DllInjectionResult.cs rename to plugins/IngameOverlays/Overlay.Common/Loader/DllInjectionResult.cs index db353a87..1427c8b4 100644 --- a/plugins/IngameOverlays/BrowserOverlay/Loader/DllInjectionResult.cs +++ b/plugins/IngameOverlays/Overlay.Common/Loader/DllInjectionResult.cs @@ -1,4 +1,4 @@ -namespace BrowserOverlay.Loader +namespace Overlay.Common.Loader { public enum DllInjectionResult { diff --git a/plugins/IngameOverlays/TextOverlay/Loader/DllInjector.cs b/plugins/IngameOverlays/Overlay.Common/Loader/DllInjector.cs similarity index 93% rename from plugins/IngameOverlays/TextOverlay/Loader/DllInjector.cs rename to plugins/IngameOverlays/Overlay.Common/Loader/DllInjector.cs index 50231c59..f2b8a364 100644 --- a/plugins/IngameOverlays/TextOverlay/Loader/DllInjector.cs +++ b/plugins/IngameOverlays/Overlay.Common/Loader/DllInjector.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -7,7 +7,7 @@ using System.Runtime.InteropServices; using System.Text; -namespace osuOverlay.Loader +namespace Overlay.Common.Loader { public class DllInjector { @@ -43,10 +43,10 @@ static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttribut IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); [DllImport("kernel32.dll", SetLastError = true)] - static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds); - const UInt32 WAIT_ABANDONED = 0x00000080; - const UInt32 WAIT_OBJECT_0 = 0x00000000; - const UInt32 WAIT_TIMEOUT = 0x00000102; + static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds); + const uint WAIT_ABANDONED = 0x00000080; + const uint WAIT_OBJECT_0 = 0x00000000; + const uint WAIT_TIMEOUT = 0x00000102; static DllInjector _instance; @@ -157,7 +157,7 @@ public IEnumerable ListModules(string procName) protected virtual (bool Success, int ErrorCode) BInject(uint pToBeInjected, string sDllPath, IntPtr? LoadLibraryAAddress = null) { - IntPtr hndProc = OpenProcess((0x2 | 0x8 | 0x10 | 0x20 | 0x400), 1, pToBeInjected); + IntPtr hndProc = OpenProcess(0x2 | 0x8 | 0x10 | 0x20 | 0x400, 1, pToBeInjected); if (hndProc == INTPTR_ZERO) { @@ -171,7 +171,7 @@ protected virtual (bool Success, int ErrorCode) BInject(uint pToBeInjected, stri return (false, 4); } - IntPtr lpAddress = VirtualAllocEx(hndProc, (IntPtr)null, (IntPtr)sDllPath.Length, (0x1000 | 0x2000), 0X40); + IntPtr lpAddress = VirtualAllocEx(hndProc, (IntPtr)null, (IntPtr)sDllPath.Length, 0x1000 | 0x2000, 0X40); if (lpAddress == INTPTR_ZERO) { diff --git a/plugins/IngameOverlays/TextOverlay/Loader/InjectionResult.cs b/plugins/IngameOverlays/Overlay.Common/Loader/InjectionResult.cs similarity index 88% rename from plugins/IngameOverlays/TextOverlay/Loader/InjectionResult.cs rename to plugins/IngameOverlays/Overlay.Common/Loader/InjectionResult.cs index 01e29517..228d4d93 100644 --- a/plugins/IngameOverlays/TextOverlay/Loader/InjectionResult.cs +++ b/plugins/IngameOverlays/Overlay.Common/Loader/InjectionResult.cs @@ -1,4 +1,4 @@ -namespace osuOverlay.Loader +namespace Overlay.Common.Loader { public class InjectionResult { @@ -9,7 +9,7 @@ public class InjectionResult public InjectionResult(DllInjectionResult resultCode, int ErrorCode, int Win32ErrorCode, string Result) { - this.ResultCode = resultCode; + ResultCode = resultCode; this.ErrorCode = ErrorCode; this.Win32ErrorCode = Win32ErrorCode; this.Result = Result; diff --git a/plugins/IngameOverlays/BrowserOverlay/Loader/KnownOsuModules.cs b/plugins/IngameOverlays/Overlay.Common/Loader/KnownOsuModules.cs similarity index 99% rename from plugins/IngameOverlays/BrowserOverlay/Loader/KnownOsuModules.cs rename to plugins/IngameOverlays/Overlay.Common/Loader/KnownOsuModules.cs index e6c45752..f09c2534 100644 --- a/plugins/IngameOverlays/BrowserOverlay/Loader/KnownOsuModules.cs +++ b/plugins/IngameOverlays/Overlay.Common/Loader/KnownOsuModules.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace BrowserOverlay.Loader +namespace Overlay.Common.Loader { internal static class KnownOsuModules { diff --git a/plugins/IngameOverlays/BrowserOverlay/Loader/Loader.cs b/plugins/IngameOverlays/Overlay.Common/Loader/Loader.cs similarity index 95% rename from plugins/IngameOverlays/BrowserOverlay/Loader/Loader.cs rename to plugins/IngameOverlays/Overlay.Common/Loader/Loader.cs index 9ba000fd..bdd133a4 100644 --- a/plugins/IngameOverlays/BrowserOverlay/Loader/Loader.cs +++ b/plugins/IngameOverlays/Overlay.Common/Loader/Loader.cs @@ -4,11 +4,10 @@ using System.IO; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; -namespace BrowserOverlay.Loader +namespace Overlay.Common.Loader { - public class Loader : ApplicationContext + public class Loader { private string _lastMessage = string.Empty; public event EventHandler BeforeInjection; diff --git a/plugins/IngameOverlays/BrowserOverlay/Loader/LoaderWatchdog.cs b/plugins/IngameOverlays/Overlay.Common/Loader/LoaderWatchdog.cs similarity index 81% rename from plugins/IngameOverlays/BrowserOverlay/Loader/LoaderWatchdog.cs rename to plugins/IngameOverlays/Overlay.Common/Loader/LoaderWatchdog.cs index d4265f0a..fe8ec3f1 100644 --- a/plugins/IngameOverlays/BrowserOverlay/Loader/LoaderWatchdog.cs +++ b/plugins/IngameOverlays/Overlay.Common/Loader/LoaderWatchdog.cs @@ -3,11 +3,10 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -using System.Windows.Forms; using StreamCompanionTypes.Enums; using StreamCompanionTypes.Interfaces.Services; -namespace BrowserOverlay.Loader +namespace Overlay.Common.Loader { public class LoaderWatchdog { @@ -16,18 +15,19 @@ public class LoaderWatchdog public string DllLocation { get; set; } public Progress InjectionProgressReporter; private readonly Loader _loader = new Loader(); - private Process _currentOsuProcess; + private Process? _currentOsuProcess; public event EventHandler BeforeInjection { add => _loader.BeforeInjection += value; remove => _loader.BeforeInjection -= value; } - public LoaderWatchdog(ILogger logger, string dllLocation, string processName = "osu!") + public LoaderWatchdog(ILogger logger, string dllLocation, Progress injectionProgressReporter, string processName = "osu!") { _logger = logger; _processName = processName; DllLocation = dllLocation; + InjectionProgressReporter = injectionProgressReporter; BeforeInjection += OnBeforeInjection; } @@ -41,7 +41,7 @@ private void OnBeforeInjection(object sender, EventArgs e) _logger.Log("osu! module list is clean", LogLevel.Debug); } - public async Task WatchForProcessStart(CancellationToken token) + public async Task WatchForProcessStart(CancellationToken token, IProgress overlayStatusReporter) { try { @@ -63,12 +63,7 @@ public async Task WatchForProcessStart(CancellationToken token) { if (_currentOsuProcess == null && GetProcess() != null && lastResult != DllInjectionResult.Timeout) { - _ = Task.Run(() => - { - MessageBox.Show( - "In order to load browser overlay you need to restart your osu!", - "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); - }); + _ = Task.Run(() => overlayStatusReporter.Report(new(ReportType.Information, "In order to load ingame overlay you need to restart your osu!"))); } _logger.Log("Not injected - waiting for either osu! start or restart.", LogLevel.Information); @@ -76,7 +71,7 @@ public async Task WatchForProcessStart(CancellationToken token) resultCode = result.ResultCode; if (token.IsCancellationRequested) return; - HandleInjectionResult(result, true); + HandleInjectionResult(result, overlayStatusReporter, true); lastResult = result.ResultCode; } @@ -126,26 +121,26 @@ private Process GetProcess() return null; } - private void HandleInjectionResult(InjectionResult helperProcessResult, bool showErrors = false) + private void HandleInjectionResult(InjectionResult helperProcessResult, IProgress overlayStatusReporter, bool showErrors = false) { string message = null; switch (helperProcessResult.ResultCode) { case DllInjectionResult.DllNotFound: message = - "Could not find browser overlay file to add to osu!... this shouldn't happen, if it does(you see this message) please report this."; + "Could not find overlay file to add to osu!... this shouldn't happen, if it does(you see this message) please report this."; break; case DllInjectionResult.HelperProcessFailed: case DllInjectionResult.InjectionFailed: { //ERROR_ACCESS_DENIED - if (helperProcessResult.Win32ErrorCode == 5 || (helperProcessResult.Win32ErrorCode == 0 && helperProcessResult.ErrorCode == -2)) + if (helperProcessResult.Win32ErrorCode == 5 || helperProcessResult.Win32ErrorCode == 0 && helperProcessResult.ErrorCode == -2) { - message = $"Your antivirus has blocked an attempt to add browser overlay to osu!. Adding an antivirus exception to SC folder & installing browser overlay again might help."; + message = $"Your antivirus has blocked an attempt to add overlay to osu!. Adding an antivirus exception to SC folder & installing overlay again might help."; } else { - message = "Could not add browser overlay to osu!. Most likely SC doesn't have enough premissions - restart SC as administrator and try again. If that doesn't solve it - please report "; + message = "Could not add overlay to osu!. Most likely SC doesn't have enough premissions - restart SC as administrator and try again. If that doesn't solve it - please report "; } break; } @@ -162,7 +157,7 @@ private void HandleInjectionResult(InjectionResult helperProcessResult, bool sho _logger.Log($"{helperProcessResult}", LogLevel.Debug); if (showErrors && helperProcessResult.ResultCode != DllInjectionResult.GameProcessNotFound) { - MessageBox.Show(message + Environment.NewLine + $"Raw error data: {helperProcessResult}", "StreamCompanion - browser overlay Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + overlayStatusReporter.Report(new(ReportType.Error, message + Environment.NewLine + $"Raw error data: {helperProcessResult}")); } } diff --git a/plugins/IngameOverlays/TextOverlay/Loader/ProcessExtensions.cs b/plugins/IngameOverlays/Overlay.Common/Loader/ProcessExtensions.cs similarity index 96% rename from plugins/IngameOverlays/TextOverlay/Loader/ProcessExtensions.cs rename to plugins/IngameOverlays/Overlay.Common/Loader/ProcessExtensions.cs index a5f7c115..a738253a 100644 --- a/plugins/IngameOverlays/TextOverlay/Loader/ProcessExtensions.cs +++ b/plugins/IngameOverlays/Overlay.Common/Loader/ProcessExtensions.cs @@ -3,7 +3,7 @@ using System.Diagnostics; using System.Runtime.InteropServices; -namespace osuOverlay.Loader +namespace Overlay.Common.Loader { static class ProcessExtensions { @@ -33,7 +33,7 @@ public enum SnapshotFlags : uint All = 0x0000001F } - [StructLayoutAttribute(LayoutKind.Sequential)] + [StructLayout(LayoutKind.Sequential)] public struct MODULEENTRY32 { public uint dwSize; diff --git a/plugins/IngameOverlays/Overlay.Common/Overlay.Common.csproj b/plugins/IngameOverlays/Overlay.Common/Overlay.Common.csproj new file mode 100644 index 00000000..682efa67 --- /dev/null +++ b/plugins/IngameOverlays/Overlay.Common/Overlay.Common.csproj @@ -0,0 +1,22 @@ + + + + net6.0 + enable + + + + + + + + + Always + + + + + + + + diff --git a/plugins/IngameOverlays/Overlay.Common/OverlayReport.cs b/plugins/IngameOverlays/Overlay.Common/OverlayReport.cs new file mode 100644 index 00000000..8db349d0 --- /dev/null +++ b/plugins/IngameOverlays/Overlay.Common/OverlayReport.cs @@ -0,0 +1,14 @@ +namespace Overlay.Common +{ + public class OverlayReport + { + public ReportType ReportType; + public string Message; + + public OverlayReport(ReportType reportType, string message) + { + ReportType = reportType; + Message = message; + } + } +} diff --git a/plugins/IngameOverlays/Overlay.Common/ReportType.cs b/plugins/IngameOverlays/Overlay.Common/ReportType.cs new file mode 100644 index 00000000..2922c4ec --- /dev/null +++ b/plugins/IngameOverlays/Overlay.Common/ReportType.cs @@ -0,0 +1,8 @@ +namespace Overlay.Common +{ + public enum ReportType + { + Information, + Error + } +} diff --git a/plugins/IngameOverlays/TextOverlay/Dlls/X32ProcessOverlayHelper.exe b/plugins/IngameOverlays/TextOverlay/Dlls/X32ProcessOverlayHelper.exe deleted file mode 100644 index f55f3c4f5c157b3e3719044b2e8bab4278d1fa3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13824 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 diff --git a/plugins/IngameOverlays/TextOverlay/Dlls/osuOverlay.dll b/plugins/IngameOverlays/TextOverlay/Dlls/textOverlay.dll similarity index 100% rename from plugins/IngameOverlays/TextOverlay/Dlls/osuOverlay.dll rename to plugins/IngameOverlays/TextOverlay/Dlls/textOverlay.dll diff --git a/plugins/IngameOverlays/TextOverlay/IngameOverlay.cs b/plugins/IngameOverlays/TextOverlay/IngameOverlay.cs deleted file mode 100644 index 5eaa60b4..00000000 --- a/plugins/IngameOverlays/TextOverlay/IngameOverlay.cs +++ /dev/null @@ -1,258 +0,0 @@ -using System; -using System.Diagnostics; -using System.IO; -using System.Threading; -using System.Threading.Tasks; -using System.Windows.Forms; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using osuOverlay.Loader; -using StreamCompanionTypes; -using StreamCompanionTypes.DataTypes; -using StreamCompanionTypes.Interfaces; -using StreamCompanionTypes.Enums; -using StreamCompanionTypes.Interfaces.Consumers; -using StreamCompanionTypes.Interfaces.Services; -using StreamCompanionTypes.Interfaces.Sources; - -namespace osuOverlay -{ - public class IngameOverlay : IPlugin, ISettingsSource, IMapDataConsumer, IDisposable - { - public static readonly ConfigEntry EnableIngameOverlay = new ConfigEntry("EnableIngameOverlay", true); - - private ISettings _settings; - private readonly Delegates.Restart _restarter; - public string SettingGroup { get; } = "In-game overlay__Text overlay"; - private IngameOverlaySettings _overlaySettings; - private ILogger _logger; - private Process _currentOsuProcess; - Loader.Loader loader = new Loader.Loader(); - private Progress progressReporter; - private bool _pauseProcessTracking; - - public string Description { get; } = ""; - public string Name { get; } = "TextIngameOverlay"; - public string Author { get; } = "Piotrekol"; - public string Url { get; } = ""; - public string UpdateUrl { get; } = ""; - CancellationTokenSource cancellationToken = new CancellationTokenSource(); - - public IngameOverlay(ILogger logger, ISettings settings, Delegates.Restart restarter) - { - _logger = logger; - _settings = settings; - _restarter = restarter; - var enabled = _settings.Get(EnableIngameOverlay); - if (enabled && BrowserOverlayIsEnabled(_settings)) - { - _settings.Add(EnableIngameOverlay.Name, false); - - var infoText = - $"TextIngameOverlay and BrowserIngameOverlay can't be ran at the same time.{Environment.NewLine} TextIngameOverlay was disabled in order to prevent osu! crash."; - _logger.Log(infoText, LogLevel.Warning); - MessageBox.Show(infoText, "TextIngameOverlay Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); - } - - if (_settings.Get(EnableIngameOverlay)) - { - progressReporter = new Progress(s => _logger.Log(s, LogLevel.Debug)); - Task.Run(() => WatchForProcessStart(cancellationToken.Token), cancellationToken.Token); - } - } - - private bool BrowserOverlayIsEnabled(ISettings settings) - { - if (settings.SettingsEntries.TryGetValue("BrowserOverlay", out var rawBrowserOverlayConfig)) - { - var config = JsonConvert.DeserializeObject(rawBrowserOverlayConfig?.ToString() ?? ""); - if (config.TryGetValue("Enabled", out var enabledToken) && bool.TryParse(enabledToken?.ToString() ?? "", out var browserOverlayEnabled)) - { - return browserOverlayEnabled; - } - } - - return false; - } - - private Process GetOsuProcess() - { - foreach (var process in Process.GetProcesses()) - { - if (process.ProcessName == "osu!") - { - return process; - } - } - - return null; - } - - private bool IsAlreadyInjected() - { - return loader.IsAlreadyInjected(GetFullDllLocation()); - } - - private async Task Inject() - { - try - { - return await loader.Inject(GetFullDllLocation(), progressReporter, cancellationToken.Token); - } - catch (TaskCanceledException) - { - return new InjectionResult(DllInjectionResult.Cancelled, 0, 0, "Task cancelled"); - } - } - public async Task WatchForProcessStart(CancellationToken token) - { - try - { - var lastResult = DllInjectionResult.GameProcessNotFound; - while (true) - { - if (token.IsCancellationRequested) - return; - - if (_currentOsuProcess == null || SafeHasExited(_currentOsuProcess)) - { - _logger.Log("Checking osu! overlay injection status.", LogLevel.Debug); - var resultCode = DllInjectionResult.Success; - if (IsAlreadyInjected()) - { - _logger.Log("Already injected & running.", LogLevel.Debug); - } - else - { - if (_currentOsuProcess == null && GetOsuProcess() != null && lastResult != DllInjectionResult.Timeout) - { - _ = Task.Run(() => - { - MessageBox.Show( - "In order to load StreamCompanion osu! overlay you need to restart your osu!", - "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); - }); - } - _logger.Log("Not injected - waiting for either osu! start or restart.", LogLevel.Information); - - var result = await Inject(); - resultCode = result.ResultCode; - HandleInjectionResult(result, true); - lastResult = result.ResultCode; - } - - if (resultCode == DllInjectionResult.Success) - { - if (_currentOsuProcess == null || SafeHasExited(_currentOsuProcess)) - { - _currentOsuProcess = GetOsuProcess(); - } - } - } - - while (_pauseProcessTracking) - { - await Task.Delay(1000); - } - - await Task.Delay(2000); - } - } - catch (TaskCanceledException) - { - } - } - private void HandleInjectionResult(InjectionResult helperProcessResult, bool showErrors = false) - { - string message = null; - switch (helperProcessResult.ResultCode) - { - case DllInjectionResult.DllNotFound: - message = - "Could not find osuOverlay file to add to osu!... this shouldn't happen, if it does(you see this message) please report this."; - break; - case DllInjectionResult.HelperProcessFailed: - case DllInjectionResult.InjectionFailed: - { - //ERROR_ACCESS_DENIED - if (helperProcessResult.Win32ErrorCode == 5 || (helperProcessResult.Win32ErrorCode == 0 && helperProcessResult.ErrorCode == -2)) - { - message = $"Your antivirus has blocked an attempt to add browser overlay to osu!. Adding an antivirus exception to SC folder & installing text overlay again might help."; - } - else - { - message = "Could not add overlay to osu! most likely SC doesn't have enough premissions - restart SC as administrator and try again. If that doesn't solve it - please report "; - } - break; - } - case DllInjectionResult.Cancelled: - case DllInjectionResult.GameProcessNotFound: - case DllInjectionResult.Timeout: - return; - case DllInjectionResult.Success: - _logger.Log("Injection success.", LogLevel.Information); - return; - } - - _logger.Log($"Injection failed: {message}", LogLevel.Information); - _logger.Log($"{helperProcessResult}", LogLevel.Debug); - if (showErrors && helperProcessResult.ResultCode != DllInjectionResult.GameProcessNotFound && !cancellationToken.IsCancellationRequested) - { - MessageBox.Show(message + Environment.NewLine + $"Raw error data: {helperProcessResult}", "StreamCompanion - text overlay Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - - public bool SafeHasExited(Process process) - { - - try - { - return process.HasExited; - } - catch - { - return true; - } - } - - private string GetFilesFolder() => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins", "Dlls"); - - private string GetFullFreeTypeLocation() => Path.Combine(GetFilesFolder(), "FreeType.dll"); - private string GetFullDllLocation() => Path.Combine(GetFilesFolder(), "osuOverlay.dll"); - public void Free() - { - _overlaySettings?.Dispose(); - } - - public object GetUiSettings() - { - if (_overlaySettings == null || _overlaySettings.IsDisposed) - { - _overlaySettings = new IngameOverlaySettings(_settings); - _overlaySettings.OverlayToggled += (_, value) => _restarter($"Text overlay was toggled. isEnabled:{value}"); - } - return _overlaySettings; - } - - public Task SetNewMapAsync(IMapSearchResult map, CancellationToken cancellationToken) - { - try - { - _pauseProcessTracking = (map.Action & (OsuStatus.Playing | OsuStatus.Watching)) != 0; - } - catch - { - // ignored - } - - return Task.CompletedTask; - } - - public void Dispose() - { - _overlaySettings?.Dispose(); - cancellationToken.Cancel(); - _currentOsuProcess?.Dispose(); - } - } -} \ No newline at end of file diff --git a/plugins/IngameOverlays/TextOverlay/Loader/DllInjectionResult.cs b/plugins/IngameOverlays/TextOverlay/Loader/DllInjectionResult.cs deleted file mode 100644 index 3e4bd4af..00000000 --- a/plugins/IngameOverlays/TextOverlay/Loader/DllInjectionResult.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace osuOverlay.Loader -{ - public enum DllInjectionResult - { - Success = 0, - DllNotFound = 10, - GameProcessNotFound = 11, - InjectionFailed = 12, - Timeout = 13, - Cancelled = 14, - HelperProcessFailed = 15, - } -} \ No newline at end of file diff --git a/plugins/IngameOverlays/TextOverlay/Loader/Loader.cs b/plugins/IngameOverlays/TextOverlay/Loader/Loader.cs deleted file mode 100644 index 8105e790..00000000 --- a/plugins/IngameOverlays/TextOverlay/Loader/Loader.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.Diagnostics; -using System.IO; -using System.Threading; -using System.Threading.Tasks; -using System.Windows.Forms; - -namespace osuOverlay.Loader -{ - public class Loader : ApplicationContext - { - private string _lastMessage = string.Empty; - - public bool IsAlreadyInjected(string dllLocation) - => DllInjector.GetInstance.IsAlreadyLoaded("osu!", Path.GetFileName(dllLocation)).LoadedResult == - DllInjector.LoadedResult.Loaded; - - public async Task Inject(string dllLocation, IProgress progress, - CancellationToken cancellationToken) - { - while (GetOsuProcess() != null) - { - await Task.Delay(2000, cancellationToken); - Report(progress, "Waiting for osu! process to close"); - } - - Process process; - do - { - await Task.Delay(2000, cancellationToken); - Report(progress, "Waiting for osu! process to start"); - } while (!( - (process = GetOsuProcess()) != null - && !process.MainWindowTitle.Contains("osu! updater") - && !string.IsNullOrEmpty(process.MainWindowTitle)) - ); - - progress?.Report("Injecting"); - - DllInjector dllInjector = DllInjector.GetInstance; - var result = dllInjector.Inject("osu!", dllLocation); - - return new InjectionResult(result.InjectionResult, result.errorCode, result.Win32Error, "_"); - } - - private void Report(IProgress progress, string message) - { - if (_lastMessage == message) - return; - - _lastMessage = message; - progress?.Report(message); - } - - private Process GetOsuProcess() - { - foreach (var process in Process.GetProcesses()) - { - if (process.ProcessName == "osu!") - { - return process; - } - } - - return null; - } - } -} \ No newline at end of file diff --git a/plugins/IngameOverlays/TextOverlay/TextIngameOverlay.csproj b/plugins/IngameOverlays/TextOverlay/TextIngameOverlay.csproj index 6996b16c..81c6548d 100644 --- a/plugins/IngameOverlays/TextOverlay/TextIngameOverlay.csproj +++ b/plugins/IngameOverlays/TextOverlay/TextIngameOverlay.csproj @@ -9,18 +9,15 @@ false true TextIngameOverlay - - - ..\..\..\build\Debug\Plugins\ - - ..\..\..\build\Release_unsafe\Plugins\ + + bin\Debug_temp\ + + + bin\Release_temp\ - - - - + UserControl @@ -28,10 +25,7 @@ Always - - Always - - + Always @@ -41,4 +35,12 @@ + + + + + + + + \ No newline at end of file diff --git a/plugins/IngameOverlays/TextOverlay/TextOverlay.cs b/plugins/IngameOverlays/TextOverlay/TextOverlay.cs new file mode 100644 index 00000000..1f359254 --- /dev/null +++ b/plugins/IngameOverlays/TextOverlay/TextOverlay.cs @@ -0,0 +1,107 @@ +using System; +using System.IO; +using System.Threading; +using System.Windows.Forms; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using StreamCompanionTypes.DataTypes; +using StreamCompanionTypes.Interfaces; +using StreamCompanionTypes.Enums; +using StreamCompanionTypes.Interfaces.Services; +using StreamCompanionTypes.Interfaces.Sources; +using Overlay.Common.Loader; +using Overlay.Common; +using StreamCompanion.Common; + +namespace TextOverlay +{ + public class TextOverlay : IPlugin, ISettingsSource, IDisposable + { + public static readonly ConfigEntry EnableIngameOverlay = new ConfigEntry("EnableIngameOverlay", true); + + private ISettings _settings; + private readonly Delegates.Restart _restarter; + public string SettingGroup { get; } = "In-game overlay__Text overlay"; + private TextOverlaySettings _overlaySettings; + private ILogger _logger; + private LoaderWatchdog _loaderWatchdog; + + public string Description { get; } = ""; + public string Name { get; } = "TextIngameOverlay"; + public string Author { get; } = "Piotrekol"; + public string Url { get; } = ""; + public string UpdateUrl { get; } = ""; + CancellationTokenSource cancellationToken = new CancellationTokenSource(); + + public TextOverlay(ILogger logger, ISettings settings, Delegates.Restart restarter) + { + _logger = logger; + _settings = settings; + _restarter = restarter; + var enabled = _settings.Get(EnableIngameOverlay); + if (enabled && BrowserOverlayIsEnabled(_settings)) + { + _settings.Add(EnableIngameOverlay.Name, false); + + var infoText = + $"TextIngameOverlay and BrowserIngameOverlay can't be ran at the same time.{Environment.NewLine} TextIngameOverlay was disabled in order to prevent osu! crash."; + _logger.Log(infoText, LogLevel.Warning); + MessageBox.Show(infoText, "TextIngameOverlay Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + + if (_settings.Get(EnableIngameOverlay)) + { + _loaderWatchdog = new LoaderWatchdog(_logger, GetFullDllLocation(), new Progress(s => _logger.Log(s, LogLevel.Debug))); + _ = _loaderWatchdog.WatchForProcessStart(CancellationToken.None, new Progress(HandleOverlayReport)).HandleExceptions(); + } + } + + private bool BrowserOverlayIsEnabled(ISettings settings) + { + if (settings.SettingsEntries.TryGetValue("BrowserOverlay", out var rawBrowserOverlayConfig)) + { + var config = JsonConvert.DeserializeObject(rawBrowserOverlayConfig?.ToString() ?? ""); + if (config.TryGetValue("Enabled", out var enabledToken) && bool.TryParse(enabledToken?.ToString() ?? "", out var browserOverlayEnabled)) + { + return browserOverlayEnabled; + } + } + + return false; + } + + private void HandleOverlayReport(OverlayReport report) + { + const string messageBoxTitle = "StreamCompanion - Text overlay"; + switch (report.ReportType) + { + case ReportType.Information: + MessageBox.Show(report.Message, messageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Information); + break; + case ReportType.Error: + MessageBox.Show(report.Message, messageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); + break; + } + } + + private string GetFilesFolder() => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins", "Dlls"); + private string GetFullDllLocation() => Path.Combine(GetFilesFolder(), "textOverlay.dll"); + + public void Free() => _overlaySettings?.Dispose(); + public object GetUiSettings() + { + if (_overlaySettings == null || _overlaySettings.IsDisposed) + { + _overlaySettings = new TextOverlaySettings(_settings); + _overlaySettings.OverlayToggled += (_, value) => _restarter($"Text overlay was toggled. isEnabled:{value}"); + } + return _overlaySettings; + } + + public void Dispose() + { + _overlaySettings?.Dispose(); + cancellationToken.Cancel(); + } + } +} \ No newline at end of file diff --git a/plugins/IngameOverlays/TextOverlay/IngameOverlaySettings.Designer.cs b/plugins/IngameOverlays/TextOverlay/TextOverlaySettings.Designer.cs similarity index 97% rename from plugins/IngameOverlays/TextOverlay/IngameOverlaySettings.Designer.cs rename to plugins/IngameOverlays/TextOverlay/TextOverlaySettings.Designer.cs index e9e40e98..56113689 100644 --- a/plugins/IngameOverlays/TextOverlay/IngameOverlaySettings.Designer.cs +++ b/plugins/IngameOverlays/TextOverlay/TextOverlaySettings.Designer.cs @@ -1,6 +1,6 @@ -namespace osuOverlay +namespace TextOverlay { - partial class IngameOverlaySettings + partial class TextOverlaySettings { /// /// Required designer variable. diff --git a/plugins/IngameOverlays/TextOverlay/IngameOverlaySettings.cs b/plugins/IngameOverlays/TextOverlay/TextOverlaySettings.cs similarity index 74% rename from plugins/IngameOverlays/TextOverlay/IngameOverlaySettings.cs rename to plugins/IngameOverlays/TextOverlay/TextOverlaySettings.cs index f00bc939..0f273217 100644 --- a/plugins/IngameOverlays/TextOverlay/IngameOverlaySettings.cs +++ b/plugins/IngameOverlays/TextOverlay/TextOverlaySettings.cs @@ -3,25 +3,25 @@ using StreamCompanionTypes; using StreamCompanionTypes.Interfaces.Services; -namespace osuOverlay +namespace TextOverlay { - public partial class IngameOverlaySettings : UserControl + public partial class TextOverlaySettings : UserControl { private readonly ISettings _settings; public event EventHandler OverlayToggled; - public IngameOverlaySettings(ISettings settings) + public TextOverlaySettings(ISettings settings) { _settings = settings; InitializeComponent(); - checkBox_ingameOverlay.Checked = _settings.Get(IngameOverlay.EnableIngameOverlay); + checkBox_ingameOverlay.Checked = _settings.Get(TextOverlay.EnableIngameOverlay); checkBox_ingameOverlay.CheckedChanged += CheckBoxIngameOverlayOnCheckedChanged; } private void CheckBoxIngameOverlayOnCheckedChanged(object sender, EventArgs eventArgs) { - _settings.Add(IngameOverlay.EnableIngameOverlay.Name, checkBox_ingameOverlay.Checked); + _settings.Add(TextOverlay.EnableIngameOverlay.Name, checkBox_ingameOverlay.Checked); OnOverlayToggled(checkBox_ingameOverlay.Checked); } diff --git a/plugins/IngameOverlays/TextOverlay/IngameOverlaySettings.resx b/plugins/IngameOverlays/TextOverlay/TextOverlaySettings.resx similarity index 100% rename from plugins/IngameOverlays/TextOverlay/IngameOverlaySettings.resx rename to plugins/IngameOverlays/TextOverlay/TextOverlaySettings.resx