上传文件至 /

This commit is contained in:
2025-10-13 18:17:54 +08:00
parent a5cb390129
commit f7a280029f
13 changed files with 1519 additions and 0 deletions

359
Main.cs Normal file
View File

@@ -0,0 +1,359 @@
using MAI2System;
using MelonLoader;
using System;
using System.Collections;
using System.IO;
using System.Reflection;
using HarmonyLib;
using SinmaiAssist.Attributes;
using SinmaiAssist.Cheat;
using SinmaiAssist.Common;
using SinmaiAssist.Config;
using SinmaiAssist.Fix;
using SinmaiAssist.GUI;
using SinmaiAssist.Utils;
using UnityEngine;
using Path = System.IO.Path;
namespace SinmaiAssist
{
public static partial class BuildInfo
{
public const string Name = "Sinmai-Assist";
public const string Description = "SlimMod Melon Version For Sinmai";
public const string Author = "x";
public const string Company = "Nya~";
public const string Version = "2.0.0";
public const string DownloadLink = null;
}
public class SinmaiAssist : MelonMod
{
private MainGUI _mainGUI;
private static bool _isPatchFailed = false;
private static ConfigManager<MainConfig> _mainConfigManager;
private static ConfigManager<KeyBindConfig> _keyBindConfigManager;
private static WebServer.WebServer _webServer;
public static MainConfig MainConfig;
public static KeyBindConfig KeyBindConfig;
public static string GameID = "Unknown";
public static uint GameVersion = 00000;
public override void OnInitializeMelon()
{
if(!Directory.Exists($"./{BuildInfo.Name}")) Directory.CreateDirectory($"./{BuildInfo.Name}");
// 初始化UnityLogger
if(File.Exists($"./{BuildInfo.Name}/Unity.log")) File.Delete($"{BuildInfo.Name}/Unity.log");
File.WriteAllText($"./{BuildInfo.Name}/Unity.log", "");
Application.logMessageReceived += OnLogMessageReceived;
PrintLogo();
_mainGUI = new MainGUI();
// 加载配置文件
try
{
var keyBindCoverter = new KeyBindConfig.Converter();
_mainConfigManager = new ConfigManager<MainConfig>($"./{BuildInfo.Name}/config.yml");
_keyBindConfigManager = new ConfigManager<KeyBindConfig>($"./{BuildInfo.Name}/keybind.yml", keyBindCoverter);
MainConfig = _mainConfigManager.GetConfig();
KeyBindConfig = _keyBindConfigManager.GetConfig();
DummyLoginPanel.DummyUserId = MainConfig.Common.DummyLogin.DefaultUserId.ToString();
DebugPanel.UnityLogger = MainConfig.Common.UnityLogger.Enable;
MelonLogger.Msg("Config Load Complete.");
}
catch (Exception e)
{
MelonLogger.Error($"Error initializing mod config: \n{e}");
return;
}
// 初始化WebServer
if (MainConfig.ModSetting.WebServer.Enable)
{
_webServer = new WebServer.WebServer(
MainConfig.ModSetting.WebServer.Host,
MainConfig.ModSetting.WebServer.Port,
MainConfig.ModSetting.WebServer.Token
);
_webServer.Start();
}
// 输出设备摄像头列表
File.Delete($"{BuildInfo.Name}/WebCameraList.txt");
WebCamDevice[] devices = WebCamTexture.devices;
string CameraList = "\nConnected Web Cameras:\n";
for (int i = 0; i < devices.Length; i++)
{
WebCamDevice webCamDevice = devices[i];
CameraList = CameraList + "Name: " + webCamDevice.name + "\n";
CameraList += $"ID: {i}\n";
WebCamTexture webCamTexture = new WebCamTexture(webCamDevice.name);
webCamTexture.Play();
CameraList += $"Resolution: {webCamTexture.width}x{webCamTexture.height}\n";
CameraList += $"FPS: {webCamTexture.requestedFPS}\n";
webCamTexture.Stop();
CameraList += "\n";
}
File.AppendAllText($"{BuildInfo.Name}/WebCameraList.txt", CameraList);
try
{
GameID = (string)typeof(ConstParameter).GetField("GameIDStr",
BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy).GetValue(null);
GameVersion = (uint)typeof(ConstParameter).GetField("NowGameVersion",
BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy).GetValue(null);
if (GameVersion < 24000)
{
MelonLogger.Warning($"Using untested version ({GameVersion}) maybe case some unexcepted problems!");
}
}
catch (Exception e)
{
MelonLogger.Error("Failed to get GameIDStr and GameVersion");
MelonLogger.Error(e);
}
MelonLogger.Msg($"GameInfo: {GameID} {GameVersion} ");
// 弃用的神秘判断代码
// var Codes = new List<int> { 83, 68, 71, 66 };
// var str = string.Concat(Codes.Select(code => (char)code));
if (MainConfig.ModSetting.SafeMode)
{
MelonLogger.Warning("Safe mode is enabled, Disable all patch");
return;
}
// 加载Patch
Patch(typeof(HarmonyLibPatch),true);
// DummyLogin
if (MainConfig.Common.DummyLogin.Enable)
{
if (GameID.Equals("SDGB"))
{
Patch(typeof(DummyChimeLogin));
}
else
{
if (File.Exists("DEVICE/aime.txt"))
DummyLoginPanel.DummyLoginCode = File.ReadAllText("DEVICE/aime.txt").Trim();
Patch(typeof(DummyAimeLogin));
}
}
if (MainConfig.Common.CustomCameraId.Enable)
{
if (MainConfig.Common.DummyLogin.Enable)
{
MelonLogger.Warning("DummyLogin enabled, CustomCameraId has been automatically disabled.");
}
else
{
Patch(typeof(CustomCameraId));
}
}
// Common
if (MainConfig.Common.AutoBackupData) Patch(typeof(AutoBackupData));
if (MainConfig.Common.InfinityTimer) Patch(typeof(InfinityTimer));
if (MainConfig.Common.InfinityTimerLegacy) Patch(typeof(InfinityTimerLegacy));
if (MainConfig.Common.DisableBackground) Patch(typeof(DisableBackground));
if (MainConfig.Common.DisableMask) Patch(typeof(DisableMask));
if (MainConfig.Common.SinglePlayer.Enable) Patch(typeof(SinglePlayer));
if (MainConfig.Common.ForceQuickRetry) Patch(typeof(ForceQuickRetry));
if (MainConfig.Common.ForwardATouchRegionToButton) Patch(typeof(ForwardATouchRegionToButton));
// 存在资源加载问题,现已禁用
// if (MainConfig.Common.QuickBoot) Patch(typeof(QuickBoot));
if (MainConfig.Common.BlockCoin) Patch(typeof(BlockCoin));
if (MainConfig.Common.SkipWarningScreen) Patch(typeof(SkipWarningScreen));
if (MainConfig.Common.SkipFade) Patch(typeof(SkipFade));
if (MainConfig.Common.NetworkLogger.Enable) Patch(typeof(NetworkLogger));
if (MainConfig.Common.CustomVersionText.Enable) Patch(typeof(CustomVersionText));
if (MainConfig.Common.IgnoreAnyGameInformation) Patch(typeof(IgnoreAnyGameInformation));
if (MainConfig.Common.ChangeDefaultOption) Patch(typeof(ChangeDefaultOption));
if (MainConfig.Common.ChangeFadeStyle) Patch(typeof(ChangeFadeStyle));
if (MainConfig.Common.ChangeGameSettings.Enable) Patch(typeof(ChangeGameSettings));
//Fix
if (MainConfig.Fix.DisableEnvironmentCheck) Patch(typeof(DisableEnvironmentCheck));
if (MainConfig.Fix.DisableEncryption) Patch(typeof(DisableEncryption));
if (MainConfig.Fix.DisableReboot) Patch(typeof(DisableReboot));
if (MainConfig.Fix.DisableIniClear) Patch(typeof(DisableIniClear));
if (MainConfig.Fix.FixDebugInput) Patch(typeof(FixDebugInput));
if (MainConfig.Fix.FixCheckAuth) Patch(typeof(FixCheckAuth));
if (MainConfig.Fix.ForceAsServer) Patch(typeof(ForceAsServer));
if (MainConfig.Fix.SkipCakeHashCheck) Patch(typeof(SkipCakeHashCheck));
if (MainConfig.Fix.SkipSpecialNumCheck) Patch(typeof(SkipSpecialNumCheck));
if (MainConfig.Fix.SkipVersionCheck) Patch(typeof(SkipVersionCheck));
if (MainConfig.Fix.RestoreCertificateValidation) Patch(typeof(RestoreCertificateValidation));
if (MainConfig.Fix.RewriteNoteJudgeTiming.Enable) Patch(typeof(RewriteNoteJudgeTiming));
//Cheat
if (MainConfig.Cheat.AutoPlay) Patch(typeof(AutoPlay));
if (MainConfig.Cheat.FastSkip) Patch(typeof(FastSkip));
if (MainConfig.Cheat.ChartController) Patch(typeof(ChartController));
if (MainConfig.Cheat.AllCollection) Patch(typeof(AllCollection));
if (MainConfig.Cheat.UnlockMusic) Patch(typeof(UnlockMusic));
if (MainConfig.Cheat.UnlockMaster) Patch(typeof(UnlockMaster));
if (MainConfig.Cheat.UnlockUtage.Enable) Patch(typeof(UnlockUtage));
if (MainConfig.Cheat.UnlockEvent) Patch(typeof(UnlockEvent));
if (MainConfig.Cheat.ResetLoginBonusRecord) Patch(typeof(ResetLoginBonusRecord));
if (MainConfig.Cheat.ForceCurrentIsBest) Patch(typeof(ForceCurrentIsBest));
if (MainConfig.Cheat.SetAllCharacterAsSameAndLock) Patch(typeof(SetAllCharacterAsSameAndLock));
if (MainConfig.Cheat.RewriteLoginBonusStamp.Enable) Patch(typeof(RewriteLoginBonusStamp));
// 默认加载项
Patch(typeof(PrintUserData));
Patch(typeof(InputManager));
Patch(typeof(GameMessageManager));
if(_isPatchFailed) PatchFailedWarn();
MelonLogger.Msg("Loading completed");
}
public override void OnApplicationQuit()
{
if (MainConfig.ModSetting.WebServer.Enable && _webServer.IsRunning()) _webServer.Stop();
}
public override void OnGUI()
{
_mainGUI.OnGUI();
if (MainConfig.Common.ShowFPS) ShowFPS.OnGUI();
if (MainConfig.ModSetting.ShowInfo) ShowVersionInfo.OnGUI();
}
private void OnLogMessageReceived(string condition, string stackTrace, LogType type)
{
string logString = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] [{type}] {condition}\n{stackTrace}";
if (MainConfig.Common.UnityLogger.Enable) File.AppendAllText(Path.Combine($"{BuildInfo.Name}/Unity.log"),logString + "\n");
if (MainConfig.Common.UnityLogger.Enable && MainConfig.Common.UnityLogger.PrintToConsole)
{
switch (type)
{
case LogType.Error:
case LogType.Exception:
MelonLogger.Error($"[UnityLogger] [{type}]: {condition}\n{stackTrace}");
break;
case LogType.Warning:
MelonLogger.Warning($"[UnityLogger] [{type}]: {condition}\n{stackTrace}");
break;
case LogType.Assert:
case LogType.Log:
default:
MelonLogger.Msg($"[UnityLogger] [{type}]: {condition}\n{stackTrace}");
break;
}
}
}
private static bool Patch(Type type, bool noLoggerPrint = false)
{
try
{
var enableGameVersion = type.GetCustomAttribute<EnableGameVersionAttribute>();
if (enableGameVersion != null && !enableGameVersion.ShouldEnable())
{
MelonLogger.Warning(
$"Patch: {type} skipped ,Game version need Min {enableGameVersion.MinGameVersion} Max {enableGameVersion.MaxGameVersion}");
return false;
}
if (!noLoggerPrint) MelonLogger.Msg($"> Patch: {type}");
HarmonyLib.Harmony.CreateAndPatchAll(type);
return true;
}
catch (Exception e)
{
MelonLogger.Error($"Patch: {type} failed.");
MelonLogger.Error(e.Message);
MelonLogger.Error(e.Source);
MelonLogger.Error(e.TargetSite);
MelonLogger.Error(e.InnerException);
MelonLogger.Error(e.StackTrace);
_isPatchFailed = true;
return false;
}
}
private static void PrintLogo()
{
MelonLogger.Msg("\n" +
"\r\n _____ _ __ ___ _ ___ _ __ " +
"\r\n / ___/(_)___ / |/ /___ _(_) / | __________(_)____/ /_" +
"\r\n \\__ \\/ / __ \\/ /|_/ / __ `/ /_____/ /| | / ___/ ___/ / ___/ __/" +
"\r\n ___/ / / / / / / / / /_/ / /_____/ ___ |(__ |__ ) (__ ) /_ " +
"\r\n/____/_/_/ /_/_/ /_/\\__,_/_/ /_/ |_/____/____/_/____/\\__/ " +
"\r\n " +
"\r\n=================================================================" +
$"\r\n Version: {BuildInfo.Version} ({BuildInfo.CommitHash}) Build Date: {BuildInfo.BuildDate}" +
$"\r\n Author: {BuildInfo.Author}");
MelonLogger.Warning("\n" +
"\r\n=================================================================" +
"\r\n这是一个作弊Mod后果自负,Mod仅限测试使用禁止用于其他操作!" +
"\r\nThis is a cheat mod. Use at your own risk!" +
"\r\n这是一个免费的开源Mod项目禁止倒卖!" +
"\r\nThis is a free and open-source mod. Resale is strictly prohibited." +
"\r\n如果你花了钱买了这个Mod那你很愚蠢。" +
"\r\nIf you paid for this mod, you are stupid." +
"\r\n================================================================="
);
}
private static void PatchFailedWarn()
{
MelonLogger.Warning("\r\n=================================================================" +
"\r\nFailed to patch some methods." +
"\r\nPlease ensure that you are using an unmodified version of Assembly-CSharp.dll with a version greater than 1.40.0," +
"\r\nas modifications or lower versions can cause function mismatches, preventing the required functions from being found." +
"\r\nCheck for conflicting mods, or enabled incompatible options." +
"\r\nIf you believe this is an error, please report the issue to the mod author." +
"\r\n=================================================================");
}
}
public class HarmonyLibPatch
{
[HarmonyPostfix]
[HarmonyPatch("HarmonyLib.PatchTools", "GetPatchMethod")]
public static void GetPatchMethod(ref MethodInfo __result)
{
if (__result != null)
{
var enableGameVersion = __result.GetCustomAttribute<EnableGameVersionAttribute>();
if (enableGameVersion != null && !enableGameVersion.ShouldEnable())
{
#if DEBUG
MelonLogger.Warning($" Patch: {__result.ReflectedType}.{__result.Name} skipped, Game version need Min {enableGameVersion.MinGameVersion} Max {enableGameVersion.MaxGameVersion}");
#endif
__result = null;
}
}
}
[HarmonyPostfix]
[HarmonyPatch("HarmonyLib.PatchTools", "GetPatchMethods")]
public static void GetPatchMethods(ref IList __result)
{
for (int i = 0; i < __result.Count; i++)
{
var harmonyMethod = Traverse.Create(__result[i]).Field("info").GetValue() as HarmonyMethod;
var method = harmonyMethod.method;
var enableGameVersion = method.GetCustomAttribute<EnableGameVersionAttribute>();
if (enableGameVersion != null && !enableGameVersion.ShouldEnable())
{
#if DEBUG
MelonLogger.Warning($" Patch: {method.ReflectedType}.{method.Name} skipped, Game version need Min {enableGameVersion.MinGameVersion} Max {enableGameVersion.MaxGameVersion}");
#endif
__result.RemoveAt(i);
i--;
}
}
}
}
}