sega 8a6d23b77d Реорг Scripts
Разделено на 4 модуля
- Menu
- Gameplay
- Settings
- Common
2026-07-15 10:49:55 +03:00

347 lines
9.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 = FindAnyObjectByType<Defender>();
// Если не нашли - создаем новый
if (_instance == null)
{
GameObject go = new GameObject(typeof(Defender).Name);
_instance = go.AddComponent<Defender>();
// Опционально: делаем объект неуничтожаемым при смене сцены
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
}