Files
Sinmai-Assist/Cheat/FastSkip.cs
2025-10-13 18:18:32 +08:00

290 lines
13 KiB
C#

using HarmonyLib;
using MAI2.Util;
using Manager;
using Manager.UserDatas;
using MelonLoader;
using Monitor;
using Process;
using System;
using System.Reflection;
using UnityEngine;
namespace SinmaiAssist.Cheat;
internal class FastSkip
{
private enum GameSequence
{
Init,
Sync,
Start,
StartWait,
Play,
PlayEnd,
Result,
ResultEnd,
FinalWait,
Release
}
public static bool CustomSkip = false;
public static bool SkipButton = false;
public static bool Force1Miss = false;
public static int CustomAchivement = 0;
private static bool _isSkip = false;
private static bool _Miss = false;
[HarmonyPostfix]
[HarmonyPatch(typeof(GameProcess), "OnUpdate")]
public static void Skip(GameProcess __instance)
{
try
{
System.Type processBaseType = typeof(GameProcess).BaseType;
GameSequence _sequence = (GameSequence)typeof(GameProcess).GetField("_sequence", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance);
var UpdateSubbMonitorDataMethod = typeof(GameProcess).GetMethod("UpdateSubbMonitorData", BindingFlags.NonPublic | BindingFlags.Instance);
var SetReleaseMethod = typeof(GameProcess).GetMethod("SetRelease", BindingFlags.NonPublic | BindingFlags.Instance);
var IsPartyPlayMethod = typeof(GameProcess).GetMethod("IsPartyPlay", BindingFlags.NonPublic | BindingFlags.Instance);
var containerField = processBaseType.GetField("container", BindingFlags.NonPublic | BindingFlags.Instance);
ProcessDataContainer container = (ProcessDataContainer)containerField.GetValue(__instance);
if (_sequence >= GameSequence.Play && _sequence < GameSequence.Release && !GameManager.IsNoteCheckMode)
{
_isSkip = false;
if (DebugInput.GetKeyDown(KeyCode.Space) || SkipButton)
{
_isSkip = true;
GameMonitor[] monitors = (GameMonitor[])typeof(GameProcess).GetField("_monitors", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance);
if (CustomSkip)
{
for (int i = 0; i < monitors.Length; i++)
{
monitors[i].Seek(0);
}
NotesManager.StartPlay(0);
NotesManager.Pause(true);
bool IsPartyPlay = (bool)IsPartyPlayMethod.Invoke(__instance, null);
Singleton<GamePlayManager>.Instance.Initialize(IsPartyPlay);
uint maxCombo = 0u;
for (int i = 0; i < monitors.Length; i++)
{
if (Singleton<UserDataManager>.Instance.GetUserData(i).IsEntry)
{
monitors[i].ForceAchivement(CustomAchivement, 0);
maxCombo += Singleton<GamePlayManager>.Instance.GetGameScore(i).MaxCombo;
}
}
GameScoreList gameScore = Singleton<GamePlayManager>.Instance.GetGameScore(2);
if (gameScore.IsEnable && !gameScore.IsHuman())
{
for (int i = 0; i < 2; i++)
{
if (Singleton<UserDataManager>.Instance.GetUserData(i).IsEntry && GameManager.SelectGhostID[i] != GhostManager.GhostTarget.End)
{
UserGhost ghostToEnum = Singleton<GhostManager>.Instance.GetGhostToEnum(GameManager.SelectGhostID[i]);
gameScore.SetForceAchivement_Battle((float)GameManager.ConvAchiveIntToDecimal(ghostToEnum.Achievement));
break;
}
}
}
for (int i = 0; i < monitors.Length; i++)
{
if (Singleton<UserDataManager>.Instance.GetUserData(i).IsEntry)
{
Singleton<GamePlayManager>.Instance.GetGameScore(i).SetChain(maxCombo);
}
}
}
if (_isSkip)
{
for (int i = 0; i < monitors.Length; i++)
{
if (Singleton<UserDataManager>.Instance.GetUserData(i).IsEntry)
{
UpdateSubbMonitorDataMethod.Invoke(__instance, new object[] { i });
Message[] message = (Message[])typeof(GameProcess).GetField("_message", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance);
container.processManager.SendMessage(message[i]);
Singleton<GamePlayManager>.Instance.SetSyncResult(i);
}
}
SetReleaseMethod.Invoke(__instance, null);
SkipButton = false;
}
}
}
}
catch (Exception e)
{
MelonLogger.Error(e);
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(GameScoreList), "SetForceAchivement")]
public static bool SetForceAchivement(int achivement, int dxscore, GameScoreList __instance)
{
decimal num1 = achivement;
if (num1 >= 100.0m && num1 <= 100.4m) num1 = 100.3m;
long num2;
long num3;
if (num1 > 100.0m)
{
num2 = (long)((decimal)__instance.ScoreTotal._allPerfectScore * (num1 - 1.0m) * 0.01m);
num3 = __instance.ScoreTotal._breakBonusScore;
}
else
{
num2 = (long)((decimal)__instance.ScoreTotal._allPerfectScore * (num1 * 0.99m * 0.01m));
num3 = (long)((decimal)__instance.ScoreTotal._breakBonusScore * num1 * 0.01m);
}
NoteJudge.ETiming[] NoteArray = new NoteJudge.ETiming[7]
{
NoteJudge.ETiming.Critical,
NoteJudge.ETiming.FastGreat,
NoteJudge.ETiming.FastGreat2nd,
NoteJudge.ETiming.LateGreat,
NoteJudge.ETiming.LateGreat2nd,
NoteJudge.ETiming.LateGreat3rd,
NoteJudge.ETiming.LateGood
};
int monitorIndex = (int)typeof(GameScoreList).GetField("_monitorIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance);
NoteDataList noteList = NotesManager.Instance(monitorIndex).getReader().GetNoteList();
foreach (NoteData item in noteList)
{
if (!item.type.isBreakScore())
{
continue;
}
bool flag = false;
NoteJudge.ETiming[] array2 = NoteArray;
foreach (NoteJudge.ETiming eTiming in array2)
{
NoteScore.EScoreType eScoreType = GamePlayManager.NoteType2ScoreType(item.type.getEnum());
if (0m <= (decimal)(num2 - NoteScore.GetJudgeScore(eTiming, NoteScore.EScoreType.Break)) && 0m <= (decimal)(num3 - NoteScore.GetJudgeScore(eTiming, NoteScore.EScoreType.BreakBonus)))
{
num2 -= NoteScore.GetJudgeScore(eTiming, eScoreType);
num3 -= NoteScore.GetJudgeScore(eTiming, NoteScore.EScoreType.BreakBonus);
__instance.SetResult(item.indexNote, eScoreType, eTiming);
flag = true;
break;
}
}
if (!flag)
{
__instance.SetResult(item.indexNote, NoteScore.EScoreType.Break, NoteJudge.ETiming.TooFast);
_Miss = true;
}
}
int num4 = 0;
int num5 = 0;
long num6 = 0L;
for (int j = 0; j < NoteArray.Length; j++)
{
long num7 = num2;
long num8 = 0L;
num8 += __instance.ScoreTotal.GetTapNum() * NoteScore.GetJudgeScore(NoteArray[j]);
num8 += __instance.ScoreTotal.GetHoldNum() * NoteScore.GetJudgeScore(NoteArray[j], NoteScore.EScoreType.Hold);
num8 += __instance.ScoreTotal.GetSlideNum() * NoteScore.GetJudgeScore(NoteArray[j], NoteScore.EScoreType.Slide);
num8 += __instance.ScoreTotal.GetTouchNum() * NoteScore.GetJudgeScore(NoteArray[j], NoteScore.EScoreType.Touch);
if (num8 <= num7)
{
num6 = num7 - num8;
num5 = ((num4 != 0) ? (num4 - 1) : 0);
break;
}
num4++;
}
if (num4 >= NoteArray.Length)
{
num4 = NoteArray.Length - 1;
}
foreach (NoteData item2 in noteList)
{
if (item2.type.isSlideScore())
{
NoteScore.EScoreType eScoreType2 = GamePlayManager.NoteType2ScoreType(item2.type.getEnum());
NoteJudge.ETiming eTiming2 = NoteArray[num4];
NoteJudge.ETiming eTiming3 = NoteArray[num5];
if (0m <= (decimal)num6 && 0m <= (decimal)(num2 - NoteScore.GetJudgeScore(eTiming3, eScoreType2)))
{
num6 -= NoteScore.GetJudgeScore(eTiming3, eScoreType2) - NoteScore.GetJudgeScore(eTiming2, eScoreType2);
num2 -= NoteScore.GetJudgeScore(eTiming3, eScoreType2);
__instance.SetResult(item2.indexNote, eScoreType2, eTiming3);
}
else if (0m <= (decimal)(num2 - NoteScore.GetJudgeScore(eTiming2, eScoreType2)))
{
num2 -= NoteScore.GetJudgeScore(eTiming2, eScoreType2);
__instance.SetResult(item2.indexNote, eScoreType2, eTiming2);
}
else
{
__instance.SetResult(item2.indexNote, eScoreType2, NoteJudge.ETiming.TooFast);
_Miss = true;
}
}
}
foreach (NoteData item3 in noteList)
{
if (item3.type.isHoldScore())
{
NoteScore.EScoreType eScoreType3 = GamePlayManager.NoteType2ScoreType(item3.type.getEnum());
NoteJudge.ETiming eTiming4 = NoteArray[num4];
NoteJudge.ETiming eTiming5 = NoteArray[num5];
if (0m <= (decimal)num6 && 0m <= (decimal)(num2 - NoteScore.GetJudgeScore(eTiming5, eScoreType3)))
{
num6 -= NoteScore.GetJudgeScore(eTiming5, eScoreType3) - NoteScore.GetJudgeScore(eTiming4, eScoreType3);
num2 -= NoteScore.GetJudgeScore(eTiming5, eScoreType3);
__instance.SetResult(item3.indexNote, eScoreType3, eTiming5);
}
else if (0m <= (decimal)(num2 - NoteScore.GetJudgeScore(eTiming4, eScoreType3)))
{
num2 -= NoteScore.GetJudgeScore(eTiming4, eScoreType3);
__instance.SetResult(item3.indexNote, eScoreType3, eTiming4);
}
else
{
__instance.SetResult(item3.indexNote, eScoreType3, NoteJudge.ETiming.TooFast);
_Miss = true;
}
}
}
foreach (NoteData item4 in noteList)
{
if (item4.type.isTapScore())
{
NoteScore.EScoreType eScoreType4 = GamePlayManager.NoteType2ScoreType(item4.type.getEnum());
NoteJudge.ETiming eTiming6 = NoteArray[num4];
NoteJudge.ETiming eTiming7 = NoteArray[num5];
if (Force1Miss && !_Miss)
{
__instance.SetResult(item4.indexNote, eScoreType4, NoteJudge.ETiming.TooFast);
_Miss = true;
continue;
}
if (0m < (decimal)num6 && 0m <= (decimal)(num2 - NoteScore.GetJudgeScore(eTiming7, eScoreType4)))
{
num6 -= NoteScore.GetJudgeScore(eTiming7, eScoreType4) - NoteScore.GetJudgeScore(eTiming6, eScoreType4);
num2 -= NoteScore.GetJudgeScore(eTiming7, eScoreType4);
__instance.SetResult(item4.indexNote, eScoreType4, eTiming7);
}
else if (0m <= (decimal)(num2 - NoteScore.GetJudgeScore(eTiming6, eScoreType4)))
{
num2 -= NoteScore.GetJudgeScore(eTiming6, eScoreType4);
__instance.SetResult(item4.indexNote, eScoreType4, eTiming6);
}
else if (0m < (decimal)num2)
{
num2 -= NoteScore.GetJudgeScore(eTiming6, eScoreType4);
__instance.SetResult(item4.indexNote, eScoreType4, eTiming6);
}
else
{
__instance.SetResult(item4.indexNote, eScoreType4, NoteJudge.ETiming.TooFast);
_Miss = true;
}
}
}
return false;
}
}