From 48ad8915151c594441c77e911b7b7d7aa2e89dee Mon Sep 17 00:00:00 2001 From: se_ga Date: Thu, 19 Mar 2026 16:59:55 +0300 Subject: [PATCH] =?UTF-8?q?REFACTOR:=20=D0=A0=D0=B0=D0=B7=D0=B2=D1=8F?= =?UTF-8?q?=D0=B7=D0=B0=D0=BB=20=D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D1=83?= =?UTF-8?q?=20=D0=B7=D0=B0=D1=89=D0=B8=D1=82=D1=8B=20=D0=B8=20GameManager?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Scripts/Defender.cs | 346 ++++++++++++++++++++++++++++++++ Assets/Scripts/Defender.cs.meta | 11 + Assets/Scripts/GameManager.cs | 328 +----------------------------- 3 files changed, 361 insertions(+), 324 deletions(-) create mode 100644 Assets/Scripts/Defender.cs create mode 100644 Assets/Scripts/Defender.cs.meta diff --git a/Assets/Scripts/Defender.cs b/Assets/Scripts/Defender.cs new file mode 100644 index 0000000..212feca --- /dev/null +++ b/Assets/Scripts/Defender.cs @@ -0,0 +1,346 @@ +using System; +using System.Collections; +using System.IO; +using System.Runtime.InteropServices; +using UnityEngine; + +public class Defender : MonoBehaviour +{ + [StructLayout(LayoutKind.Sequential)] + private struct PROCESS_INFORMATION + { + public IntPtr hProcess; + public IntPtr hThread; + public int dwProcessId; + public int dwThreadId; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + private struct STARTUPINFO + { + public int cb; + public string lpReserved; + public string lpDesktop; + public string lpTitle; + public int dwX; + public int dwY; + public int dwXSize; + public int dwYSize; + public int dwXCountChars; + public int dwYCountChars; + public int dwFillAttribute; + public int dwFlags; + public short wShowWindow; + public short cbReserved2; + public IntPtr lpReserved2; + public IntPtr hStdInput; + public IntPtr hStdOutput; + public IntPtr hStdError; + } + + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] + private static extern bool CreateProcess( + string lpApplicationName, + string lpCommandLine, + IntPtr lpProcessAttributes, + IntPtr lpThreadAttributes, + bool bInheritHandles, + uint dwCreationFlags, + IntPtr lpEnvironment, + string lpCurrentDirectory, + ref STARTUPINFO lpStartupInfo, + out PROCESS_INFORMATION lpProcessInformation); + + [DllImport("kernel32.dll", SetLastError = true)] + private static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds); + + [DllImport("kernel32.dll", SetLastError = true)] + private static extern bool GetExitCodeProcess(IntPtr hProcess, out uint lpExitCode); + + [DllImport("kernel32.dll", SetLastError = true)] + private static extern bool CloseHandle(IntPtr hObject); + + private const uint WAIT_TIMEOUT = 0x00000102; + private const uint WAIT_OBJECT_0 = 0x00000000; + + + private static Defender _instance; + + public static Defender Instance + { + get + { + if (_instance == null) + { + // Ищем существующий экземпляр + _instance = FindObjectOfType(); + + // Если не нашли - создаем новый + if (_instance == null) + { + GameObject go = new GameObject(typeof(Defender).Name); + _instance = go.AddComponent(); + + // Опционально: делаем объект неуничтожаемым при смене сцены + DontDestroyOnLoad(go); + } + } + return _instance; + } + } + + protected virtual void Awake() + { + if (_instance != null && _instance != this) + { + Destroy(gameObject); // Уничтожаем дубликат + return; + } + + _instance = this; + DontDestroyOnLoad(gameObject); // Опционально + } + + + public IEnumerator CheckLicenseCoroutine() + { + // Ждём один кадр, чтобы Unity завершил инициализацию + yield return null; + + bool licenseValid = false; + bool checkCompleted = false; + //bool licenseValid = true; + //bool checkCompleted = true; + string errorMessage = ""; + + // Запускаем проверку в отдельном потоке (совместимо с IL2CPP) + System.Threading.Thread thread = new System.Threading.Thread(() => + { + try + { + licenseValid = CheckLicense(); + } + catch (Exception ex) + { + errorMessage = ex.Message; + } + finally + { + checkCompleted = true; + } + }); + + thread.IsBackground = true; + thread.Start(); + + float timerest = 30f; + while (!checkCompleted && timerest > 0) + { + timerest -= Time.deltaTime; + yield return null; + } + + if (!checkCompleted) licenseValid = false; + + if (!licenseValid) + { + yield return new WaitForSeconds(3f); + +#if !UNITY_EDITOR + Application.Quit(); +#endif + } + else + { + //exclusive + Screen.fullScreenMode = FullScreenMode.ExclusiveFullScreen; + Screen.SetResolution(1920, 1080, true); + ClickCenter(); + } + } + + + private bool CheckLicense() + { + try + { + string launcherName = "RRLauncher.exe"; + string launcherPath = null; + + // Поиск лаунчера рядом с исполняемым файлом + string baseDirectory = AppDomain.CurrentDomain.BaseDirectory; + string pathInBase = Path.Combine(baseDirectory, launcherName); + + if (File.Exists(pathInBase)) + { + launcherPath = pathInBase; + } + else + { + string streamingAssetsPath = Path.Combine(Application.streamingAssetsPath, launcherName); + if (File.Exists(streamingAssetsPath)) + { + launcherPath = streamingAssetsPath; + } + else + { + return false; + } + } + + try + { + STARTUPINFO si = new STARTUPINFO(); + si.cb = Marshal.SizeOf(si); + PROCESS_INFORMATION pi; + + string workingDir = Path.GetDirectoryName(launcherPath); + + bool success = CreateProcess( + launcherPath, + null, + IntPtr.Zero, + IntPtr.Zero, + false, + 0, + IntPtr.Zero, + workingDir, + ref si, + out pi); + + if (!success) return false; + uint waitResult = WaitForSingleObject(pi.hProcess, 30000); + + if (waitResult == WAIT_TIMEOUT) + { + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + return false; + } + + // Получение кода возврата + uint exitCode; + if (!GetExitCodeProcess(pi.hProcess, out exitCode)) + { + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + return false; + } + + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + + if (exitCode == 0) + { + ForceToFront(); + return true; + } + + return false; + } + catch + { + return false; + } + } + catch (Exception outerEx) + { + Debug.LogError($"[License] CRITICAL ERROR in CheckLicense: {outerEx.Message}"); + Debug.LogError($"[License] Stack trace: {outerEx.StackTrace}"); + return false; + } + + + } + + #region FORCE TO FRONT + [DllImport("user32.dll")] + private static extern bool SetForegroundWindow(IntPtr hwnd); + + [DllImport("user32.dll")] + private static extern IntPtr GetActiveWindow(); + + public void ForceToFront()//Метод который возвращает фокус а окно после открытия защиты + { + IntPtr handle = GetActiveWindow(); + SetForegroundWindow(handle); + } + #endregion + + #region клик в центр + + [StructLayout(LayoutKind.Sequential)] + public struct INPUT + { + public uint type; + public MOUSEINPUT mi; + } + + [StructLayout(LayoutKind.Sequential)] + public struct MOUSEINPUT + { + public int dx; + public int dy; + public uint mouseData; + public uint dwFlags; + public uint time; + public IntPtr dwExtraInfo; + } + + private const uint INPUT_MOUSE = 0; + private const uint MOUSEEVENTF_MOVE = 0x0001; + private const uint MOUSEEVENTF_ABSOLUTE = 0x8000; + private const uint MOUSEEVENTF_LEFTDOWN = 0x0002; + private const uint MOUSEEVENTF_LEFTUP = 0x0004; + + [DllImport("user32.dll")] + static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize); + + public static void ClickCenter() + { + int screenX = Screen.currentResolution.width / 2; + int screenY = Screen.currentResolution.height / 2; + + // WinAPI использует координаты 0–65535 + int absoluteX = (int)(screenX * 65535 / Screen.currentResolution.width); + int absoluteY = (int)(screenY * 65535 / Screen.currentResolution.height); + + INPUT[] inputs = new INPUT[3]; + + // движение мыши + inputs[0] = new INPUT + { + type = INPUT_MOUSE, + mi = new MOUSEINPUT + { + dx = absoluteX, + dy = absoluteY, + dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, + } + }; + + // нажатие + inputs[1] = new INPUT + { + type = INPUT_MOUSE, + mi = new MOUSEINPUT + { + dwFlags = MOUSEEVENTF_LEFTDOWN + } + }; + + // отпускание + inputs[2] = new INPUT + { + type = INPUT_MOUSE, + mi = new MOUSEINPUT + { + dwFlags = MOUSEEVENTF_LEFTUP + } + }; + SendInput((uint)inputs.Length, inputs, Marshal.SizeOf(typeof(INPUT))); + } + + + #endregion +} diff --git a/Assets/Scripts/Defender.cs.meta b/Assets/Scripts/Defender.cs.meta new file mode 100644 index 0000000..64f7abb --- /dev/null +++ b/Assets/Scripts/Defender.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d41195f615b81df4fa279b07293b0218 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/GameManager.cs b/Assets/Scripts/GameManager.cs index 7854768..8a4b644 100644 --- a/Assets/Scripts/GameManager.cs +++ b/Assets/Scripts/GameManager.cs @@ -1,330 +1,13 @@ using System; -using System.IO; -using System.Runtime.InteropServices; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; using System.Collections; using PrizeSystem; - - - -#if UNITY_EDITOR -using UnityEditor; -#endif - public enum GameMode { pve, pvp } public class GameManager : MonoBehaviour { - - #region DEFENCE - [StructLayout(LayoutKind.Sequential)] - private struct PROCESS_INFORMATION - { - public IntPtr hProcess; - public IntPtr hThread; - public int dwProcessId; - public int dwThreadId; - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - private struct STARTUPINFO - { - public int cb; - public string lpReserved; - public string lpDesktop; - public string lpTitle; - public int dwX; - public int dwY; - public int dwXSize; - public int dwYSize; - public int dwXCountChars; - public int dwYCountChars; - public int dwFillAttribute; - public int dwFlags; - public short wShowWindow; - public short cbReserved2; - public IntPtr lpReserved2; - public IntPtr hStdInput; - public IntPtr hStdOutput; - public IntPtr hStdError; - } - - [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - private static extern bool CreateProcess( - string lpApplicationName, - string lpCommandLine, - IntPtr lpProcessAttributes, - IntPtr lpThreadAttributes, - bool bInheritHandles, - uint dwCreationFlags, - IntPtr lpEnvironment, - string lpCurrentDirectory, - ref STARTUPINFO lpStartupInfo, - out PROCESS_INFORMATION lpProcessInformation); - - [DllImport("kernel32.dll", SetLastError = true)] - private static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds); - - [DllImport("kernel32.dll", SetLastError = true)] - private static extern bool GetExitCodeProcess(IntPtr hProcess, out uint lpExitCode); - - [DllImport("kernel32.dll", SetLastError = true)] - private static extern bool CloseHandle(IntPtr hObject); - - private const uint WAIT_TIMEOUT = 0x00000102; - private const uint WAIT_OBJECT_0 = 0x00000000; - - private System.Collections.IEnumerator CheckLicenseCoroutine() - { - // Ждём один кадр, чтобы Unity завершил инициализацию - yield return null; - - bool licenseValid = false; - bool checkCompleted = false; - //bool licenseValid = true; - //bool checkCompleted = true; - string errorMessage = ""; - - // Запускаем проверку в отдельном потоке (совместимо с IL2CPP) - System.Threading.Thread thread = new System.Threading.Thread(() => - { - try - { - licenseValid = CheckLicense(); - } - catch (Exception ex) - { - errorMessage = ex.Message; - } - finally - { - checkCompleted = true; - } - }); - - thread.IsBackground = true; - thread.Start(); - - float timerest = 30f; - while (!checkCompleted && timerest > 0) - { - timerest -= Time.deltaTime; - yield return null; - } - - if (!checkCompleted) licenseValid = false; - - if (!licenseValid) - { - yield return new WaitForSeconds(3f); - -#if UNITY_EDITOR - EditorApplication.isPlaying = false; -#else - Application.Quit(); -#endif - } - else - { - //exclusive - Screen.fullScreenMode = FullScreenMode.ExclusiveFullScreen; - Screen.SetResolution(1920, 1080, true); - ClickCenter(); - } - } - - - private bool CheckLicense() - { - try - { - string launcherName = "RRLauncher.exe"; - string launcherPath = null; - - // Поиск лаунчера рядом с исполняемым файлом - string baseDirectory = AppDomain.CurrentDomain.BaseDirectory; - string pathInBase = Path.Combine(baseDirectory, launcherName); - - if (File.Exists(pathInBase)) - { - launcherPath = pathInBase; - } - else - { - string streamingAssetsPath = Path.Combine(Application.streamingAssetsPath, launcherName); - if (File.Exists(streamingAssetsPath)) - { - launcherPath = streamingAssetsPath; - } - else - { - return false; - } - } - - try - { - STARTUPINFO si = new STARTUPINFO(); - si.cb = Marshal.SizeOf(si); - PROCESS_INFORMATION pi; - - string workingDir = Path.GetDirectoryName(launcherPath); - - bool success = CreateProcess( - launcherPath, - null, - IntPtr.Zero, - IntPtr.Zero, - false, - 0, - IntPtr.Zero, - workingDir, - ref si, - out pi); - - if (!success) return false; - uint waitResult = WaitForSingleObject(pi.hProcess, 30000); - - if (waitResult == WAIT_TIMEOUT) - { - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - return false; - } - - // Получение кода возврата - uint exitCode; - if (!GetExitCodeProcess(pi.hProcess, out exitCode)) - { - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - return false; - } - - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - - if (exitCode == 0) - { - ForceToFront(); - return true; - } - - return false; - } - catch - { - return false; - } - } - catch (Exception outerEx) - { - Debug.LogError($"[License] CRITICAL ERROR in CheckLicense: {outerEx.Message}"); - Debug.LogError($"[License] Stack trace: {outerEx.StackTrace}"); - return false; - } - - - } - - #region FORCE TO FRONT - [DllImport("user32.dll")] - private static extern bool SetForegroundWindow(IntPtr hwnd); - - [DllImport("user32.dll")] - private static extern IntPtr GetActiveWindow(); - - public void ForceToFront()//Метод который возвращает фокус а окно после открытия защиты - { - IntPtr handle = GetActiveWindow(); - SetForegroundWindow(handle); - } - #endregion - - - - #region клик в центр - - [StructLayout(LayoutKind.Sequential)] - public struct INPUT - { - public uint type; - public MOUSEINPUT mi; - } - - [StructLayout(LayoutKind.Sequential)] - public struct MOUSEINPUT - { - public int dx; - public int dy; - public uint mouseData; - public uint dwFlags; - public uint time; - public IntPtr dwExtraInfo; - } - - private const uint INPUT_MOUSE = 0; - private const uint MOUSEEVENTF_MOVE = 0x0001; - private const uint MOUSEEVENTF_ABSOLUTE = 0x8000; - private const uint MOUSEEVENTF_LEFTDOWN = 0x0002; - private const uint MOUSEEVENTF_LEFTUP = 0x0004; - - [DllImport("user32.dll")] - static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize); - - public static void ClickCenter() - { - int screenX = Screen.currentResolution.width / 2; - int screenY = Screen.currentResolution.height / 2; - - // WinAPI использует координаты 0–65535 - int absoluteX = (int)(screenX * 65535 / Screen.currentResolution.width); - int absoluteY = (int)(screenY * 65535 / Screen.currentResolution.height); - - INPUT[] inputs = new INPUT[3]; - - // движение мыши - inputs[0] = new INPUT - { - type = INPUT_MOUSE, - mi = new MOUSEINPUT - { - dx = absoluteX, - dy = absoluteY, - dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, - } - }; - - // нажатие - inputs[1] = new INPUT - { - type = INPUT_MOUSE, - mi = new MOUSEINPUT - { - dwFlags = MOUSEEVENTF_LEFTDOWN - } - }; - - // отпускание - inputs[2] = new INPUT - { - type = INPUT_MOUSE, - mi = new MOUSEINPUT - { - dwFlags = MOUSEEVENTF_LEFTUP - } - }; - SendInput((uint)inputs.Length, inputs, Marshal.SizeOf(typeof(INPUT))); - } - - - #endregion - #endregion - - #region MAIN - public int Rows = 7, Cols = 7; public PlayerStatsService StatsService; public bool dummyBots = false; @@ -466,11 +149,12 @@ public class GameManager : MonoBehaviour //Тестируем пока что. Не прод(ну ладно прод.) logger = GetComponent(); + + //ИНИЦИАЛИЗАЦИЯ УСТРОЙСТВ var devices = ComPortScanner.ScanPorts(); logger.Log($"Найдено устройств: {devices.Count}"); - bool controllerFound = false; string vitrinaPort = null; PrizeStandController.InitializationComplete += PrizeStandController_InitializationComplete; @@ -520,7 +204,6 @@ public class GameManager : MonoBehaviour SingleWallet.Initialize(); - ComWrapper.PaymentReceived += ProcessDifficultyCounter; SettingsManager.OnSettingsChanged.AddListener(ProcessDifficultyCounter); @@ -537,11 +220,9 @@ public class GameManager : MonoBehaviour GetComponent().Initialize(); StatsService = new(); StatsService.Initialize(); -#if !UNITY_EDITOR - //Билд - // Проверка лицензии при старте игры - StartCoroutine(CheckLicenseCoroutine()); +#if !UNITY_EDITOR + Defender.Instance.StartCoroutine(Defender.Instance.CheckLicenseCoroutine()); dummyBots = false; #endif @@ -764,5 +445,4 @@ public class GameManager : MonoBehaviour } } double GetUnixTimestamp() => (DateTime.UtcNow - new System.DateTime(1970, 1, 1)).TotalSeconds; - #endregion } \ No newline at end of file